├── .gitignore ├── data ├── import_data.txt └── gen_data.py ├── utils └── fake_libc_include │ ├── aio.h │ ├── ar.h │ ├── argz.h │ ├── cpio.h │ ├── envz.h │ ├── err.h │ ├── fenv.h │ ├── ftw.h │ ├── glob.h │ ├── grp.h │ ├── math.h │ ├── ndbm.h │ ├── poll.h │ ├── pwd.h │ ├── tar.h │ ├── time.h │ ├── utmp.h │ ├── zlib.h │ ├── _ansi.h │ ├── _syslist.h │ ├── alloca.h │ ├── arpa │ └── inet.h │ ├── assert.h │ ├── complex.h │ ├── ctype.h │ ├── dirent.h │ ├── dlfcn.h │ ├── endian.h │ ├── errno.h │ ├── fastmath.h │ ├── fcntl.h │ ├── features.h │ ├── float.h │ ├── fmtmsg.h │ ├── fnmatch.h │ ├── getopt.h │ ├── iconv.h │ ├── ieeefp.h │ ├── inttypes.h │ ├── iso646.h │ ├── langinfo.h │ ├── libgen.h │ ├── libintl.h │ ├── limits.h │ ├── locale.h │ ├── malloc.h │ ├── monetary.h │ ├── mqueue.h │ ├── net │ └── if.h │ ├── netdb.h │ ├── newlib.h │ ├── nl_types.h │ ├── paths.h │ ├── process.h │ ├── pthread.h │ ├── reent.h │ ├── regdef.h │ ├── regex.h │ ├── sched.h │ ├── search.h │ ├── semaphore.h │ ├── setjmp.h │ ├── signal.h │ ├── spawn.h │ ├── stdarg.h │ ├── stdbool.h │ ├── stddef.h │ ├── stdint.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ ├── strings.h │ ├── stropts.h │ ├── sys │ ├── ioctl.h │ ├── ipc.h │ ├── mman.h │ ├── msg.h │ ├── poll.h │ ├── sem.h │ ├── shm.h │ ├── stat.h │ ├── time.h │ ├── times.h │ ├── types.h │ ├── uio.h │ ├── un.h │ ├── wait.h │ ├── resource.h │ ├── select.h │ ├── socket.h │ ├── statvfs.h │ ├── sysctl.h │ └── utsname.h │ ├── syslog.h │ ├── termios.h │ ├── tgmath.h │ ├── trace.h │ ├── ulimit.h │ ├── unctrl.h │ ├── unistd.h │ ├── utime.h │ ├── utmpx.h │ ├── wchar.h │ ├── wctype.h │ ├── wordexp.h │ ├── xcb │ └── xcb.h │ ├── linux │ ├── socket.h │ └── version.h │ ├── netinet │ ├── in.h │ └── tcp.h │ ├── openssl │ ├── err.h │ ├── evp.h │ ├── hmac.h │ ├── ssl.h │ └── x509v3.h │ ├── asm-generic │ └── int-ll64.h │ ├── mir_toolkit │ └── client_types.h │ ├── X11 │ ├── Xlib.h │ ├── _X11_fake_defines.h │ └── _X11_fake_typedefs.h │ ├── _fake_typedefs.h │ └── _fake_defines.h ├── img ├── select_031544426682.pdf ├── general_025129180938.pdf └── general_043840904339.pdf ├── testing ├── definitions.py ├── gen_query.py ├── make_plot.py └── measure_overhead.py ├── versions ├── sqlite_disp │ ├── jitsrc │ │ └── jitCommons.h │ └── Makefile ├── sqlite_jit │ ├── jitsrc │ │ ├── jitCommons.h │ │ ├── emit.h │ │ ├── jitUtils.c │ │ ├── jitUtils.h │ │ ├── txtBuf.h │ │ ├── jit.h │ │ ├── jit.c │ │ ├── txtBuf.c │ │ ├── opimpl.h │ │ └── jitted_func.h │ └── Makefile └── sqlite_jit_spec │ ├── jitsrc │ ├── jitCommons.h │ ├── emit.h │ ├── jitUtils.c │ ├── jitUtils.h │ ├── txtBuf.h │ ├── jit.h │ ├── jit.c │ ├── txtBuf.c │ ├── opimpl.h │ └── jitted_func.h │ └── Makefile ├── generator ├── cfiles │ ├── emitTemplate.h │ └── emitTemplate.c ├── gen_util.py ├── vdbe_opcode.py ├── construct_emit.py └── template_gen.py ├── vars.mk ├── README.md ├── Makefile ├── src ├── vxworks.h ├── msvc.h ├── os_setup.h ├── mem0.c ├── os_win.h ├── mutex.h ├── hwtime.h ├── fault.c ├── os_common.h ├── hash.h ├── random.c ├── legacy.c ├── walker.c ├── wal.h ├── table.c ├── mutex_noop.c ├── sqliteLimit.h ├── pcache.h ├── vdbetrace.c ├── parse.h └── hash.c ├── jit.mk └── results ├── general_043840904339 ├── general_025129180938 └── select_031544426682 /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .* 3 | !/.gitignore 4 | -------------------------------------------------------------------------------- /data/import_data.txt: -------------------------------------------------------------------------------- 1 | CREATE TABLE test (i INTEGER); 2 | .import data/data.txt test 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/aio.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/ar.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/argz.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/cpio.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/envz.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/err.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/fenv.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/ftw.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/glob.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/grp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/math.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/ndbm.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/poll.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/pwd.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/tar.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/time.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/utmp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/zlib.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/_ansi.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/_syslist.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/alloca.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/arpa/inet.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/assert.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/complex.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/ctype.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/dirent.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/dlfcn.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/endian.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/errno.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/fastmath.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/fcntl.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/features.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/float.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/fmtmsg.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/fnmatch.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/getopt.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/iconv.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/ieeefp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/inttypes.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/iso646.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/langinfo.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/libgen.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/libintl.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/limits.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/locale.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/malloc.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/monetary.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/mqueue.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/net/if.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/netdb.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/newlib.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/nl_types.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/paths.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/process.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/pthread.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/reent.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/regdef.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/regex.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sched.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/search.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/semaphore.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/setjmp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/signal.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/spawn.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stdarg.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stdbool.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stddef.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stdint.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stdio.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stdlib.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/string.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/strings.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/stropts.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/ioctl.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/ipc.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/mman.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/msg.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/poll.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/sem.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/shm.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/stat.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/time.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/times.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/types.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/uio.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/un.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/wait.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/syslog.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/termios.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/tgmath.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/trace.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/ulimit.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/unctrl.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/unistd.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/utime.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/utmpx.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/wchar.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/wctype.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/wordexp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/xcb/xcb.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/linux/socket.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/linux/version.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/netinet/in.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/netinet/tcp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/openssl/err.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/openssl/evp.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/openssl/hmac.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/openssl/ssl.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/openssl/x509v3.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/resource.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/select.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/socket.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/statvfs.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/sysctl.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/sys/utsname.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /img/select_031544426682.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexKashuba/SQLite_JIT/HEAD/img/select_031544426682.pdf -------------------------------------------------------------------------------- /testing/definitions.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | PROJECT_DIR = str(Path(__file__).resolve().parent.parent) -------------------------------------------------------------------------------- /utils/fake_libc_include/asm-generic/int-ll64.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /utils/fake_libc_include/mir_toolkit/client_types.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | -------------------------------------------------------------------------------- /img/general_025129180938.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexKashuba/SQLite_JIT/HEAD/img/general_025129180938.pdf -------------------------------------------------------------------------------- /img/general_043840904339.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexKashuba/SQLite_JIT/HEAD/img/general_043840904339.pdf -------------------------------------------------------------------------------- /utils/fake_libc_include/X11/Xlib.h: -------------------------------------------------------------------------------- 1 | #include "_fake_defines.h" 2 | #include "_fake_typedefs.h" 3 | #include "_X11_fake_defines.h" 4 | #include "_X11_fake_typedefs.h" 5 | -------------------------------------------------------------------------------- /data/gen_data.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | max_val = np.iinfo(np.int32).max 3 | data = np.random.randint(0, max_val, size=10**8) 4 | np.savetxt('data/data.txt', data, fmt='%d') 5 | 6 | -------------------------------------------------------------------------------- /versions/sqlite_disp/jitsrc/jitCommons.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_COMMONS_H 2 | #define JIT_COMMONS_H 3 | 4 | typedef enum {OK, ERROR, NO_MEM, ROW, DEOPT} jitRc; 5 | typedef jitRc (*pJitFunc)(Vdbe*); 6 | 7 | #endif /* JIT_COMMONS_H */ -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/jitCommons.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_COMMONS_H 2 | #define JIT_COMMONS_H 3 | 4 | typedef enum {OK, ERROR, NO_MEM, ROW, DEOPT} jitRc; 5 | typedef jitRc (*pJitFunc)(Vdbe*); 6 | 7 | #endif /* JIT_COMMONS_H */ -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/jitCommons.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_COMMONS_H 2 | #define JIT_COMMONS_H 3 | 4 | typedef enum {OK, ERROR, NO_MEM, ROW, DEOPT} jitRc; 5 | typedef jitRc (*pJitFunc)(Vdbe*); 6 | 7 | #endif /* JIT_COMMONS_H */ -------------------------------------------------------------------------------- /generator/cfiles/emitTemplate.h: -------------------------------------------------------------------------------- 1 | #ifndef EMIT_H 2 | #define EMIT_H 3 | #include "txtBuf.h" 4 | #include "jit.h" 5 | 6 | #include "sqliteInt.h" 7 | #include "vdbeInt.h" 8 | 9 | TxtBuf *emitTxt(Vdbe *p, int start_pos, int end_pos); 10 | 11 | #endif /* EMIT_H */ 12 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/emit.h: -------------------------------------------------------------------------------- 1 | #ifndef EMIT_H 2 | #define EMIT_H 3 | #include "txtBuf.h" 4 | #include "jit.h" 5 | #include "opcodeTemplates.h" 6 | 7 | #include "sqliteInt.h" 8 | #include "vdbeInt.h" 9 | 10 | 11 | TxtBuf *emitTxt(Vdbe *p, int start_pos, int end_pos); 12 | #endif /* EMIT_H */ 13 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/emit.h: -------------------------------------------------------------------------------- 1 | #ifndef EMIT_H 2 | #define EMIT_H 3 | #include "txtBuf.h" 4 | #include "jit.h" 5 | #include "opcodeTemplates.h" 6 | 7 | #include "sqliteInt.h" 8 | #include "vdbeInt.h" 9 | 10 | 11 | TxtBuf *emitTxt(Vdbe *p, int start_pos, int end_pos); 12 | #endif /* EMIT_H */ 13 | -------------------------------------------------------------------------------- /utils/fake_libc_include/X11/_X11_fake_defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _X11_FAKE_DEFINES_H 2 | #define _X11_FAKE_DEFINES_H 3 | 4 | #define Atom CARD32 5 | #define Bool int 6 | #define KeySym CARD32 7 | #define Pixmap CARD32 8 | #define Time CARD32 9 | #define _XFUNCPROTOBEGIN 10 | #define _XFUNCPROTOEND 11 | #define _Xconst const 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/jitUtils.c: -------------------------------------------------------------------------------- 1 | #include "jitUtils.h" 2 | 3 | #ifdef JITDEBUG 4 | int allocs = 0; 5 | void printAllocs(){ 6 | printf("Outstanding smallocs: %d\n", allocs); 7 | } 8 | #endif 9 | 10 | void *smalloc(size_t size){ 11 | void *buf = malloc(size); 12 | if (!buf) 13 | err(1, "No memory"); 14 | 15 | #ifdef JITDEBUG 16 | allocs++; 17 | #endif 18 | 19 | return buf; 20 | } -------------------------------------------------------------------------------- /versions/sqlite_disp/Makefile: -------------------------------------------------------------------------------- 1 | include ../../jit.mk 2 | 3 | TMP_DIRS = $(VOBJ_DIR) 4 | JITSRC := $(shell find $(JIT_DIR) -name '*.c') 5 | VOBJS = $(JITSRC:$(JIT_DIR)/%.c=$(VOBJ_DIR)/%.lo) 6 | 7 | all: $(TMP_DIRS) sqlite_disp 8 | 9 | clean: 10 | rm -f $(BIN_DIR)/sqlite_disp $(JITOBJS) $(VOBJS) 11 | 12 | sqlite_disp: $(SHAREDOBJS) $(VOBJS) 13 | $(CC) $(LDFLAGS) $(SHAREDOBJS) $(VOBJS) $(SYSTEM_LIBS) -o $(BIN_DIR)/$@ 14 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/jitUtils.c: -------------------------------------------------------------------------------- 1 | #include "jitUtils.h" 2 | 3 | #ifdef JITDEBUG 4 | int allocs = 0; 5 | void printAllocs(){ 6 | printf("Outstanding smallocs: %d\n", allocs); 7 | } 8 | #endif 9 | 10 | void *smalloc(size_t size){ 11 | void *buf = malloc(size); 12 | if (!buf) 13 | err(1, "No memory"); 14 | 15 | #ifdef JITDEBUG 16 | allocs++; 17 | #endif 18 | 19 | return buf; 20 | } -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/jitUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_UTILS_H 2 | #define JIT_UTILS_H 3 | #include 4 | #include 5 | #include 6 | 7 | void *smalloc(size_t size); 8 | 9 | #ifdef JITDEBUG 10 | extern int allocs; 11 | void printAllocs(); 12 | #include 13 | #define sfree(ptr) do{allocs--; free(ptr);}while(0); 14 | #else 15 | #define sfree(ptr) free(ptr); 16 | #endif 17 | 18 | #endif /* JIT_UTILS_H */ -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/jitUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_UTILS_H 2 | #define JIT_UTILS_H 3 | #include 4 | #include 5 | #include 6 | 7 | void *smalloc(size_t size); 8 | 9 | #ifdef JITDEBUG 10 | extern int allocs; 11 | void printAllocs(); 12 | #include 13 | #define sfree(ptr) do{allocs--; free(ptr);}while(0); 14 | #else 15 | #define sfree(ptr) free(ptr); 16 | #endif 17 | 18 | #endif /* JIT_UTILS_H */ -------------------------------------------------------------------------------- /versions/sqlite_jit/Makefile: -------------------------------------------------------------------------------- 1 | include ../../jit.mk 2 | 3 | all: $(TMP_DIRS) sqlite sqlite_jit libsqlite.so 4 | 5 | clean: 6 | rm -f $(BIN_DIR)/sqlite_jit $(BIN_DIR)/sqlite $(JITOBJS) $(VOBJS) 7 | 8 | sqlite: $(GEN_FILES) $(SHAREDOBJS) $(VOBJS) 9 | $(CC) $(LDFLAGS) $(SHAREDOBJS) $(VOBJS) $(SYSTEM_LIBS) -o $(BIN_DIR)/$@ 10 | 11 | sqlite_jit: $(GEN_FILES) $(SHAREDOBJS) $(JITOBJS) 12 | $(CC) $(LDFLAGS) $(SHAREDOBJS) $(JITOBJS) $(SYSTEM_LIBS) -o $(BIN_DIR)/$@ 13 | 14 | -------------------------------------------------------------------------------- /vars.mk: -------------------------------------------------------------------------------- 1 | VARS_MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | PROJECT_ROOT := $(realpath $(dir $(VARS_MKFILE_PATH))) 3 | 4 | GEN_DIR := $(PROJECT_ROOT)/generator 5 | SRC_DIR := $(PROJECT_ROOT)/src 6 | SRC := $(shell find $(SRC_DIR) -name '*.c') 7 | FAKE_INCLUDES := $(PROJECT_ROOT)/utils/fake_libc_include 8 | BIN_DIR = $(PROJECT_ROOT)/bin 9 | 10 | CFLAGS = -Wall -fPIC -DHAVE_READLINE -DHAVE_EDITLINE -I$(SRC_DIR) 11 | LDFLAGS += -fPIC 12 | SYSTEM_LIBS = -ldl -lpthread -lreadline 13 | 14 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/Makefile: -------------------------------------------------------------------------------- 1 | include ../../jit.mk 2 | 3 | all: $(TMP_DIRS) sqlite_spec sqlite_jit_spec libsqlite.so 4 | 5 | clean: 6 | rm -f $(BIN_DIR)/sqlite_jit_spec $(BIN_DIR)/sqlite_spec $(JITOBJS) $(VOBJS) 7 | 8 | sqlite_spec: $(GEN_FILES) $(SHAREDOBJS) $(VOBJS) 9 | $(CC) $(LDFLAGS) $(SHAREDOBJS) $(VOBJS) $(SYSTEM_LIBS) -o $(BIN_DIR)/$@ 10 | 11 | sqlite_jit_spec: $(GEN_FILES) $(SHAREDOBJS) $(JITOBJS) 12 | $(CC) $(LDFLAGS) $(SHAREDOBJS) $(JITOBJS) $(SYSTEM_LIBS) -o $(BIN_DIR)/$@ 13 | 14 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/txtBuf.h: -------------------------------------------------------------------------------- 1 | #ifndef TXTBUF_H 2 | #define TXTBUF_H 3 | 4 | #include 5 | #include 6 | 7 | #define TXT_BUFSIZE 1024 8 | #define DECLR_BUFSIZE 5 9 | 10 | typedef struct TxtBuf{ 11 | char *buf; 12 | size_t size, len; 13 | } TxtBuf; 14 | 15 | void *smalloc(size_t size); 16 | 17 | TxtBuf *initTxtBuf(size_t size); 18 | void freeTxtBuf(TxtBuf **ppBuf); 19 | void writeToBuf(TxtBuf **ppBuf, const char *fmt, ...); 20 | void appendToBuf(TxtBuf **ppDst, TxtBuf *pSrc); 21 | 22 | #endif /* TXTBUF_H */ -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/txtBuf.h: -------------------------------------------------------------------------------- 1 | #ifndef TXTBUF_H 2 | #define TXTBUF_H 3 | 4 | #include 5 | #include 6 | 7 | #define TXT_BUFSIZE 1024 8 | #define DECLR_BUFSIZE 5 9 | 10 | typedef struct TxtBuf{ 11 | char *buf; 12 | size_t size, len; 13 | } TxtBuf; 14 | 15 | void *smalloc(size_t size); 16 | 17 | TxtBuf *initTxtBuf(size_t size); 18 | void freeTxtBuf(TxtBuf **ppBuf); 19 | void writeToBuf(TxtBuf **ppBuf, const char *fmt, ...); 20 | void appendToBuf(TxtBuf **ppDst, TxtBuf *pSrc); 21 | 22 | #endif /* TXTBUF_H */ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SQLite_JIT 2 | 3 | ## Building all versions 4 | Run `make` from the top directory of the project. 5 | 6 | ## Building a particular version 7 | Run `make` from the directory of the relevant version. 8 | 9 | ## Running the experiments 10 | Run `make experiments` to run all the experiments from the paper. 11 | The command will produce three files with the measurements in the `results` directory and three images in the `img` directory. 12 | 13 | Run `make A` to run experiment A. The same applies for other experiments. 14 | ## Dependencies 15 | The experiments require the following python3 packages: 16 | * `seaborn` 17 | * `scikit-learn` 18 | 19 | Bulding the templates requires `pycparser`. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include vars.mk 2 | 3 | VERSIONS = sqlite sqlite_jit sqlite_disp sqlite_spec sqlite_jit_spec 4 | VERSIONS_DIR = $(PROJECT_ROOT)/versions 5 | COMMANDS = all clean clean-all debug 6 | TMP_DIRS = $(BIN_DIR) $(PROJECT_ROOT)/img $(PROJECT_ROOT)/results 7 | 8 | all: $(TMP_DIRS) 9 | for v in $(VERSIONS_DIR)/*; do cd $$v && $(MAKE); done; 10 | 11 | $(TMP_DIRS): 12 | mkdir -p $@ 13 | 14 | EXPERIMENTS = A B C 15 | 16 | experiments: $(EXPERIMENTS) 17 | $(EXPERIMENTS): data/test.db #$(VERSIONS) 18 | python3 testing/measure_overhead.py $@ -n 10 -r 5 | xargs python3 testing/make_plot.py $@ -f 19 | 20 | data/test.db: data/data.txt 21 | $(BIN_DIR)/sqlite data/test.db < data/import_data.txt 22 | 23 | data/data.txt: 24 | python3 data/gen_data.py 25 | 26 | #sqlite%: 27 | # cd $(VERSIONS_DIR)/$@ && $(MAKE) 28 | 29 | uninstall: 30 | rm -rf $(TMP_DIRS) 31 | for v in $(VERSIONS_DIR)/*; do cd $$v && $(MAKE) $@; done; 32 | 33 | $(COMMANDS): 34 | for v in $(VERSIONS_DIR)/*; do cd $$v && $(MAKE) $@; done; 35 | 36 | .PHONY: $(COMMANDS) uninstall 37 | -------------------------------------------------------------------------------- /src/vxworks.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2015-03-02 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ****************************************************************************** 12 | ** 13 | ** This file contains code that is specific to Wind River's VxWorks 14 | */ 15 | #if defined(__RTP__) || defined(_WRS_KERNEL) 16 | /* This is VxWorks. Set up things specially for that OS 17 | */ 18 | #include 19 | #include /* amalgamator: dontcache */ 20 | #define OS_VXWORKS 1 21 | #define SQLITE_OS_OTHER 0 22 | #define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1 23 | #define SQLITE_OMIT_LOAD_EXTENSION 1 24 | #define SQLITE_ENABLE_LOCKING_STYLE 0 25 | #define HAVE_UTIME 1 26 | #else 27 | /* This is not VxWorks. */ 28 | #define OS_VXWORKS 0 29 | #define HAVE_FCHOWN 1 30 | #define HAVE_READLINK 1 31 | #define HAVE_LSTAT 1 32 | #endif /* defined(_WRS_KERNEL) */ 33 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/jit.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_H 2 | #define JIT_H 3 | 4 | #include 5 | #include 6 | #include "txtBuf.h" 7 | #include "emit.h" 8 | #include "jitUtils.h" 9 | #include "sqliteInt.h" 10 | #include "vdbeInt.h" 11 | #include "jitCommons.h" 12 | 13 | #define FILE_PREFIX "jitted_func" 14 | #define JITSRC_PATH "/tmp/"FILE_PREFIX".c" 15 | 16 | #ifdef JITDEBUG 17 | #define OPTS " -O0 -g -fno-omit-frame-pointer " 18 | #else 19 | #define OPTS " -O2 " 20 | #endif 21 | 22 | #define XSTR(X) #X 23 | #define STR(X) XSTR(X) 24 | 25 | #define LIB_PATH STR(ROOT_DIR)"/lib/" 26 | 27 | #ifdef JITDEBUG 28 | #define DEBUG_PREP "cc -E -P "JITSRC_PATH INCLUDES" | sed $'s/__NL__/\\\n/g' > /tmp/jit_prep.c && mv /tmp/jit_prep.c /tmp/jitted_func.c && " 29 | #else 30 | #define DEBUG_PREP 31 | #endif 32 | #define INCLUDES " -I"STR(ROOT_DIR)"/jitsrc -I"STR(PROJECT_DIR)"/src " 33 | 34 | #define COMPILE_COMAND DEBUG_PREP"cc "JITSRC_PATH OPTS "-o "LIB_PATH FILE_PREFIX".so -fPIC -shared "INCLUDES" -Wl,-rpath,"LIB_PATH",-lsqlite,-L,"LIB_PATH 35 | 36 | pJitFunc jitLoop(Vdbe *p, int start_pos, int end_pos); 37 | int isJittable(Op *pOp); 38 | 39 | #endif /* JIT_H */ 40 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/jit.h: -------------------------------------------------------------------------------- 1 | #ifndef JIT_H 2 | #define JIT_H 3 | 4 | #include 5 | #include 6 | #include "txtBuf.h" 7 | #include "emit.h" 8 | #include "jitUtils.h" 9 | #include "sqliteInt.h" 10 | #include "vdbeInt.h" 11 | #include "jitCommons.h" 12 | 13 | #define FILE_PREFIX "jitted_func" 14 | #define JITSRC_PATH "/tmp/"FILE_PREFIX".c" 15 | 16 | #ifdef JITDEBUG 17 | #define OPTS " -O0 -g -fno-omit-frame-pointer " 18 | #else 19 | #define OPTS " -O2 " 20 | #endif 21 | 22 | #define XSTR(X) #X 23 | #define STR(X) XSTR(X) 24 | 25 | #define LIB_PATH STR(ROOT_DIR)"/lib/" 26 | 27 | #ifdef JITDEBUG 28 | #define DEBUG_PREP "cc -E -P "JITSRC_PATH INCLUDES" | sed $'s/__NL__/\\\n/g' > /tmp/jit_prep.c && mv /tmp/jit_prep.c /tmp/jitted_func.c && " 29 | #else 30 | #define DEBUG_PREP 31 | #endif 32 | #define INCLUDES " -I"STR(ROOT_DIR)"/jitsrc -I"STR(PROJECT_DIR)"/src " 33 | 34 | #define COMPILE_COMAND DEBUG_PREP"cc "JITSRC_PATH OPTS "-o "LIB_PATH FILE_PREFIX".so -fPIC -shared "INCLUDES" -Wl,-rpath,"LIB_PATH",-lsqlite,-L,"LIB_PATH 35 | 36 | pJitFunc jitLoop(Vdbe *p, int start_pos, int end_pos); 37 | int isJittable(Op *pOp); 38 | 39 | #endif /* JIT_H */ 40 | -------------------------------------------------------------------------------- /src/msvc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2015 January 12 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ****************************************************************************** 12 | ** 13 | ** This file contains code that is specific to MSVC. 14 | */ 15 | #ifndef SQLITE_MSVC_H 16 | #define SQLITE_MSVC_H 17 | 18 | #if defined(_MSC_VER) 19 | #pragma warning(disable : 4054) 20 | #pragma warning(disable : 4055) 21 | #pragma warning(disable : 4100) 22 | #pragma warning(disable : 4127) 23 | #pragma warning(disable : 4130) 24 | #pragma warning(disable : 4152) 25 | #pragma warning(disable : 4189) 26 | #pragma warning(disable : 4206) 27 | #pragma warning(disable : 4210) 28 | #pragma warning(disable : 4232) 29 | #pragma warning(disable : 4244) 30 | #pragma warning(disable : 4305) 31 | #pragma warning(disable : 4306) 32 | #pragma warning(disable : 4702) 33 | #pragma warning(disable : 4706) 34 | #endif /* defined(_MSC_VER) */ 35 | 36 | #endif /* SQLITE_MSVC_H */ 37 | -------------------------------------------------------------------------------- /utils/fake_libc_include/X11/_X11_fake_typedefs.h: -------------------------------------------------------------------------------- 1 | #ifndef _X11_FAKE_TYPEDEFS_H 2 | #define _X11_FAKE_TYPEDEFS_H 3 | 4 | typedef char* XPointer; 5 | typedef unsigned char KeyCode; 6 | typedef unsigned int CARD32; 7 | typedef unsigned long VisualID; 8 | typedef unsigned long XIMResetState; 9 | typedef unsigned long XID; 10 | typedef XID Window; 11 | typedef XID Colormap; 12 | typedef XID Cursor; 13 | typedef XID Drawable; 14 | typedef void* XtPointer; 15 | typedef XtPointer XtRequestId; 16 | typedef struct Display Display; 17 | typedef struct Screen Screen; 18 | typedef struct Status Status; 19 | typedef struct Visual Visual; 20 | typedef struct Widget *Widget; 21 | typedef struct XColor XColor; 22 | typedef struct XClassHint XClassHint; 23 | typedef struct XEvent XEvent; 24 | typedef struct XFontStruct XFontStruct; 25 | typedef struct XGCValues XGCValues; 26 | typedef struct XKeyEvent XKeyEvent; 27 | typedef struct XKeyPressedEvent XKeyPressedEvent; 28 | typedef struct XPoint XPoint; 29 | typedef struct XRectangle XRectangle; 30 | typedef struct XSelectionRequestEvent XSelectionRequestEvent; 31 | typedef struct XWindowChanges XWindowChanges; 32 | typedef struct _XGC _XCG; 33 | typedef struct _XGC *GC; 34 | typedef struct _XIC *XIC; 35 | typedef struct _XIM *XIM; 36 | typedef struct _XImage XImage; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/jit.c: -------------------------------------------------------------------------------- 1 | #include "jit.h" 2 | 3 | void writeToFile(TxtBuf *txt){ 4 | FILE* jit_f = fopen(JITSRC_PATH, "w+"); 5 | if (!jit_f) 6 | err(1, "Couldn't open file for jit"); 7 | if (!fputs(txt->buf, jit_f)) 8 | err(1, "Couldn't write to file for jit"); 9 | 10 | fclose(jit_f); 11 | } 12 | 13 | void compileFile(){ 14 | #ifdef JITDEBUG 15 | puts(COMPILE_COMAND); 16 | #endif 17 | 18 | FILE *compiler = popen(COMPILE_COMAND, "r"); 19 | if (!compiler) 20 | err(1, "Failed to start compiler for jit "); 21 | 22 | int rc = pclose(compiler); 23 | if (rc != 0) 24 | err(1, "Failed to compile jit func"); 25 | } 26 | 27 | void *dl = NULL; 28 | 29 | pJitFunc getJitFunc(){ 30 | if (dl) 31 | dlclose(dl); 32 | dl = dlopen(LIB_PATH FILE_PREFIX".so", RTLD_LAZY | RTLD_GLOBAL); 33 | if (!dl) 34 | err(1, "Couldn't open jit func"); 35 | pJitFunc jittedFunc = dlsym(dl, "jitted_func"); 36 | if (!jittedFunc) 37 | err(1, "Couldn't find symbol for jitted func "); 38 | 39 | return jittedFunc; 40 | } 41 | 42 | pJitFunc jitLoop(Vdbe *pVdbe, int start_pos, int end_pos){ 43 | TxtBuf *txt = emitTxt(pVdbe, start_pos, end_pos); 44 | if(!txt) 45 | return NULL; 46 | #ifdef JITDEBUG 47 | puts(txt->buf); 48 | #endif 49 | writeToFile(txt); 50 | compileFile(); 51 | freeTxtBuf(&txt); 52 | #ifdef JITDEBUG 53 | printAllocs(); 54 | #endif 55 | return getJitFunc(); 56 | } 57 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/jit.c: -------------------------------------------------------------------------------- 1 | #include "jit.h" 2 | 3 | void writeToFile(TxtBuf *txt){ 4 | FILE* jit_f = fopen(JITSRC_PATH, "w+"); 5 | if (!jit_f) 6 | err(1, "Couldn't open file for jit"); 7 | if (!fputs(txt->buf, jit_f)) 8 | err(1, "Couldn't write to file for jit"); 9 | 10 | fclose(jit_f); 11 | } 12 | 13 | void compileFile(){ 14 | #ifdef JITDEBUG 15 | puts(COMPILE_COMAND); 16 | #endif 17 | 18 | FILE *compiler = popen(COMPILE_COMAND, "r"); 19 | if (!compiler) 20 | err(1, "Failed to start compiler for jit "); 21 | 22 | int rc = pclose(compiler); 23 | if (rc != 0) 24 | err(1, "Failed to compile jit func"); 25 | } 26 | 27 | void *dl = NULL; 28 | 29 | pJitFunc getJitFunc(){ 30 | if (dl) 31 | dlclose(dl); 32 | dl = dlopen(LIB_PATH FILE_PREFIX".so", RTLD_LAZY | RTLD_GLOBAL); 33 | if (!dl) 34 | err(1, "Couldn't open jit func"); 35 | pJitFunc jittedFunc = dlsym(dl, "jitted_func"); 36 | if (!jittedFunc) 37 | err(1, "Couldn't find symbol for jitted func "); 38 | 39 | return jittedFunc; 40 | } 41 | 42 | pJitFunc jitLoop(Vdbe *pVdbe, int start_pos, int end_pos){ 43 | TxtBuf *txt = emitTxt(pVdbe, start_pos, end_pos); 44 | if(!txt) 45 | return NULL; 46 | #ifdef JITDEBUG 47 | puts(txt->buf); 48 | #endif 49 | writeToFile(txt); 50 | compileFile(); 51 | freeTxtBuf(&txt); 52 | #ifdef JITDEBUG 53 | printAllocs(); 54 | #endif 55 | return getJitFunc(); 56 | } 57 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/txtBuf.c: -------------------------------------------------------------------------------- 1 | #include "txtBuf.h" 2 | #include 3 | #include 4 | #include "jitUtils.h" 5 | 6 | TxtBuf *initTxtBuf(size_t size){ 7 | TxtBuf *txtBuf = smalloc(sizeof(TxtBuf)); 8 | txtBuf->buf = smalloc(sizeof(*txtBuf->buf)*size); 9 | txtBuf->size = size; 10 | txtBuf->len = 0; 11 | return txtBuf; 12 | } 13 | 14 | void freeTxtBuf(TxtBuf **ppBuf){ 15 | sfree((*ppBuf)->buf); 16 | sfree(*ppBuf); 17 | *ppBuf = NULL; 18 | } 19 | 20 | void writeToBuf(TxtBuf **ppBuf, const char *fmt, ...){ 21 | TxtBuf *pBuf = *ppBuf; 22 | va_list valist; 23 | va_start(valist, fmt); 24 | int str_len = vsnprintf(pBuf->buf, pBuf->size-1, fmt, valist); 25 | if (str_len >= pBuf->size){ 26 | freeTxtBuf(&pBuf); 27 | pBuf = initTxtBuf(str_len+1); 28 | *ppBuf = pBuf; 29 | va_start(valist, fmt); 30 | vsnprintf(pBuf->buf, pBuf->size-1, fmt, valist); 31 | } 32 | pBuf->len = str_len; 33 | va_end(valist); 34 | } 35 | 36 | void appendToBuf(TxtBuf **ppDst, TxtBuf *pSrc){ 37 | TxtBuf *pDst = *ppDst; 38 | size_t full_len = pDst->len + pSrc->len; 39 | if (pDst->size < full_len+1){ 40 | TxtBuf *newDst = initTxtBuf(pDst->size+full_len+1); 41 | memcpy(newDst->buf, pDst->buf, pDst->len+1); 42 | freeTxtBuf(&pDst); 43 | *ppDst = newDst; 44 | pDst = *ppDst; 45 | } 46 | strncat(pDst->buf, pSrc->buf, pSrc->len); 47 | pDst->len = full_len; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/txtBuf.c: -------------------------------------------------------------------------------- 1 | #include "txtBuf.h" 2 | #include 3 | #include 4 | #include "jitUtils.h" 5 | 6 | TxtBuf *initTxtBuf(size_t size){ 7 | TxtBuf *txtBuf = smalloc(sizeof(TxtBuf)); 8 | txtBuf->buf = smalloc(sizeof(*txtBuf->buf)*size); 9 | txtBuf->size = size; 10 | txtBuf->len = 0; 11 | return txtBuf; 12 | } 13 | 14 | void freeTxtBuf(TxtBuf **ppBuf){ 15 | sfree((*ppBuf)->buf); 16 | sfree(*ppBuf); 17 | *ppBuf = NULL; 18 | } 19 | 20 | void writeToBuf(TxtBuf **ppBuf, const char *fmt, ...){ 21 | TxtBuf *pBuf = *ppBuf; 22 | va_list valist; 23 | va_start(valist, fmt); 24 | int str_len = vsnprintf(pBuf->buf, pBuf->size-1, fmt, valist); 25 | if (str_len >= pBuf->size){ 26 | freeTxtBuf(&pBuf); 27 | pBuf = initTxtBuf(str_len+1); 28 | *ppBuf = pBuf; 29 | va_start(valist, fmt); 30 | vsnprintf(pBuf->buf, pBuf->size-1, fmt, valist); 31 | } 32 | pBuf->len = str_len; 33 | va_end(valist); 34 | } 35 | 36 | void appendToBuf(TxtBuf **ppDst, TxtBuf *pSrc){ 37 | TxtBuf *pDst = *ppDst; 38 | size_t full_len = pDst->len + pSrc->len; 39 | if (pDst->size < full_len+1){ 40 | TxtBuf *newDst = initTxtBuf(pDst->size+full_len+1); 41 | memcpy(newDst->buf, pDst->buf, pDst->len+1); 42 | freeTxtBuf(&pDst); 43 | *ppDst = newDst; 44 | pDst = *ppDst; 45 | } 46 | strncat(pDst->buf, pSrc->buf, pSrc->len); 47 | pDst->len = full_len; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /testing/gen_query.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import subprocess 3 | from definitions import PROJECT_DIR 4 | 5 | ten_percent_bound = 250000000 6 | entries = 100000000 7 | 8 | def gen_query(n_tests=5, test_range=5, step=100, selectivity=0): 9 | 10 | if selectivity != 0: 11 | selectivity_test = "i<{} or".format(selectivity*ten_percent_bound) 12 | command = 'echo "select count(i) from test where i<{0};" | {1}/bin/sqlite {1}/data/test.db ' 13 | command = command.format(selectivity*ten_percent_bound, PROJECT_DIR) 14 | res = subprocess.run(command, shell=True, stdout=subprocess.PIPE) 15 | selection_n = round(int(res.stdout.decode('utf-8'))/entries*100, 3) 16 | else: 17 | selectivity_test = "" 18 | selection_n = 0 19 | 20 | begin = "select i from test where {}".format(selectivity_test) 21 | selection = ["(i<{} and i>{})".format(i, i+test_range) for i in range(1, n_tests*step, step)] 22 | selection = " or ".join(selection) 23 | query = begin + selection + ";" 24 | 25 | return query, selection_n 26 | 27 | if __name__ == "__main__": 28 | parser = argparse.ArgumentParser() 29 | parser.add_argument("-n", help="number of tests", action="store", type=int, default=5) 30 | parser.add_argument("-r", help="test range", action="store", type=int, default=5) 31 | parser.add_argument("-s", help="step between tests", action="store", type=int, default=100) 32 | parser.add_argument("-l", help="selectivity", action="store", type=int, default=0) 33 | args = parser.parse_args() 34 | 35 | query = gen_query(args.n, args.r, args.s, args.l) 36 | print(query[0]) 37 | -------------------------------------------------------------------------------- /src/os_setup.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2013 November 25 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ****************************************************************************** 12 | ** 13 | ** This file contains pre-processor directives related to operating system 14 | ** detection and/or setup. 15 | */ 16 | #ifndef SQLITE_OS_SETUP_H 17 | #define SQLITE_OS_SETUP_H 18 | 19 | /* 20 | ** Figure out if we are dealing with Unix, Windows, or some other operating 21 | ** system. 22 | ** 23 | ** After the following block of preprocess macros, all of SQLITE_OS_UNIX, 24 | ** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of 25 | ** the three will be 1. The other two will be 0. 26 | */ 27 | #if defined(SQLITE_OS_OTHER) 28 | # if SQLITE_OS_OTHER==1 29 | # undef SQLITE_OS_UNIX 30 | # define SQLITE_OS_UNIX 0 31 | # undef SQLITE_OS_WIN 32 | # define SQLITE_OS_WIN 0 33 | # else 34 | # undef SQLITE_OS_OTHER 35 | # endif 36 | #endif 37 | #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) 38 | # define SQLITE_OS_OTHER 0 39 | # ifndef SQLITE_OS_WIN 40 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ 41 | defined(__MINGW32__) || defined(__BORLANDC__) 42 | # define SQLITE_OS_WIN 1 43 | # define SQLITE_OS_UNIX 0 44 | # else 45 | # define SQLITE_OS_WIN 0 46 | # define SQLITE_OS_UNIX 1 47 | # endif 48 | # else 49 | # define SQLITE_OS_UNIX 0 50 | # endif 51 | #else 52 | # ifndef SQLITE_OS_WIN 53 | # define SQLITE_OS_WIN 0 54 | # endif 55 | #endif 56 | 57 | #endif /* SQLITE_OS_SETUP_H */ 58 | -------------------------------------------------------------------------------- /generator/gen_util.py: -------------------------------------------------------------------------------- 1 | from vdbe_opcode import get_opcode 2 | from pycparser import c_parser, parse_file, c_generator 3 | from pycparser.c_ast import NodeVisitor, ArrayRef, Assignment, ID, Return, Goto 4 | import re 5 | 6 | class CodeFinder(NodeVisitor): 7 | def __init__(self): 8 | self.funcs_dict = {} 9 | self.funcs = [] 10 | self.switches = [] 11 | self.cases = [] 12 | 13 | def visit_FuncDef(self, node): 14 | self.funcs_dict[node.decl.name] = node 15 | 16 | def visit_Switch(self, node): 17 | self.switches.append(node.stmt) 18 | 19 | def visit_Case(self, node): 20 | self.cases.append(node) 21 | 22 | def get_switches(self, node): 23 | self.visit(node) 24 | switches = self.switches 25 | self.switches = [] 26 | return switches 27 | 28 | def get_cases(self, node): 29 | self.visit(node) 30 | cases = self.cases 31 | self.cases = [] 32 | return cases 33 | 34 | def get_funcs(self, node): 35 | self.visit(node) 36 | funcs = self.funcs_dict.values() 37 | self.funcs_dict = {} 38 | return funcs 39 | 40 | def find_func(self, name, node): 41 | self.visit(node) 42 | func = self.funcs_dict.get(name, None) 43 | self.funcs_dict = {} 44 | return func 45 | 46 | class OpcodeFinder(NodeVisitor): 47 | def __init__(self, node): 48 | self.node = node 49 | VDBE_EXEC = "sqlite3VdbeExec" 50 | finder = CodeFinder() 51 | vdbe_exec_f = finder.find_func(VDBE_EXEC, node) 52 | self.cases = finder.get_cases(finder.get_switches(vdbe_exec_f.body)[0]) 53 | 54 | def find_opcode_impl(self, opcode_name): 55 | opcode = get_opcode(opcode_name) 56 | i = 0 57 | length = len(self.cases) 58 | #TODO: look for breaks instead 59 | while i < length and int(self.cases[i].expr.value) != opcode: 60 | i+=1 61 | 62 | while i < length: 63 | if len(self.cases[i].stmts) > 0: 64 | return self.cases[i] 65 | i+=1 66 | 67 | return None 68 | 69 | -------------------------------------------------------------------------------- /src/mem0.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2008 October 28 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** 13 | ** This file contains a no-op memory allocation drivers for use when 14 | ** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented 15 | ** here always fail. SQLite will not operate with these drivers. These 16 | ** are merely placeholders. Real drivers must be substituted using 17 | ** sqlite3_config() before SQLite will operate. 18 | */ 19 | #include "sqliteInt.h" 20 | 21 | /* 22 | ** This version of the memory allocator is the default. It is 23 | ** used when no other memory allocator is specified using compile-time 24 | ** macros. 25 | */ 26 | #ifdef SQLITE_ZERO_MALLOC 27 | 28 | /* 29 | ** No-op versions of all memory allocation routines 30 | */ 31 | static void *sqlite3MemMalloc(int nByte){ return 0; } 32 | static void sqlite3MemFree(void *pPrior){ return; } 33 | static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; } 34 | static int sqlite3MemSize(void *pPrior){ return 0; } 35 | static int sqlite3MemRoundup(int n){ return n; } 36 | static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } 37 | static void sqlite3MemShutdown(void *NotUsed){ return; } 38 | 39 | /* 40 | ** This routine is the only routine in this file with external linkage. 41 | ** 42 | ** Populate the low-level memory allocation function pointers in 43 | ** sqlite3GlobalConfig.m with pointers to the routines in this file. 44 | */ 45 | void sqlite3MemSetDefault(void){ 46 | static const sqlite3_mem_methods defaultMethods = { 47 | sqlite3MemMalloc, 48 | sqlite3MemFree, 49 | sqlite3MemRealloc, 50 | sqlite3MemSize, 51 | sqlite3MemRoundup, 52 | sqlite3MemInit, 53 | sqlite3MemShutdown, 54 | 0 55 | }; 56 | sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); 57 | } 58 | 59 | #endif /* SQLITE_ZERO_MALLOC */ 60 | -------------------------------------------------------------------------------- /generator/cfiles/emitTemplate.c: -------------------------------------------------------------------------------- 1 | #include "emitTemplate.h" 2 | #define HEADER \ 3 | "#include \"opcodeTemplates.h\" \n\ 4 | #include \"jitted_func.h\" \n\ 5 | jitRc jitted_func(Vdbe *p){ \n\ 6 | Op *aOp = p->aOp; \n\ 7 | Op *pOp; \n\ 8 | Mem *aMem = p->aMem;\n\ 9 | Mem *pIn1 = 0;\n\ 10 | Mem *pIn2 = 0;\n\ 11 | Mem *pIn3 = 0;\n\ 12 | Mem *pOut = 0;\n\ 13 | int rc = OK; \n\ 14 | sqlite3 *db = p->db;\n\ 15 | u8 encoding = ENC(db); \n\ 16 | int iCompare = 0;\n\ 17 | unsigned nVmStep = 0;\n\ 18 | unsigned nProgressLimit;\n" 19 | 20 | 21 | #define FOOTER \ 22 | "L%d:\n\ 23 | return 0; \n\ 24 | }\n" 25 | 26 | 27 | #define NXT_TEMPLATE \ 28 | "L%d: \n\ 29 | {\n\ 30 | VdbeCursor *pC = p->apCsr[%d]; \n\ 31 | rc = ((int (*)(BtCursor *, int))%p)(pC->uc.pCursor, %d); \n\ 32 | pC->cacheStatus = CACHE_STALE; \n\ 33 | if( rc==SQLITE_OK ){ \n\ 34 | pC->nullRow = 0; \n\ 35 | p->aCounter[%d]++; \n\ 36 | goto L%d; \n\ 37 | } \n\ 38 | p->pc = %d + 1; \n\ 39 | return SQLITE_OK; \n\ 40 | \n};" 41 | 42 | void emitNext(Vdbe *p, Op *pOp, TxtBuf **buf, int pos){ 43 | int jmpPos = pOp->p2; 44 | writeToBuf(buf, NXT_TEMPLATE, pos, pOp->p1, pOp->p4.xAdvance, pOp->p3, pOp->p5, jmpPos, pos); 45 | } 46 | 47 | TxtBuf *emitTxt(Vdbe *p, int start_pos, int end_pos){ 48 | TxtBuf *txt = initTxtBuf(TXT_BUFSIZE); 49 | TxtBuf *tmp = initTxtBuf(TXT_BUFSIZE); 50 | 51 | int nJittedOps = 0; 52 | 53 | writeToBuf(&txt, "%s", HEADER); 54 | 55 | for(int i = start_pos; i < end_pos+1; i++){ 56 | Op *cOp = &p->aOp[i]; 57 | nJittedOps++; 58 | switch(cOp->opcode){ 59 | case OP_Next: 60 | emitNext(p, cOp, &tmp, i); 61 | break; 62 | 63 | default: 64 | warnx("%s not implemented.\n", sqlite3OpcodeName(cOp->opcode)); 65 | freeTxtBuf(&txt); 66 | freeTxtBuf(&tmp); 67 | return NULL; 68 | } 69 | 70 | appendToBuf(&txt, tmp); 71 | } 72 | 73 | writeToBuf(&tmp, FOOTER, end_pos+1); 74 | appendToBuf(&txt, tmp); 75 | freeTxtBuf(&tmp); 76 | fprintf(stderr, "jitted ops: %d, ", nJittedOps); 77 | return txt; 78 | } 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /jit.mk: -------------------------------------------------------------------------------- 1 | JIT_MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | PROJECT_ROOT := $(realpath $(dir $(JIT_MKFILE_PATH))) 3 | 4 | include $(PROJECT_ROOT)/vars.mk 5 | 6 | ROOT_DIR = $(shell pwd) 7 | VERSION_NAME = $(basename $(notdir $(ROOT_DIR))) 8 | JIT_DIR = $(ROOT_DIR)/jitsrc 9 | LIB_DIR = $(ROOT_DIR)/lib 10 | #use shared objects for all versions 11 | SHAREDOBJ_DIR = $(PROJECT_ROOT)/shared_obj 12 | #use shared objects per version 13 | #SHAREDOBJ_DIR = $(ROOT_DIR)/shared_obj 14 | SHAREDOBJS = $(SRC:$(SRC_DIR)/%.c=$(SHAREDOBJ_DIR)/%.lo) 15 | JITOBJ_DIR = $(ROOT_DIR)/jit_obj 16 | VOBJ_DIR = $(ROOT_DIR)/v_obj 17 | TMP = $(ROOT_DIR)/tmp 18 | GEN_CODE_DIR = $(GEN_DIR)/out/$(VERSION_NAME) 19 | GEN_FILES = $(JIT_DIR)/emit.c $(JIT_DIR)/opcodeTemplates.h 20 | 21 | CFLAGS += -I$(JIT_DIR) 22 | TMP_DIRS = $(SHAREDOBJ_DIR) $(JITOBJ_DIR) $(LIB_DIR) $(VOBJ_DIR) $(TMP) $(GEN_CODE_DIR) 23 | 24 | JITSRC := $(sort $(shell find $(JIT_DIR) -name '*.c') $(JIT_DIR)/emit.c) 25 | JITOBJS = $(JITSRC:$(JIT_DIR)/%.c=$(JITOBJ_DIR)/%.lo) 26 | VOBJS = $(JITSRC:$(JIT_DIR)/%.c=$(VOBJ_DIR)/%.lo) 27 | 28 | OPTS = -O3 29 | 30 | all: 31 | 32 | debug: GEN_FLAGS += -d 33 | debug: OPTS = -DJITDEBUG -g -O0 34 | debug: LDFLAGS += -g 35 | debug: clean all 36 | 37 | CFLAGS += $(OPTS) 38 | 39 | clean-all: 40 | $(MAKE) clean 41 | rm -f $(SHAREDOBJS) 42 | rm -f $(GEN_FILES) 43 | rm -f $(TMP)/* 44 | rm -f $(GEN_CODE_DIR)/* 45 | rm -f $(LIB_DIR)/* 46 | 47 | $(SHAREDOBJ_DIR)/%.lo: $(SRC_DIR)/%.c 48 | $(CC) -c $(CFLAGS) $< -o $@ 49 | 50 | $(JITOBJ_DIR)/%.lo: $(JIT_DIR)/%.c 51 | $(CC) -c $(CFLAGS) -DJIT -DROOT_DIR=$(ROOT_DIR) -DPROJECT_DIR=$(PROJECT_ROOT) $< -o $@ 52 | 53 | $(VOBJ_DIR)/%.lo: $(JIT_DIR)/%.c 54 | $(CC) -c $(CFLAGS) -DNJIT $< -o $@ 55 | 56 | libsqlite.so: $(SHAREDOBJS) $(JITOBJS) 57 | $(CC) $(LDFLAGS) $(SHAREDOBJS) $(JITOBJS) $(SYSTEM_LIBS) -shared -o $(LIB_DIR)/$@ 58 | 59 | $(GEN_FILES): $(TMP)/vdbe_prep.c $(GEN_DIR)/cfiles/emitTemplate_prep.c 60 | python3 $(GEN_DIR)/construct_emit.py -i $< -o $(GEN_CODE_DIR) 61 | cp $(GEN_CODE_DIR)/* $(JIT_DIR) 62 | 63 | $(TMP)/vdbe_prep.c: $(JIT_DIR)/vdbe.c 64 | $(CC) -E -I$(JIT_DIR) -I$(SRC_DIR) -I$(FAKE_INCLUDES) $< | sed 's/__attribute__((noinline))//g' > $@ 65 | 66 | $(GEN_DIR)/cfiles/emitTemplate_prep.c: $(GEN_DIR)/cfiles/emitTemplate.c 67 | $(CC) -E -I$(JIT_DIR) -I$(SRC_DIR) -I$(FAKE_INCLUDES) $< | sed 's/__attribute__((noinline))//g' > $@ 68 | 69 | $(TMP_DIRS): 70 | mkdir -p $@ 71 | 72 | uninstall: 73 | $(MAKE) clean-all 74 | rm -rf $(TMP_DIRS) 75 | -------------------------------------------------------------------------------- /src/os_win.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2013 November 25 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ****************************************************************************** 12 | ** 13 | ** This file contains code that is specific to Windows. 14 | */ 15 | #ifndef SQLITE_OS_WIN_H 16 | #define SQLITE_OS_WIN_H 17 | 18 | /* 19 | ** Include the primary Windows SDK header file. 20 | */ 21 | #include "windows.h" 22 | 23 | #ifdef __CYGWIN__ 24 | # include 25 | # include /* amalgamator: dontcache */ 26 | #endif 27 | 28 | /* 29 | ** Determine if we are dealing with Windows NT. 30 | ** 31 | ** We ought to be able to determine if we are compiling for Windows 9x or 32 | ** Windows NT using the _WIN32_WINNT macro as follows: 33 | ** 34 | ** #if defined(_WIN32_WINNT) 35 | ** # define SQLITE_OS_WINNT 1 36 | ** #else 37 | ** # define SQLITE_OS_WINNT 0 38 | ** #endif 39 | ** 40 | ** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as 41 | ** it ought to, so the above test does not work. We'll just assume that 42 | ** everything is Windows NT unless the programmer explicitly says otherwise 43 | ** by setting SQLITE_OS_WINNT to 0. 44 | */ 45 | #if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) 46 | # define SQLITE_OS_WINNT 1 47 | #endif 48 | 49 | /* 50 | ** Determine if we are dealing with Windows CE - which has a much reduced 51 | ** API. 52 | */ 53 | #if defined(_WIN32_WCE) 54 | # define SQLITE_OS_WINCE 1 55 | #else 56 | # define SQLITE_OS_WINCE 0 57 | #endif 58 | 59 | /* 60 | ** Determine if we are dealing with WinRT, which provides only a subset of 61 | ** the full Win32 API. 62 | */ 63 | #if !defined(SQLITE_OS_WINRT) 64 | # define SQLITE_OS_WINRT 0 65 | #endif 66 | 67 | /* 68 | ** For WinCE, some API function parameters do not appear to be declared as 69 | ** volatile. 70 | */ 71 | #if SQLITE_OS_WINCE 72 | # define SQLITE_WIN32_VOLATILE 73 | #else 74 | # define SQLITE_WIN32_VOLATILE volatile 75 | #endif 76 | 77 | /* 78 | ** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() 79 | ** functions are not available (e.g. those not using MSVC, Cygwin, etc). 80 | */ 81 | #if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ 82 | SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) 83 | # define SQLITE_OS_WIN_THREADS 1 84 | #else 85 | # define SQLITE_OS_WIN_THREADS 0 86 | #endif 87 | 88 | #endif /* SQLITE_OS_WIN_H */ 89 | -------------------------------------------------------------------------------- /src/mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2007 August 28 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** 13 | ** This file contains the common header for all mutex implementations. 14 | ** The sqliteInt.h header #includes this file so that it is available 15 | ** to all source files. We break it out in an effort to keep the code 16 | ** better organized. 17 | ** 18 | ** NOTE: source files should *not* #include this header file directly. 19 | ** Source files should #include the sqliteInt.h file and let that file 20 | ** include this one indirectly. 21 | */ 22 | 23 | 24 | /* 25 | ** Figure out what version of the code to use. The choices are 26 | ** 27 | ** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The 28 | ** mutexes implementation cannot be overridden 29 | ** at start-time. 30 | ** 31 | ** SQLITE_MUTEX_NOOP For single-threaded applications. No 32 | ** mutual exclusion is provided. But this 33 | ** implementation can be overridden at 34 | ** start-time. 35 | ** 36 | ** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. 37 | ** 38 | ** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. 39 | */ 40 | #if !SQLITE_THREADSAFE 41 | # define SQLITE_MUTEX_OMIT 42 | #endif 43 | #if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) 44 | # if SQLITE_OS_UNIX 45 | # define SQLITE_MUTEX_PTHREADS 46 | # elif SQLITE_OS_WIN 47 | # define SQLITE_MUTEX_W32 48 | # else 49 | # define SQLITE_MUTEX_NOOP 50 | # endif 51 | #endif 52 | 53 | #ifdef SQLITE_MUTEX_OMIT 54 | /* 55 | ** If this is a no-op implementation, implement everything as macros. 56 | */ 57 | #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) 58 | #define sqlite3_mutex_free(X) 59 | #define sqlite3_mutex_enter(X) 60 | #define sqlite3_mutex_try(X) SQLITE_OK 61 | #define sqlite3_mutex_leave(X) 62 | #define sqlite3_mutex_held(X) ((void)(X),1) 63 | #define sqlite3_mutex_notheld(X) ((void)(X),1) 64 | #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) 65 | #define sqlite3MutexInit() SQLITE_OK 66 | #define sqlite3MutexEnd() 67 | #define MUTEX_LOGIC(X) 68 | #else 69 | #define MUTEX_LOGIC(X) X 70 | #endif /* defined(SQLITE_MUTEX_OMIT) */ 71 | -------------------------------------------------------------------------------- /src/hwtime.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2008 May 27 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ****************************************************************************** 12 | ** 13 | ** This file contains inline asm code for retrieving "high-performance" 14 | ** counters for x86 class CPUs. 15 | */ 16 | #ifndef SQLITE_HWTIME_H 17 | #define SQLITE_HWTIME_H 18 | 19 | /* 20 | ** The following routine only works on pentium-class (or newer) processors. 21 | ** It uses the RDTSC opcode to read the cycle count value out of the 22 | ** processor and returns that value. This can be used for high-res 23 | ** profiling. 24 | */ 25 | #if (defined(__GNUC__) || defined(_MSC_VER)) && \ 26 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) 27 | 28 | #if defined(__GNUC__) 29 | 30 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ 31 | unsigned int lo, hi; 32 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); 33 | return (sqlite_uint64)hi << 32 | lo; 34 | } 35 | 36 | #elif defined(_MSC_VER) 37 | 38 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ 39 | __asm { 40 | rdtsc 41 | ret ; return value at EDX:EAX 42 | } 43 | } 44 | 45 | #endif 46 | 47 | #elif (defined(__GNUC__) && defined(__x86_64__)) 48 | 49 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ 50 | unsigned long val; 51 | __asm__ __volatile__ ("rdtsc" : "=A" (val)); 52 | return val; 53 | } 54 | 55 | #elif (defined(__GNUC__) && defined(__ppc__)) 56 | 57 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ 58 | unsigned long long retval; 59 | unsigned long junk; 60 | __asm__ __volatile__ ("\n\ 61 | 1: mftbu %1\n\ 62 | mftb %L0\n\ 63 | mftbu %0\n\ 64 | cmpw %0,%1\n\ 65 | bne 1b" 66 | : "=r" (retval), "=r" (junk)); 67 | return retval; 68 | } 69 | 70 | #else 71 | 72 | #error Need implementation of sqlite3Hwtime() for your platform. 73 | 74 | /* 75 | ** To compile without implementing sqlite3Hwtime() for your platform, 76 | ** you can remove the above #error and use the following 77 | ** stub function. You will lose timing support for many 78 | ** of the debugging and testing utilities, but it should at 79 | ** least compile and run. 80 | */ 81 | sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } 82 | 83 | #endif 84 | 85 | #endif /* !defined(SQLITE_HWTIME_H) */ 86 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/opimpl.h: -------------------------------------------------------------------------------- 1 | #include "sqliteInt.h" 2 | #include "vdbeInt.h" 3 | 4 | #define OP_EXEC_JIT 200 5 | 6 | #define Deephemeralize_JIT(P) \ 7 | if( ((P)->flags&MEM_Ephem)!=0 \ 8 | && sqlite3VdbeMemMakeWriteable(P) ){ jit_err = NO_MEM;} 9 | 10 | typedef enum {OK, ERROR, NO_MEM, ROW} jit_code; 11 | 12 | //#define LE_IMPL ((void) 0) 13 | //#define CPY_IMPL ((void) 0) 14 | 15 | 16 | //#define LE_IMPL(goto_label) goto_label: le_impl(aMem, aOp, ppOp) 17 | 18 | //#define CPY_IMPL(goto_label) goto_label: cpy_impl(aMem, pOp) 19 | 20 | 21 | #define LE_IMPL(label, jump_false) \ 22 | label : ;\ 23 | pIn1 = &aMem[pOp->p1]; \ 24 | pIn3 = &aMem[pOp->p3]; \ 25 | if(pIn3->u.i <= pIn1->u.i){ \ 26 | pOp = &aOp[pOp->p2 - 1]; \ 27 | goto jump_false; \ 28 | } \ 29 | 30 | #define GE_IMPL(label, jump_false) \ 31 | label : ;\ 32 | pOp++;\ 33 | pIn1 = &aMem[pOp->p1]; \ 34 | pIn3 = &aMem[pOp->p3]; \ 35 | pOp++;\ 36 | if(pIn3->u.i >= pIn1->u.i){ \ 37 | pOp = &aOp[pOp->p2 - 1]; \ 38 | goto jump_false; \ 39 | } \ 40 | 41 | #define CPY_IMPL(label) \ 42 | label : ;\ 43 | pOp++;\ 44 | pIn1 = &aMem[pOp->p1]; \ 45 | pOut = &aMem[pOp->p2]; \ 46 | n = pOp->p3; \ 47 | while( 1 ){ \ 48 | sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); \ 49 | if( (n--)==0 ) break; \ 50 | pOut++; \ 51 | pIn1++; \ 52 | } \ 53 | 54 | #define NXT_IMPL(label, jump) \ 55 | label : ; \ 56 | pOp++;\ 57 | pC = p->apCsr[pOp->p1]; \ 58 | printf("%d", (pC == NULL));\ 59 | rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); \ 60 | pC->cacheStatus = CACHE_STALE; \ 61 | if( rc==SQLITE_OK ){ \ 62 | pC->nullRow = 0; \ 63 | p->aCounter[pOp->p5]++; \ 64 | pOp = &aOp[pOp->p2 - 1]; \ 65 | goto jump; \ 66 | } \ 67 | 68 | #define RSLT_IMPL(label) \ 69 | label : \ 70 | {\ 71 | p->pResultSet = &aMem[pOp->p1]; \ 72 | p->pc = (int)(pOp - aOp) + 1; \ 73 | return ROW; \ 74 | } \ 75 | 76 | 77 | /* 78 | void le_impl(Mem *aMem, Op *aOp, Op **ppOp) { 79 | DEBUG("LE_IMPL_START"); 80 | Op *pOp = *ppOp; 81 | Mem *pIn1 = &aMem[pOp->p1]; 82 | Mem *pIn3 = &aMem[pOp->p3]; 83 | assert( (pOp->p5 & SQLITE_AFF_MASK)>=SQLITE_AFF_NUMERIC ); 84 | if(pIn3->u.i <= pIn1->u.i){ 85 | pOp = &aOp[pOp->p2 - 1]; 86 | } 87 | 88 | *ppOp = pOp; 89 | } 90 | 91 | void cpy_impl(Mem *aMem, Op *pOp){ 92 | DEBUG("CPY_IMPL_START"); 93 | Mem *pIn1 = &aMem[pOp->p1]; 94 | Mem *pOut = &aMem[pOp->p2]; 95 | int n; 96 | n = pOp->p3; 97 | while( 1 ){ 98 | sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); 99 | if((pOut->flags&MEM_Ephem) == 0) 100 | DEBUG("CPY: MEM_Ephem set"); 101 | Deephemeralize_JIT(pOut); 102 | if( (n--)==0 ) break; 103 | pOut++; 104 | pIn1++; 105 | } 106 | } 107 | */ 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/opimpl.h: -------------------------------------------------------------------------------- 1 | #include "sqliteInt.h" 2 | #include "vdbeInt.h" 3 | 4 | #define OP_EXEC_JIT 200 5 | 6 | #define Deephemeralize_JIT(P) \ 7 | if( ((P)->flags&MEM_Ephem)!=0 \ 8 | && sqlite3VdbeMemMakeWriteable(P) ){ jit_err = NO_MEM;} 9 | 10 | typedef enum {OK, ERROR, NO_MEM, ROW} jit_code; 11 | 12 | //#define LE_IMPL ((void) 0) 13 | //#define CPY_IMPL ((void) 0) 14 | 15 | 16 | //#define LE_IMPL(goto_label) goto_label: le_impl(aMem, aOp, ppOp) 17 | 18 | //#define CPY_IMPL(goto_label) goto_label: cpy_impl(aMem, pOp) 19 | 20 | 21 | #define LE_IMPL(label, jump_false) \ 22 | label : ;\ 23 | pIn1 = &aMem[pOp->p1]; \ 24 | pIn3 = &aMem[pOp->p3]; \ 25 | if(pIn3->u.i <= pIn1->u.i){ \ 26 | pOp = &aOp[pOp->p2 - 1]; \ 27 | goto jump_false; \ 28 | } \ 29 | 30 | #define GE_IMPL(label, jump_false) \ 31 | label : ;\ 32 | pOp++;\ 33 | pIn1 = &aMem[pOp->p1]; \ 34 | pIn3 = &aMem[pOp->p3]; \ 35 | pOp++;\ 36 | if(pIn3->u.i >= pIn1->u.i){ \ 37 | pOp = &aOp[pOp->p2 - 1]; \ 38 | goto jump_false; \ 39 | } \ 40 | 41 | #define CPY_IMPL(label) \ 42 | label : ;\ 43 | pOp++;\ 44 | pIn1 = &aMem[pOp->p1]; \ 45 | pOut = &aMem[pOp->p2]; \ 46 | n = pOp->p3; \ 47 | while( 1 ){ \ 48 | sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); \ 49 | if( (n--)==0 ) break; \ 50 | pOut++; \ 51 | pIn1++; \ 52 | } \ 53 | 54 | #define NXT_IMPL(label, jump) \ 55 | label : ; \ 56 | pOp++;\ 57 | pC = p->apCsr[pOp->p1]; \ 58 | printf("%d", (pC == NULL));\ 59 | rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); \ 60 | pC->cacheStatus = CACHE_STALE; \ 61 | if( rc==SQLITE_OK ){ \ 62 | pC->nullRow = 0; \ 63 | p->aCounter[pOp->p5]++; \ 64 | pOp = &aOp[pOp->p2 - 1]; \ 65 | goto jump; \ 66 | } \ 67 | 68 | #define RSLT_IMPL(label) \ 69 | label : \ 70 | {\ 71 | p->pResultSet = &aMem[pOp->p1]; \ 72 | p->pc = (int)(pOp - aOp) + 1; \ 73 | return ROW; \ 74 | } \ 75 | 76 | 77 | /* 78 | void le_impl(Mem *aMem, Op *aOp, Op **ppOp) { 79 | DEBUG("LE_IMPL_START"); 80 | Op *pOp = *ppOp; 81 | Mem *pIn1 = &aMem[pOp->p1]; 82 | Mem *pIn3 = &aMem[pOp->p3]; 83 | assert( (pOp->p5 & SQLITE_AFF_MASK)>=SQLITE_AFF_NUMERIC ); 84 | if(pIn3->u.i <= pIn1->u.i){ 85 | pOp = &aOp[pOp->p2 - 1]; 86 | } 87 | 88 | *ppOp = pOp; 89 | } 90 | 91 | void cpy_impl(Mem *aMem, Op *pOp){ 92 | DEBUG("CPY_IMPL_START"); 93 | Mem *pIn1 = &aMem[pOp->p1]; 94 | Mem *pOut = &aMem[pOp->p2]; 95 | int n; 96 | n = pOp->p3; 97 | while( 1 ){ 98 | sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); 99 | if((pOut->flags&MEM_Ephem) == 0) 100 | DEBUG("CPY: MEM_Ephem set"); 101 | Deephemeralize_JIT(pOut); 102 | if( (n--)==0 ) break; 103 | pOut++; 104 | pIn1++; 105 | } 106 | } 107 | */ 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/fault.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2008 Jan 22 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** 13 | ** This file contains code to support the concept of "benign" 14 | ** malloc failures (when the xMalloc() or xRealloc() method of the 15 | ** sqlite3_mem_methods structure fails to allocate a block of memory 16 | ** and returns 0). 17 | ** 18 | ** Most malloc failures are non-benign. After they occur, SQLite 19 | ** abandons the current operation and returns an error code (usually 20 | ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily 21 | ** fatal. For example, if a malloc fails while resizing a hash table, this 22 | ** is completely recoverable simply by not carrying out the resize. The 23 | ** hash table will continue to function normally. So a malloc failure 24 | ** during a hash table resize is a benign fault. 25 | */ 26 | 27 | #include "sqliteInt.h" 28 | 29 | #ifndef SQLITE_UNTESTABLE 30 | 31 | /* 32 | ** Global variables. 33 | */ 34 | typedef struct BenignMallocHooks BenignMallocHooks; 35 | static SQLITE_WSD struct BenignMallocHooks { 36 | void (*xBenignBegin)(void); 37 | void (*xBenignEnd)(void); 38 | } sqlite3Hooks = { 0, 0 }; 39 | 40 | /* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks 41 | ** structure. If writable static data is unsupported on the target, 42 | ** we have to locate the state vector at run-time. In the more common 43 | ** case where writable static data is supported, wsdHooks can refer directly 44 | ** to the "sqlite3Hooks" state vector declared above. 45 | */ 46 | #ifdef SQLITE_OMIT_WSD 47 | # define wsdHooksInit \ 48 | BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) 49 | # define wsdHooks x[0] 50 | #else 51 | # define wsdHooksInit 52 | # define wsdHooks sqlite3Hooks 53 | #endif 54 | 55 | 56 | /* 57 | ** Register hooks to call when sqlite3BeginBenignMalloc() and 58 | ** sqlite3EndBenignMalloc() are called, respectively. 59 | */ 60 | void sqlite3BenignMallocHooks( 61 | void (*xBenignBegin)(void), 62 | void (*xBenignEnd)(void) 63 | ){ 64 | wsdHooksInit; 65 | wsdHooks.xBenignBegin = xBenignBegin; 66 | wsdHooks.xBenignEnd = xBenignEnd; 67 | } 68 | 69 | /* 70 | ** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that 71 | ** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() 72 | ** indicates that subsequent malloc failures are non-benign. 73 | */ 74 | void sqlite3BeginBenignMalloc(void){ 75 | wsdHooksInit; 76 | if( wsdHooks.xBenignBegin ){ 77 | wsdHooks.xBenignBegin(); 78 | } 79 | } 80 | void sqlite3EndBenignMalloc(void){ 81 | wsdHooksInit; 82 | if( wsdHooks.xBenignEnd ){ 83 | wsdHooks.xBenignEnd(); 84 | } 85 | } 86 | 87 | #endif /* #ifndef SQLITE_UNTESTABLE */ 88 | -------------------------------------------------------------------------------- /src/os_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2004 May 22 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ****************************************************************************** 12 | ** 13 | ** This file contains macros and a little bit of code that is common to 14 | ** all of the platform-specific files (os_*.c) and is #included into those 15 | ** files. 16 | ** 17 | ** This file should be #included by the os_*.c files only. It is not a 18 | ** general purpose header file. 19 | */ 20 | #ifndef _OS_COMMON_H_ 21 | #define _OS_COMMON_H_ 22 | 23 | /* 24 | ** At least two bugs have slipped in because we changed the MEMORY_DEBUG 25 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the 26 | ** switch. The following code should catch this problem at compile-time. 27 | */ 28 | #ifdef MEMORY_DEBUG 29 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." 30 | #endif 31 | 32 | /* 33 | ** Macros for performance tracing. Normally turned off. Only works 34 | ** on i486 hardware. 35 | */ 36 | #ifdef SQLITE_PERFORMANCE_TRACE 37 | 38 | /* 39 | ** hwtime.h contains inline assembler code for implementing 40 | ** high-performance timing routines. 41 | */ 42 | #include "hwtime.h" 43 | 44 | static sqlite_uint64 g_start; 45 | static sqlite_uint64 g_elapsed; 46 | #define TIMER_START g_start=sqlite3Hwtime() 47 | #define TIMER_END g_elapsed=sqlite3Hwtime()-g_start 48 | #define TIMER_ELAPSED g_elapsed 49 | #else 50 | #define TIMER_START 51 | #define TIMER_END 52 | #define TIMER_ELAPSED ((sqlite_uint64)0) 53 | #endif 54 | 55 | /* 56 | ** If we compile with the SQLITE_TEST macro set, then the following block 57 | ** of code will give us the ability to simulate a disk I/O error. This 58 | ** is used for testing the I/O recovery logic. 59 | */ 60 | #if defined(SQLITE_TEST) 61 | extern int sqlite3_io_error_hit; 62 | extern int sqlite3_io_error_hardhit; 63 | extern int sqlite3_io_error_pending; 64 | extern int sqlite3_io_error_persist; 65 | extern int sqlite3_io_error_benign; 66 | extern int sqlite3_diskfull_pending; 67 | extern int sqlite3_diskfull; 68 | #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) 69 | #define SimulateIOError(CODE) \ 70 | if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ 71 | || sqlite3_io_error_pending-- == 1 ) \ 72 | { local_ioerr(); CODE; } 73 | static void local_ioerr(){ 74 | IOTRACE(("IOERR\n")); 75 | sqlite3_io_error_hit++; 76 | if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; 77 | } 78 | #define SimulateDiskfullError(CODE) \ 79 | if( sqlite3_diskfull_pending ){ \ 80 | if( sqlite3_diskfull_pending == 1 ){ \ 81 | local_ioerr(); \ 82 | sqlite3_diskfull = 1; \ 83 | sqlite3_io_error_hit = 1; \ 84 | CODE; \ 85 | }else{ \ 86 | sqlite3_diskfull_pending--; \ 87 | } \ 88 | } 89 | #else 90 | #define SimulateIOErrorBenign(X) 91 | #define SimulateIOError(A) 92 | #define SimulateDiskfullError(A) 93 | #endif /* defined(SQLITE_TEST) */ 94 | 95 | /* 96 | ** When testing, keep a count of the number of open files. 97 | */ 98 | #if defined(SQLITE_TEST) 99 | extern int sqlite3_open_file_count; 100 | #define OpenCounter(X) sqlite3_open_file_count+=(X) 101 | #else 102 | #define OpenCounter(X) 103 | #endif /* defined(SQLITE_TEST) */ 104 | 105 | #endif /* !defined(_OS_COMMON_H_) */ 106 | -------------------------------------------------------------------------------- /src/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2001 September 22 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This is the header file for the generic hash-table implementation 13 | ** used in SQLite. 14 | */ 15 | #ifndef SQLITE_HASH_H 16 | #define SQLITE_HASH_H 17 | 18 | /* Forward declarations of structures. */ 19 | typedef struct Hash Hash; 20 | typedef struct HashElem HashElem; 21 | 22 | /* A complete hash table is an instance of the following structure. 23 | ** The internals of this structure are intended to be opaque -- client 24 | ** code should not attempt to access or modify the fields of this structure 25 | ** directly. Change this structure only by using the routines below. 26 | ** However, some of the "procedures" and "functions" for modifying and 27 | ** accessing this structure are really macros, so we can't really make 28 | ** this structure opaque. 29 | ** 30 | ** All elements of the hash table are on a single doubly-linked list. 31 | ** Hash.first points to the head of this list. 32 | ** 33 | ** There are Hash.htsize buckets. Each bucket points to a spot in 34 | ** the global doubly-linked list. The contents of the bucket are the 35 | ** element pointed to plus the next _ht.count-1 elements in the list. 36 | ** 37 | ** Hash.htsize and Hash.ht may be zero. In that case lookup is done 38 | ** by a linear search of the global list. For small tables, the 39 | ** Hash.ht table is never allocated because if there are few elements 40 | ** in the table, it is faster to do a linear search than to manage 41 | ** the hash table. 42 | */ 43 | struct Hash { 44 | unsigned int htsize; /* Number of buckets in the hash table */ 45 | unsigned int count; /* Number of entries in this table */ 46 | HashElem *first; /* The first element of the array */ 47 | struct _ht { /* the hash table */ 48 | int count; /* Number of entries with this hash */ 49 | HashElem *chain; /* Pointer to first entry with this hash */ 50 | } *ht; 51 | }; 52 | 53 | /* Each element in the hash table is an instance of the following 54 | ** structure. All elements are stored on a single doubly-linked list. 55 | ** 56 | ** Again, this structure is intended to be opaque, but it can't really 57 | ** be opaque because it is used by macros. 58 | */ 59 | struct HashElem { 60 | HashElem *next, *prev; /* Next and previous elements in the table */ 61 | void *data; /* Data associated with this element */ 62 | const char *pKey; /* Key associated with this element */ 63 | }; 64 | 65 | /* 66 | ** Access routines. To delete, insert a NULL pointer. 67 | */ 68 | void sqlite3HashInit(Hash*); 69 | void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); 70 | void *sqlite3HashFind(const Hash*, const char *pKey); 71 | void sqlite3HashClear(Hash*); 72 | 73 | /* 74 | ** Macros for looping over all elements of a hash table. The idiom is 75 | ** like this: 76 | ** 77 | ** Hash h; 78 | ** HashElem *p; 79 | ** ... 80 | ** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ 81 | ** SomeStructure *pData = sqliteHashData(p); 82 | ** // do something with pData 83 | ** } 84 | */ 85 | #define sqliteHashFirst(H) ((H)->first) 86 | #define sqliteHashNext(E) ((E)->next) 87 | #define sqliteHashData(E) ((E)->data) 88 | /* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ 89 | /* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ 90 | 91 | /* 92 | ** Number of entries in a hash table 93 | */ 94 | /* #define sqliteHashCount(H) ((H)->count) // NOT USED */ 95 | 96 | #endif /* SQLITE_HASH_H */ 97 | -------------------------------------------------------------------------------- /generator/vdbe_opcode.py: -------------------------------------------------------------------------------- 1 | opcodes = {"OP_Savepoint":0, 2 | "OP_AutoCommit":1, 3 | "OP_Transaction":2, 4 | "OP_SorterNext":3, 5 | "OP_PrevIfOpen":4, 6 | "OP_NextIfOpen":5, 7 | "OP_Prev":6, 8 | "OP_Next":7, 9 | "OP_Checkpoint":8, 10 | "OP_JournalMode":9, 11 | "OP_Vacuum":10, 12 | "OP_VFilter":11, 13 | "OP_VUpdate":12, 14 | "OP_Goto":13, 15 | "OP_Gosub":14, 16 | "OP_InitCoroutine":15, 17 | "OP_Yield":16, 18 | "OP_MustBeInt":17, 19 | "OP_Jump":18, 20 | "OP_Not":19, 21 | "OP_Once":20, 22 | "OP_If":21, 23 | "OP_IfNot":22, 24 | "OP_IfNullRow":23, 25 | "OP_SeekLT":24, 26 | "OP_SeekLE":25, 27 | "OP_SeekGE":26, 28 | "OP_SeekGT":27, 29 | "OP_NoConflict":28, 30 | "OP_NotFound":29, 31 | "OP_Found":30, 32 | "OP_SeekRowid":31, 33 | "OP_NotExists":32, 34 | "OP_Last":33, 35 | "OP_IfSmaller":34, 36 | "OP_SorterSort":35, 37 | "OP_Sort":36, 38 | "OP_Rewind":37, 39 | "OP_IdxLE":38, 40 | "OP_IdxGT":39, 41 | "OP_IdxLT":40, 42 | "OP_IdxGE":41, 43 | "OP_RowSetRead":42, 44 | "OP_Or":43, 45 | "OP_And":44, 46 | "OP_RowSetTest":45, 47 | "OP_Program":46, 48 | "OP_FkIfZero":47, 49 | "OP_IfPos":48, 50 | "OP_IfNotZero":49, 51 | "OP_IsNull":50, 52 | "OP_NotNull":51, 53 | "OP_Ne":52, 54 | "OP_Eq":53, 55 | "OP_Gt":54, 56 | "OP_Le":55, 57 | "OP_Lt":56, 58 | "OP_Ge":57, 59 | "OP_ElseNotEq":58, 60 | "OP_DecrJumpZero":59, 61 | "OP_IncrVacuum":60, 62 | "OP_VNext":61, 63 | "OP_Init":62, 64 | "OP_Return":63, 65 | "OP_EndCoroutine":64, 66 | "OP_HaltIfNull":65, 67 | "OP_Halt":66, 68 | "OP_Integer":67, 69 | "OP_Int64":68, 70 | "OP_String":69, 71 | "OP_Null":70, 72 | "OP_SoftNull":71, 73 | "OP_Blob":72, 74 | "OP_Variable":73, 75 | "OP_Move":74, 76 | "OP_Copy":75, 77 | "OP_SCopy":76, 78 | "OP_IntCopy":77, 79 | "OP_ResultRow":78, 80 | "OP_CollSeq":79, 81 | "OP_AddImm":80, 82 | "OP_RealAffinity":81, 83 | "OP_Cast":82, 84 | "OP_Permutation":83, 85 | "OP_BitAnd":84, 86 | "OP_BitOr":85, 87 | "OP_ShiftLeft":86, 88 | "OP_ShiftRight":87, 89 | "OP_Add":88, 90 | "OP_Subtract":89, 91 | "OP_Multiply":90, 92 | "OP_Divide":91, 93 | "OP_Remainder":92, 94 | "OP_Concat":93, 95 | "OP_Compare":94, 96 | "OP_BitNot":95, 97 | "OP_Offset":96, 98 | "OP_String8":97, 99 | "OP_Column":98, 100 | "OP_Affinity":99, 101 | "OP_MakeRecord":100, 102 | "OP_Count":101, 103 | "OP_ReadCookie":102, 104 | "OP_SetCookie":103, 105 | "OP_ReopenIdx":104, 106 | "OP_OpenRead":105, 107 | "OP_OpenWrite":106, 108 | "OP_OpenDup":107, 109 | "OP_OpenAutoindex":108, 110 | "OP_OpenEphemeral":109, 111 | "OP_SorterOpen":110, 112 | "OP_SequenceTest":111, 113 | "OP_OpenPseudo":112, 114 | "OP_Close":113, 115 | "OP_ColumnsUsed":114, 116 | "OP_Sequence":115, 117 | "OP_NewRowid":116, 118 | "OP_Insert":117, 119 | "OP_InsertInt":118, 120 | "OP_Delete":119, 121 | "OP_ResetCount":120, 122 | "OP_SorterCompare":121, 123 | "OP_SorterData":122, 124 | "OP_RowData":123, 125 | "OP_Rowid":124, 126 | "OP_NullRow":125, 127 | "OP_SeekEnd":126, 128 | "OP_SorterInsert":127, 129 | "OP_IdxInsert":128, 130 | "OP_IdxDelete":129, 131 | "OP_DeferredSeek":130, 132 | "OP_IdxRowid":131, 133 | "OP_Real":132, 134 | "OP_Destroy":133, 135 | "OP_Clear":134, 136 | "OP_ResetSorter":135, 137 | "OP_CreateBtree":136, 138 | "OP_SqlExec":137, 139 | "OP_ParseSchema":138, 140 | "OP_LoadAnalysis":139, 141 | "OP_DropTable":140, 142 | "OP_DropIndex":141, 143 | "OP_DropTrigger":142, 144 | "OP_IntegrityCk":143, 145 | "OP_RowSetAdd":144, 146 | "OP_Param":145, 147 | "OP_FkCounter":146, 148 | "OP_MemMax":147, 149 | "OP_OffsetLimit":148, 150 | "OP_AggStep0":149, 151 | "OP_AggStep":150, 152 | "OP_AggFinal":151, 153 | "OP_Expire":152, 154 | "OP_TableLock":153, 155 | "OP_VBegin":154, 156 | "OP_VCreate":155, 157 | "OP_VDestroy":156, 158 | "OP_VOpen":157, 159 | "OP_VColumn":158, 160 | "OP_VRename":159, 161 | "OP_Pagecount":160, 162 | "OP_MaxPgcnt":161, 163 | "OP_PureFunc0":162, 164 | "OP_Function0":163, 165 | "OP_PureFunc":164, 166 | "OP_Function":165, 167 | "OP_Trace":166, 168 | "OP_CursorHint":167, 169 | "OP_Noop":168, 170 | "OP_Explain":169} 171 | 172 | def get_opcode(opcode_number): 173 | return opcodes[opcode_number] -------------------------------------------------------------------------------- /generator/construct_emit.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | import logging 4 | import sys 5 | from vdbe_opcode import get_opcode 6 | from pycparser import c_parser, parse_file, c_generator 7 | from pycparser.c_ast import NodeVisitor, ArrayRef, Assignment, ID as cID, \ 8 | Return, Goto, FuncCall, ExprList, Break, Case 9 | from pathlib import Path 10 | from gen_util import OpcodeFinder, CodeFinder 11 | from template_gen import OpcodeTemplateGenerator 12 | import re 13 | from copy import deepcopy 14 | 15 | parent_dir = str(Path(__file__).resolve().parent) 16 | 17 | # This is not required if you've installed pycparser into 18 | # your site-packages/ with setup.py 19 | sys.path.extend(['.', '..']) 20 | 21 | class EmitterGenerator(c_generator.CGenerator): 22 | 23 | def __init__(self): 24 | super().__init__() 25 | self.emitter_ast = parse_file(parent_dir+'/cfiles/emitTemplate_prep.c', use_cpp=False) 26 | finder = CodeFinder() 27 | self.emitFunc = finder.find_func('emitTxt', self.emitter_ast) 28 | self.switch = finder.get_switches(self.emitFunc.body)[0] 29 | self.emit_funcs = [] 30 | self.func_defs = finder.get_funcs(self.emitter_ast) 31 | 32 | def __get_call(self, name): 33 | return FuncCall(cID(name), ExprList([cID(s) for s in 'p,cOp,&tmp,i'.split(',')])) 34 | 35 | def __get_case(self, op_gen): 36 | func_call = self.__get_call('emit{}'.format(op_gen.name)) 37 | return Case(cID(op_gen.opcode_name), [func_call, Break()]) 38 | 39 | def add_impl(self, op_gen): 40 | EMIT_FUNC_TEMPL = ''' 41 | static void emit{}(Vdbe *p, Op *pOp, TxtBuf **buf, int pos) {{ 42 | writeToBuf(buf, "{}; \\n", {}); 43 | }} ''' 44 | func_str = EMIT_FUNC_TEMPL.format(op_gen.name, op_gen.get_format_str(), ', '.join(op_gen.params)) 45 | self.switch.block_items.insert(0, self.__get_case(op_gen)) 46 | self.emit_funcs.append(func_str) 47 | 48 | def get_code(self): 49 | include_str = '#include "emit.h"\n' 50 | code = include_str + '\n'.join(self.emit_funcs + [self.visit(f) for f in self.func_defs]) 51 | return code 52 | 53 | def generate_code(filename): 54 | ast = parse_file(filename, use_cpp=False) 55 | opcodes_to_implement = ["OP_Multiply", "OP_Subtract", "OP_Divide", "OP_Integer", "OP_Add" , "OP_ResultRow", "OP_Column", "OP_Le", "OP_Lt", "OP_Ge", "OP_Gt", "OP_Copy", "OP_AggStep", "OP_Eq", "OP_Ne"] 56 | opcode_finder = OpcodeFinder(ast) 57 | code = [] 58 | emitGen = EmitterGenerator() 59 | for opcode_name in opcodes_to_implement: 60 | opcode_impl = opcode_finder.find_opcode_impl(opcode_name) 61 | if opcode_impl is None: 62 | logger = logging.getLogger("constructor") 63 | logger.warning("{} not found".format(opcode_name)) 64 | else: 65 | op_gen = OpcodeTemplateGenerator(opcode_name, debug_mode) 66 | op_templ = op_gen.visit_Opcode(deepcopy(opcode_impl)) 67 | emitGen.add_impl(op_gen) 68 | code.append(op_templ) 69 | 70 | return ("\n \n".join(code), emitGen.get_code()) 71 | 72 | debug_mode = False 73 | 74 | if __name__ == "__main__": 75 | parser = argparse.ArgumentParser() 76 | parser.add_argument("-i", help="preprocessed vdbe file", action="store", default=parent_dir+"/cfiles/vdbe_prep.c") 77 | parser.add_argument("-o", help="output directory", action="store", default=parent_dir+'/out/') 78 | parser.add_argument("-d", help="set to debug mode", action="store_const", const=True, default=False) 79 | args = parser.parse_args() 80 | templates, emitter = generate_code(args.i) 81 | 82 | debug_mode = args.d 83 | out_dir = args.o 84 | try: 85 | templ_f = out_dir+'/opcodeTemplates.h' 86 | emit_f = out_dir+'/emit.c' 87 | 88 | with open(templ_f, "w") as f: 89 | f.write(templates) 90 | 91 | with open(emit_f, 'w') as f: 92 | f.write(emitter) 93 | except Exception as e: 94 | print(e) 95 | parser.print_help() 96 | -------------------------------------------------------------------------------- /versions/sqlite_jit/jitsrc/jitted_func.h: -------------------------------------------------------------------------------- 1 | #ifndef JITTED_FUNC_H 2 | #define JITTED_FUNC_H 3 | 4 | #include "sqliteInt.h" 5 | #include "vdbeInt.h" 6 | #include "jitCommons.h" 7 | 8 | /* 9 | ** Return the register of pOp->p2 after first preparing it to be 10 | ** overwritten with an integer value. 11 | */ 12 | static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ 13 | sqlite3VdbeMemSetNull(pOut); 14 | pOut->flags = MEM_Int; 15 | return pOut; 16 | } 17 | static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ 18 | Mem *pOut; 19 | pOut = &p->aMem[pOp->p2]; 20 | if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ 21 | return out2PrereleaseWithClear(pOut); 22 | }else{ 23 | pOut->flags = MEM_Int; 24 | return pOut; 25 | } 26 | } 27 | 28 | 29 | /* 30 | ** pMem currently only holds a string type (or maybe a BLOB that we can 31 | ** interpret as a string if we want to). Compute its corresponding 32 | ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields 33 | ** accordingly. 34 | */ 35 | static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ 36 | assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); 37 | assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); 38 | if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ 39 | return 0; 40 | } 41 | if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){ 42 | return MEM_Int; 43 | } 44 | return MEM_Real; 45 | } 46 | 47 | /* 48 | ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or 49 | ** none. 50 | ** 51 | ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. 52 | ** But it does set pMem->u.r and pMem->u.i appropriately. 53 | */ 54 | static u16 numericType(Mem *pMem){ 55 | if( pMem->flags & (MEM_Int|MEM_Real) ){ 56 | return pMem->flags & (MEM_Int|MEM_Real); 57 | } 58 | if( pMem->flags & (MEM_Str|MEM_Blob) ){ 59 | return computeNumericType(pMem); 60 | } 61 | return 0; 62 | } 63 | 64 | static void applyNumericAffinity(Mem *pRec, int bTryForInt){ 65 | double rValue; 66 | i64 iValue; 67 | u8 enc = pRec->enc; 68 | assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); 69 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; 70 | if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ 71 | pRec->u.i = iValue; 72 | pRec->flags |= MEM_Int; 73 | }else{ 74 | pRec->u.r = rValue; 75 | pRec->flags |= MEM_Real; 76 | if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); 77 | } 78 | /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the 79 | ** string representation after computing a numeric equivalent, because the 80 | ** string representation might not be the canonical representation for the 81 | ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */ 82 | pRec->flags &= ~MEM_Str; 83 | } 84 | 85 | static void applyAffinity( 86 | Mem *pRec, /* The value to apply affinity to */ 87 | char affinity, /* The affinity to be applied */ 88 | u8 enc /* Use this text encoding */ 89 | ){ 90 | if( affinity>=SQLITE_AFF_NUMERIC ){ 91 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL 92 | || affinity==SQLITE_AFF_NUMERIC ); 93 | if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ 94 | if( (pRec->flags & MEM_Real)==0 ){ 95 | if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); 96 | }else{ 97 | sqlite3VdbeIntegerAffinity(pRec); 98 | } 99 | } 100 | }else if( affinity==SQLITE_AFF_TEXT ){ 101 | /* Only attempt the conversion to TEXT if there is an integer or real 102 | ** representation (blob and NULL do not get converted) but no string 103 | ** representation. It would be harmless to repeat the conversion if 104 | ** there is already a string rep, but it is pointless to waste those 105 | ** CPU cycles. */ 106 | if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ 107 | if( (pRec->flags&(MEM_Real|MEM_Int)) ){ 108 | sqlite3VdbeMemStringify(pRec, enc, 1); 109 | } 110 | } 111 | pRec->flags &= ~(MEM_Real|MEM_Int); 112 | } 113 | } 114 | 115 | 116 | 117 | #endif /* JITTED_FUNC_H */ 118 | -------------------------------------------------------------------------------- /versions/sqlite_jit_spec/jitsrc/jitted_func.h: -------------------------------------------------------------------------------- 1 | #ifndef JITTED_FUNC_H 2 | #define JITTED_FUNC_H 3 | 4 | #include "sqliteInt.h" 5 | #include "vdbeInt.h" 6 | #include "jitCommons.h" 7 | 8 | /* 9 | ** Return the register of pOp->p2 after first preparing it to be 10 | ** overwritten with an integer value. 11 | */ 12 | static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ 13 | sqlite3VdbeMemSetNull(pOut); 14 | pOut->flags = MEM_Int; 15 | return pOut; 16 | } 17 | static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ 18 | Mem *pOut; 19 | pOut = &p->aMem[pOp->p2]; 20 | if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ 21 | return out2PrereleaseWithClear(pOut); 22 | }else{ 23 | pOut->flags = MEM_Int; 24 | return pOut; 25 | } 26 | } 27 | 28 | 29 | /* 30 | ** pMem currently only holds a string type (or maybe a BLOB that we can 31 | ** interpret as a string if we want to). Compute its corresponding 32 | ** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields 33 | ** accordingly. 34 | */ 35 | static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ 36 | assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); 37 | assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); 38 | if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ 39 | return 0; 40 | } 41 | if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){ 42 | return MEM_Int; 43 | } 44 | return MEM_Real; 45 | } 46 | 47 | /* 48 | ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or 49 | ** none. 50 | ** 51 | ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. 52 | ** But it does set pMem->u.r and pMem->u.i appropriately. 53 | */ 54 | static u16 numericType(Mem *pMem){ 55 | if( pMem->flags & (MEM_Int|MEM_Real) ){ 56 | return pMem->flags & (MEM_Int|MEM_Real); 57 | } 58 | if( pMem->flags & (MEM_Str|MEM_Blob) ){ 59 | return computeNumericType(pMem); 60 | } 61 | return 0; 62 | } 63 | 64 | static void applyNumericAffinity(Mem *pRec, int bTryForInt){ 65 | double rValue; 66 | i64 iValue; 67 | u8 enc = pRec->enc; 68 | assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); 69 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; 70 | if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ 71 | pRec->u.i = iValue; 72 | pRec->flags |= MEM_Int; 73 | }else{ 74 | pRec->u.r = rValue; 75 | pRec->flags |= MEM_Real; 76 | if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); 77 | } 78 | /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the 79 | ** string representation after computing a numeric equivalent, because the 80 | ** string representation might not be the canonical representation for the 81 | ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */ 82 | pRec->flags &= ~MEM_Str; 83 | } 84 | 85 | static void applyAffinity( 86 | Mem *pRec, /* The value to apply affinity to */ 87 | char affinity, /* The affinity to be applied */ 88 | u8 enc /* Use this text encoding */ 89 | ){ 90 | if( affinity>=SQLITE_AFF_NUMERIC ){ 91 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL 92 | || affinity==SQLITE_AFF_NUMERIC ); 93 | if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ 94 | if( (pRec->flags & MEM_Real)==0 ){ 95 | if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); 96 | }else{ 97 | sqlite3VdbeIntegerAffinity(pRec); 98 | } 99 | } 100 | }else if( affinity==SQLITE_AFF_TEXT ){ 101 | /* Only attempt the conversion to TEXT if there is an integer or real 102 | ** representation (blob and NULL do not get converted) but no string 103 | ** representation. It would be harmless to repeat the conversion if 104 | ** there is already a string rep, but it is pointless to waste those 105 | ** CPU cycles. */ 106 | if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ 107 | if( (pRec->flags&(MEM_Real|MEM_Int)) ){ 108 | sqlite3VdbeMemStringify(pRec, enc, 1); 109 | } 110 | } 111 | pRec->flags &= ~(MEM_Real|MEM_Int); 112 | } 113 | } 114 | 115 | 116 | 117 | #endif /* JITTED_FUNC_H */ 118 | -------------------------------------------------------------------------------- /testing/make_plot.py: -------------------------------------------------------------------------------- 1 | import matplotlib 2 | matplotlib.use('Agg') 3 | import pandas as pd 4 | import numpy as np 5 | import seaborn as sns 6 | import sklearn.linear_model 7 | import re 8 | import argparse 9 | from matplotlib import pyplot as plt 10 | from pathlib import Path 11 | import matplotlib.ticker as ticker 12 | 13 | PROJECT_DIR = str(Path(__file__).resolve().parent.parent) 14 | 15 | sns.set() 16 | sns.set_context("paper", font_scale=1.7) 17 | sns.set_style("whitegrid", { 18 | "font.family": "serif", 19 | "font.serif": ["Times", "Palatino", "serif"], 20 | }) 21 | sns.set_palette("colorblind") 22 | 23 | def get_df(file_path): 24 | df = pd.read_csv(file_path) 25 | df['total'] = df['user']+df['system'] 26 | df['elapsed'] = df['elapsed'].apply(lambda x: float(x.split(':')[1])) 27 | return df 28 | 29 | def add_line(df, type_str, x, y, name, marker): 30 | vals = df[df['type'] == type_str][[x,y]] 31 | regr = sklearn.linear_model.LinearRegression() 32 | regr.fit(vals[x].values.reshape(-1, 1), vals[y].values.reshape(-1, 1)) 33 | baseline_label = name + ' (slope={})'.format(round(regr.coef_[0][0], 3)) 34 | return sns.regplot(x=vals[x], y=vals[y], x_estimator=np.mean, truncate=True, label=baseline_label, marker=marker) #, scatter_kws={"s": 30}) 35 | 36 | def make_plot(df, x, y, baseline='sqlite', jit='sqlite_jit'): 37 | f = plt.figure(num=None, figsize=(7, 4.5), dpi=100) 38 | add_line(df, baseline, x, y, "Baseline", "X") 39 | ax = add_line(df, jit, x, y, "JIT", "s") 40 | 41 | return ax, f 42 | 43 | def make_spec_plot(df, y = 'total', title=''): 44 | ax, f = make_plot(df, 'jitops', y, baseline='sqlite_spec', jit='sqlite_jit_spec') 45 | xlim_max = max(df['jitops'])+5 46 | ylim_max = max(df[y])+1 47 | 48 | ax.set(xlim=(-1,xlim_max), ylim=(-1,ylim_max)) 49 | ax.set_title(title) 50 | ax.set_ylabel('CPU Time (s)') 51 | ax.set_xlabel('Number of jitted operations') 52 | plt.legend(frameon=True) 53 | return f 54 | 55 | def make_general_plot(df, y = 'total', title=''): 56 | x = 'jitops' 57 | ax, f = make_plot(df, x, y) 58 | ax = add_line(df, "sqlite_disp", x, y, "Threaded", 'D') 59 | 60 | compile_time = df.loc[df['type'] == 'sqlite_jit']['compile_time'] 61 | x_jit = df.loc[df['type'] == 'sqlite_jit']['jitops'] 62 | regr = sklearn.linear_model.LinearRegression() 63 | regr.fit(x_jit.values.reshape(-1, 1), compile_time.values.reshape(-1, 1)) 64 | compile_label = 'Compilation (slope={})'.format(round(regr.coef_[0][0], 3)) 65 | sns.regplot(x=x_jit, y=compile_time, x_estimator=np.mean, truncate=True, label=compile_label, marker='o') 66 | 67 | 68 | xlim_max = max(df['jitops'])+5 69 | ylim_max = max(df[y])+3 70 | 71 | ax.set(xlim=(-1,xlim_max), ylim=(-1,ylim_max)) 72 | ax.set_title(title) 73 | ax.set_ylabel('CPU Time (s)') 74 | ax.set_xlabel('Number of jitted operations') 75 | plt.legend(frameon=True) 76 | return f 77 | 78 | 79 | def make_selectivity_plot(df, y = 'total', title=''): 80 | x = 'selectivity' 81 | ax, f = make_plot(df, x, y) 82 | ax = add_line(df, "sqlite_disp", x, y, "Threaded", 'D') 83 | xlim_max = max(df['selectivity']) 84 | xlim_max += int(xlim_max*0.1) 85 | ylim_max = max(df[y]) 86 | ylim_max += int(ylim_max*0.2) 87 | 88 | ax.set(xlim=(-10,xlim_max), ylim=(0,ylim_max)) 89 | ax.set_ylabel('CPU Time (s)') 90 | ax.set_xlabel('Percent of selected entries') 91 | #ax.yaxis.set_major_locator(ticker.MultipleLocator(2)) 92 | plt.legend(frameon=True, loc='lower right') 93 | 94 | return f 95 | 96 | if __name__ == '__main__': 97 | parser = argparse.ArgumentParser() 98 | parser.add_argument("experiment", help="which experiment to run: a|A, b|B, c|C", action='store') 99 | parser.add_argument("-f", help="input file with the measurements", action='store') 100 | args = parser.parse_args() 101 | df = get_df(args.f) 102 | name = args.f.split('/')[-1] 103 | if args.experiment.lower() == 'a': 104 | f = make_general_plot(df) 105 | elif args.experiment.lower() == 'b': 106 | f = make_selectivity_plot(df) 107 | elif args.experiment.lower() == 'c': 108 | f = make_spec_plot(df) 109 | 110 | file_path = PROJECT_DIR+"/img/{}.pdf".format(name) 111 | f.savefig(file_path, bbox_inches='tight') 112 | print(file_path) 113 | -------------------------------------------------------------------------------- /src/random.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2001 September 15 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This file contains code to implement a pseudo-random number 13 | ** generator (PRNG) for SQLite. 14 | ** 15 | ** Random numbers are used by some of the database backends in order 16 | ** to generate random integer keys for tables or random filenames. 17 | */ 18 | #include "sqliteInt.h" 19 | 20 | 21 | /* All threads share a single random number generator. 22 | ** This structure is the current state of the generator. 23 | */ 24 | static SQLITE_WSD struct sqlite3PrngType { 25 | unsigned char isInit; /* True if initialized */ 26 | unsigned char i, j; /* State variables */ 27 | unsigned char s[256]; /* State variables */ 28 | } sqlite3Prng; 29 | 30 | /* 31 | ** Return N random bytes. 32 | */ 33 | void sqlite3_randomness(int N, void *pBuf){ 34 | unsigned char t; 35 | unsigned char *zBuf = pBuf; 36 | 37 | /* The "wsdPrng" macro will resolve to the pseudo-random number generator 38 | ** state vector. If writable static data is unsupported on the target, 39 | ** we have to locate the state vector at run-time. In the more common 40 | ** case where writable static data is supported, wsdPrng can refer directly 41 | ** to the "sqlite3Prng" state vector declared above. 42 | */ 43 | #ifdef SQLITE_OMIT_WSD 44 | struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); 45 | # define wsdPrng p[0] 46 | #else 47 | # define wsdPrng sqlite3Prng 48 | #endif 49 | 50 | #if SQLITE_THREADSAFE 51 | sqlite3_mutex *mutex; 52 | #endif 53 | 54 | #ifndef SQLITE_OMIT_AUTOINIT 55 | if( sqlite3_initialize() ) return; 56 | #endif 57 | 58 | #if SQLITE_THREADSAFE 59 | mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); 60 | #endif 61 | 62 | sqlite3_mutex_enter(mutex); 63 | if( N<=0 || pBuf==0 ){ 64 | wsdPrng.isInit = 0; 65 | sqlite3_mutex_leave(mutex); 66 | return; 67 | } 68 | 69 | /* Initialize the state of the random number generator once, 70 | ** the first time this routine is called. The seed value does 71 | ** not need to contain a lot of randomness since we are not 72 | ** trying to do secure encryption or anything like that... 73 | ** 74 | ** Nothing in this file or anywhere else in SQLite does any kind of 75 | ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random 76 | ** number generator) not as an encryption device. 77 | */ 78 | if( !wsdPrng.isInit ){ 79 | int i; 80 | char k[256]; 81 | wsdPrng.j = 0; 82 | wsdPrng.i = 0; 83 | sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); 84 | for(i=0; i<256; i++){ 85 | wsdPrng.s[i] = (u8)i; 86 | } 87 | for(i=0; i<256; i++){ 88 | wsdPrng.j += wsdPrng.s[i] + k[i]; 89 | t = wsdPrng.s[wsdPrng.j]; 90 | wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; 91 | wsdPrng.s[i] = t; 92 | } 93 | wsdPrng.isInit = 1; 94 | } 95 | 96 | assert( N>0 ); 97 | do{ 98 | wsdPrng.i++; 99 | t = wsdPrng.s[wsdPrng.i]; 100 | wsdPrng.j += t; 101 | wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; 102 | wsdPrng.s[wsdPrng.j] = t; 103 | t += wsdPrng.s[wsdPrng.i]; 104 | *(zBuf++) = wsdPrng.s[t]; 105 | }while( --N ); 106 | sqlite3_mutex_leave(mutex); 107 | } 108 | 109 | #ifndef SQLITE_UNTESTABLE 110 | /* 111 | ** For testing purposes, we sometimes want to preserve the state of 112 | ** PRNG and restore the PRNG to its saved state at a later time, or 113 | ** to reset the PRNG to its initial state. These routines accomplish 114 | ** those tasks. 115 | ** 116 | ** The sqlite3_test_control() interface calls these routines to 117 | ** control the PRNG. 118 | */ 119 | static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; 120 | void sqlite3PrngSaveState(void){ 121 | memcpy( 122 | &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), 123 | &GLOBAL(struct sqlite3PrngType, sqlite3Prng), 124 | sizeof(sqlite3Prng) 125 | ); 126 | } 127 | void sqlite3PrngRestoreState(void){ 128 | memcpy( 129 | &GLOBAL(struct sqlite3PrngType, sqlite3Prng), 130 | &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), 131 | sizeof(sqlite3Prng) 132 | ); 133 | } 134 | #endif /* SQLITE_UNTESTABLE */ 135 | -------------------------------------------------------------------------------- /generator/template_gen.py: -------------------------------------------------------------------------------- 1 | from vdbe_opcode import get_opcode 2 | from pycparser import c_parser, parse_file, c_generator 3 | from pycparser.c_ast import NodeVisitor, ArrayRef, Assignment, ID, Return, Goto 4 | import re 5 | import logging 6 | 7 | class OpcodeTemplateGenerator(c_generator.CGenerator): 8 | def __init__(self, opcode_name, debug_mode): 9 | super().__init__() 10 | self.debug_mode = debug_mode 11 | self.opcode_name = opcode_name 12 | self.opcode = get_opcode(opcode_name) 13 | self.name = re.match(r"OP_(\w*)", opcode_name).group(1).upper() 14 | self.param_names = ['pos', 'next'] 15 | self.params = ['pos', 'pos+1'] 16 | self.formats = ['%d', '%d'] 17 | self.breakable = 0 18 | self.goto_error_re = re.compile(r"(\w*error\w*|no_mem|too_big)") 19 | self.goto_dict = {} 20 | 21 | def get_name(self): 22 | return "{}_TEMPL".format(self.name) 23 | 24 | def get_format_str(self): 25 | return "{}({})".format(self.get_name(), ",".join(self.formats)) 26 | 27 | def get_macro(self): 28 | return "{}({})".format(self.get_name(), ",".join(self.param_names)) 29 | 30 | def get_header(self): 31 | HEADER = "#define {} \\\nL##pos: \\\n" 32 | return HEADER.format(self.get_macro()) 33 | 34 | def visit_Opcode(self, node): 35 | pOp_assignment = Assignment('=', ID("pOp"), ArrayRef(ID("&aOp"), ID("pos"))) 36 | try: 37 | node.stmts[0].block_items = [pOp_assignment] + node.stmts[0].block_items 38 | except Exception as e: 39 | logger = logging.getLogger("OpGen") 40 | logger.error("Opcode implementation not enclosed in a block!") 41 | 42 | code = self.visit(node) 43 | if self.debug_mode: 44 | code = ["__NL__"+line+"\\" for line in code.split("\n") if line.strip() != ";"] 45 | else: 46 | code = [line+"\\" for line in code.split("\n") if line.strip() != ";"] 47 | code_str = "\n".join(code[1:])[:-1] 48 | 49 | return self.get_header() + code_str+'; \n' 50 | 51 | def visit_Switch(self, node): 52 | return self.visit_Breakable(node) 53 | 54 | def visit_For(self, node): 55 | return self.visit_Breakable(node) 56 | 57 | def visit_While(self, node): 58 | return self.visit_Breakable(node) 59 | 60 | def visit_Breakable(self, node): 61 | self.breakable += 1 62 | method = 'visit_' + node.__class__.__name__ 63 | string = getattr(super(), method, self.generic_visit)(node) 64 | self.breakable -= 1 65 | return string 66 | 67 | def visit_Break(self, node): 68 | if self.breakable == 0: 69 | return 'goto L##next;' 70 | else: 71 | return super().visit_Break(node) 72 | 73 | def visit_StructRef(self, node): 74 | string = super().visit_StructRef(node) 75 | try: 76 | if (node.name.name == "pOp" and 77 | re.match("p[1,2,3]", node.field.name) is not None): 78 | self.__add_param(string, 'j'+node.field.name, '%d') 79 | return 'j'+node.field.name 80 | 81 | if node.name.name == "pOp" and node.field.name == "opcode": 82 | return str(self.opcode) 83 | 84 | except Exception as e: 85 | logger = logging.getLogger("OpGen") 86 | logger.warning(e) 87 | 88 | return string 89 | 90 | def visit_FuncCall(self, node): 91 | if node.name.name == "assert": 92 | return "" 93 | return super().visit_FuncCall(node) 94 | 95 | def __add_param(self, param, param_name, format_str): 96 | if not param_name in self.param_names: 97 | self.param_names.append(param_name) 98 | self.params.append(param) 99 | self.formats.append(format_str) 100 | 101 | def visit_Label(self, node): 102 | return super().visit_Label(node).replace(':', '##pos:') 103 | 104 | def visit_Goto(self, node): 105 | if self.goto_error_re.match(node.name) is not None: 106 | return 'return ERROR;' 107 | 108 | elif node.name == "vdbe_return": 109 | rc = "ROW" if self.name.find("ROW") != -1 else "OK" 110 | return 'return {};'.format(rc) 111 | 112 | elif node.name == "jump_to_p2": 113 | if not "p2" in self.param_names: 114 | self.__add_param('pOp->p2', 'jp2', '%d') 115 | 116 | return 'goto L##jp2;' 117 | 118 | else: 119 | return super().visit_Goto(node).replace(';', '##pos;') 120 | 121 | -------------------------------------------------------------------------------- /testing/measure_overhead.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import subprocess 3 | import re 4 | from gen_query import gen_query 5 | import argparse 6 | import logging 7 | from definitions import PROJECT_DIR 8 | 9 | HEADER = "jitops,user,system,elapsed,cpu,compile_time,type,selectivity\n" 10 | JIT = "sqlite_jit" 11 | DISPATCH = "sqlite_disp" 12 | BASELINE = "sqlite" 13 | JIT_SPEC = "sqlite_jit_spec" 14 | BASELINE_SPEC = "sqlite_spec" 15 | logger = logging.getLogger("measure") 16 | logging.basicConfig(level=logging.INFO) 17 | 18 | def get_args(): 19 | parser = argparse.ArgumentParser() 20 | parser.add_argument("test", help="the experiment to run: A | B | C | all", action="store", default='general') 21 | parser.add_argument("-n", help="number of tests", action="store", type=int, default=5) 22 | parser.add_argument("-r", help="number of repetitions", action="store", type=int, default=5) 23 | parser.add_argument("--debug", help="enable debug prints", action="store_const", const=True, default=False) 24 | 25 | return parser.parse_args(), parser 26 | 27 | def run_test(query, name): 28 | path = PROJECT_DIR + '/bin/' + name 29 | command = '/usr/bin/time -f "%U,%S,%E,%P" /bin/bash -c \'echo "{}" | {} {}/data/test.db \'' 30 | command = command.format(query, path, PROJECT_DIR) 31 | 32 | if args.debug: 33 | logger.info(command) 34 | 35 | res=subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) 36 | res_str = res.stderr.decode('utf-8') 37 | 38 | compile_time = '0' 39 | jit_ops = -1 40 | try: 41 | jit_ops = int(re.match("jitted ops: (\d+)", res_str).group(1)) 42 | res_str = re.sub('jitted ops: \d+, ', '', res_str) 43 | 44 | compile_command = '/usr/bin/time -f "%U %S" bash -c "cc /tmp/jitted_func.c -O2 -o /tmp/dummy_obj.so -I{0}/src -I{0}/versions/sqlite_jit/jitsrc -lsqlite -L{0}/versions/sqlite_jit/lib/ -fPIC -shared"'.format(PROJECT_DIR) 45 | compile_res = subprocess.run(compile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) 46 | compile_time = str(round(sum(map(float, compile_res.stderr.decode('utf-8').split())), 3)) 47 | except: 48 | pass 49 | 50 | res_str = res_str.strip() 51 | res_str = ",".join([res_str, compile_time, name]) 52 | return res_str, jit_ops 53 | 54 | def run_test_versions(f, n_query_tests, versions, selectivity=0): 55 | query, selection = gen_query(n_tests=n_query_tests, selectivity=selectivity) 56 | jit_ops = 0 57 | 58 | for version in versions: 59 | res, new_jit_ops = run_test(query, version) 60 | jit_ops = max(jit_ops, new_jit_ops) 61 | f.write("{},{},{}\n".format(jit_ops, res,selection)) 62 | 63 | def run_general_tests(versions): 64 | f, file_name = get_file("general") 65 | f.write(HEADER) 66 | j = 1 67 | for i in range(1, n_tests*3+1, 3): 68 | logger.info("test: {}/{}".format(j, n_tests)) 69 | j+=1 70 | for repetition in range(repetitions): 71 | logger.info("{}/{}".format(repetition+1, repetitions)) 72 | run_test_versions(f, i, versions) 73 | f.close() 74 | print(file_name) 75 | 76 | def run_selectivity_tests(): 77 | n_query_tests = 30 78 | n_select_range = 9 79 | name = "select" 80 | f, file_name = get_file(name) 81 | f.write(HEADER) 82 | j = 1 83 | versions = [JIT, BASELINE, DISPATCH] 84 | for i in range(n_select_range): 85 | logger.info("test: {}/{}".format(j, n_select_range)) 86 | j+=1 87 | for repetition in range(repetitions): 88 | logger.info("{}/{}".format(repetition+1, repetitions)) 89 | run_test_versions(f, n_query_tests, versions, i) 90 | f.close() 91 | print(file_name) 92 | 93 | def get_file(name="result"): 94 | time = str(datetime.datetime.now().time()).replace(':', '').replace('.', '') 95 | file_name = "{}/results/{}_{}".format(PROJECT_DIR, name, time) 96 | f = open(file_name, 'w') 97 | return f, file_name 98 | 99 | 100 | args, parser = get_args() 101 | repetitions = args.r 102 | n_tests = args.n 103 | args.test = args.test.upper() 104 | if args.test == 'A': 105 | run_general_tests([JIT, BASELINE, DISPATCH]) 106 | elif args.test == 'B': 107 | run_selectivity_tests() 108 | elif args.test == 'C': 109 | run_general_tests([JIT_SPEC, BASELINE_SPEC]) 110 | elif args.test == 'all': 111 | run_general_tests([JIT, BASELINE, DISPATCH]) 112 | run_selectivity_tests() 113 | run_general_tests([JIT_SPEC, BASELINE_SPEC]) 114 | else: 115 | logger.error("No such command: {}".format(args.test)) 116 | parser.print_help() 117 | -------------------------------------------------------------------------------- /results/general_043840904339: -------------------------------------------------------------------------------- 1 | jitops,user,system,elapsed,cpu,compile_time,type,selectivity 2 | 6,1.67,0.24,0:02.00,95%,0.06,sqlite_jit_spec,0 3 | 6,2.17,0.24,0:02.52,95%,0,sqlite_spec,0 4 | 6,1.68,0.22,0:01.99,95%,0.07,sqlite_jit_spec,0 5 | 6,2.16,0.24,0:02.51,95%,0,sqlite_spec,0 6 | 6,1.67,0.23,0:01.98,95%,0.07,sqlite_jit_spec,0 7 | 6,2.16,0.24,0:02.51,95%,0,sqlite_spec,0 8 | 6,1.66,0.23,0:01.98,95%,0.07,sqlite_jit_spec,0 9 | 6,2.16,0.26,0:02.52,95%,0,sqlite_spec,0 10 | 6,1.69,0.22,0:02.00,95%,0.07,sqlite_jit_spec,0 11 | 6,2.16,0.24,0:02.51,95%,0,sqlite_spec,0 12 | 12,1.75,0.23,0:02.07,95%,0.12,sqlite_jit_spec,0 13 | 12,3.00,0.21,0:03.35,95%,0,sqlite_spec,0 14 | 12,1.73,0.26,0:02.09,95%,0.12,sqlite_jit_spec,0 15 | 12,2.99,0.23,0:03.36,95%,0,sqlite_spec,0 16 | 12,1.76,0.23,0:02.09,95%,0.12,sqlite_jit_spec,0 17 | 12,2.99,0.23,0:03.36,95%,0,sqlite_spec,0 18 | 12,1.76,0.23,0:02.08,95%,0.12,sqlite_jit_spec,0 19 | 12,3.02,0.20,0:03.36,95%,0,sqlite_spec,0 20 | 12,1.74,0.25,0:02.08,95%,0.12,sqlite_jit_spec,0 21 | 12,2.98,0.23,0:03.35,95%,0,sqlite_spec,0 22 | 18,1.82,0.26,0:02.17,95%,0.17,sqlite_jit_spec,0 23 | 18,3.85,0.24,0:04.27,95%,0,sqlite_spec,0 24 | 18,1.84,0.23,0:02.17,95%,0.17,sqlite_jit_spec,0 25 | 18,3.85,0.23,0:04.26,95%,0,sqlite_spec,0 26 | 18,1.84,0.24,0:02.17,95%,0.17,sqlite_jit_spec,0 27 | 18,3.85,0.24,0:04.27,95%,0,sqlite_spec,0 28 | 18,1.81,0.25,0:02.16,95%,0.17,sqlite_jit_spec,0 29 | 18,3.83,0.25,0:04.27,95%,0,sqlite_spec,0 30 | 18,1.82,0.25,0:02.17,95%,0.17,sqlite_jit_spec,0 31 | 18,3.86,0.22,0:04.26,95%,0,sqlite_spec,0 32 | 24,2.00,0.24,0:02.33,95%,0.22,sqlite_jit_spec,0 33 | 24,4.69,0.26,0:05.17,95%,0,sqlite_spec,0 34 | 24,1.99,0.25,0:02.34,95%,0.22,sqlite_jit_spec,0 35 | 24,4.70,0.25,0:05.17,95%,0,sqlite_spec,0 36 | 24,2.05,0.25,0:02.40,95%,0.22,sqlite_jit_spec,0 37 | 24,4.72,0.23,0:05.17,95%,0,sqlite_spec,0 38 | 24,2.01,0.23,0:02.34,95%,0.22,sqlite_jit_spec,0 39 | 24,4.69,0.26,0:05.17,95%,0,sqlite_spec,0 40 | 24,2.01,0.23,0:02.34,95%,0.23,sqlite_jit_spec,0 41 | 24,4.72,0.23,0:05.17,95%,0,sqlite_spec,0 42 | 30,2.00,0.23,0:02.33,95%,0.28,sqlite_jit_spec,0 43 | 30,6.45,0.19,0:06.93,95%,0,sqlite_spec,0 44 | 30,2.03,0.20,0:02.34,95%,0.28,sqlite_jit_spec,0 45 | 30,6.30,0.22,0:06.80,95%,0,sqlite_spec,0 46 | 30,1.99,0.24,0:02.33,95%,0.28,sqlite_jit_spec,0 47 | 30,6.28,0.25,0:06.80,95%,0,sqlite_spec,0 48 | 30,1.99,0.24,0:02.33,95%,0.28,sqlite_jit_spec,0 49 | 30,6.27,0.25,0:06.81,95%,0,sqlite_spec,0 50 | 30,2.00,0.23,0:02.33,95%,0.28,sqlite_jit_spec,0 51 | 30,6.29,0.25,0:06.82,95%,0,sqlite_spec,0 52 | 36,2.03,0.27,0:02.40,95%,0.35,sqlite_jit_spec,0 53 | 36,7.17,0.23,0:07.72,95%,0,sqlite_spec,0 54 | 36,2.06,0.23,0:02.40,95%,0.36,sqlite_jit_spec,0 55 | 36,7.27,0.22,0:07.81,95%,0,sqlite_spec,0 56 | 36,2.06,0.24,0:02.40,95%,0.35,sqlite_jit_spec,0 57 | 36,7.16,0.22,0:07.70,95%,0,sqlite_spec,0 58 | 36,2.06,0.23,0:02.40,95%,0.35,sqlite_jit_spec,0 59 | 36,7.13,0.23,0:07.67,95%,0,sqlite_spec,0 60 | 36,2.02,0.26,0:02.39,95%,0.35,sqlite_jit_spec,0 61 | 36,7.13,0.22,0:07.67,95%,0,sqlite_spec,0 62 | 42,2.15,0.26,0:02.51,95%,0.42,sqlite_jit_spec,0 63 | 42,7.94,0.24,0:08.54,95%,0,sqlite_spec,0 64 | 42,2.14,0.24,0:02.50,95%,0.42,sqlite_jit_spec,0 65 | 42,7.97,0.22,0:08.55,95%,0,sqlite_spec,0 66 | 42,2.12,0.26,0:02.49,95%,0.42,sqlite_jit_spec,0 67 | 42,7.96,0.22,0:08.53,95%,0,sqlite_spec,0 68 | 42,2.17,0.21,0:02.49,95%,0.43,sqlite_jit_spec,0 69 | 42,7.96,0.23,0:08.54,95%,0,sqlite_spec,0 70 | 42,2.17,0.25,0:02.53,95%,0.42,sqlite_jit_spec,0 71 | 42,8.18,0.22,0:08.77,95%,0,sqlite_spec,0 72 | 48,2.33,0.22,0:02.66,95%,0.52,sqlite_jit_spec,0 73 | 48,9.32,0.21,0:09.94,95%,0,sqlite_spec,0 74 | 48,2.23,0.24,0:02.58,95%,0.5,sqlite_jit_spec,0 75 | 48,8.81,0.24,0:09.43,95%,0,sqlite_spec,0 76 | 48,2.20,0.26,0:02.57,95%,0.49,sqlite_jit_spec,0 77 | 48,8.79,0.26,0:09.44,95%,0,sqlite_spec,0 78 | 48,2.21,0.25,0:02.58,95%,0.48,sqlite_jit_spec,0 79 | 48,8.89,0.22,0:09.50,95%,0,sqlite_spec,0 80 | 48,2.19,0.27,0:02.58,95%,0.48,sqlite_jit_spec,0 81 | 48,8.81,0.24,0:09.43,95%,0,sqlite_spec,0 82 | 54,2.31,0.25,0:02.68,95%,0.59,sqlite_jit_spec,0 83 | 54,9.64,0.27,0:10.33,95%,0,sqlite_spec,0 84 | 54,2.35,0.22,0:02.68,95%,0.58,sqlite_jit_spec,0 85 | 54,9.62,0.28,0:10.33,95%,0,sqlite_spec,0 86 | 54,2.34,0.23,0:02.68,95%,0.58,sqlite_jit_spec,0 87 | 54,9.62,0.28,0:10.33,95%,0,sqlite_spec,0 88 | 54,2.35,0.22,0:02.69,95%,0.58,sqlite_jit_spec,0 89 | 54,9.67,0.23,0:10.32,95%,0,sqlite_spec,0 90 | 54,2.34,0.23,0:02.69,95%,0.58,sqlite_jit_spec,0 91 | 54,9.65,0.24,0:10.32,95%,0,sqlite_spec,0 92 | 60,2.42,0.21,0:02.75,95%,0.66,sqlite_jit_spec,0 93 | 60,10.48,0.22,0:11.16,95%,0,sqlite_spec,0 94 | 60,2.38,0.25,0:02.75,95%,0.65,sqlite_jit_spec,0 95 | 60,10.46,0.23,0:11.15,95%,0,sqlite_spec,0 96 | 60,2.43,0.20,0:02.75,95%,0.66,sqlite_jit_spec,0 97 | 60,10.49,0.21,0:11.16,95%,0,sqlite_spec,0 98 | 60,2.38,0.25,0:02.76,95%,0.65,sqlite_jit_spec,0 99 | 60,10.48,0.22,0:11.16,95%,0,sqlite_spec,0 100 | 60,2.38,0.25,0:02.75,95%,0.66,sqlite_jit_spec,0 101 | 60,10.49,0.21,0:11.15,95%,0,sqlite_spec,0 102 | -------------------------------------------------------------------------------- /utils/fake_libc_include/_fake_typedefs.h: -------------------------------------------------------------------------------- 1 | #ifndef _FAKE_TYPEDEFS_H 2 | #define _FAKE_TYPEDEFS_H 3 | 4 | typedef int size_t; 5 | typedef int __builtin_va_list; 6 | typedef int __gnuc_va_list; 7 | typedef int va_list; 8 | typedef int __int8_t; 9 | typedef int __uint8_t; 10 | typedef int __int16_t; 11 | typedef int __uint16_t; 12 | typedef int __int_least16_t; 13 | typedef int __uint_least16_t; 14 | typedef int __int32_t; 15 | typedef int __uint32_t; 16 | typedef int __int64_t; 17 | typedef int __uint64_t; 18 | typedef int __int_least32_t; 19 | typedef int __uint_least32_t; 20 | typedef int __s8; 21 | typedef int __u8; 22 | typedef int __s16; 23 | typedef int __u16; 24 | typedef int __s32; 25 | typedef int __u32; 26 | typedef int __s64; 27 | typedef int __u64; 28 | typedef int _LOCK_T; 29 | typedef int _LOCK_RECURSIVE_T; 30 | typedef int _off_t; 31 | typedef int __dev_t; 32 | typedef int __uid_t; 33 | typedef int __gid_t; 34 | typedef int _off64_t; 35 | typedef int _fpos_t; 36 | typedef int _ssize_t; 37 | typedef int wint_t; 38 | typedef int _mbstate_t; 39 | typedef int _flock_t; 40 | typedef int _iconv_t; 41 | typedef int __ULong; 42 | typedef int __FILE; 43 | typedef int ptrdiff_t; 44 | typedef int wchar_t; 45 | typedef int __off_t; 46 | typedef int __pid_t; 47 | typedef int __loff_t; 48 | typedef int u_char; 49 | typedef int u_short; 50 | typedef int u_int; 51 | typedef int u_long; 52 | typedef int ushort; 53 | typedef int uint; 54 | typedef int clock_t; 55 | typedef int time_t; 56 | typedef int daddr_t; 57 | typedef int caddr_t; 58 | typedef int ino_t; 59 | typedef int off_t; 60 | typedef int dev_t; 61 | typedef int uid_t; 62 | typedef int gid_t; 63 | typedef int pid_t; 64 | typedef int key_t; 65 | typedef int ssize_t; 66 | typedef int mode_t; 67 | typedef int nlink_t; 68 | typedef int fd_mask; 69 | typedef int _types_fd_set; 70 | typedef int clockid_t; 71 | typedef int timer_t; 72 | typedef int useconds_t; 73 | typedef int suseconds_t; 74 | typedef int FILE; 75 | typedef int fpos_t; 76 | typedef int cookie_read_function_t; 77 | typedef int cookie_write_function_t; 78 | typedef int cookie_seek_function_t; 79 | typedef int cookie_close_function_t; 80 | typedef int cookie_io_functions_t; 81 | typedef int div_t; 82 | typedef int ldiv_t; 83 | typedef int lldiv_t; 84 | typedef int sigset_t; 85 | typedef int __sigset_t; 86 | typedef int _sig_func_ptr; 87 | typedef int sig_atomic_t; 88 | typedef int __tzrule_type; 89 | typedef int __tzinfo_type; 90 | typedef int mbstate_t; 91 | typedef int sem_t; 92 | typedef int pthread_t; 93 | typedef int pthread_attr_t; 94 | typedef int pthread_mutex_t; 95 | typedef int pthread_mutexattr_t; 96 | typedef int pthread_cond_t; 97 | typedef int pthread_condattr_t; 98 | typedef int pthread_key_t; 99 | typedef int pthread_once_t; 100 | typedef int pthread_rwlock_t; 101 | typedef int pthread_rwlockattr_t; 102 | typedef int pthread_spinlock_t; 103 | typedef int pthread_barrier_t; 104 | typedef int pthread_barrierattr_t; 105 | typedef int jmp_buf; 106 | typedef int rlim_t; 107 | typedef int sa_family_t; 108 | typedef int sigjmp_buf; 109 | typedef int stack_t; 110 | typedef int siginfo_t; 111 | typedef int z_stream; 112 | 113 | /* C99 exact-width integer types */ 114 | typedef int int8_t; 115 | typedef int uint8_t; 116 | typedef int int16_t; 117 | typedef int uint16_t; 118 | typedef int int32_t; 119 | typedef int uint32_t; 120 | typedef int int64_t; 121 | typedef int uint64_t; 122 | 123 | /* C99 minimum-width integer types */ 124 | typedef int int_least8_t; 125 | typedef int uint_least8_t; 126 | typedef int int_least16_t; 127 | typedef int uint_least16_t; 128 | typedef int int_least32_t; 129 | typedef int uint_least32_t; 130 | typedef int int_least64_t; 131 | typedef int uint_least64_t; 132 | 133 | /* C99 fastest minimum-width integer types */ 134 | typedef int int_fast8_t; 135 | typedef int uint_fast8_t; 136 | typedef int int_fast16_t; 137 | typedef int uint_fast16_t; 138 | typedef int int_fast32_t; 139 | typedef int uint_fast32_t; 140 | typedef int int_fast64_t; 141 | typedef int uint_fast64_t; 142 | 143 | /* C99 integer types capable of holding object pointers */ 144 | typedef int intptr_t; 145 | typedef int uintptr_t; 146 | 147 | /* C99 greatest-width integer types */ 148 | typedef int intmax_t; 149 | typedef int uintmax_t; 150 | 151 | /* C99 stdbool.h bool type. _Bool is built-in in C99 */ 152 | typedef _Bool bool; 153 | 154 | /* Mir typedefs */ 155 | typedef void* MirEGLNativeWindowType; 156 | typedef void* MirEGLNativeDisplayType; 157 | typedef struct MirConnection MirConnection; 158 | typedef struct MirSurface MirSurface; 159 | typedef struct MirSurfaceSpec MirSurfaceSpec; 160 | typedef struct MirScreencast MirScreencast; 161 | typedef struct MirPromptSession MirPromptSession; 162 | typedef struct MirBufferStream MirBufferStream; 163 | typedef struct MirPersistentId MirPersistentId; 164 | typedef struct MirBlob MirBlob; 165 | typedef struct MirDisplayConfig MirDisplayConfig; 166 | 167 | /* xcb typedefs */ 168 | typedef struct xcb_connection_t xcb_connection_t; 169 | typedef uint32_t xcb_window_t; 170 | typedef uint32_t xcb_visualid_t; 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /src/legacy.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2001 September 15 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** Main file for the SQLite library. The routines in this file 13 | ** implement the programmer interface to the library. Routines in 14 | ** other files are for internal use by SQLite and should not be 15 | ** accessed by users of the library. 16 | */ 17 | 18 | #include "sqliteInt.h" 19 | 20 | /* 21 | ** Execute SQL code. Return one of the SQLITE_ success/failure 22 | ** codes. Also write an error message into memory obtained from 23 | ** malloc() and make *pzErrMsg point to that message. 24 | ** 25 | ** If the SQL is a query, then for each row in the query result 26 | ** the xCallback() function is called. pArg becomes the first 27 | ** argument to xCallback(). If xCallback=NULL then no callback 28 | ** is invoked, even for queries. 29 | */ 30 | int sqlite3_exec( 31 | sqlite3 *db, /* The database on which the SQL executes */ 32 | const char *zSql, /* The SQL to be executed */ 33 | sqlite3_callback xCallback, /* Invoke this callback routine */ 34 | void *pArg, /* First argument to xCallback() */ 35 | char **pzErrMsg /* Write error messages here */ 36 | ){ 37 | int rc = SQLITE_OK; /* Return code */ 38 | const char *zLeftover; /* Tail of unprocessed SQL */ 39 | sqlite3_stmt *pStmt = 0; /* The current SQL statement */ 40 | char **azCols = 0; /* Names of result columns */ 41 | int callbackIsInit; /* True if callback data is initialized */ 42 | 43 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; 44 | if( zSql==0 ) zSql = ""; 45 | 46 | sqlite3_mutex_enter(db->mutex); 47 | sqlite3Error(db, SQLITE_OK); 48 | while( rc==SQLITE_OK && zSql[0] ){ 49 | int nCol; 50 | char **azVals = 0; 51 | 52 | pStmt = 0; 53 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); 54 | assert( rc==SQLITE_OK || pStmt==0 ); 55 | if( rc!=SQLITE_OK ){ 56 | continue; 57 | } 58 | if( !pStmt ){ 59 | /* this happens for a comment or white-space */ 60 | zSql = zLeftover; 61 | continue; 62 | } 63 | 64 | callbackIsInit = 0; 65 | nCol = sqlite3_column_count(pStmt); 66 | 67 | while( 1 ){ 68 | int i; 69 | rc = sqlite3_step(pStmt); 70 | 71 | /* Invoke the callback function if required */ 72 | if( xCallback && (SQLITE_ROW==rc || 73 | (SQLITE_DONE==rc && !callbackIsInit 74 | && db->flags&SQLITE_NullCallback)) ){ 75 | if( !callbackIsInit ){ 76 | azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); 77 | if( azCols==0 ){ 78 | goto exec_out; 79 | } 80 | for(i=0; ierrMask)==rc ); 140 | sqlite3_mutex_leave(db->mutex); 141 | return rc; 142 | } 143 | -------------------------------------------------------------------------------- /utils/fake_libc_include/_fake_defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _FAKE_DEFINES_H 2 | #define _FAKE_DEFINES_H 3 | 4 | #define NULL 0 5 | #define BUFSIZ 1024 6 | #define FOPEN_MAX 20 7 | #define FILENAME_MAX 1024 8 | 9 | #ifndef SEEK_SET 10 | #define SEEK_SET 0 /* set file offset to offset */ 11 | #endif 12 | #ifndef SEEK_CUR 13 | #define SEEK_CUR 1 /* set file offset to current plus offset */ 14 | #endif 15 | #ifndef SEEK_END 16 | #define SEEK_END 2 /* set file offset to EOF plus offset */ 17 | #endif 18 | 19 | #define __LITTLE_ENDIAN 1234 20 | #define LITTLE_ENDIAN __LITTLE_ENDIAN 21 | #define __BIG_ENDIAN 4321 22 | #define BIG_ENDIAN __BIG_ENDIAN 23 | #define __BYTE_ORDER __LITTLE_ENDIAN 24 | #define BYTE_ORDER __BYTE_ORDER 25 | 26 | #define EXIT_FAILURE 1 27 | #define EXIT_SUCCESS 0 28 | 29 | #define UCHAR_MAX 255 30 | #define USHRT_MAX 65535 31 | #define UINT_MAX 4294967295U 32 | #define RAND_MAX 32767 33 | #define INT_MAX 32767 34 | 35 | /* C99 inttypes.h defines */ 36 | #define PRId8 "d" 37 | #define PRIi8 "i" 38 | #define PRIo8 "o" 39 | #define PRIu8 "u" 40 | #define PRIx8 "x" 41 | #define PRIX8 "X" 42 | #define PRId16 "d" 43 | #define PRIi16 "i" 44 | #define PRIo16 "o" 45 | #define PRIu16 "u" 46 | #define PRIx16 "x" 47 | #define PRIX16 "X" 48 | #define PRId32 "d" 49 | #define PRIi32 "i" 50 | #define PRIo32 "o" 51 | #define PRIu32 "u" 52 | #define PRIx32 "x" 53 | #define PRIX32 "X" 54 | #define PRId64 "d" 55 | #define PRIi64 "i" 56 | #define PRIo64 "o" 57 | #define PRIu64 "u" 58 | #define PRIx64 "x" 59 | #define PRIX64 "X" 60 | #define PRIdLEAST8 "d" 61 | #define PRIiLEAST8 "i" 62 | #define PRIoLEAST8 "o" 63 | #define PRIuLEAST8 "u" 64 | #define PRIxLEAST8 "x" 65 | #define PRIXLEAST8 "X" 66 | #define PRIdLEAST16 "d" 67 | #define PRIiLEAST16 "i" 68 | #define PRIoLEAST16 "o" 69 | #define PRIuLEAST16 "u" 70 | #define PRIxLEAST16 "x" 71 | #define PRIXLEAST16 "X" 72 | #define PRIdLEAST32 "d" 73 | #define PRIiLEAST32 "i" 74 | #define PRIoLEAST32 "o" 75 | #define PRIuLEAST32 "u" 76 | #define PRIxLEAST32 "x" 77 | #define PRIXLEAST32 "X" 78 | #define PRIdLEAST64 "d" 79 | #define PRIiLEAST64 "i" 80 | #define PRIoLEAST64 "o" 81 | #define PRIuLEAST64 "u" 82 | #define PRIxLEAST64 "x" 83 | #define PRIXLEAST64 "X" 84 | #define PRIdFAST8 "d" 85 | #define PRIiFAST8 "i" 86 | #define PRIoFAST8 "o" 87 | #define PRIuFAST8 "u" 88 | #define PRIxFAST8 "x" 89 | #define PRIXFAST8 "X" 90 | #define PRIdFAST16 "d" 91 | #define PRIiFAST16 "i" 92 | #define PRIoFAST16 "o" 93 | #define PRIuFAST16 "u" 94 | #define PRIxFAST16 "x" 95 | #define PRIXFAST16 "X" 96 | #define PRIdFAST32 "d" 97 | #define PRIiFAST32 "i" 98 | #define PRIoFAST32 "o" 99 | #define PRIuFAST32 "u" 100 | #define PRIxFAST32 "x" 101 | #define PRIXFAST32 "X" 102 | #define PRIdFAST64 "d" 103 | #define PRIiFAST64 "i" 104 | #define PRIoFAST64 "o" 105 | #define PRIuFAST64 "u" 106 | #define PRIxFAST64 "x" 107 | #define PRIXFAST64 "X" 108 | #define PRIdPTR "d" 109 | #define PRIiPTR "i" 110 | #define PRIoPTR "o" 111 | #define PRIuPTR "u" 112 | #define PRIxPTR "x" 113 | #define PRIXPTR "X" 114 | #define PRIdMAX "d" 115 | #define PRIiMAX "i" 116 | #define PRIoMAX "o" 117 | #define PRIuMAX "u" 118 | #define PRIxMAX "x" 119 | #define PRIXMAX "X" 120 | #define SCNd8 "d" 121 | #define SCNi8 "i" 122 | #define SCNo8 "o" 123 | #define SCNu8 "u" 124 | #define SCNx8 "x" 125 | #define SCNd16 "d" 126 | #define SCNi16 "i" 127 | #define SCNo16 "o" 128 | #define SCNu16 "u" 129 | #define SCNx16 "x" 130 | #define SCNd32 "d" 131 | #define SCNi32 "i" 132 | #define SCNo32 "o" 133 | #define SCNu32 "u" 134 | #define SCNx32 "x" 135 | #define SCNd64 "d" 136 | #define SCNi64 "i" 137 | #define SCNo64 "o" 138 | #define SCNu64 "u" 139 | #define SCNx64 "x" 140 | #define SCNdLEAST8 "d" 141 | #define SCNiLEAST8 "i" 142 | #define SCNoLEAST8 "o" 143 | #define SCNuLEAST8 "u" 144 | #define SCNxLEAST8 "x" 145 | #define SCNdLEAST16 "d" 146 | #define SCNiLEAST16 "i" 147 | #define SCNoLEAST16 "o" 148 | #define SCNuLEAST16 "u" 149 | #define SCNxLEAST16 "x" 150 | #define SCNdLEAST32 "d" 151 | #define SCNiLEAST32 "i" 152 | #define SCNoLEAST32 "o" 153 | #define SCNuLEAST32 "u" 154 | #define SCNxLEAST32 "x" 155 | #define SCNdLEAST64 "d" 156 | #define SCNiLEAST64 "i" 157 | #define SCNoLEAST64 "o" 158 | #define SCNuLEAST64 "u" 159 | #define SCNxLEAST64 "x" 160 | #define SCNdFAST8 "d" 161 | #define SCNiFAST8 "i" 162 | #define SCNoFAST8 "o" 163 | #define SCNuFAST8 "u" 164 | #define SCNxFAST8 "x" 165 | #define SCNdFAST16 "d" 166 | #define SCNiFAST16 "i" 167 | #define SCNoFAST16 "o" 168 | #define SCNuFAST16 "u" 169 | #define SCNxFAST16 "x" 170 | #define SCNdFAST32 "d" 171 | #define SCNiFAST32 "i" 172 | #define SCNoFAST32 "o" 173 | #define SCNuFAST32 "u" 174 | #define SCNxFAST32 "x" 175 | #define SCNdFAST64 "d" 176 | #define SCNiFAST64 "i" 177 | #define SCNoFAST64 "o" 178 | #define SCNuFAST64 "u" 179 | #define SCNxFAST64 "x" 180 | #define SCNdPTR "d" 181 | #define SCNiPTR "i" 182 | #define SCNoPTR "o" 183 | #define SCNuPTR "u" 184 | #define SCNxPTR "x" 185 | #define SCNdMAX "d" 186 | #define SCNiMAX "i" 187 | #define SCNoMAX "o" 188 | #define SCNuMAX "u" 189 | #define SCNxMAX "x" 190 | 191 | /* C99 stdbool.h defines */ 192 | #define __bool_true_false_are_defined 1 193 | #define false 0 194 | #define true 1 195 | 196 | /* va_arg macros and type*/ 197 | #define va_start(_ap, _type) __builtin_va_start((_ap)) 198 | #define va_arg(_ap, _type) __builtin_va_arg((_ap)) 199 | #define va_end(_list) 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /src/walker.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2008 August 16 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This file contains routines used for walking the parser tree for 13 | ** an SQL statement. 14 | */ 15 | #include "sqliteInt.h" 16 | #include 17 | #include 18 | 19 | 20 | /* 21 | ** Walk an expression tree. Invoke the callback once for each node 22 | ** of the expression, while descending. (In other words, the callback 23 | ** is invoked before visiting children.) 24 | ** 25 | ** The return value from the callback should be one of the WRC_* 26 | ** constants to specify how to proceed with the walk. 27 | ** 28 | ** WRC_Continue Continue descending down the tree. 29 | ** 30 | ** WRC_Prune Do not descend into child nodes, but allow 31 | ** the walk to continue with sibling nodes. 32 | ** 33 | ** WRC_Abort Do no more callbacks. Unwind the stack and 34 | ** return from the top-level walk call. 35 | ** 36 | ** The return value from this routine is WRC_Abort to abandon the tree walk 37 | ** and WRC_Continue to continue. 38 | */ 39 | static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ 40 | int rc; 41 | testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); 42 | testcase( ExprHasProperty(pExpr, EP_Reduced) ); 43 | while(1){ 44 | rc = pWalker->xExprCallback(pWalker, pExpr); 45 | if( rc ) return rc & WRC_Abort; 46 | if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ 47 | if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; 48 | assert( pExpr->x.pList==0 || pExpr->pRight==0 ); 49 | if( pExpr->pRight ){ 50 | pExpr = pExpr->pRight; 51 | continue; 52 | }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ 53 | if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; 54 | }else if( pExpr->x.pList ){ 55 | if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; 56 | } 57 | } 58 | break; 59 | } 60 | return WRC_Continue; 61 | } 62 | int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ 63 | return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; 64 | } 65 | 66 | /* 67 | ** Call sqlite3WalkExpr() for every expression in list p or until 68 | ** an abort request is seen. 69 | */ 70 | int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ 71 | int i; 72 | struct ExprList_item *pItem; 73 | if( p ){ 74 | for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ 75 | if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; 76 | } 77 | } 78 | return WRC_Continue; 79 | } 80 | 81 | /* 82 | ** Walk all expressions associated with SELECT statement p. Do 83 | ** not invoke the SELECT callback on p, but do (of course) invoke 84 | ** any expr callbacks and SELECT callbacks that come from subqueries. 85 | ** Return WRC_Abort or WRC_Continue. 86 | */ 87 | int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ 88 | if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; 89 | if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; 90 | if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; 91 | if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; 92 | if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; 93 | if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; 94 | return WRC_Continue; 95 | } 96 | 97 | /* 98 | ** Walk the parse trees associated with all subqueries in the 99 | ** FROM clause of SELECT statement p. Do not invoke the select 100 | ** callback on p, but do invoke it on each FROM clause subquery 101 | ** and on any subqueries further down in the tree. Return 102 | ** WRC_Abort or WRC_Continue; 103 | */ 104 | int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ 105 | SrcList *pSrc; 106 | int i; 107 | struct SrcList_item *pItem; 108 | 109 | pSrc = p->pSrc; 110 | assert( pSrc!=0 ); 111 | for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ 112 | if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ 113 | return WRC_Abort; 114 | } 115 | if( pItem->fg.isTabFunc 116 | && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) 117 | ){ 118 | return WRC_Abort; 119 | } 120 | } 121 | return WRC_Continue; 122 | } 123 | 124 | /* 125 | ** Call sqlite3WalkExpr() for every expression in Select statement p. 126 | ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and 127 | ** on the compound select chain, p->pPrior. 128 | ** 129 | ** If it is not NULL, the xSelectCallback() callback is invoked before 130 | ** the walk of the expressions and FROM clause. The xSelectCallback2() 131 | ** method is invoked following the walk of the expressions and FROM clause, 132 | ** but only if both xSelectCallback and xSelectCallback2 are both non-NULL 133 | ** and if the expressions and FROM clause both return WRC_Continue; 134 | ** 135 | ** Return WRC_Continue under normal conditions. Return WRC_Abort if 136 | ** there is an abort request. 137 | ** 138 | ** If the Walker does not have an xSelectCallback() then this routine 139 | ** is a no-op returning WRC_Continue. 140 | */ 141 | int sqlite3WalkSelect(Walker *pWalker, Select *p){ 142 | int rc; 143 | if( p==0 ) return WRC_Continue; 144 | if( pWalker->xSelectCallback==0 ) return WRC_Continue; 145 | do{ 146 | rc = pWalker->xSelectCallback(pWalker, p); 147 | if( rc ) return rc & WRC_Abort; 148 | if( sqlite3WalkSelectExpr(pWalker, p) 149 | || sqlite3WalkSelectFrom(pWalker, p) 150 | ){ 151 | return WRC_Abort; 152 | } 153 | if( pWalker->xSelectCallback2 ){ 154 | pWalker->xSelectCallback2(pWalker, p); 155 | } 156 | p = p->pPrior; 157 | }while( p!=0 ); 158 | return WRC_Continue; 159 | } 160 | -------------------------------------------------------------------------------- /src/wal.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2010 February 1 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This header file defines the interface to the write-ahead logging 13 | ** system. Refer to the comments below and the header comment attached to 14 | ** the implementation of each function in log.c for further details. 15 | */ 16 | 17 | #ifndef SQLITE_WAL_H 18 | #define SQLITE_WAL_H 19 | 20 | #include "sqliteInt.h" 21 | 22 | /* Macros for extracting appropriate sync flags for either transaction 23 | ** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): 24 | */ 25 | #define WAL_SYNC_FLAGS(X) ((X)&0x03) 26 | #define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) 27 | 28 | #ifdef SQLITE_OMIT_WAL 29 | # define sqlite3WalOpen(x,y,z) 0 30 | # define sqlite3WalLimit(x,y) 31 | # define sqlite3WalClose(v,w,x,y,z) 0 32 | # define sqlite3WalBeginReadTransaction(y,z) 0 33 | # define sqlite3WalEndReadTransaction(z) 34 | # define sqlite3WalDbsize(y) 0 35 | # define sqlite3WalBeginWriteTransaction(y) 0 36 | # define sqlite3WalEndWriteTransaction(x) 0 37 | # define sqlite3WalUndo(x,y,z) 0 38 | # define sqlite3WalSavepoint(y,z) 39 | # define sqlite3WalSavepointUndo(y,z) 0 40 | # define sqlite3WalFrames(u,v,w,x,y,z) 0 41 | # define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 42 | # define sqlite3WalCallback(z) 0 43 | # define sqlite3WalExclusiveMode(y,z) 0 44 | # define sqlite3WalHeapMemory(z) 0 45 | # define sqlite3WalFramesize(z) 0 46 | # define sqlite3WalFindFrame(x,y,z) 0 47 | # define sqlite3WalFile(x) 0 48 | #else 49 | 50 | #define WAL_SAVEPOINT_NDATA 4 51 | 52 | /* Connection to a write-ahead log (WAL) file. 53 | ** There is one object of this type for each pager. 54 | */ 55 | typedef struct Wal Wal; 56 | 57 | /* Open and close a connection to a write-ahead log. */ 58 | int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); 59 | int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *); 60 | 61 | /* Set the limiting size of a WAL file. */ 62 | void sqlite3WalLimit(Wal*, i64); 63 | 64 | /* Used by readers to open (lock) and close (unlock) a snapshot. A 65 | ** snapshot is like a read-transaction. It is the state of the database 66 | ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and 67 | ** preserves the current state even if the other threads or processes 68 | ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the 69 | ** transaction and releases the lock. 70 | */ 71 | int sqlite3WalBeginReadTransaction(Wal *pWal, int *); 72 | void sqlite3WalEndReadTransaction(Wal *pWal); 73 | 74 | /* Read a page from the write-ahead log, if it is present. */ 75 | int sqlite3WalFindFrame(Wal *, Pgno, u32 *); 76 | int sqlite3WalReadFrame(Wal *, u32, int, u8 *); 77 | 78 | /* If the WAL is not empty, return the size of the database. */ 79 | Pgno sqlite3WalDbsize(Wal *pWal); 80 | 81 | /* Obtain or release the WRITER lock. */ 82 | int sqlite3WalBeginWriteTransaction(Wal *pWal); 83 | int sqlite3WalEndWriteTransaction(Wal *pWal); 84 | 85 | /* Undo any frames written (but not committed) to the log */ 86 | int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); 87 | 88 | /* Return an integer that records the current (uncommitted) write 89 | ** position in the WAL */ 90 | void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); 91 | 92 | /* Move the write position of the WAL back to iFrame. Called in 93 | ** response to a ROLLBACK TO command. */ 94 | int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); 95 | 96 | /* Write a frame or frames to the log. */ 97 | int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); 98 | 99 | /* Copy pages from the log to the database file */ 100 | int sqlite3WalCheckpoint( 101 | Wal *pWal, /* Write-ahead log connection */ 102 | sqlite3 *db, /* Check this handle's interrupt flag */ 103 | int eMode, /* One of PASSIVE, FULL and RESTART */ 104 | int (*xBusy)(void*), /* Function to call when busy */ 105 | void *pBusyArg, /* Context argument for xBusyHandler */ 106 | int sync_flags, /* Flags to sync db file with (or 0) */ 107 | int nBuf, /* Size of buffer nBuf */ 108 | u8 *zBuf, /* Temporary buffer to use */ 109 | int *pnLog, /* OUT: Number of frames in WAL */ 110 | int *pnCkpt /* OUT: Number of backfilled frames in WAL */ 111 | ); 112 | 113 | /* Return the value to pass to a sqlite3_wal_hook callback, the 114 | ** number of frames in the WAL at the point of the last commit since 115 | ** sqlite3WalCallback() was called. If no commits have occurred since 116 | ** the last call, then return 0. 117 | */ 118 | int sqlite3WalCallback(Wal *pWal); 119 | 120 | /* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) 121 | ** by the pager layer on the database file. 122 | */ 123 | int sqlite3WalExclusiveMode(Wal *pWal, int op); 124 | 125 | /* Return true if the argument is non-NULL and the WAL module is using 126 | ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the 127 | ** WAL module is using shared-memory, return false. 128 | */ 129 | int sqlite3WalHeapMemory(Wal *pWal); 130 | 131 | #ifdef SQLITE_ENABLE_SNAPSHOT 132 | int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); 133 | void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); 134 | int sqlite3WalSnapshotRecover(Wal *pWal); 135 | #endif 136 | 137 | #ifdef SQLITE_ENABLE_ZIPVFS 138 | /* If the WAL file is not empty, return the number of bytes of content 139 | ** stored in each frame (i.e. the db page-size when the WAL was created). 140 | */ 141 | int sqlite3WalFramesize(Wal *pWal); 142 | #endif 143 | 144 | /* Return the sqlite3_file object for the WAL file */ 145 | sqlite3_file *sqlite3WalFile(Wal *pWal); 146 | 147 | #endif /* ifndef SQLITE_OMIT_WAL */ 148 | #endif /* SQLITE_WAL_H */ 149 | -------------------------------------------------------------------------------- /results/general_025129180938: -------------------------------------------------------------------------------- 1 | jitops,user,system,elapsed,cpu,compile_time,type,selectivity 2 | 6,2.27,0.28,0:02.66,95%,0.07,sqlite_jit,0 3 | 6,2.95,0.23,0:03.31,95%,0,sqlite,0 4 | 6,2.60,0.24,0:02.96,95%,0,sqlite_disp,0 5 | 6,2.10,0.27,0:02.48,95%,0.07,sqlite_jit,0 6 | 6,2.65,0.28,0:03.06,95%,0,sqlite,0 7 | 6,2.63,0.21,0:02.97,95%,0,sqlite_disp,0 8 | 6,2.11,0.27,0:02.49,95%,0.07,sqlite_jit,0 9 | 6,2.66,0.24,0:03.03,95%,0,sqlite,0 10 | 6,2.68,0.22,0:03.03,95%,0,sqlite_disp,0 11 | 6,2.15,0.23,0:02.48,95%,0.07,sqlite_jit,0 12 | 6,2.69,0.20,0:03.02,95%,0,sqlite,0 13 | 6,2.61,0.23,0:02.96,95%,0,sqlite_disp,0 14 | 6,2.16,0.22,0:02.48,95%,0.07,sqlite_jit,0 15 | 6,2.65,0.24,0:03.02,95%,0,sqlite,0 16 | 6,2.59,0.26,0:02.97,95%,0,sqlite_disp,0 17 | 12,2.84,0.24,0:03.21,95%,0.11,sqlite_jit,0 18 | 12,3.98,0.23,0:04.39,95%,0,sqlite,0 19 | 12,3.54,0.23,0:03.94,95%,0,sqlite_disp,0 20 | 12,2.66,0.24,0:03.03,95%,0.12,sqlite_jit,0 21 | 12,3.85,0.23,0:04.26,95%,0,sqlite,0 22 | 12,3.53,0.25,0:03.95,95%,0,sqlite_disp,0 23 | 12,2.66,0.23,0:03.02,95%,0.12,sqlite_jit,0 24 | 12,3.86,0.22,0:04.27,95%,0,sqlite,0 25 | 12,3.56,0.22,0:03.95,95%,0,sqlite_disp,0 26 | 12,2.65,0.24,0:03.02,95%,0.12,sqlite_jit,0 27 | 12,3.86,0.23,0:04.27,95%,0,sqlite,0 28 | 12,3.56,0.24,0:03.96,95%,0,sqlite_disp,0 29 | 12,2.65,0.25,0:03.03,95%,0.12,sqlite_jit,0 30 | 12,4.00,0.24,0:04.43,95%,0,sqlite,0 31 | 12,3.55,0.23,0:03.95,95%,0,sqlite_disp,0 32 | 18,3.21,0.24,0:03.61,95%,0.17,sqlite_jit,0 33 | 18,5.80,0.24,0:06.30,95%,0,sqlite,0 34 | 18,5.29,0.23,0:05.76,95%,0,sqlite_disp,0 35 | 18,3.21,0.25,0:03.61,95%,0.16,sqlite_jit,0 36 | 18,5.82,0.21,0:06.29,95%,0,sqlite,0 37 | 18,5.32,0.20,0:05.76,95%,0,sqlite_disp,0 38 | 18,3.24,0.22,0:03.60,95%,0.16,sqlite_jit,0 39 | 18,5.81,0.22,0:06.29,95%,0,sqlite,0 40 | 18,5.27,0.24,0:05.76,95%,0,sqlite_disp,0 41 | 18,3.35,0.26,0:03.77,95%,0.17,sqlite_jit,0 42 | 18,5.80,0.23,0:06.30,95%,0,sqlite,0 43 | 18,5.45,0.22,0:05.92,95%,0,sqlite_disp,0 44 | 18,3.21,0.25,0:03.61,95%,0.16,sqlite_jit,0 45 | 18,5.80,0.24,0:06.30,95%,0,sqlite,0 46 | 18,5.29,0.24,0:05.77,95%,0,sqlite_disp,0 47 | 24,3.88,0.23,0:04.29,95%,0.21,sqlite_jit,0 48 | 24,6.98,0.21,0:07.50,95%,0,sqlite,0 49 | 24,6.25,0.22,0:06.75,95%,0,sqlite_disp,0 50 | 24,3.85,0.27,0:04.30,95%,0.22,sqlite_jit,0 51 | 24,6.93,0.23,0:07.47,95%,0,sqlite,0 52 | 24,6.25,0.22,0:06.74,95%,0,sqlite_disp,0 53 | 24,3.90,0.22,0:04.30,95%,0.21,sqlite_jit,0 54 | 24,6.92,0.26,0:07.48,95%,0,sqlite,0 55 | 24,6.24,0.23,0:06.75,95%,0,sqlite_disp,0 56 | 24,3.88,0.23,0:04.29,95%,0.22,sqlite_jit,0 57 | 24,6.98,0.21,0:07.50,95%,0,sqlite,0 58 | 24,6.27,0.22,0:06.77,95%,0,sqlite_disp,0 59 | 24,3.86,0.25,0:04.30,95%,0.22,sqlite_jit,0 60 | 24,7.03,0.24,0:07.58,95%,0,sqlite,0 61 | 24,6.23,0.25,0:06.76,95%,0,sqlite_disp,0 62 | 30,4.47,0.24,0:04.91,95%,0.27,sqlite_jit,0 63 | 30,8.10,0.25,0:08.71,95%,0,sqlite,0 64 | 30,7.13,0.27,0:07.71,95%,0,sqlite_disp,0 65 | 30,4.45,0.27,0:04.92,95%,0.28,sqlite_jit,0 66 | 30,8.10,0.25,0:08.71,95%,0,sqlite,0 67 | 30,7.17,0.24,0:07.73,95%,0,sqlite_disp,0 68 | 30,4.46,0.26,0:04.92,95%,0.27,sqlite_jit,0 69 | 30,8.11,0.25,0:08.71,95%,0,sqlite,0 70 | 30,7.17,0.23,0:07.72,95%,0,sqlite_disp,0 71 | 30,4.49,0.23,0:04.92,95%,0.27,sqlite_jit,0 72 | 30,8.20,0.23,0:08.79,95%,0,sqlite,0 73 | 30,7.15,0.25,0:07.72,95%,0,sqlite_disp,0 74 | 30,4.45,0.26,0:04.91,95%,0.27,sqlite_jit,0 75 | 30,8.12,0.24,0:08.72,95%,0,sqlite,0 76 | 30,7.16,0.24,0:07.73,95%,0,sqlite_disp,0 77 | 36,4.99,0.31,0:05.53,95%,0.34,sqlite_jit,0 78 | 36,9.25,0.26,0:09.92,95%,0,sqlite,0 79 | 36,8.16,0.24,0:08.76,95%,0,sqlite_disp,0 80 | 36,5.01,0.29,0:05.54,95%,0.34,sqlite_jit,0 81 | 36,9.27,0.24,0:09.92,95%,0,sqlite,0 82 | 36,8.18,0.23,0:08.77,95%,0,sqlite_disp,0 83 | 36,5.05,0.26,0:05.53,95%,0.34,sqlite_jit,0 84 | 36,9.26,0.22,0:09.88,95%,0,sqlite,0 85 | 36,8.14,0.23,0:08.73,95%,0,sqlite_disp,0 86 | 36,5.05,0.25,0:05.53,95%,0.34,sqlite_jit,0 87 | 36,9.29,0.23,0:09.92,95%,0,sqlite,0 88 | 36,8.14,0.20,0:08.70,95%,0,sqlite_disp,0 89 | 36,5.04,0.26,0:05.53,95%,0.34,sqlite_jit,0 90 | 36,9.29,0.23,0:09.93,95%,0,sqlite,0 91 | 36,8.14,0.22,0:08.72,95%,0,sqlite_disp,0 92 | 42,5.57,0.26,0:06.08,95%,0.4,sqlite_jit,0 93 | 42,10.40,0.25,0:11.10,95%,0,sqlite,0 94 | 42,9.07,0.23,0:09.70,95%,0,sqlite_disp,0 95 | 42,5.58,0.24,0:06.07,95%,0.4,sqlite_jit,0 96 | 42,10.44,0.25,0:11.15,95%,0,sqlite,0 97 | 42,9.05,0.23,0:09.69,95%,0,sqlite_disp,0 98 | 42,5.57,0.26,0:06.08,95%,0.41,sqlite_jit,0 99 | 42,10.43,0.22,0:11.11,95%,0,sqlite,0 100 | 42,9.07,0.22,0:09.69,95%,0,sqlite_disp,0 101 | 42,5.58,0.24,0:06.08,95%,0.4,sqlite_jit,0 102 | 42,10.43,0.22,0:11.10,95%,0,sqlite,0 103 | 42,9.07,0.22,0:09.69,95%,0,sqlite_disp,0 104 | 42,5.67,0.24,0:06.17,95%,0.4,sqlite_jit,0 105 | 42,10.43,0.22,0:11.10,95%,0,sqlite,0 106 | 42,9.08,0.21,0:09.69,95%,0,sqlite_disp,0 107 | 48,6.59,0.23,0:07.11,95%,0.47,sqlite_jit,0 108 | 48,11.58,0.24,0:12.33,95%,0,sqlite,0 109 | 48,10.00,0.25,0:10.69,95%,0,sqlite_disp,0 110 | 48,6.64,0.18,0:07.12,95%,0.47,sqlite_jit,0 111 | 48,11.59,0.22,0:12.31,95%,0,sqlite,0 112 | 48,10.00,0.26,0:10.70,95%,0,sqlite_disp,0 113 | 48,6.60,0.22,0:07.11,95%,0.47,sqlite_jit,0 114 | 48,11.58,0.21,0:12.29,95%,0,sqlite,0 115 | 48,10.02,0.24,0:10.70,95%,0,sqlite_disp,0 116 | 48,6.58,0.24,0:07.11,95%,0.47,sqlite_jit,0 117 | 48,11.62,0.24,0:12.37,95%,0,sqlite,0 118 | 48,10.04,0.21,0:10.69,95%,0,sqlite_disp,0 119 | 48,6.59,0.22,0:07.11,95%,0.46,sqlite_jit,0 120 | 48,11.59,0.22,0:12.32,95%,0,sqlite,0 121 | 48,10.01,0.27,0:10.72,95%,0,sqlite_disp,0 122 | 54,7.09,0.26,0:07.67,95%,0.55,sqlite_jit,0 123 | 54,12.71,0.22,0:13.48,95%,0,sqlite,0 124 | 54,10.93,0.25,0:11.66,95%,0,sqlite_disp,0 125 | 54,7.11,0.24,0:07.67,95%,0.54,sqlite_jit,0 126 | 54,12.75,0.22,0:13.52,95%,0,sqlite,0 127 | 54,10.95,0.23,0:11.65,95%,0,sqlite_disp,0 128 | 54,7.10,0.26,0:07.67,95%,0.55,sqlite_jit,0 129 | 54,12.68,0.26,0:13.49,95%,0,sqlite,0 130 | 54,10.95,0.23,0:11.66,95%,0,sqlite_disp,0 131 | 54,7.08,0.27,0:07.66,95%,0.55,sqlite_jit,0 132 | 54,12.74,0.19,0:13.49,95%,0,sqlite,0 133 | 54,10.94,0.23,0:11.65,95%,0,sqlite_disp,0 134 | 54,7.09,0.27,0:07.67,95%,0.55,sqlite_jit,0 135 | 54,12.69,0.24,0:13.48,95%,0,sqlite,0 136 | 54,10.95,0.23,0:11.65,95%,0,sqlite_disp,0 137 | 60,7.74,0.31,0:08.39,95%,0.63,sqlite_jit,0 138 | 60,13.90,0.19,0:14.68,95%,0,sqlite,0 139 | 60,11.92,0.23,0:12.67,95%,0,sqlite_disp,0 140 | 60,7.79,0.28,0:08.42,95%,0.63,sqlite_jit,0 141 | 60,13.90,0.22,0:14.72,95%,0,sqlite,0 142 | 60,11.93,0.23,0:12.67,95%,0,sqlite_disp,0 143 | 60,7.74,0.32,0:08.41,95%,0.63,sqlite_jit,0 144 | 60,13.87,0.21,0:14.68,95%,0,sqlite,0 145 | 60,12.03,0.20,0:12.75,95%,0,sqlite_disp,0 146 | 60,7.76,0.31,0:08.42,95%,0.62,sqlite_jit,0 147 | 60,13.91,0.22,0:14.73,95%,0,sqlite,0 148 | 60,11.90,0.23,0:12.65,95%,0,sqlite_disp,0 149 | 60,7.78,0.27,0:08.39,95%,0.62,sqlite_jit,0 150 | 60,13.86,0.23,0:14.69,95%,0,sqlite,0 151 | 60,11.93,0.21,0:12.66,95%,0,sqlite_disp,0 152 | -------------------------------------------------------------------------------- /results/select_031544426682: -------------------------------------------------------------------------------- 1 | jitops,user,system,elapsed,cpu,compile_time,type,selectivity 2 | 64,8.55,0.26,0:09.19,95%,0.67,sqlite_jit,0 3 | 64,14.56,0.25,0:15.44,95%,0,sqlite,0 4 | 64,12.71,0.20,0:13.46,95%,0,sqlite_disp,0 5 | 64,8.56,0.25,0:09.19,95%,0.68,sqlite_jit,0 6 | 64,14.57,0.22,0:15.43,95%,0,sqlite,0 7 | 64,12.51,0.22,0:13.28,95%,0,sqlite_disp,0 8 | 64,8.56,0.25,0:09.19,95%,0.68,sqlite_jit,0 9 | 64,14.60,0.26,0:15.50,95%,0,sqlite,0 10 | 64,12.51,0.25,0:13.30,95%,0,sqlite_disp,0 11 | 64,8.58,0.24,0:09.19,95%,0.68,sqlite_jit,0 12 | 64,14.59,0.26,0:15.48,95%,0,sqlite,0 13 | 64,12.49,0.25,0:13.29,95%,0,sqlite_disp,0 14 | 64,8.55,0.26,0:09.20,95%,0.67,sqlite_jit,0 15 | 64,14.61,0.24,0:15.49,95%,0,sqlite,0 16 | 64,12.52,0.22,0:13.29,95%,0,sqlite_disp,0 17 | 65,10.68,0.29,0:11.44,95%,0.71,sqlite_jit,12.092 18 | 65,15.57,0.27,0:16.51,95%,0,sqlite,12.092 19 | 65,13.80,0.29,0:14.69,95%,0,sqlite_disp,12.092 20 | 65,10.66,0.27,0:11.40,95%,0.71,sqlite_jit,12.092 21 | 65,15.69,0.27,0:16.65,95%,0,sqlite,12.092 22 | 65,13.70,0.27,0:14.57,95%,0,sqlite_disp,12.092 23 | 65,10.69,0.27,0:11.43,95%,0.72,sqlite_jit,12.092 24 | 65,15.69,0.28,0:16.65,95%,0,sqlite,12.092 25 | 65,13.74,0.26,0:14.61,95%,0,sqlite_disp,12.092 26 | 65,10.70,0.30,0:11.47,95%,0.71,sqlite_jit,12.092 27 | 65,15.57,0.28,0:16.53,95%,0,sqlite,12.092 28 | 65,13.70,0.25,0:14.54,95%,0,sqlite_disp,12.092 29 | 65,10.64,0.32,0:11.42,95%,0.72,sqlite_jit,12.092 30 | 65,15.55,0.28,0:16.50,95%,0,sqlite,12.092 31 | 65,13.78,0.28,0:14.67,95%,0,sqlite_disp,12.092 32 | 65,12.40,0.33,0:13.28,95%,0.71,sqlite_jit,24.183 33 | 65,16.07,0.29,0:17.07,95%,0,sqlite,24.183 34 | 65,14.36,0.30,0:15.30,95%,0,sqlite_disp,24.183 35 | 65,12.33,0.33,0:13.21,95%,0.7,sqlite_jit,24.183 36 | 65,16.09,0.28,0:17.07,95%,0,sqlite,24.183 37 | 65,14.41,0.28,0:15.33,95%,0,sqlite_disp,24.183 38 | 65,12.24,0.31,0:13.09,95%,0.72,sqlite_jit,24.183 39 | 65,16.10,0.26,0:17.05,95%,0,sqlite,24.183 40 | 65,14.41,0.28,0:15.32,95%,0,sqlite_disp,24.183 41 | 65,12.22,0.32,0:13.09,95%,0.71,sqlite_jit,24.183 42 | 65,16.08,0.28,0:17.06,95%,0,sqlite,24.183 43 | 65,14.42,0.35,0:15.41,95%,0,sqlite_disp,24.183 44 | 65,12.32,0.35,0:13.22,95%,0.71,sqlite_jit,24.183 45 | 65,16.08,0.30,0:17.09,95%,0,sqlite,24.183 46 | 65,14.35,0.32,0:15.30,95%,0,sqlite_disp,24.183 47 | 65,13.87,0.34,0:14.82,95%,0.71,sqlite_jit,36.27 48 | 65,16.59,0.32,0:17.63,95%,0,sqlite,36.27 49 | 65,15.07,0.35,0:16.08,95%,0,sqlite_disp,36.27 50 | 65,13.71,0.36,0:14.68,95%,0.71,sqlite_jit,36.27 51 | 65,16.70,0.29,0:17.71,95%,0,sqlite,36.27 52 | 65,15.09,0.31,0:16.06,95%,0,sqlite_disp,36.27 53 | 65,13.73,0.34,0:14.68,95%,0.71,sqlite_jit,36.27 54 | 65,16.59,0.30,0:17.61,95%,0,sqlite,36.27 55 | 65,15.09,0.31,0:16.06,95%,0,sqlite_disp,36.27 56 | 65,13.71,0.36,0:14.68,95%,0.71,sqlite_jit,36.27 57 | 65,16.70,0.28,0:17.71,95%,0,sqlite,36.27 58 | 65,15.28,0.31,0:16.26,95%,0,sqlite_disp,36.27 59 | 65,13.83,0.35,0:14.78,95%,0.71,sqlite_jit,36.27 60 | 65,16.60,0.31,0:17.63,95%,0,sqlite,36.27 61 | 65,15.13,0.38,0:16.18,95%,0,sqlite_disp,36.27 62 | 65,15.13,0.38,0:16.18,95%,0.72,sqlite_jit,48.361 63 | 65,17.01,0.36,0:18.12,95%,0,sqlite,48.361 64 | 65,15.71,0.40,0:16.81,95%,0,sqlite_disp,48.361 65 | 65,15.13,0.38,0:16.17,95%,0.71,sqlite_jit,48.361 66 | 65,17.15,0.38,0:18.29,95%,0,sqlite,48.361 67 | 65,15.75,0.38,0:16.83,95%,0,sqlite_disp,48.361 68 | 65,15.12,0.38,0:16.17,95%,0.72,sqlite_jit,48.361 69 | 65,17.37,0.37,0:18.50,95%,0,sqlite,48.361 70 | 65,15.81,0.37,0:16.88,95%,0,sqlite_disp,48.361 71 | 65,15.11,0.39,0:16.17,95%,0.72,sqlite_jit,48.361 72 | 65,17.49,0.38,0:18.63,95%,0,sqlite,48.361 73 | 65,15.76,0.35,0:16.81,95%,0,sqlite_disp,48.361 74 | 65,15.13,0.38,0:16.17,95%,0.7,sqlite_jit,48.361 75 | 65,17.02,0.39,0:18.15,95%,0,sqlite,48.361 76 | 65,15.71,0.38,0:16.79,95%,0,sqlite_disp,48.361 77 | 65,16.52,0.42,0:17.67,95%,0.72,sqlite_jit,60.449 78 | 65,17.67,0.36,0:18.80,95%,0,sqlite,60.449 79 | 65,17.79,0.37,0:18.96,95%,0,sqlite_disp,60.449 80 | 65,16.46,0.46,0:17.65,95%,0.72,sqlite_jit,60.449 81 | 65,17.70,0.38,0:18.86,95%,0,sqlite,60.449 82 | 65,16.71,0.40,0:17.86,95%,0,sqlite_disp,60.449 83 | 65,16.74,0.45,0:17.93,95%,0.71,sqlite_jit,60.449 84 | 65,17.65,0.38,0:18.80,95%,0,sqlite,60.449 85 | 65,16.60,0.42,0:17.77,95%,0,sqlite_disp,60.449 86 | 65,17.10,0.42,0:18.28,95%,0.72,sqlite_jit,60.449 87 | 65,17.63,0.40,0:18.79,95%,0,sqlite,60.449 88 | 65,16.70,0.39,0:17.83,95%,0,sqlite_disp,60.449 89 | 65,16.49,0.45,0:17.67,95%,0.71,sqlite_jit,60.449 90 | 65,17.60,0.42,0:18.80,95%,0,sqlite,60.449 91 | 65,16.61,0.42,0:17.78,95%,0,sqlite_disp,60.449 92 | 65,18.11,0.43,0:19.34,95%,0.71,sqlite_jit,72.544 93 | 65,18.19,0.42,0:19.40,95%,0,sqlite,72.544 94 | 65,17.39,0.43,0:18.61,95%,0,sqlite_disp,72.544 95 | 65,17.70,0.52,0:19.00,95%,0.72,sqlite_jit,72.544 96 | 65,18.19,0.45,0:19.43,95%,0,sqlite,72.544 97 | 65,17.62,0.44,0:18.86,95%,0,sqlite_disp,72.544 98 | 65,18.47,0.45,0:19.73,95%,0.73,sqlite_jit,72.544 99 | 65,18.20,0.45,0:19.44,95%,0,sqlite,72.544 100 | 65,17.48,0.46,0:18.73,95%,0,sqlite_disp,72.544 101 | 65,17.69,0.51,0:18.99,95%,0.71,sqlite_jit,72.544 102 | 65,18.27,0.47,0:19.53,95%,0,sqlite,72.544 103 | 65,17.37,0.45,0:18.60,95%,0,sqlite_disp,72.544 104 | 65,17.72,0.52,0:19.02,95%,0.71,sqlite_jit,72.544 105 | 65,18.09,0.46,0:19.33,95%,0,sqlite,72.544 106 | 65,17.30,0.46,0:18.54,95%,0,sqlite_disp,72.544 107 | 65,19.44,0.49,0:20.79,95%,0.72,sqlite_jit,84.638 108 | 65,18.76,0.46,0:20.04,95%,0,sqlite,84.638 109 | 65,18.15,0.53,0:19.50,95%,0,sqlite_disp,84.638 110 | 65,18.81,0.57,0:20.21,95%,0.7,sqlite_jit,84.638 111 | 65,18.74,0.48,0:20.04,95%,0,sqlite,84.638 112 | 65,18.13,0.49,0:19.44,95%,0,sqlite_disp,84.638 113 | 65,19.57,0.53,0:20.96,95%,0.72,sqlite_jit,84.638 114 | 65,19.30,0.43,0:20.57,95%,0,sqlite,84.638 115 | 65,18.08,0.51,0:19.41,95%,0,sqlite_disp,84.638 116 | 65,18.97,0.56,0:20.37,95%,0.71,sqlite_jit,84.638 117 | 65,18.69,0.51,0:20.01,95%,0,sqlite,84.638 118 | 65,18.24,0.50,0:19.56,95%,0,sqlite_disp,84.638 119 | 65,18.85,0.55,0:20.22,95%,0.71,sqlite_jit,84.638 120 | 65,19.08,0.52,0:20.44,95%,0,sqlite,84.638 121 | 65,18.02,0.56,0:19.40,95%,0,sqlite_disp,84.638 122 | 65,20.69,0.61,0:22.22,95%,0.72,sqlite_jit,96.735 123 | 65,19.23,0.56,0:20.64,95%,0,sqlite,96.735 124 | 65,18.75,0.58,0:20.19,95%,0,sqlite_disp,96.735 125 | 65,19.90,0.57,0:21.35,95%,0.72,sqlite_jit,96.735 126 | 65,19.20,0.53,0:20.58,95%,0,sqlite,96.735 127 | 65,18.79,0.54,0:20.18,95%,0,sqlite_disp,96.735 128 | 65,20.54,0.59,0:22.03,95%,0.71,sqlite_jit,96.735 129 | 65,19.16,0.51,0:20.50,95%,0,sqlite,96.735 130 | 65,18.73,0.55,0:20.13,95%,0,sqlite_disp,96.735 131 | 65,19.89,0.58,0:21.34,95%,0.7,sqlite_jit,96.735 132 | 65,19.33,0.55,0:20.73,95%,0,sqlite,96.735 133 | 65,18.71,0.51,0:20.07,95%,0,sqlite_disp,96.735 134 | 65,20.10,0.58,0:21.57,95%,0.71,sqlite_jit,96.735 135 | 65,19.23,0.54,0:20.61,95%,0,sqlite,96.735 136 | 65,18.73,0.54,0:20.12,95%,0,sqlite_disp,96.735 137 | -------------------------------------------------------------------------------- /src/table.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2001 September 15 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This file contains the sqlite3_get_table() and sqlite3_free_table() 13 | ** interface routines. These are just wrappers around the main 14 | ** interface routine of sqlite3_exec(). 15 | ** 16 | ** These routines are in a separate files so that they will not be linked 17 | ** if they are not used. 18 | */ 19 | #include "sqliteInt.h" 20 | 21 | #ifndef SQLITE_OMIT_GET_TABLE 22 | 23 | /* 24 | ** This structure is used to pass data from sqlite3_get_table() through 25 | ** to the callback function is uses to build the result. 26 | */ 27 | typedef struct TabResult { 28 | char **azResult; /* Accumulated output */ 29 | char *zErrMsg; /* Error message text, if an error occurs */ 30 | u32 nAlloc; /* Slots allocated for azResult[] */ 31 | u32 nRow; /* Number of rows in the result */ 32 | u32 nColumn; /* Number of columns in the result */ 33 | u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ 34 | int rc; /* Return code from sqlite3_exec() */ 35 | } TabResult; 36 | 37 | /* 38 | ** This routine is called once for each row in the result table. Its job 39 | ** is to fill in the TabResult structure appropriately, allocating new 40 | ** memory as necessary. 41 | */ 42 | static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ 43 | TabResult *p = (TabResult*)pArg; /* Result accumulator */ 44 | int need; /* Slots needed in p->azResult[] */ 45 | int i; /* Loop counter */ 46 | char *z; /* A single column of result */ 47 | 48 | /* Make sure there is enough space in p->azResult to hold everything 49 | ** we need to remember from this invocation of the callback. 50 | */ 51 | if( p->nRow==0 && argv!=0 ){ 52 | need = nCol*2; 53 | }else{ 54 | need = nCol; 55 | } 56 | if( p->nData + need > p->nAlloc ){ 57 | char **azNew; 58 | p->nAlloc = p->nAlloc*2 + need; 59 | azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc ); 60 | if( azNew==0 ) goto malloc_failed; 61 | p->azResult = azNew; 62 | } 63 | 64 | /* If this is the first row, then generate an extra row containing 65 | ** the names of all columns. 66 | */ 67 | if( p->nRow==0 ){ 68 | p->nColumn = nCol; 69 | for(i=0; iazResult[p->nData++] = z; 73 | } 74 | }else if( (int)p->nColumn!=nCol ){ 75 | sqlite3_free(p->zErrMsg); 76 | p->zErrMsg = sqlite3_mprintf( 77 | "sqlite3_get_table() called with two or more incompatible queries" 78 | ); 79 | p->rc = SQLITE_ERROR; 80 | return 1; 81 | } 82 | 83 | /* Copy over the row data 84 | */ 85 | if( argv!=0 ){ 86 | for(i=0; iazResult[p->nData++] = z; 96 | } 97 | p->nRow++; 98 | } 99 | return 0; 100 | 101 | malloc_failed: 102 | p->rc = SQLITE_NOMEM_BKPT; 103 | return 1; 104 | } 105 | 106 | /* 107 | ** Query the database. But instead of invoking a callback for each row, 108 | ** malloc() for space to hold the result and return the entire results 109 | ** at the conclusion of the call. 110 | ** 111 | ** The result that is written to ***pazResult is held in memory obtained 112 | ** from malloc(). But the caller cannot free this memory directly. 113 | ** Instead, the entire table should be passed to sqlite3_free_table() when 114 | ** the calling procedure is finished using it. 115 | */ 116 | int sqlite3_get_table( 117 | sqlite3 *db, /* The database on which the SQL executes */ 118 | const char *zSql, /* The SQL to be executed */ 119 | char ***pazResult, /* Write the result table here */ 120 | int *pnRow, /* Write the number of rows in the result here */ 121 | int *pnColumn, /* Write the number of columns of result here */ 122 | char **pzErrMsg /* Write error messages here */ 123 | ){ 124 | int rc; 125 | TabResult res; 126 | 127 | #ifdef SQLITE_ENABLE_API_ARMOR 128 | if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; 129 | #endif 130 | *pazResult = 0; 131 | if( pnColumn ) *pnColumn = 0; 132 | if( pnRow ) *pnRow = 0; 133 | if( pzErrMsg ) *pzErrMsg = 0; 134 | res.zErrMsg = 0; 135 | res.nRow = 0; 136 | res.nColumn = 0; 137 | res.nData = 1; 138 | res.nAlloc = 20; 139 | res.rc = SQLITE_OK; 140 | res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); 141 | if( res.azResult==0 ){ 142 | db->errCode = SQLITE_NOMEM; 143 | return SQLITE_NOMEM_BKPT; 144 | } 145 | res.azResult[0] = 0; 146 | rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); 147 | assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); 148 | res.azResult[0] = SQLITE_INT_TO_PTR(res.nData); 149 | if( (rc&0xff)==SQLITE_ABORT ){ 150 | sqlite3_free_table(&res.azResult[1]); 151 | if( res.zErrMsg ){ 152 | if( pzErrMsg ){ 153 | sqlite3_free(*pzErrMsg); 154 | *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); 155 | } 156 | sqlite3_free(res.zErrMsg); 157 | } 158 | db->errCode = res.rc; /* Assume 32-bit assignment is atomic */ 159 | return res.rc; 160 | } 161 | sqlite3_free(res.zErrMsg); 162 | if( rc!=SQLITE_OK ){ 163 | sqlite3_free_table(&res.azResult[1]); 164 | return rc; 165 | } 166 | if( res.nAlloc>res.nData ){ 167 | char **azNew; 168 | azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData ); 169 | if( azNew==0 ){ 170 | sqlite3_free_table(&res.azResult[1]); 171 | db->errCode = SQLITE_NOMEM; 172 | return SQLITE_NOMEM_BKPT; 173 | } 174 | res.azResult = azNew; 175 | } 176 | *pazResult = &res.azResult[1]; 177 | if( pnColumn ) *pnColumn = res.nColumn; 178 | if( pnRow ) *pnRow = res.nRow; 179 | return rc; 180 | } 181 | 182 | /* 183 | ** This routine frees the space the sqlite3_get_table() malloced. 184 | */ 185 | void sqlite3_free_table( 186 | char **azResult /* Result returned from sqlite3_get_table() */ 187 | ){ 188 | if( azResult ){ 189 | int i, n; 190 | azResult--; 191 | assert( azResult!=0 ); 192 | n = SQLITE_PTR_TO_INT(azResult[0]); 193 | for(i=1; icnt>0; 92 | } 93 | static int debugMutexNotheld(sqlite3_mutex *pX){ 94 | sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; 95 | return p==0 || p->cnt==0; 96 | } 97 | 98 | /* 99 | ** Initialize and deinitialize the mutex subsystem. 100 | */ 101 | static int debugMutexInit(void){ return SQLITE_OK; } 102 | static int debugMutexEnd(void){ return SQLITE_OK; } 103 | 104 | /* 105 | ** The sqlite3_mutex_alloc() routine allocates a new 106 | ** mutex and returns a pointer to it. If it returns NULL 107 | ** that means that a mutex could not be allocated. 108 | */ 109 | static sqlite3_mutex *debugMutexAlloc(int id){ 110 | static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1]; 111 | sqlite3_debug_mutex *pNew = 0; 112 | switch( id ){ 113 | case SQLITE_MUTEX_FAST: 114 | case SQLITE_MUTEX_RECURSIVE: { 115 | pNew = sqlite3Malloc(sizeof(*pNew)); 116 | if( pNew ){ 117 | pNew->id = id; 118 | pNew->cnt = 0; 119 | } 120 | break; 121 | } 122 | default: { 123 | #ifdef SQLITE_ENABLE_API_ARMOR 124 | if( id-2<0 || id-2>=ArraySize(aStatic) ){ 125 | (void)SQLITE_MISUSE_BKPT; 126 | return 0; 127 | } 128 | #endif 129 | pNew = &aStatic[id-2]; 130 | pNew->id = id; 131 | break; 132 | } 133 | } 134 | return (sqlite3_mutex*)pNew; 135 | } 136 | 137 | /* 138 | ** This routine deallocates a previously allocated mutex. 139 | */ 140 | static void debugMutexFree(sqlite3_mutex *pX){ 141 | sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; 142 | assert( p->cnt==0 ); 143 | if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){ 144 | sqlite3_free(p); 145 | }else{ 146 | #ifdef SQLITE_ENABLE_API_ARMOR 147 | (void)SQLITE_MISUSE_BKPT; 148 | #endif 149 | } 150 | } 151 | 152 | /* 153 | ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt 154 | ** to enter a mutex. If another thread is already within the mutex, 155 | ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return 156 | ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK 157 | ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can 158 | ** be entered multiple times by the same thread. In such cases the, 159 | ** mutex must be exited an equal number of times before another thread 160 | ** can enter. If the same thread tries to enter any other kind of mutex 161 | ** more than once, the behavior is undefined. 162 | */ 163 | static void debugMutexEnter(sqlite3_mutex *pX){ 164 | sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; 165 | assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); 166 | p->cnt++; 167 | } 168 | static int debugMutexTry(sqlite3_mutex *pX){ 169 | sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; 170 | assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); 171 | p->cnt++; 172 | return SQLITE_OK; 173 | } 174 | 175 | /* 176 | ** The sqlite3_mutex_leave() routine exits a mutex that was 177 | ** previously entered by the same thread. The behavior 178 | ** is undefined if the mutex is not currently entered or 179 | ** is not currently allocated. SQLite will never do either. 180 | */ 181 | static void debugMutexLeave(sqlite3_mutex *pX){ 182 | sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; 183 | assert( debugMutexHeld(pX) ); 184 | p->cnt--; 185 | assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); 186 | } 187 | 188 | sqlite3_mutex_methods const *sqlite3NoopMutex(void){ 189 | static const sqlite3_mutex_methods sMutex = { 190 | debugMutexInit, 191 | debugMutexEnd, 192 | debugMutexAlloc, 193 | debugMutexFree, 194 | debugMutexEnter, 195 | debugMutexTry, 196 | debugMutexLeave, 197 | 198 | debugMutexHeld, 199 | debugMutexNotheld 200 | }; 201 | 202 | return &sMutex; 203 | } 204 | #endif /* SQLITE_DEBUG */ 205 | 206 | /* 207 | ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation 208 | ** is used regardless of the run-time threadsafety setting. 209 | */ 210 | #ifdef SQLITE_MUTEX_NOOP 211 | sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ 212 | return sqlite3NoopMutex(); 213 | } 214 | #endif /* defined(SQLITE_MUTEX_NOOP) */ 215 | #endif /* !defined(SQLITE_MUTEX_OMIT) */ 216 | -------------------------------------------------------------------------------- /src/sqliteLimit.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2007 May 7 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** 13 | ** This file defines various limits of what SQLite can process. 14 | */ 15 | 16 | /* 17 | ** The maximum length of a TEXT or BLOB in bytes. This also 18 | ** limits the size of a row in a table or index. 19 | ** 20 | ** The hard limit is the ability of a 32-bit signed integer 21 | ** to count the size: 2^31-1 or 2147483647. 22 | */ 23 | #ifndef SQLITE_MAX_LENGTH 24 | # define SQLITE_MAX_LENGTH 1000000000 25 | #endif 26 | 27 | /* 28 | ** This is the maximum number of 29 | ** 30 | ** * Columns in a table 31 | ** * Columns in an index 32 | ** * Columns in a view 33 | ** * Terms in the SET clause of an UPDATE statement 34 | ** * Terms in the result set of a SELECT statement 35 | ** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. 36 | ** * Terms in the VALUES clause of an INSERT statement 37 | ** 38 | ** The hard upper limit here is 32676. Most database people will 39 | ** tell you that in a well-normalized database, you usually should 40 | ** not have more than a dozen or so columns in any table. And if 41 | ** that is the case, there is no point in having more than a few 42 | ** dozen values in any of the other situations described above. 43 | */ 44 | #ifndef SQLITE_MAX_COLUMN 45 | # define SQLITE_MAX_COLUMN 2000 46 | #endif 47 | 48 | /* 49 | ** The maximum length of a single SQL statement in bytes. 50 | ** 51 | ** It used to be the case that setting this value to zero would 52 | ** turn the limit off. That is no longer true. It is not possible 53 | ** to turn this limit off. 54 | */ 55 | #ifndef SQLITE_MAX_SQL_LENGTH 56 | # define SQLITE_MAX_SQL_LENGTH 1000000000 57 | #endif 58 | 59 | /* 60 | ** The maximum depth of an expression tree. This is limited to 61 | ** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might 62 | ** want to place more severe limits on the complexity of an 63 | ** expression. 64 | ** 65 | ** A value of 0 used to mean that the limit was not enforced. 66 | ** But that is no longer true. The limit is now strictly enforced 67 | ** at all times. 68 | */ 69 | #ifndef SQLITE_MAX_EXPR_DEPTH 70 | # define SQLITE_MAX_EXPR_DEPTH 1000 71 | #endif 72 | 73 | /* 74 | ** The maximum number of terms in a compound SELECT statement. 75 | ** The code generator for compound SELECT statements does one 76 | ** level of recursion for each term. A stack overflow can result 77 | ** if the number of terms is too large. In practice, most SQL 78 | ** never has more than 3 or 4 terms. Use a value of 0 to disable 79 | ** any limit on the number of terms in a compount SELECT. 80 | */ 81 | #ifndef SQLITE_MAX_COMPOUND_SELECT 82 | # define SQLITE_MAX_COMPOUND_SELECT 500 83 | #endif 84 | 85 | /* 86 | ** The maximum number of opcodes in a VDBE program. 87 | ** Not currently enforced. 88 | */ 89 | #ifndef SQLITE_MAX_VDBE_OP 90 | # define SQLITE_MAX_VDBE_OP 250000000 91 | #endif 92 | 93 | /* 94 | ** The maximum number of arguments to an SQL function. 95 | */ 96 | #ifndef SQLITE_MAX_FUNCTION_ARG 97 | # define SQLITE_MAX_FUNCTION_ARG 127 98 | #endif 99 | 100 | /* 101 | ** The suggested maximum number of in-memory pages to use for 102 | ** the main database table and for temporary tables. 103 | ** 104 | ** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, 105 | ** which means the cache size is limited to 2048000 bytes of memory. 106 | ** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be 107 | ** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. 108 | */ 109 | #ifndef SQLITE_DEFAULT_CACHE_SIZE 110 | # define SQLITE_DEFAULT_CACHE_SIZE -2000 111 | #endif 112 | 113 | /* 114 | ** The default number of frames to accumulate in the log file before 115 | ** checkpointing the database in WAL mode. 116 | */ 117 | #ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 118 | # define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000 119 | #endif 120 | 121 | /* 122 | ** The maximum number of attached databases. This must be between 0 123 | ** and 125. The upper bound of 125 is because the attached databases are 124 | ** counted using a signed 8-bit integer which has a maximum value of 127 125 | ** and we have to allow 2 extra counts for the "main" and "temp" databases. 126 | */ 127 | #ifndef SQLITE_MAX_ATTACHED 128 | # define SQLITE_MAX_ATTACHED 10 129 | #endif 130 | 131 | 132 | /* 133 | ** The maximum value of a ?nnn wildcard that the parser will accept. 134 | */ 135 | #ifndef SQLITE_MAX_VARIABLE_NUMBER 136 | # define SQLITE_MAX_VARIABLE_NUMBER 999 137 | #endif 138 | 139 | /* Maximum page size. The upper bound on this value is 65536. This a limit 140 | ** imposed by the use of 16-bit offsets within each page. 141 | ** 142 | ** Earlier versions of SQLite allowed the user to change this value at 143 | ** compile time. This is no longer permitted, on the grounds that it creates 144 | ** a library that is technically incompatible with an SQLite library 145 | ** compiled with a different limit. If a process operating on a database 146 | ** with a page-size of 65536 bytes crashes, then an instance of SQLite 147 | ** compiled with the default page-size limit will not be able to rollback 148 | ** the aborted transaction. This could lead to database corruption. 149 | */ 150 | #ifdef SQLITE_MAX_PAGE_SIZE 151 | # undef SQLITE_MAX_PAGE_SIZE 152 | #endif 153 | #define SQLITE_MAX_PAGE_SIZE 65536 154 | 155 | 156 | /* 157 | ** The default size of a database page. 158 | */ 159 | #ifndef SQLITE_DEFAULT_PAGE_SIZE 160 | # define SQLITE_DEFAULT_PAGE_SIZE 4096 161 | #endif 162 | #if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE 163 | # undef SQLITE_DEFAULT_PAGE_SIZE 164 | # define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE 165 | #endif 166 | 167 | /* 168 | ** Ordinarily, if no value is explicitly provided, SQLite creates databases 169 | ** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain 170 | ** device characteristics (sector-size and atomic write() support), 171 | ** SQLite may choose a larger value. This constant is the maximum value 172 | ** SQLite will choose on its own. 173 | */ 174 | #ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE 175 | # define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 176 | #endif 177 | #if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE 178 | # undef SQLITE_MAX_DEFAULT_PAGE_SIZE 179 | # define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE 180 | #endif 181 | 182 | 183 | /* 184 | ** Maximum number of pages in one database file. 185 | ** 186 | ** This is really just the default value for the max_page_count pragma. 187 | ** This value can be lowered (or raised) at run-time using that the 188 | ** max_page_count macro. 189 | */ 190 | #ifndef SQLITE_MAX_PAGE_COUNT 191 | # define SQLITE_MAX_PAGE_COUNT 1073741823 192 | #endif 193 | 194 | /* 195 | ** Maximum length (in bytes) of the pattern in a LIKE or GLOB 196 | ** operator. 197 | */ 198 | #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH 199 | # define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 200 | #endif 201 | 202 | /* 203 | ** Maximum depth of recursion for triggers. 204 | ** 205 | ** A value of 1 means that a trigger program will not be able to itself 206 | ** fire any triggers. A value of 0 means that no trigger programs at all 207 | ** may be executed. 208 | */ 209 | #ifndef SQLITE_MAX_TRIGGER_DEPTH 210 | # define SQLITE_MAX_TRIGGER_DEPTH 1000 211 | #endif 212 | -------------------------------------------------------------------------------- /src/pcache.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2008 August 05 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This header file defines the interface that the sqlite page cache 13 | ** subsystem. 14 | */ 15 | 16 | #ifndef _PCACHE_H_ 17 | 18 | typedef struct PgHdr PgHdr; 19 | typedef struct PCache PCache; 20 | 21 | /* 22 | ** Every page in the cache is controlled by an instance of the following 23 | ** structure. 24 | */ 25 | struct PgHdr { 26 | sqlite3_pcache_page *pPage; /* Pcache object page handle */ 27 | void *pData; /* Page data */ 28 | void *pExtra; /* Extra content */ 29 | PCache *pCache; /* PRIVATE: Cache that owns this page */ 30 | PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ 31 | Pager *pPager; /* The pager this page is part of */ 32 | Pgno pgno; /* Page number for this page */ 33 | #ifdef SQLITE_CHECK_PAGES 34 | u32 pageHash; /* Hash of page content */ 35 | #endif 36 | u16 flags; /* PGHDR flags defined below */ 37 | 38 | /********************************************************************** 39 | ** Elements above, except pCache, are public. All that follow are 40 | ** private to pcache.c and should not be accessed by other modules. 41 | ** pCache is grouped with the public elements for efficiency. 42 | */ 43 | i16 nRef; /* Number of users of this page */ 44 | PgHdr *pDirtyNext; /* Next element in list of dirty pages */ 45 | PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ 46 | /* NB: pDirtyNext and pDirtyPrev are undefined if the 47 | ** PgHdr object is not dirty */ 48 | }; 49 | 50 | /* Bit values for PgHdr.flags */ 51 | #define PGHDR_CLEAN 0x001 /* Page not on the PCache.pDirty list */ 52 | #define PGHDR_DIRTY 0x002 /* Page is on the PCache.pDirty list */ 53 | #define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */ 54 | #define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before 55 | ** writing this page to the database */ 56 | #define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */ 57 | #define PGHDR_MMAP 0x020 /* This is an mmap page object */ 58 | 59 | #define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */ 60 | 61 | /* Initialize and shutdown the page cache subsystem */ 62 | int sqlite3PcacheInitialize(void); 63 | void sqlite3PcacheShutdown(void); 64 | 65 | /* Page cache buffer management: 66 | ** These routines implement SQLITE_CONFIG_PAGECACHE. 67 | */ 68 | void sqlite3PCacheBufferSetup(void *, int sz, int n); 69 | 70 | /* Create a new pager cache. 71 | ** Under memory stress, invoke xStress to try to make pages clean. 72 | ** Only clean and unpinned pages can be reclaimed. 73 | */ 74 | int sqlite3PcacheOpen( 75 | int szPage, /* Size of every page */ 76 | int szExtra, /* Extra space associated with each page */ 77 | int bPurgeable, /* True if pages are on backing store */ 78 | int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ 79 | void *pStress, /* Argument to xStress */ 80 | PCache *pToInit /* Preallocated space for the PCache */ 81 | ); 82 | 83 | /* Modify the page-size after the cache has been created. */ 84 | int sqlite3PcacheSetPageSize(PCache *, int); 85 | 86 | /* Return the size in bytes of a PCache object. Used to preallocate 87 | ** storage space. 88 | */ 89 | int sqlite3PcacheSize(void); 90 | 91 | /* One release per successful fetch. Page is pinned until released. 92 | ** Reference counted. 93 | */ 94 | sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); 95 | int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); 96 | PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); 97 | void sqlite3PcacheRelease(PgHdr*); 98 | 99 | void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ 100 | void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ 101 | void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ 102 | void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ 103 | void sqlite3PcacheClearWritable(PCache*); 104 | 105 | /* Change a page number. Used by incr-vacuum. */ 106 | void sqlite3PcacheMove(PgHdr*, Pgno); 107 | 108 | /* Remove all pages with pgno>x. Reset the cache if x==0 */ 109 | void sqlite3PcacheTruncate(PCache*, Pgno x); 110 | 111 | /* Get a list of all dirty pages in the cache, sorted by page number */ 112 | PgHdr *sqlite3PcacheDirtyList(PCache*); 113 | 114 | /* Reset and close the cache object */ 115 | void sqlite3PcacheClose(PCache*); 116 | 117 | /* Clear flags from pages of the page cache */ 118 | void sqlite3PcacheClearSyncFlags(PCache *); 119 | 120 | /* Discard the contents of the cache */ 121 | void sqlite3PcacheClear(PCache*); 122 | 123 | /* Return the total number of outstanding page references */ 124 | int sqlite3PcacheRefCount(PCache*); 125 | 126 | /* Increment the reference count of an existing page */ 127 | void sqlite3PcacheRef(PgHdr*); 128 | 129 | int sqlite3PcachePageRefcount(PgHdr*); 130 | 131 | /* Return the total number of pages stored in the cache */ 132 | int sqlite3PcachePagecount(PCache*); 133 | 134 | #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) 135 | /* Iterate through all dirty pages currently stored in the cache. This 136 | ** interface is only available if SQLITE_CHECK_PAGES is defined when the 137 | ** library is built. 138 | */ 139 | void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); 140 | #endif 141 | 142 | #if defined(SQLITE_DEBUG) 143 | /* Check invariants on a PgHdr object */ 144 | int sqlite3PcachePageSanity(PgHdr*); 145 | #endif 146 | 147 | /* Set and get the suggested cache-size for the specified pager-cache. 148 | ** 149 | ** If no global maximum is configured, then the system attempts to limit 150 | ** the total number of pages cached by purgeable pager-caches to the sum 151 | ** of the suggested cache-sizes. 152 | */ 153 | void sqlite3PcacheSetCachesize(PCache *, int); 154 | #ifdef SQLITE_TEST 155 | int sqlite3PcacheGetCachesize(PCache *); 156 | #endif 157 | 158 | /* Set or get the suggested spill-size for the specified pager-cache. 159 | ** 160 | ** The spill-size is the minimum number of pages in cache before the cache 161 | ** will attempt to spill dirty pages by calling xStress. 162 | */ 163 | int sqlite3PcacheSetSpillsize(PCache *, int); 164 | 165 | /* Free up as much memory as possible from the page cache */ 166 | void sqlite3PcacheShrink(PCache*); 167 | 168 | #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 169 | /* Try to return memory used by the pcache module to the main memory heap */ 170 | int sqlite3PcacheReleaseMemory(int); 171 | #endif 172 | 173 | #ifdef SQLITE_TEST 174 | void sqlite3PcacheStats(int*,int*,int*,int*); 175 | #endif 176 | 177 | void sqlite3PCacheSetDefault(void); 178 | 179 | /* Return the header size */ 180 | int sqlite3HeaderSizePcache(void); 181 | int sqlite3HeaderSizePcache1(void); 182 | 183 | /* Number of dirty pages as a percentage of the configured cache size */ 184 | int sqlite3PCachePercentDirty(PCache*); 185 | 186 | #endif /* _PCACHE_H_ */ 187 | -------------------------------------------------------------------------------- /src/vdbetrace.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2009 November 25 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** 13 | ** This file contains code used to insert the values of host parameters 14 | ** (aka "wildcards") into the SQL text output by sqlite3_trace(). 15 | ** 16 | ** The Vdbe parse-tree explainer is also found here. 17 | */ 18 | #include "sqliteInt.h" 19 | #include "vdbeInt.h" 20 | 21 | #ifndef SQLITE_OMIT_TRACE 22 | 23 | /* 24 | ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of 25 | ** bytes in this text up to but excluding the first character in 26 | ** a host parameter. If the text contains no host parameters, return 27 | ** the total number of bytes in the text. 28 | */ 29 | static int findNextHostParameter(const char *zSql, int *pnToken){ 30 | int tokenType; 31 | int nTotal = 0; 32 | int n; 33 | 34 | *pnToken = 0; 35 | while( zSql[0] ){ 36 | n = sqlite3GetToken((u8*)zSql, &tokenType); 37 | assert( n>0 && tokenType!=TK_ILLEGAL ); 38 | if( tokenType==TK_VARIABLE ){ 39 | *pnToken = n; 40 | break; 41 | } 42 | nTotal += n; 43 | zSql += n; 44 | } 45 | return nTotal; 46 | } 47 | 48 | /* 49 | ** This function returns a pointer to a nul-terminated string in memory 50 | ** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the 51 | ** string contains a copy of zRawSql but with host parameters expanded to 52 | ** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, 53 | ** then the returned string holds a copy of zRawSql with "-- " prepended 54 | ** to each line of text. 55 | ** 56 | ** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then 57 | ** then long strings and blobs are truncated to that many bytes. This 58 | ** can be used to prevent unreasonably large trace strings when dealing 59 | ** with large (multi-megabyte) strings and blobs. 60 | ** 61 | ** The calling function is responsible for making sure the memory returned 62 | ** is eventually freed. 63 | ** 64 | ** ALGORITHM: Scan the input string looking for host parameters in any of 65 | ** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within 66 | ** string literals, quoted identifier names, and comments. For text forms, 67 | ** the host parameter index is found by scanning the prepared 68 | ** statement for the corresponding OP_Variable opcode. Once the host 69 | ** parameter index is known, locate the value in p->aVar[]. Then render 70 | ** the value as a literal in place of the host parameter name. 71 | */ 72 | char *sqlite3VdbeExpandSql( 73 | Vdbe *p, /* The prepared statement being evaluated */ 74 | const char *zRawSql /* Raw text of the SQL statement */ 75 | ){ 76 | sqlite3 *db; /* The database connection */ 77 | int idx = 0; /* Index of a host parameter */ 78 | int nextIndex = 1; /* Index of next ? host parameter */ 79 | int n; /* Length of a token prefix */ 80 | int nToken; /* Length of the parameter token */ 81 | int i; /* Loop counter */ 82 | Mem *pVar; /* Value of a host parameter */ 83 | StrAccum out; /* Accumulate the output here */ 84 | #ifndef SQLITE_OMIT_UTF16 85 | Mem utf8; /* Used to convert UTF16 into UTF8 for display */ 86 | #endif 87 | char zBase[100]; /* Initial working space */ 88 | 89 | db = p->db; 90 | sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), 91 | db->aLimit[SQLITE_LIMIT_LENGTH]); 92 | if( db->nVdbeExec>1 ){ 93 | while( *zRawSql ){ 94 | const char *zStart = zRawSql; 95 | while( *(zRawSql++)!='\n' && *zRawSql ); 96 | sqlite3StrAccumAppend(&out, "-- ", 3); 97 | assert( (zRawSql - zStart) > 0 ); 98 | sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); 99 | } 100 | }else if( p->nVar==0 ){ 101 | sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); 102 | }else{ 103 | while( zRawSql[0] ){ 104 | n = findNextHostParameter(zRawSql, &nToken); 105 | assert( n>0 ); 106 | sqlite3StrAccumAppend(&out, zRawSql, n); 107 | zRawSql += n; 108 | assert( zRawSql[0] || nToken==0 ); 109 | if( nToken==0 ) break; 110 | if( zRawSql[0]=='?' ){ 111 | if( nToken>1 ){ 112 | assert( sqlite3Isdigit(zRawSql[1]) ); 113 | sqlite3GetInt32(&zRawSql[1], &idx); 114 | }else{ 115 | idx = nextIndex; 116 | } 117 | }else{ 118 | assert( zRawSql[0]==':' || zRawSql[0]=='$' || 119 | zRawSql[0]=='@' || zRawSql[0]=='#' ); 120 | testcase( zRawSql[0]==':' ); 121 | testcase( zRawSql[0]=='$' ); 122 | testcase( zRawSql[0]=='@' ); 123 | testcase( zRawSql[0]=='#' ); 124 | idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); 125 | assert( idx>0 ); 126 | } 127 | zRawSql += nToken; 128 | nextIndex = idx + 1; 129 | assert( idx>0 && idx<=p->nVar ); 130 | pVar = &p->aVar[idx-1]; 131 | if( pVar->flags & MEM_Null ){ 132 | sqlite3StrAccumAppend(&out, "NULL", 4); 133 | }else if( pVar->flags & MEM_Int ){ 134 | sqlite3XPrintf(&out, "%lld", pVar->u.i); 135 | }else if( pVar->flags & MEM_Real ){ 136 | sqlite3XPrintf(&out, "%!.15g", pVar->u.r); 137 | }else if( pVar->flags & MEM_Str ){ 138 | int nOut; /* Number of bytes of the string text to include in output */ 139 | #ifndef SQLITE_OMIT_UTF16 140 | u8 enc = ENC(db); 141 | if( enc!=SQLITE_UTF8 ){ 142 | memset(&utf8, 0, sizeof(utf8)); 143 | utf8.db = db; 144 | sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); 145 | if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ 146 | out.accError = STRACCUM_NOMEM; 147 | out.nAlloc = 0; 148 | } 149 | pVar = &utf8; 150 | } 151 | #endif 152 | nOut = pVar->n; 153 | #ifdef SQLITE_TRACE_SIZE_LIMIT 154 | if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ 155 | nOut = SQLITE_TRACE_SIZE_LIMIT; 156 | while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } 157 | } 158 | #endif 159 | sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); 160 | #ifdef SQLITE_TRACE_SIZE_LIMIT 161 | if( nOutn ){ 162 | sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); 163 | } 164 | #endif 165 | #ifndef SQLITE_OMIT_UTF16 166 | if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); 167 | #endif 168 | }else if( pVar->flags & MEM_Zero ){ 169 | sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); 170 | }else{ 171 | int nOut; /* Number of bytes of the blob to include in output */ 172 | assert( pVar->flags & MEM_Blob ); 173 | sqlite3StrAccumAppend(&out, "x'", 2); 174 | nOut = pVar->n; 175 | #ifdef SQLITE_TRACE_SIZE_LIMIT 176 | if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; 177 | #endif 178 | for(i=0; iz[i]&0xff); 180 | } 181 | sqlite3StrAccumAppend(&out, "'", 1); 182 | #ifdef SQLITE_TRACE_SIZE_LIMIT 183 | if( nOutn ){ 184 | sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); 185 | } 186 | #endif 187 | } 188 | } 189 | } 190 | if( out.accError ) sqlite3StrAccumReset(&out); 191 | return sqlite3StrAccumFinish(&out); 192 | } 193 | 194 | #endif /* #ifndef SQLITE_OMIT_TRACE */ 195 | -------------------------------------------------------------------------------- /src/parse.h: -------------------------------------------------------------------------------- 1 | #define TK_SEMI 1 2 | #define TK_EXPLAIN 2 3 | #define TK_QUERY 3 4 | #define TK_PLAN 4 5 | #define TK_BEGIN 5 6 | #define TK_TRANSACTION 6 7 | #define TK_DEFERRED 7 8 | #define TK_IMMEDIATE 8 9 | #define TK_EXCLUSIVE 9 10 | #define TK_COMMIT 10 11 | #define TK_END 11 12 | #define TK_ROLLBACK 12 13 | #define TK_SAVEPOINT 13 14 | #define TK_RELEASE 14 15 | #define TK_TO 15 16 | #define TK_TABLE 16 17 | #define TK_CREATE 17 18 | #define TK_IF 18 19 | #define TK_NOT 19 20 | #define TK_EXISTS 20 21 | #define TK_TEMP 21 22 | #define TK_LP 22 23 | #define TK_RP 23 24 | #define TK_AS 24 25 | #define TK_WITHOUT 25 26 | #define TK_COMMA 26 27 | #define TK_ABORT 27 28 | #define TK_ACTION 28 29 | #define TK_AFTER 29 30 | #define TK_ANALYZE 30 31 | #define TK_ASC 31 32 | #define TK_ATTACH 32 33 | #define TK_BEFORE 33 34 | #define TK_BY 34 35 | #define TK_CASCADE 35 36 | #define TK_CAST 36 37 | #define TK_CONFLICT 37 38 | #define TK_DATABASE 38 39 | #define TK_DESC 39 40 | #define TK_DETACH 40 41 | #define TK_EACH 41 42 | #define TK_FAIL 42 43 | #define TK_OR 43 44 | #define TK_AND 44 45 | #define TK_IS 45 46 | #define TK_MATCH 46 47 | #define TK_LIKE_KW 47 48 | #define TK_BETWEEN 48 49 | #define TK_IN 49 50 | #define TK_ISNULL 50 51 | #define TK_NOTNULL 51 52 | #define TK_NE 52 53 | #define TK_EQ 53 54 | #define TK_GT 54 55 | #define TK_LE 55 56 | #define TK_LT 56 57 | #define TK_GE 57 58 | #define TK_ESCAPE 58 59 | #define TK_ID 59 60 | #define TK_COLUMNKW 60 61 | #define TK_FOR 61 62 | #define TK_IGNORE 62 63 | #define TK_INITIALLY 63 64 | #define TK_INSTEAD 64 65 | #define TK_NO 65 66 | #define TK_KEY 66 67 | #define TK_OF 67 68 | #define TK_OFFSET 68 69 | #define TK_PRAGMA 69 70 | #define TK_RAISE 70 71 | #define TK_RECURSIVE 71 72 | #define TK_REPLACE 72 73 | #define TK_RESTRICT 73 74 | #define TK_ROW 74 75 | #define TK_TRIGGER 75 76 | #define TK_VACUUM 76 77 | #define TK_VIEW 77 78 | #define TK_VIRTUAL 78 79 | #define TK_WITH 79 80 | #define TK_REINDEX 80 81 | #define TK_RENAME 81 82 | #define TK_CTIME_KW 82 83 | #define TK_ANY 83 84 | #define TK_BITAND 84 85 | #define TK_BITOR 85 86 | #define TK_LSHIFT 86 87 | #define TK_RSHIFT 87 88 | #define TK_PLUS 88 89 | #define TK_MINUS 89 90 | #define TK_STAR 90 91 | #define TK_SLASH 91 92 | #define TK_REM 92 93 | #define TK_CONCAT 93 94 | #define TK_COLLATE 94 95 | #define TK_BITNOT 95 96 | #define TK_INDEXED 96 97 | #define TK_STRING 97 98 | #define TK_JOIN_KW 98 99 | #define TK_CONSTRAINT 99 100 | #define TK_DEFAULT 100 101 | #define TK_NULL 101 102 | #define TK_PRIMARY 102 103 | #define TK_UNIQUE 103 104 | #define TK_CHECK 104 105 | #define TK_REFERENCES 105 106 | #define TK_AUTOINCR 106 107 | #define TK_ON 107 108 | #define TK_INSERT 108 109 | #define TK_DELETE 109 110 | #define TK_UPDATE 110 111 | #define TK_SET 111 112 | #define TK_DEFERRABLE 112 113 | #define TK_FOREIGN 113 114 | #define TK_DROP 114 115 | #define TK_UNION 115 116 | #define TK_ALL 116 117 | #define TK_EXCEPT 117 118 | #define TK_INTERSECT 118 119 | #define TK_SELECT 119 120 | #define TK_VALUES 120 121 | #define TK_DISTINCT 121 122 | #define TK_DOT 122 123 | #define TK_FROM 123 124 | #define TK_JOIN 124 125 | #define TK_USING 125 126 | #define TK_ORDER 126 127 | #define TK_GROUP 127 128 | #define TK_HAVING 128 129 | #define TK_LIMIT 129 130 | #define TK_WHERE 130 131 | #define TK_INTO 131 132 | #define TK_FLOAT 132 133 | #define TK_BLOB 133 134 | #define TK_INTEGER 134 135 | #define TK_VARIABLE 135 136 | #define TK_CASE 136 137 | #define TK_WHEN 137 138 | #define TK_THEN 138 139 | #define TK_ELSE 139 140 | #define TK_INDEX 140 141 | #define TK_ALTER 141 142 | #define TK_ADD 142 143 | #define TK_ISNOT 143 144 | #define TK_FUNCTION 144 145 | #define TK_COLUMN 145 146 | #define TK_AGG_FUNCTION 146 147 | #define TK_AGG_COLUMN 147 148 | #define TK_UMINUS 148 149 | #define TK_UPLUS 149 150 | #define TK_REGISTER 150 151 | #define TK_VECTOR 151 152 | #define TK_SELECT_COLUMN 152 153 | #define TK_IF_NULL_ROW 153 154 | #define TK_ASTERISK 154 155 | #define TK_SPAN 155 156 | #define TK_END_OF_FILE 156 157 | #define TK_UNCLOSED_STRING 157 158 | #define TK_SPACE 158 159 | #define TK_ILLEGAL 159 160 | 161 | /* The token codes above must all fit in 8 bits */ 162 | #define TKFLG_MASK 0xff 163 | 164 | /* Flags that can be added to a token code when it is not 165 | ** being stored in a u8: */ 166 | #define TKFLG_DONTFOLD 0x100 /* Omit constant folding optimizations */ 167 | -------------------------------------------------------------------------------- /src/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2001 September 22 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This is the implementation of generic hash-tables 13 | ** used in SQLite. 14 | */ 15 | #include "sqliteInt.h" 16 | #include 17 | 18 | /* Turn bulk memory into a hash table object by initializing the 19 | ** fields of the Hash structure. 20 | ** 21 | ** "pNew" is a pointer to the hash table that is to be initialized. 22 | */ 23 | void sqlite3HashInit(Hash *pNew){ 24 | assert( pNew!=0 ); 25 | pNew->first = 0; 26 | pNew->count = 0; 27 | pNew->htsize = 0; 28 | pNew->ht = 0; 29 | } 30 | 31 | /* Remove all entries from a hash table. Reclaim all memory. 32 | ** Call this routine to delete a hash table or to reset a hash table 33 | ** to the empty state. 34 | */ 35 | void sqlite3HashClear(Hash *pH){ 36 | HashElem *elem; /* For looping over all elements of the table */ 37 | 38 | assert( pH!=0 ); 39 | elem = pH->first; 40 | pH->first = 0; 41 | sqlite3_free(pH->ht); 42 | pH->ht = 0; 43 | pH->htsize = 0; 44 | while( elem ){ 45 | HashElem *next_elem = elem->next; 46 | sqlite3_free(elem); 47 | elem = next_elem; 48 | } 49 | pH->count = 0; 50 | } 51 | 52 | /* 53 | ** The hashing function. 54 | */ 55 | static unsigned int strHash(const char *z){ 56 | unsigned int h = 0; 57 | unsigned char c; 58 | while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ 59 | /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). 60 | ** 0x9e3779b1 is 2654435761 which is the closest prime number to 61 | ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ 62 | h += sqlite3UpperToLower[c]; 63 | h *= 0x9e3779b1; 64 | } 65 | return h; 66 | } 67 | 68 | 69 | /* Link pNew element into the hash table pH. If pEntry!=0 then also 70 | ** insert pNew into the pEntry hash bucket. 71 | */ 72 | static void insertElement( 73 | Hash *pH, /* The complete hash table */ 74 | struct _ht *pEntry, /* The entry into which pNew is inserted */ 75 | HashElem *pNew /* The element to be inserted */ 76 | ){ 77 | HashElem *pHead; /* First element already in pEntry */ 78 | if( pEntry ){ 79 | pHead = pEntry->count ? pEntry->chain : 0; 80 | pEntry->count++; 81 | pEntry->chain = pNew; 82 | }else{ 83 | pHead = 0; 84 | } 85 | if( pHead ){ 86 | pNew->next = pHead; 87 | pNew->prev = pHead->prev; 88 | if( pHead->prev ){ pHead->prev->next = pNew; } 89 | else { pH->first = pNew; } 90 | pHead->prev = pNew; 91 | }else{ 92 | pNew->next = pH->first; 93 | if( pH->first ){ pH->first->prev = pNew; } 94 | pNew->prev = 0; 95 | pH->first = pNew; 96 | } 97 | } 98 | 99 | 100 | /* Resize the hash table so that it cantains "new_size" buckets. 101 | ** 102 | ** The hash table might fail to resize if sqlite3_malloc() fails or 103 | ** if the new size is the same as the prior size. 104 | ** Return TRUE if the resize occurs and false if not. 105 | */ 106 | static int rehash(Hash *pH, unsigned int new_size){ 107 | struct _ht *new_ht; /* The new hash table */ 108 | HashElem *elem, *next_elem; /* For looping over existing elements */ 109 | 110 | #if SQLITE_MALLOC_SOFT_LIMIT>0 111 | if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ 112 | new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); 113 | } 114 | if( new_size==pH->htsize ) return 0; 115 | #endif 116 | 117 | /* The inability to allocates space for a larger hash table is 118 | ** a performance hit but it is not a fatal error. So mark the 119 | ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of 120 | ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() 121 | ** only zeroes the requested number of bytes whereas this module will 122 | ** use the actual amount of space allocated for the hash table (which 123 | ** may be larger than the requested amount). 124 | */ 125 | sqlite3BeginBenignMalloc(); 126 | new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); 127 | sqlite3EndBenignMalloc(); 128 | 129 | if( new_ht==0 ) return 0; 130 | sqlite3_free(pH->ht); 131 | pH->ht = new_ht; 132 | pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); 133 | memset(new_ht, 0, new_size*sizeof(struct _ht)); 134 | for(elem=pH->first, pH->first=0; elem; elem = next_elem){ 135 | unsigned int h = strHash(elem->pKey) % new_size; 136 | next_elem = elem->next; 137 | insertElement(pH, &new_ht[h], elem); 138 | } 139 | return 1; 140 | } 141 | 142 | /* This function (for internal use only) locates an element in an 143 | ** hash table that matches the given key. If no element is found, 144 | ** a pointer to a static null element with HashElem.data==0 is returned. 145 | ** If pH is not NULL, then the hash for this key is written to *pH. 146 | */ 147 | static HashElem *findElementWithHash( 148 | const Hash *pH, /* The pH to be searched */ 149 | const char *pKey, /* The key we are searching for */ 150 | unsigned int *pHash /* Write the hash value here */ 151 | ){ 152 | HashElem *elem; /* Used to loop thru the element list */ 153 | int count; /* Number of elements left to test */ 154 | unsigned int h; /* The computed hash */ 155 | static HashElem nullElement = { 0, 0, 0, 0 }; 156 | 157 | if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ 158 | struct _ht *pEntry; 159 | h = strHash(pKey) % pH->htsize; 160 | pEntry = &pH->ht[h]; 161 | elem = pEntry->chain; 162 | count = pEntry->count; 163 | }else{ 164 | h = 0; 165 | elem = pH->first; 166 | count = pH->count; 167 | } 168 | if( pHash ) *pHash = h; 169 | while( count-- ){ 170 | assert( elem!=0 ); 171 | if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ 172 | return elem; 173 | } 174 | elem = elem->next; 175 | } 176 | return &nullElement; 177 | } 178 | 179 | /* Remove a single entry from the hash table given a pointer to that 180 | ** element and a hash on the element's key. 181 | */ 182 | static void removeElementGivenHash( 183 | Hash *pH, /* The pH containing "elem" */ 184 | HashElem* elem, /* The element to be removed from the pH */ 185 | unsigned int h /* Hash value for the element */ 186 | ){ 187 | struct _ht *pEntry; 188 | if( elem->prev ){ 189 | elem->prev->next = elem->next; 190 | }else{ 191 | pH->first = elem->next; 192 | } 193 | if( elem->next ){ 194 | elem->next->prev = elem->prev; 195 | } 196 | if( pH->ht ){ 197 | pEntry = &pH->ht[h]; 198 | if( pEntry->chain==elem ){ 199 | pEntry->chain = elem->next; 200 | } 201 | pEntry->count--; 202 | assert( pEntry->count>=0 ); 203 | } 204 | sqlite3_free( elem ); 205 | pH->count--; 206 | if( pH->count==0 ){ 207 | assert( pH->first==0 ); 208 | assert( pH->count==0 ); 209 | sqlite3HashClear(pH); 210 | } 211 | } 212 | 213 | /* Attempt to locate an element of the hash table pH with a key 214 | ** that matches pKey. Return the data for this element if it is 215 | ** found, or NULL if there is no match. 216 | */ 217 | void *sqlite3HashFind(const Hash *pH, const char *pKey){ 218 | assert( pH!=0 ); 219 | assert( pKey!=0 ); 220 | return findElementWithHash(pH, pKey, 0)->data; 221 | } 222 | 223 | /* Insert an element into the hash table pH. The key is pKey 224 | ** and the data is "data". 225 | ** 226 | ** If no element exists with a matching key, then a new 227 | ** element is created and NULL is returned. 228 | ** 229 | ** If another element already exists with the same key, then the 230 | ** new data replaces the old data and the old data is returned. 231 | ** The key is not copied in this instance. If a malloc fails, then 232 | ** the new data is returned and the hash table is unchanged. 233 | ** 234 | ** If the "data" parameter to this function is NULL, then the 235 | ** element corresponding to "key" is removed from the hash table. 236 | */ 237 | void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ 238 | unsigned int h; /* the hash of the key modulo hash table size */ 239 | HashElem *elem; /* Used to loop thru the element list */ 240 | HashElem *new_elem; /* New element added to the pH */ 241 | 242 | assert( pH!=0 ); 243 | assert( pKey!=0 ); 244 | elem = findElementWithHash(pH,pKey,&h); 245 | if( elem->data ){ 246 | void *old_data = elem->data; 247 | if( data==0 ){ 248 | removeElementGivenHash(pH,elem,h); 249 | }else{ 250 | elem->data = data; 251 | elem->pKey = pKey; 252 | } 253 | return old_data; 254 | } 255 | if( data==0 ) return 0; 256 | new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); 257 | if( new_elem==0 ) return data; 258 | new_elem->pKey = pKey; 259 | new_elem->data = data; 260 | pH->count++; 261 | if( pH->count>=10 && pH->count > 2*pH->htsize ){ 262 | if( rehash(pH, pH->count*2) ){ 263 | assert( pH->htsize>0 ); 264 | h = strHash(pKey) % pH->htsize; 265 | } 266 | } 267 | insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); 268 | return 0; 269 | } 270 | --------------------------------------------------------------------------------