やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SQLite3をソースからビルドする(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)

 delete,update文でlimit句を使うためのビルド。

成果物

手順

 ソースをダウンロード&展開。

wget https://www.sqlite.org/2019/sqlite-src-3290000.zip
unzip sqlite-src-3290000.zip

 2.コマンドラインインターフェイスのコンパイルによると、合併(amalgamation)にある以下ソースファイルも必要らしい。

  • sqlite3.c
  • sqlite3.h
  • shell.c
wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz
tar xf sqlite-autoconf-3290000.tar.gz
cp ./sqlite-autoconf-3290000/sqlite3.c ./sqlite-src-3290000/sqlite3.c
cp ./sqlite-autoconf-3290000/sqlite3.h ./sqlite-src-3290000/sqlite3.h
cp ./sqlite-autoconf-3290000/shell.c ./sqlite-src-3290000/shell.c

 オプション付与。

./configure \
--enable-fts4 \
--enable-fts5 \
--enable-json1 \
--enable-update-limit \
--enable-geopoly \
--enable-rtree \
--enable-session \
LIBS="-lz" \
LDFLAGS="`icu-config --ldflags`" \
CFLAGS="`icu-config --cppflags` -DHAVE_READLINE=1 -DSQLITE_ALLOW_URI_AUTHORITY=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_ICU=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_MEMSYS3=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_SNAPSHOT=1 -DSQLITE_ENABLE_STMTVTAB=1 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_ENABLE_UNLOCK_NOTIFY=1 -DSQLITE_INTROSPECTION_PRAGMAS=1 -DSQLITE_USE_ALLOCA=1 -DSQLITE_USE_FCNTL_TRACE=1 -DSQLITE_HAVE_ZLIB=1"

 ビルド。

time make

確認

sqlite3
pragma compile_options;
ALLOW_URI_AUTHORITY
COMPILER=gcc-6.3.0 20170516
ENABLE_COLUMN_METADATA
ENABLE_DBSTAT_VTAB
ENABLE_FTS4
ENABLE_FTS5
ENABLE_GEOPOLY
ENABLE_ICU
ENABLE_JSON1
ENABLE_MEMSYS3
ENABLE_PREUPDATE_HOOK
ENABLE_RTREE
ENABLE_SESSION
ENABLE_SNAPSHOT
ENABLE_STMTVTAB
ENABLE_UNKNOWN_SQL_FUNCTION
ENABLE_UNLOCK_NOTIFY
ENABLE_UPDATE_DELETE_LIMIT
HAVE_ISNAN
THREADSAFE=1
USE_ALLOCA
USE_FCNTL_TRACE

 ENABLE_UPDATE_DELETE_LIMITがあった。OK。

 HAVE_ISNANはつけた覚えがないが、まあいい。

delete文でlimit句を使う

create table T(A integer);
delete from T limit 1;



 OK。near "limit": syntax errorのようなエラーが出なかった。

 指定の上限数までしか削除されないことを確認。

create table T(A integer);
insert into T values(0);
insert into T values(1);
delete from T limit 1;
select count(*) from T;
1

 OK。1件しか削除されてない。limitが効いてる。

 以前limitを使ったコードを実行する。

3_0.sql
Error: near line 4: ORDER BY without LIMIT on DELETE
0
1
3_1.sql
0
1
3_2.sql
0
1

 あ、使い方を間違っていた。deleteorder by句を使うならlimitも使えと。ですよね。limitなしでorder by句を使っても論理的に意味ないもの。

 それ以外は成功。エラーが出なくなっている。

 これでdeletelimit句が使えるようになった!

試行錯誤ログ

試行錯誤

なぜエラー?

 deletelimit句を使えなかった。SQLite_ENABLE_UPDATE_DELETE_LIMITコンパイルオプションを有効にしたのだが……。

このオプションは、UPDATEおよびDELETEステートメントでオプションのORDER BYおよびLIMIT句を有効にします 。

 オプションをONにしてビルドしたのに、有効になってないんだが。

このオプションを定義する場合、Lemonパーサージェネレーターツールを使用してparse.cファイルを生成するときにも定義する必要があります。このため、このオプションは、ライブラリがソースからビルドされる場合にのみ使用でき、Webサイト上の非Unixのようなプラットフォーム用に提供された統合または事前パッケージCファイルのコレクションからではありません。

 なに言ってるかわからん。Lemonパーサージェネレーターツールって何? 「parse.cファイルを生成するとき」っていつ? 今回それ関係あるの?ないの? 

 「ソースからビルドされる場合にのみ使用でき」るらしい。ソースからコンパイルしたつもりなのだが。「事前パッケージCファイルのコレクションからではありません」というやつか? 使うコード間違ったってこと?

ソースコード

 sqlite-autoconf-3290000.tar.gzじゃダメなの? downloadページにはにはC source code as an amalgamation. Also includes a "configure" script and TEA makefiles for the TCL Interface.とある。たしか統合(amalgamation)ではダメなんだっけ? これが原因か……。

 ならどうすればいいの? もしやsqlite-src-3290000.zipのコードを使うのか? そしてHow to compileをみてコンパイルしろって?

 4.合併の構築をみると、独自の合併(amalgamation)が必要なオプションの中にSQLITE_ENABLE_UPDATE_DELETE_LIMITがあるようだ。そして、独自の合併をするには、sqlite-src-3290000.zipのコードを使え、というわけか。

How to compile

gcc -Os -I \
-DHAVE_READLINE=1 \
... コンパイルオプション ...
shell.c sqlite3.c -ldl -lreadline -lncurses -o sqlite3

 TCLインタフェース用ライブラリは以下で作成する。

gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl
make sqlite3.c

 とあるが、上記コマンドではなく、sqlite-autoconf-3290000.tar.gzのときのビルドと同様、./configure ...makeで作れたんですけど。どゆこと?

./configure --help

 sqlite-src-3290000

./configure --help
`configure' configures sqlite 3.29.0 to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/sqlite]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-shared[=PKGS]  build shared libraries [default=yes]
  --enable-static[=PKGS]  build static libraries [default=yes]
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)
  --disable-largefile     omit support for large files
  --disable-threadsafe    Disable mutexing
  --enable-releasemode    Support libtool link to release mode
  --enable-tempstore      Use an in-ram database for temporary tables
                          (never,no,yes,always)
  --disable-tcl           do not build TCL extension
  --enable-editline       enable BSD editline support
  --disable-readline      disable readline support
  --enable-debug          enable debugging & verbose explain
  --disable-amalgamation  Disable the amalgamation and instead build all files
                          separately
  --disable-load-extension
                          Disable loading of external extensions
  --enable-memsys5        Enable MEMSYS5
  --enable-memsys3        Enable MEMSYS3
  --enable-fts3           Enable the FTS3 extension
  --enable-fts4           Enable the FTS4 extension
  --enable-fts5           Enable the FTS5 extension
  --enable-json1          Enable the JSON1 extension
  --enable-update-limit   Enable the UPDATE/DELETE LIMIT clause
  --enable-geopoly        Enable the GEOPOLY extension
  --enable-rtree          Enable the RTREE extension
  --enable-session        Enable the SESSION extension
  --enable-gcov           Enable coverage testing using gcov

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-pic              try to use only PIC/non-PIC objects [default=use
                          both]
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
  --with-tcl=DIR          directory containing tcl configuration
                          (tclConfig.sh)
  --with-readline-lib     specify readline library
  --with-readline-inc     specify readline include paths

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  TCLLIBDIR   Where to install tcl plugin

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to the package provider.

 --enable-update-limitがあった。これだ! sqlite-autoconf-3290000.tar.gzには無い。

 他にも違うところがあるようだ。うまいことオプションをつけて作ってみよう。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux

前回まで