p2: digest with in-sift FIFO, SQLite caches, Honcho context, recover
Dixie is capped (max_inflight 2, queue_depth 8, queue_wait 20s) and never queued on llama-server. Streaming chat, thinking off, 45s fallback to clean. Digest and chunk-embedding caches are content-addressed SQLite (Honcho context is not cached). Recover uses the guarded Fetcher. guardian-star is refused in code.
This commit is contained in:
Generated
+1
@@ -0,0 +1 @@
|
||||
.claude/
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# This file lists authors for copyright purposes. This file is distinct from
|
||||
# the CONTRIBUTORS files. See the latter for an explanation.
|
||||
#
|
||||
# Names should be added to this file as:
|
||||
# Name or Organization <email address>
|
||||
#
|
||||
# The email address is not required for organizations.
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Angus Dippenaar <angusdippenaar@gmail.com>
|
||||
Artyom Pervukhin <github@artyom.dev>
|
||||
Dan Kortschak <dan@kortschak.io>
|
||||
Dan Peterson <danp@danp.net>
|
||||
David Walton <david@davidwalton.com>
|
||||
Davsk Ltd Co <skinner.david@gmail.com>
|
||||
FerretDB Inc.
|
||||
Harald Albrecht <thediveo@gmx.eu>
|
||||
Ian Chechin <ian00chechin@gmail.com>
|
||||
Jaap Aarts <jaap.aarts1@gmail.com>
|
||||
Jan Mercl <0xjnml@gmail.com>
|
||||
Josh Bleecher Snyder <josharian@gmail.com>
|
||||
Josh Klein <josh.klein@outlook.com>
|
||||
Logan Snow <logansnow@protonmail.com>
|
||||
Michael Hoffmann <mhoffm@posteo.de>
|
||||
Michael Rykov <mrykov@gmail.com>
|
||||
Morgan Bazalgette <morgan@howl.moe>
|
||||
Nathan Herring <nherring@google.com>
|
||||
Ross Light <ross@zombiezen.com>
|
||||
SUSE LLC <moio@suse.com>
|
||||
Saed SayedAhmed <saadmtsa@gmail.com>
|
||||
Steffen Butzer <steffen(dot)butzer@outlook.com>
|
||||
Toni Spets <toni.spets@beeper.com>
|
||||
W. Michael Petullo <mike@flyn.org>
|
||||
Zhenghao Zhang zhangzhenghao@hotmail.com
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
# Changelog
|
||||
|
||||
Entries for v1.38.1 through v1.44.1 and for v1.49.1 were added on 2026-09-05, reconstructed from the git history and the merge requests they cite; they were missing at release time.
|
||||
|
||||
- 2026-09-15 v1.59.0:
|
||||
- Bump the pinned `modernc.org/libc` to [v1.75.7](https://gitlab.com/cznic/libc/-/tags/v1.75.7) and re-vendor `lib/` and `vec/` from `modernc.org/libsqlite3` v1.14.5 and `modernc.org/libsqlite_vec` v0.5.0, which were transpiled against it. As always, downstream `go.mod` files must pin the same `modernc.org/libc` version as this repository's `go.mod`; see the package documentation and [GitLab issue #177](https://gitlab.com/cznic/sqlite/-/issues/177). The transpiled SQLite is unchanged: still 3.53.4, byte-identical to v1.58.0 on all 20 targets. The change is beneath it. On the Linux targets libc v1.75.7 replaces the transpiled musl `memcpy`, `memmove`, `memset`, `memcmp`, `strcspn` and `fabs`, loops moving at most four bytes per step, with native Go routines backed by the runtime's vectorized `memmove` and `memclr` and by the `bytes` package; on every target `strlen` is now a word-at-a-time scan, or `bytes.IndexByte` on the 64-bit architectures. On the three CPU-bound workloads in the new Performance section of the package documentation, measured on linux/amd64 against the same SQLite 3.53.4 compiled from C with the same options, this driver went from 3.0x, 2.2x and 1.6x the CPU time of the C build to 2.0x, 1.9x and 1.3x. The other operating systems already used a native Go `memcpy` and `memmove` and see no such change. `vec/` stays at sqlite-vec v0.1.9; its re-vendor, from a transpile made with newer modernc.org/cc and modernc.org/ccgo, differs only in unreferenced macro constants and in one bounds check spelled with `INT8_MAX` instead of its value, so nothing changes in behavior there either.
|
||||
- Hand user-defined function and aggregate callbacks a pooled `*FunctionContext` instead of allocating a fresh one per call. After the `[]driver.Value` pooling of #226 this was the last driver-side heap allocation per invocation: one 16-byte object for every `Scalar`, `Step`, `WindowInverse`, `WindowValue` and `Final` call. The context now also carries the invocation's `sqlite3_context`, so accessor methods can be added to it later without touching the trampolines. Like the argument slice, it is valid only for the duration of the callback and must not be retained past its return; the documentation on `FunctionContext` and on the callbacks now says so. On the 1000-row, 3-argument noop scalar UDF benchmark this removes a further 1000 allocs/op (5756 to 4756, and 3756 to 2756 with `VolatileArgs`) and 16 KB/op; on the reporter's reproducer from #226 it removes about 12% of the remaining allocations (25.3M to 22.4M allocs/op, 553 MB to 505 MB per iteration).
|
||||
- Updates [GitLab issue #226](https://gitlab.com/cznic/sqlite/-/issues/226). See [GitLab merge request #137](https://gitlab.com/cznic/sqlite/-/merge_requests/137).
|
||||
- Add regression tests for the pooled context: two functions evaluated in one statement must receive two different `sqlite3_context` values and every callback's context must belong to the invoking connection, checked on two connections held at once and without dereferencing the context, so that a stale one is reported rather than faulted on; eight connections held at once calling a function from their own goroutines, and a function that runs a statement invoking another function, both meant for the race detector. See [GitLab merge request #138](https://gitlab.com/cznic/sqlite/-/merge_requests/138), thanks Ian Chechin!
|
||||
- Add a Performance section to the package documentation. It records the measured CPU-time ratios of this driver against the same SQLite compiled from C, that they hold under concurrency, where the gap comes from, and the two consequences for applications: index the columns that `ORDER BY`, `GROUP BY` and `WHERE` use, because a query that is merely sluggish in C can cross a deadline here, and bound the `database/sql` pool with `SetMaxOpenConns`, because a periodic query that outlasts its period piles up connections without bound. Prompted by [a report](https://github.com/coderage-labs/spillway/issues/162) that attributed a 103 s query to the driver spilling a temporary b-tree in Go; the workload showed no spill and about 2x the CPU cost of C, the wall time being unbounded overlap of periodic polls.
|
||||
|
||||
- 2026-09-01 v1.58.0:
|
||||
- Upgrade to [SQLite 3.53.4](https://sqlite.org/releaselog/3_53_4.html). Upstream's own fix for the journal-rollback data-corruption bug is part of this release, so the local super-journal patch v1.56.0 introduced — and promised to drop once upstream shipped theirs — is dropped; recovery behavior is unchanged. This also bumps the pinned `modernc.org/libc` to v1.75.6; as always, downstream modules must pin the exact `modernc.org/libc` version this module's `go.mod` pins (see [GitLab issue #177](https://gitlab.com/cznic/sqlite/-/issues/177)).
|
||||
- Add opt-in support for **Linux Open File Description (OFD) locks** on database files. A POSIX record lock is owned by the (process, inode) pair, so the kernel drops every lock the process holds on a database file whenever any descriptor of that file is closed: an `os.Open`/`Close` for a hash, a backup check or a metadata probe anywhere in the process — third-party libraries included — silently strips SQLite's transaction locks and leaves the file unprotected against other processes. With OFD locking enabled, the locks belong to the open file description that placed them and survive such a close. **Off by default, and staying off until the mode has real-world mileage**: without opting in, locking behavior is byte-for-byte that of previous releases. Enable it by setting `MODERNC_SQLITE_OFD_LOCK=1` in the environment the process starts with (any value but the empty string or one starting with `0`; read once, at library initialization), or from Go with the new `OFDLocking(true)`, which overrides the variable and must run before the first connection is opened; `OFDLockingEnabled` reports the mode in effect. The switch is deliberately **process-wide rather than a DSN parameter**: POSIX and OFD locks taken by one process are different owners to the kernel and genuinely conflict, so every connection to a database file inside one process must use the same kind, and a per-DSN knob would advertise a granularity the kernel does not offer (see the discussion in #255). Because the two kinds do not release one another, the mode is frozen at the process's first lock attempt: later attempts to change it return the new `ErrOFDLockingTooLate`, while querying, and setting the value already in effect, keep working. On kernels older than 3.15, and on filesystems that reject OFD locks, the first lock attempt falls back to POSIX locks for good and `OFDLocking` returns the new `ErrOFDLockingUnavailable` from then on, which is also how `OFDLockingEnabled` turning false reports the fallback; the same error is returned on every platform but Linux, where the API exists but OFD locks do not. Two boundaries to note: the immunity covers the locks on the database file itself, while WAL's `-shm` coordination stays on POSIX locks; and code in the same process that takes fcntl record locks of its own on a database file — which used to never conflict with SQLite's, while quietly destroying them — now conflicts with them loudly instead. The C side — `F_OFD_SETLK` routing through a designated per-inode locking descriptor that preserves upstream's `unixInodeInfo` semantics (last-unlocker release, PENDING piggybacking, `unix-excl`), guarded to `__linux__` — ships in the transpiled sources via [libsqlite3!3](https://gitlab.com/cznic/libsqlite3/-/merge_requests/3) and its follow-up hardening, with the OFD lock constants from [libc!33](https://gitlab.com/cznic/libc/-/merge_requests/33); the review rounds, the `/proc/locks` measurements behind the design, and the Tcl lock/WAL gate that runs both modes are recorded in [GitLab issue #255](https://gitlab.com/cznic/sqlite/-/issues/255) and those merge requests.
|
||||
- Add the accompanying regression tests. The four OFD scenarios contributed in merge request #136 — lock survival across a rogue `os.Close`, the interleaved-readers lock lifecycle, the read-only-first designated-descriptor migration, and the failed-first-lock cleanup — run in a re-executed child process with `MODERNC_SQLITE_OFD_LOCK=1`, since the mode is process-wide and frozen at the first lock so the suite's own process cannot switch; a positive control asserts the variable really switched the mode on before each scenario runs, and the two scenarios whose invariants hold under both modes also run in the parent process's inherited mode. `TestOFDLockingSetter` exercises the Go call path end to end in a clean child — off by default, enabled before the first connection, the kernel-visible `OFDLCK` record in `/proc/locks` as the positive control, frozen after the first lock — and on every other platform the switch is asserted to report itself unavailable.
|
||||
- Resolves [GitLab issue #255](https://gitlab.com/cznic/sqlite/-/issues/255). See [GitLab merge request #136](https://gitlab.com/cznic/sqlite/-/merge_requests/136), thanks Nathan Herring (@technosloth), and thanks Gani Georgiev (@ganigeorgiev) for pressing the opt-in default!
|
||||
|
||||
- 2026-08-19 v1.57.0:
|
||||
- Add an opt-in `_defensive` DSN query parameter that turns on SQLite's defensive mode for the connection, disabling the SQL-level features that let ordinary statements deliberately corrupt the database file. When `_defensive=1` (or any `strconv.ParseBool` true value) is supplied, the driver calls `sqlite3_db_config` with `SQLITE_DBCONFIG_DEFENSIVE` immediately after `sqlite3_open_v2` and before every other parameter is applied, so the PRAGMAs the driver itself runs, the `_pragma` list, and every statement the caller prepares are all subject to it. On such a connection `PRAGMA writable_schema=ON`, `PRAGMA journal_mode=OFF` and `PRAGMA schema_version=N` become silent no-ops, and writes to a virtual table's shadow tables (fts5's `_data`, `_idx` and so on) and to `sqlite_dbpage` fail with "table ... may not be modified"; reading those tables, ordinary use of the virtual tables that own them, and `VACUUM` are unaffected. The flag has no PRAGMA equivalent, so `sqlite3_db_config` — and therefore a DSN parameter — is the only way to reach it short of dropping to `modernc.org/sqlite/lib`. The value is parsed before `sqlite3_open_v2`, so an invalid one fails the connection without creating the database file, and the parameter must appear at most once: a repeated `_defensive` is an error rather than letting the first value silently win. Absence of the parameter, or `_defensive=0`, leaves SQLite's default behavior unchanged; existing DSNs continue to work byte-for-byte. Two limits are worth stating plainly, since the name invites more confidence than the flag earns. Defensive mode is a hardening measure, not a sandbox for hostile database files: it is one of several steps [SQLite recommends](https://www.sqlite.org/security.html) for that purpose, and this build compiles with neither `SQLITE_TRUSTED_SCHEMA=0` nor `SQLITE_DQS=0` and exposes no authorizer. And it is a property of the connection, not of the database file — a second handle opened on the same file without the parameter is unrestricted.
|
||||
- Reject the one DSN combination defensive mode would otherwise swallow in silence. `_defensive=1` together with `_journal_mode=OFF` (or `_journal=OFF`) now fails the connection instead of opening one in which neither parameter was honoured: SQLite turns `PRAGMA journal_mode=OFF` into a no-op that still reports success, so the driver would have accepted the mode, executed it, and left the journal untouched without telling anyone. The check runs in the validation phase introduced in v1.55.0, before any statement executes, so a rejected DSN cannot leave the database half-configured. `_pragma` remains the exception it has always been: `_pragma=journal_mode(OFF)` alongside `_defensive=1` still runs and is still silently ignored by SQLite. Only DSNs using `_defensive` can be affected, and that parameter is new, so no DSN that opened before changes behavior.
|
||||
- See [GitHub pull request #6](https://github.com/modernc-org/sqlite/pull/6), thanks wsman!
|
||||
- Ship the sqlite-vec license notice this module has been missing. `modernc.org/sqlite/vec` has bundled the transpiled [sqlite-vec](https://github.com/asg017/sqlite-vec) sources since v1.47.0, but the module carried only its own BSD-3-Clause `LICENSE` and the public-domain SQLite notice. sqlite-vec is Copyright (c) 2024 Alex Garcia, dual-licensed Apache-2.0 OR MIT and used here under MIT, whose terms require the copyright and permission notice to accompany substantial portions of the software — which 2.8 MB of transpiled `vec/` plainly is. The notice now ships as `LICENSE-SQLITE_VEC` in the module root, byte-identical to the `LICENSE-MIT` in the upstream v0.1.9 archive and named after the file `modernc.org/libsqlite_vec` extracts it into. Attribution was never absent — `vec`'s package documentation has named the extension, pinned the version and linked upstream — but the license text itself was, and the omission was ours: `vendor_libs/main.go` copied the per-target transpiles and nothing else. It now copies the notice alongside them and fails the vendoring run if it cannot, so a `make vendor` can no longer quietly drop it. The `vec` package documentation gained a License section recording that the package is under a different license from the rest of this module.
|
||||
- **The SQLite notice is renamed from `SQLITE-LICENSE` to `LICENSE-SQLITE`**; update any direct links to it. Its contents are unchanged and SQLite remains public domain. The name now matches both the new `LICENSE-SQLITE_VEC` beside it and the `LICENSE-<upstream>` convention every other modernc.org repository follows, but it is more than cosmetic: `go mod vendor` selects the files it copies into a downstream `vendor/` tree by matching each name against a fixed list of prefixes — `LICENSE` among them — so a name merely *ending* in `LICENSE` was never propagated. Both bundled notices now travel with the code into vendored builds, which is where the MIT terms on `vec/` keep applying. No code changes; no behavior changes.
|
||||
- Let a caller-constructed `Driver` register its own functions, collations and virtual table modules. `Driver` has always held four categories of registration state, but only `RegisterConnectionHook` could put anything on a constructed one: functions and collations were reachable through the package-level API alone, and modules through the package-level driver only, which left the `modules` field written and read through that instance and so process-global state wearing a per-instance field. `Driver` now has `RegisterFunction`, `RegisterScalarFunction`, `RegisterDeterministicScalarFunction`, `RegisterCollationUtf8` and `RegisterModule`, plus `Must*` variants of the first four, each registering on that `Driver` alone; the methods are safe to call concurrently, and the zero `Driver` is ready to use as-is. `vtab.RegisterModule` also honours its `db` argument now: a non-nil `db` registers on the driver backing it when that driver implements the new `vtab.ModuleRegisterer`, while a nil `db` keeps targeting the driver this package registers as `sqlite`. One existing pattern changes behavior, narrowly and loudly: `vtab.RegisterModule(db, ...)` where `db` was opened on a caller-constructed `Driver` used to discard the `db` argument and land on the `sqlite` driver, reaching every connection in the process; it now lands on the constructed driver alone, so a `sql.Open("sqlite")` connection that used to resolve such a module gets `no such module` instead. The same pattern is also the one way an existing program could hold one module name on both a constructed `Driver` and the package-level one: there the first of the two registrations used to win and the second was refused as already registered, whereas now the package-level implementation wins on the constructed `Driver`'s connections regardless of the order they ran in. Reaching that case at all means the program ignored an error the older version returned. Two smaller deviations round out the list: `Driver.RegisterModule` reports no error for such a collision, and `vtab.RegisterModule` now validates its name and module arguments before the not-implemented check, so a call with an empty name that returned `vtab: RegisterModule not wired into engine` outside this driver returns `vtab: module name must be non-empty` instead. Everything else is additive against v1.56.0: the package-level registration functions target the same driver they always did, connections still receive every module registered through the package-level path whichever `Driver` opened them, and a `db` opened on the `sqlite` driver resolves to that same driver. The isolating change discussed in [GitLab issue #254](https://gitlab.com/cznic/sqlite/-/issues/254) is deliberately not made here.
|
||||
- See [GitLab merge request #135](https://gitlab.com/cznic/sqlite/-/merge_requests/135), thanks Ian Chechin!
|
||||
- Promote `freebsd/386`, `freebsd/arm` and `netbsd/amd64` to fully supported platforms. All three are now listed in the package documentation's platform table, which had carried seventeen entries while this module shipped, cross-built and tested twenty. They arrived as **experimental** in v1.53.0 — `netbsd/amd64` reviving a port that had been broken for years, `freebsd/386` replacing a stale, effectively untested SQLite 3.41 transpile, and `freebsd/arm` entirely new — and were deliberately kept out of that table until they had accumulated real-world exposure, with promotion promised once "a period of broader real-world testing … elapses without surprises". That period has elapsed: all three have been in the builder test matrix and in `make build_all_targets` since v1.53.0, all three pass the full test suite on this release's commit alongside the seventeen platforms already listed, and no open issue reports a defect in any of them. The two `netbsd/amd64` build failures filed before the revival, [GitLab issue #202](https://gitlab.com/cznic/sqlite/-/issues/202) and [GitLab issue #234](https://gitlab.com/cznic/sqlite/-/issues/234), no longer reproduce at this commit: `Xsqlite3_is_interrupted` is present in the sources that target selects, and the `mu.enter`/`mu.leave` symbols that broke the build are gone. Documentation only — the transpiled sources under `lib/` are byte-for-byte what v1.56.0 shipped, and nothing about how these targets behave changes.
|
||||
|
||||
- 2026-08-03 v1.56.0:
|
||||
- Re-vendor the transpiled SQLite sources, picking up `modernc.org/libsqlite3`'s fix for an upstream **data-corruption bug in SQLite 3.53.3's journal rollback**. The SQLite version is unchanged at [3.53.3](https://sqlite.org/releaselog/3_53_3.html); what changes is that the amalgamation is now patched before it is transpiled. 3.53.3 reworked `readSuperJournal()` to return the super-journal name through a `char**` out-parameter, and `pager_playback()` now tests that pointer where it used to test `zSuper[0]`. A crash during the commit of a multi-database (ATTACH) transaction can leave the super-journal name and its checksum zeroed while the name length and the trailing magic survive; the checksum is a plain byte sum, so an all-zero name still validates and `readSuperJournal()` hands back a non-NULL pointer to an empty string. `pager_playback()` then calls `sqlite3OsAccess(pVfs, "", SQLITE_ACCESS_EXISTS)`, gets ENOENT, and deletes the hot journal without playing it back — leaving the database corrupted. This is not a transpilation artifact: a plain gcc build of the stock 3.53.3 amalgamation fails on the same bytes while 3.53.2 recovers them, and it is what has been making upstream's own `test/crash.test` fail intermittently, in roughly 2% of runs, on every platform. The patch restores the pre-3.53.3 behaviour of reporting a `(nul)` super-journal name and will be dropped once upstream ships its own fix. Every supported target carries it.
|
||||
- Two targets change beyond that patch. On `linux/s390x` the regenerated transpile allocates C bit-fields MSB-first, as the big-endian platform ABI requires, rather than LSB-first; this comes from `modernc.org/cc/v4` v4.29.1 and touches bit-field accesses throughout the SQLite core, s390x being this module's only big-endian target. On `linux/riscv64` the transpile was regenerated on a host running GCC 11.4.0 where the previous one used GCC 13.3.0, which drops a handful of unexported compiler-predefined macro constants (the `__FLT16_*` family, `__DBL_IS_IEC_60559__` and friends) and changes the `COMPILER=gcc-13.3.0` entry `PRAGMA compile_options` reports to `COMPILER=gcc-11.4.0`; no SQLite code generation differs. Every other target's generated code is byte-identical to v1.55.0 apart from the journal-rollback patch above.
|
||||
- Bump the pinned `modernc.org/libc` to v1.74.4, and the remaining dependencies to their current releases. v1.74.2 and v1.74.3 are retracted upstream — a `freeaddrinfo` lock leak that deadlocks name resolution — and v1.74.4 is the fix. As always, downstream modules must pin the exact `modernc.org/libc` version this module's `go.mod` pins (see [GitLab issue #177](https://gitlab.com/cznic/sqlite/-/issues/177)).
|
||||
- Documentation sweep. `openbsd/amd64` and `openbsd/arm64` join the supported platforms table in the package documentation: both have been in the builder test matrix since January and are cross-built by `make build_all_targets`, but had never been listed. The `vfs` DSN query parameter — which names a VFS registered with SQLite, such as one returned by `vfs.New` — is now documented alongside the other DSN parameters on `Driver.Open`. The "Debug and development versions" section no longer describes a `GO_GENERATE` environment variable and a `go generate` that this repository has not had since `generator.go` moved to `modernc.org/libsqlite3`; it now points at that repository and `make vendor` instead, and the stale `//go:generate` directive naming the removed file is dropped with it. `modernc.org/sqlite/vec` and `modernc.org/sqlite/vfs` gained the package doc comments they were missing, so both finally carry a synopsis on pkg.go.dev. Documentation only; no behavior changes.
|
||||
- Add `NewConnector`, returning a `database/sql/driver.Connector` for use with `sql.OpenDB`. It opens the same connections `sql.Open("sqlite", dsn)` does, from the same registered driver, so every function, collation, connection hook and virtual table module registered through this package applies to them. It exists for callers that need to interpose on the physical connections `database/sql` opens — tracing, metrics, connection-scoped setup — which `sql.Open` gives no access to: such a caller can embed the returned `Connector`, override `Connect`, and pass its own wrapper to `sql.OpenDB`. Previously the only way to reach the registered driver was the `db, _ := sql.Open("sqlite", ""); drv := db.Driver(); db.Close()` idiom, which works only because `sql.Open` does not connect and this driver does not implement `driver.DriverContext`; and the only way to get a wrapper into a `*sql.DB` was `sql.Register`, which is process-global, panics on a name it has already seen, and cannot be undone, so a library had to invent a unique driver name per configuration. `sql.OpenDB` registers nothing. Constructing a `&sqlite.Driver{}` is not an alternative — its fields are unexported, so it carries none of the registrations. `NewConnector` checks the DSN only as far as it can without opening a database — a query string that does not parse, and conflicting `vfs` parameters; everything else continues to be validated when the connection is opened, so an unknown parameter or an out-of-range value is reported by `Connect` rather than at construction. Nothing about the existing `sql.Open` path changes: `*Driver` deliberately still does not implement `driver.DriverContext`, so `sql.Open` remains lazy and DSN errors continue to surface where they always have. A runnable sample is in `examples/connector`. Resolves [GitLab issue #253](https://gitlab.com/cznic/sqlite/-/issues/253), thanks Alessandro Segala (@ItalyPaleAle)!
|
||||
- Document that a caller-constructed `sqlite.Driver` is not the driver this package registers as `"sqlite"`. Its fields are unexported, so it starts with no functions, collations or connection hooks and the only way to give it any is its own `RegisterConnectionHook` method; the package-level `Register*` functions always apply to the registered driver. Connections such a `Driver` opens therefore run without the package-level functions and collations — and because a registered function silently replaces a SQLite built-in of the same name, a `Driver` you construct can evaluate `upper(x)`, `date(x)` and the like differently from one opened through `sql.Open`. Virtual table modules are the one exception: they are held process-globally and reach every `Driver`. Constructing one remains supported for the private-hook pattern — a driver registered under a name of its own with `sql.Register` so its connection hooks apply only to its own connections — and is otherwise best avoided in favour of `sql.Open` or `NewConnector`. Documentation only; no behavior changes.
|
||||
|
||||
- 2026-07-20 v1.55.0:
|
||||
- Add `github.com/mattn/go-sqlite3`-compatible shorthand DSN query parameters to ease migration from that driver: `_busy_timeout`/`_timeout`, `_foreign_keys`/`_fk`, `_journal_mode`/`_journal`, `_synchronous`/`_sync`, `_auto_vacuum`/`_vacuum`, and `_query_only`, each setting the correspondingly named PRAGMA. Values are validated against the same set `mattn/go-sqlite3` accepts (case-insensitive) and an unrecognized value fails the connection with an error, so a typo such as `_synchronous=fu1l` or `_foreign_keys=yes_please` is reported rather than silently downgrading durability or dropping foreign-key enforcement. The keys are applied in a fixed order independent of their order in the DSN — `_busy_timeout` and `_auto_vacuum` before any `_pragma` values (`auto_vacuum` must be set before the database is first written), the rest after, and `_query_only` last — and where a key and its alias are both supplied the alias wins, matching `mattn/go-sqlite3`; selection is by presence rather than by value, so supplying the alias empty (`_foreign_keys=on&_fk=`) suppresses the PRAGMA rather than deferring to the primary key, again matching that driver. Behavior change to note: prior releases ignored these keys entirely, so a DSN carried over from a `mattn/go-sqlite3` setup changes in two ways. A recognized key that previously did nothing now takes effect — `_foreign_keys=on` begins enforcing constraints against data that may already violate them, `_journal_mode=wal` persistently converts the database file, and `_query_only=1` makes the connection read-only. And a value outside the accepted set now fails the connection with an error where the same DSN previously opened successfully — for example a duration-style `_busy_timeout=5s` or `_timeout=5000ms`, neither of which is the integer that key requires. Review such DSNs before upgrading. `_pragma` is unchanged and no pre-existing parameter changes meaning, though see the following entry for a change in when all of them are validated.
|
||||
- See [GitLab merge request #134](https://gitlab.com/cznic/sqlite/-/merge_requests/134), thanks Toni Spets (@beeper-hifi) and Ian Chechin!
|
||||
- Validate every DSN query parameter before applying any of them. Parameters were previously checked as each was reached, so a DSN whose later parameter was rejected had already executed the PRAGMAs ahead of it. Because `PRAGMA journal_mode` and `PRAGMA auto_vacuum` are persistent changes to the database file, a DSN such as `file:x.db?_journal_mode=wal&_synchronous=bogus` failed the connection and yet left `x.db` converted to WAL. A failed `Open` now leaves the database as it found it. This covers the pre-existing `_txlock`, `_timezone`, `_time_format`, `_time_integer_format`, `_inttotime` and `_texttotime` parameters as well as the shorthand keys above: all of them were validated only after the `_pragma` list had already run, so the same DSN shape — a valid `_pragma=journal_mode=wal` alongside a misspelled `_txlock` — converted the file before reporting the error. Only the values accepted for each parameter are unchanged; a DSN that opened successfully before still opens, and one that failed still fails with the same error. `_pragma` remains the sole exception, since its values are executed verbatim and cannot be checked in advance: a malformed `_pragma` is still rejected by SQLite as it runs, after any earlier `_pragma` in the list has taken effect.
|
||||
|
||||
- 2026-07-15 v1.54.0:
|
||||
- Upgrade to [SQLite 3.53.3](https://sqlite.org/releaselog/3_53_3.html). This also bumps the pinned `modernc.org/libc` to v1.74.1; as always, downstream modules must pin the exact same `modernc.org/libc` version this module's `go.mod` pins (see [GitLab issue #177](https://gitlab.com/cznic/sqlite/-/issues/177)).
|
||||
- Under the opt-in `_texttotime` DSN parameter, best-effort parse date-shaped TEXT values from columns SQLite reports with an empty declared type — aggregates and expressions over a date column (`MAX(d)`, `COALESCE(d, ...)`, `upper(d)`, `d || ''`), subqueries, and typeless real columns (`CREATE TABLE t(x)`) — into `time.Time`, instead of delivering them as a raw string that `Scan` cannot store into a `*time.Time`. The existing declared `DATE`/`DATETIME`/`TIME`/`TIMESTAMP` path is unchanged; this only adds the empty-decltype case. The conversion is strictly best-effort: a value that does not parse as a time falls through to the original string, so no `Scan` that worked before can newly fail. `ColumnTypeScanType` continues to report `string` for empty-decltype columns, since the declared type cannot prove the column is temporal. Without `_texttotime` the behavior is byte-for-byte unchanged. Resolves [GitLab issue #248](https://gitlab.com/cznic/sqlite/-/issues/248).
|
||||
- See [GitLab merge request #133](https://gitlab.com/cznic/sqlite/-/merge_requests/133), thanks Ian Chechin!
|
||||
|
||||
- 2026-06-21 v1.53.0:
|
||||
- Add **experimental** `netbsd/amd64` support, resolving the long-standing build break in [GitLab issue #246](https://gitlab.com/cznic/sqlite/-/issues/246). This target is intentionally **not yet listed among the supported platforms** in the package documentation: the port had been broken for years and is only now revived, and there is as yet no real-world experience running it under production workloads. Green CI is not the same as battle-tested — so while the full test suite (including the `pcache` and `vec` packages and the `-race` concurrency test) passes on NetBSD 10.1 / Go 1.26.3, and the entire upstream toolchain (`libc`, `cc`, `ccgo`, `libz`, `libtcl8.6`, `libsqlite3`, `libsqlite_vec`) is green on the NetBSD CI builder, the target is offered for evaluation only. If you run NetBSD, please exercise it with your own workloads and report back via #246; the intent is to promote it to a fully supported platform after a period of broader real-world testing (on the order of a month) elapses without surprises.
|
||||
- Implementation notes: the previously shipped `lib/sqlite_netbsd_amd64.go` was a stale old-generator transpile that no longer compiled (the `mu.enter`/`mu.leave` break in #246); it is replaced by a fresh new-generator transpile consistent with every other platform, and `modernc.org/sqlite/vec` (sqlite-vec) is vendored and auto-registers on netbsd. Correct operation requires the matching pinned `modernc.org/libc`, which carries two NetBSD-specific fixes found during this work: the `mmap(2)` `PAD`-argument ABI (without it, concurrent WAL access faults with SIGBUS in the WAL-index shared memory) and a working `abort(3)` (the prior stub left SQLite's crash-recovery `writecrash` test unable to terminate by signal). As usual, downstream modules must pin the exact `modernc.org/libc` version this module's `go.mod` pins.
|
||||
- See [GitLab merge request #82](https://gitlab.com/cznic/sqlite/-/merge_requests/82), thanks Leonardo Taccari (@iamleot) and Thomas Klausner (@_wiz_)!
|
||||
- Add **experimental** `freebsd/386` and `freebsd/arm` support. As with the `netbsd/amd64` target above, these two 32-bit FreeBSD ports are intentionally **not yet listed among the supported platforms** in the package documentation: `freebsd/386` previously shipped a stale, effectively untested SQLite 3.41 transpile, and `freebsd/arm` is entirely new, so neither has real-world production mileage yet. Both are now freshly transpiled at SQLite 3.53.2 consistent with every other platform, build cleanly, and pass the full test suite (core, WAL/concurrency, and the `vec` package) on the FreeBSD CI builders; they are offered for evaluation only. If you run 32-bit FreeBSD, please exercise these targets with your own workloads and report back — the intent is to promote `freebsd/386`, `freebsd/arm`, and `netbsd/amd64` to fully supported platforms in a future release cycle, once a period of broader real-world testing elapses without surprises.
|
||||
- Implementation notes: correct operation on `freebsd/arm` requires the matching pinned `modernc.org/libc` (v1.73.4), which fixes the per-arch `mmap(2)` `off_t` encoding for 32-bit FreeBSD; without it the WAL shared-memory mapping faults with SIGBUS under concurrent access, the same class of bug found on the netbsd port. As usual, downstream modules must pin the exact `modernc.org/libc` version this module's `go.mod` pins.
|
||||
- See [GitLab merge request #119](https://gitlab.com/cznic/sqlite/-/merge_requests/119), thanks Olivier Cochard-Labbé (@ocochard)!
|
||||
- Add a Go-facing wrapper for `SQLITE_CONFIG_PCACHE2`. `PageCache` is the factory and `Cache` the per-database instance, both idiomatic Go interfaces; `Page` exposes the raw `Buf` and `Extra` pointers that SQLite reads through the C pcache contract. `RegisterPageCache` and `MustRegisterPageCache` install the module process-globally before the first `sql.Open`; subsequent Open calls are gated through a one-shot `Xsqlite3_config(SQLITE_CONFIG_PCACHE2)` so a too-late Register returns `ErrPageCacheTooLate` rather than silently falling through to the built-in pcache1. The binding owns the `sqlite3_pcache_page` stub and re-consults the implementation on every Fetch, reusing the stub only when the returned `Page` value is unchanged, which keeps a bounded/evicting purgeable cache safe by construction.
|
||||
- See [GitLab merge request #126](https://gitlab.com/cznic/sqlite/-/merge_requests/126), thanks Ian Chechin!
|
||||
- Add `modernc.org/sqlite/pcache`, the reference page-cache implementation that accompanies the #126 `SQLITE_CONFIG_PCACHE2` wrapper. `pcache.New` returns a `*Pool` satisfying the `PageCache` interface; register it once with `sqlite.MustRegisterPageCache(pcache.New())` and every connection opened afterwards draws its pages from it. Each `Pool.Create` mints a fresh per-database `Cache`: a bounded, LRU-evicting page store that honours the `PRAGMA cache_size` soft cap and releases the least-recently-unpinned page when it must make room. Page memory — the `Buf` and `Extra` buffers SQLite reads through — is allocated with `libc.Xmalloc`/`libc.Xcalloc` and therefore lives off the Go heap, which keeps SQLite's interior pointer arithmetic on the page extras from tripping the race detector's checkptr enforcement. `Pool.Stats` reports aggregate lifetime counters (hits, misses, allocs, evictions, rekeys, truncates, caches) across every cache a Pool has created, so hit/miss/eviction behaviour is observable without instrumenting individual caches. Cross-connection page sharing is out of scope for now; each `Create` returns an independent per-database cache.
|
||||
- Validated end-to-end against the #126 stress workload (`cache_size=16`, 4000 BLOB rows with DELETE and `incremental_vacuum`, `integrity_check` clean under `-race`) and benchmarked for the memory-utilization goal tracked in [GitLab issue #204](https://gitlab.com/cznic/sqlite/-/issues/204).
|
||||
- See [GitLab merge request #127](https://gitlab.com/cznic/sqlite/-/merge_requests/127), thanks Ian Chechin!
|
||||
- Tighten the `modernc.org/sqlite/pcache` reference implementation per cznic's !127 review follow-ups. Adds `Stats.EasyRefusals`, a per-Pool counter for the cases where `FetchCreateEasy` returns nil at cap; SQLite reacts to a refusal by spilling dirty pages and retrying with `FetchCreateForce`, so the new field is a direct proxy for the I/O pressure the strict Easy contract imposes vs pcache1's recycle-without-spill behavior. `BenchmarkPoolEvictionChurn` was reworked to drive a rotating-residue DELETE (`k % 3 = i % 3`) and re-insert a matching batch each cycle so the spill pressure recurs and `easy-refusals/op` scales with `b.N` instead of capping at the seed's one-time first-cycle cost; both existing benchmarks now report `easy-refusals/op` alongside the page-allocs/evictions metrics. `Stats.Evictions` documentation was tightened to match the actual behavior (counts LRU eviction, `Unpin(discard=true)`, `Shrink` releases, and `Unpin(discard=false)` trimming back to target after a `FetchCreateForce` overcommit; bulk frees from `Truncate`, `Rekey` collisions, and `Destroy` are not counted). The `TestPoolRoundTripIntegrity` comment claiming the workload exercises `xRekey` ~15 times has been corrected; the SQL surface does not reliably emit xRekey here, and that codepath is covered by the unit tests instead.
|
||||
- See [GitLab merge request #130](https://gitlab.com/cznic/sqlite/-/merge_requests/130), thanks Ian Chechin!
|
||||
- Make `modernc.org/sqlite/pcache` `-race`-clean under SQLite's `cache=shared` mode. The pool already runs correctly under shared-cache because every callback into a given `Cache` is serialised internally by SQLite's `sqlite3BtreeEnter` on the `BtShared` mutex; verified empirically with a lock-free in-flight probe (max-in-flight = 1 on the canonical two-connection workload, 4 on a positive control with goroutines hitting the cache directly). However the Go race detector does not recognise SQLite's libc mutex as a happens-before edge and reports false-positive races on `Fetch` vs `Unpin` reads/writes of the per-cache state, which surfaces as `DATA RACE` failures for any user who registers the pool and runs their suite under `-race`. A `sync.Mutex` on the `cache` type is now taken on every public method (`SetSize`, `PageCount`, `Fetch`, `Unpin`, `Rekey`, `Truncate`, `Destroy`, `Shrink`), always. On the common non-shared-cache path the lock is uncontended (one atomic CAS per Lock/Unlock pair, negligible next to the SQLite work it bookends); on the shared-cache path it just rubber-stamps the order SQLite's `BtShared` mutex already established. A new `e2e_test.go` `TestSharedCacheTwoConns_Integrity` drives two `sql.Conn` against the same `cache=shared` URI with concurrent writers and asserts `PRAGMA integrity_check = ok` under `-race`; passes cleanly with the lock, would surface the false-positive without it. Design notes live in `pcache/sharing.go`.
|
||||
- See [GitLab merge request #131](https://gitlab.com/cznic/sqlite/-/merge_requests/131), thanks Ian Chechin!
|
||||
- Add a Go wrapper for `sqlite3_db_status`, the per-connection runtime counters (cache hit/miss/write/spill rates, schema and prepared-statement memory, lookaside usage, deferred foreign keys). `DBStatus` is an interface implemented by the driver connection and reached through the `database/sql` escape hatch `(*sql.Conn).Raw()`, mirroring the existing `FileControl` surface; `DBStatusOp` is a distinct typed enum of the `SQLITE_DBSTATUS_*` verbs so a counter from a different op family will not compile in its place. `Status(op, reset)` returns the `(current, high)` pair and optionally resets the counter. This also lets `modernc.org/sqlite/pcache` measure real I/O instead of the `EasyRefusals` proxy: the new `BenchmarkPoolSpillIO` reads the pager-level `SQLITE_DBSTATUS_CACHE_SPILL`/`_CACHE_WRITE` counters, which the pager maintains identically for pcache1 and the pool, making the pcache1-vs-pool comparison cznic raised on the !127 review a genuine apples-to-apples measurement. On the rotating-residue eviction-churn workload at `cache_size=16` the pool spills ~3.5x more than pcache1 (cache-spill/op 31.96 vs 8.96) for ~3% more page writes (cache-write/op 450 vs 436) at identical hit/miss, quantifying the I/O cost of the strict Easy contract that `EasyRefusals` only proxied.
|
||||
- See [GitLab merge request #132](https://gitlab.com/cznic/sqlite/-/merge_requests/132), thanks Ian Chechin!
|
||||
- Add an opt-in `_dqs` DSN query parameter that disables SQLite's double-quoted string literal compatibility quirk on a per-connection basis. When `_dqs=0` (or any `strconv.ParseBool` false value) is supplied, the driver calls `sqlite3_db_config` with `SQLITE_DBCONFIG_DQS_DDL` and `SQLITE_DBCONFIG_DQS_DML` set to off before any statement is prepared, so a double-quoted identifier that fails to resolve raises a parse error instead of silently falling back to a string literal. Absence of the parameter, or `_dqs=1`, leaves SQLite's default behavior unchanged; existing DSNs continue to work byte-for-byte. Resolves [GitLab issue #61](https://gitlab.com/cznic/sqlite/-/issues/61).
|
||||
- See [GitLab merge request #128](https://gitlab.com/cznic/sqlite/-/merge_requests/128), thanks Ian Chechin!
|
||||
- Add an opt-in `_error_rc` DSN query parameter for clearer error reporting on open-time failures. When `_error_rc=1` (or any `strconv.ParseBool` true value) is supplied, error strings synthesised from a `(rc, db)` pair only append `sqlite3_errmsg(db)` when `sqlite3_extended_errcode(db)` is consistent with the operation rc (full match first, primary code `&0xff` as fallback). On mismatch the canonical `sqlite3_errstr(rc)` is used alone, so an open-time `SQLITE_CANTOPEN` no longer carries the temporary handle's stale "out of memory" errmsg. Absence of the parameter, or `_error_rc=0`, preserves the legacy "errstr: errmsg" form byte-for-byte; existing callers that parse error strings are unaffected. The driver's `*Error.Code()` returns the same SQLite result code in both modes. Parsed before `sqlite3_open_v2` so open-time errors are covered. Resolves [GitLab issue #230](https://gitlab.com/cznic/sqlite/-/issues/230).
|
||||
- See [GitLab merge request #129](https://gitlab.com/cznic/sqlite/-/merge_requests/129), thanks Ian Chechin!
|
||||
|
||||
- 2026-06-06 v1.52.0:
|
||||
- Upgrade to [SQLite 3.53.2](https://sqlite.org/releaselog/3_53_2.html).
|
||||
- Add `Backup.Remaining` and `Backup.PageCount`, thin wrappers around the existing `sqlite3_backup_remaining` and `sqlite3_backup_pagecount` C symbols. Together they expose the per-`Step` progress counters that the underlying backup object already maintains, enabling progress reporting during online backups without dropping to `modernc.org/sqlite/lib` directly.
|
||||
- See [GitLab merge request #122](https://gitlab.com/cznic/sqlite/-/merge_requests/122), thanks Ian Chechin!
|
||||
- Drop the redundant second copy in `(*conn).columnText`, the path that backs every `Rows.Scan` into a Go `string` for a TEXT column. The value's bytes are still copied once out of SQLite-owned memory into a fresh Go buffer; that buffer is then reinterpreted as the result string with `unsafe.String` rather than copied a second time by the implicit `string([]byte)` conversion. This removes one allocation per TEXT value per row and roughly halves the bytes allocated on that path; on the new `BenchmarkColumnTextScan` cases it is ~13–20% faster for payloads of 256 B and larger, with no measurable change for very short strings. Purely internal: no API or behavioral change, and the returned string never aliases SQLite's buffer.
|
||||
- See [GitLab merge request #123](https://gitlab.com/cznic/sqlite/-/merge_requests/123), thanks Ian Chechin!
|
||||
- Cache each result column's declared type once per result set in `newRows` instead of recomputing it on every row. The TEXT branch of `Rows.Next` calls `ColumnTypeDatabaseTypeName` for every TEXT column on every row (independent of any DSN flag), which previously did a `libc.GoString` + `strings.ToUpper` each time; that lookup is now a single index into a cached, pre-uppercased `[]string`, and `ColumnTypeScanType` reads the same cache and drops its per-call `strings.ToLower`. The declared type is fixed for the lifetime of a prepared statement, so the C round-trip is paid once per column rather than once per column per row, removing exactly 1 alloc + 8 B per TEXT column per row from the `Next` hot path. The new `BenchmarkTextToTimeScan` cases show ~7% faster on a 1000-row DATETIME SELECT under `_texttotime=1`. Purely internal: `ColumnTypeDatabaseTypeName` and `ColumnTypeScanType` return identical values, no API or behavioral change.
|
||||
- See [GitLab merge request #124](https://gitlab.com/cznic/sqlite/-/merge_requests/124), thanks Ian Chechin!
|
||||
- Cache, per result column, the `parseTimeFormats` index that first parsed a TEXT-stored DATE/DATETIME/TIMESTAMP value, and try that format first on later rows instead of re-walking the list from the top. `(*conn).parseTime` previously ran `time.Parse` down the format list on every such row; for the canonical SQLite TEXT datetime format every row paid two failed `time.Parse` attempts — each allocating a `*time.ParseError` — before the match. On a 1000-row DATETIME TEXT SELECT this cuts ~50% of allocs/op and ~57% of B/op and is ~37% faster. The fall-through chain is preserved exactly: the seven formats are mutually exclusive, so the cached hint can never select a different match than the in-order scan, and the parsed `driver.Value` is identical to before. Purely internal: no API or behavioral change.
|
||||
- See [GitLab merge request #125](https://gitlab.com/cznic/sqlite/-/merge_requests/125), thanks Ian Chechin!
|
||||
|
||||
- 2026-05-28 v1.51.0:
|
||||
- Pool the `[]driver.Value` slice passed to scalar/aggregate UDF callbacks and to vtab `Filter`/`Insert`/`Update` callbacks, eliminating the dominant per-row allocation on UDF-heavy queries. Benchmarks on a 1000-row, 3-arg noop scalar UDF show ~40% fewer bytes/op and ~15% fewer allocs/op.
|
||||
- Document the matching "arguments are not valid past return" contract on `vtab.Cursor.Filter` and `vtab.Updater.Insert`/`Update`, consistent with the existing rule for `FunctionImpl.Scalar` / `AggregateFunction.Step` / `WindowInverse`.
|
||||
- Resolves [GitLab issue #226](https://gitlab.com/cznic/sqlite/-/issues/226). See [GitLab merge request #114](https://gitlab.com/cznic/sqlite/-/merge_requests/114), thanks Ian Chechin!
|
||||
- Add `FileControl.FileControlDataVersion`, a wrapper around `SQLITE_FCNTL_DATA_VERSION` for observing pager-cache data-version changes, including those made on the same connection. Useful as a primitive for application-level cache invalidation.
|
||||
- Exposed via the idiomatic `database/sql` escape hatch `(*sql.Conn).Raw()`, consistent with the existing `FileControlPersistWAL`.
|
||||
- See [GitLab merge request #115](https://gitlab.com/cznic/sqlite/-/merge_requests/115), thanks Ian Chechin!
|
||||
- Fix a regression where in-memory connections (`:memory:`, `file::memory:`, shared-cache memory URIs) were discarded by `database/sql` after a context-cancelled query, taking the entire in-memory store with them. The fix for #198 had added an `sqlite3_is_interrupted` check to the connection validator that mistakenly applied to in-memory connections too, re-introducing the bug originally fixed by !74. File-backed connections keep the existing behaviour and are still discarded after an interrupt.
|
||||
- Resolves [GitLab issue #196](https://gitlab.com/cznic/sqlite/-/issues/196). See [GitLab merge request #116](https://gitlab.com/cznic/sqlite/-/merge_requests/116), thanks Ian Chechin!
|
||||
- Add an opt-in `FunctionImpl.VolatileArgs` flag that hands TEXT and BLOB arguments to scalar and aggregate UDF callbacks as zero-copy views (`unsafe.String`/`unsafe.Slice`) over SQLite's own value buffers, eliminating the per-argument `libc.GoString`/`make([]byte)` copy that the #226 slice-pooling left as the remaining per-row allocation. On the same 1000-row, 3-arg (INTEGER/TEXT/BLOB) noop scalar UDF this removes a further ~35% of allocs/op and ~11% of bytes/op on top of #226.
|
||||
- The views are valid only for the duration of the callback and must not be retained past return or across rows; a callback that needs to keep a value must copy it. With `VolatileArgs` unset (the default) arguments keep the existing copied, caller-owned semantics, so the flag is fully backward compatible; it has no effect on integer, float, time, or NULL arguments.
|
||||
- See [GitLab merge request #120](https://gitlab.com/cznic/sqlite/-/merge_requests/120), thanks Ian Chechin!
|
||||
- Extend the opt-in `VolatileArgs` zero-copy TEXT/BLOB argument access from #120 to the virtual-table `Cursor.Filter` (`xFilter`) and `Updater.Insert`/`Update` (`xUpdate`) callbacks. A `vtab.Module` opts in by implementing the new optional `vtab.VolatileArgsOpter` interface (`VolatileArgs() bool`); the flag is read once at module registration and shared by every table created from it. On a vtab call carrying one TEXT and one BLOB argument this removes 2 allocs/op (one `libc.GoString`, one `make([]byte)`) on each of the Filter and Update paths.
|
||||
- The same safety contract as #120 applies: the views are valid only for the duration of the callback and must not be retained past return or across rows; a callback that needs to keep a value must copy it. Modules that do not implement `VolatileArgsOpter` (the default for all existing modules) are byte-for-byte unchanged, and the flag has no effect on integer, float, time, or NULL arguments.
|
||||
- See [GitLab merge request #121](https://gitlab.com/cznic/sqlite/-/merge_requests/121), thanks Ian Chechin!
|
||||
|
||||
- 2026-05-10 v1.50.1:
|
||||
- Upgrade to [SQLite 3.53.1](https://sqlite.org/releaselog/3_53_1.html).
|
||||
|
||||
- 2026-04-24 v1.50.0:
|
||||
- Upgrade to sqlite-vec [v0.1.9](https://github.com/asg017/sqlite-vec/releases/tag/v0.1.9).
|
||||
- Introduce `ColumnInfo`, enabling dynamic query builders and ORMs to retrieve underlying SQLite C-API metadata (`OriginName`, `TableName`, `DatabaseName`, and `DeclType`).
|
||||
- This feature is exposed via the idiomatic `database/sql` escape hatch `(*sql.Conn).Raw()`, avoiding custom statement handles and keeping the standard library workflow intact.
|
||||
- See [GitLab merge request #113](https://gitlab.com/cznic/sqlite/-/merge_requests/113), thanks Josh Bleecher Snyder!
|
||||
|
||||
- 2026-04-17 v1.49.1: Documentation only: update the per-platform SQLite version table in `doc.go` to 3.53.0, the version shipped since v1.49.0. No code changes.
|
||||
|
||||
- 2026-04-17 v1.49.0: Upgrade to [SQLite 3.53.0](https://sqlite.org/releaselog/3_53_0.html).
|
||||
- Added `-DSQLITE_ENABLE_DBPAGE_VTAB` to the transpilation. See ["The SQLITE_DBPAGE Virtual Table"](https://www.sqlite.org/dbpage.html) for details.
|
||||
|
||||
- 2026-04-06 v1.48.2:
|
||||
- Fix ABI mapping mismatch in the pre-update hook trampoline that caused silent truncation of large 64-bit RowIDs.
|
||||
- Ensure the Go trampoline signature correctly aligns with the public `sqlite3_preupdate_hook` C API, preventing data corruption for high-entropy keys (e.g., Snowflake IDs).
|
||||
- See [GitLab merge request #98](https://gitlab.com/cznic/sqlite/-/merge_requests/98), thanks Josh Bleecher Snyder!
|
||||
- Fix the memory allocator used in `(*conn).Deserialize`.
|
||||
- Replace `tls.Alloc` with `sqlite3_malloc64` to prevent internal allocator corruption. This ensures the buffer is safely owned by SQLite, which may resize or free it due to the `SQLITE_DESERIALIZE_RESIZEABLE` and `SQLITE_DESERIALIZE_FREEONCLOSE` flags.
|
||||
- Prevent a memory leak by properly freeing the allocated buffer if fetching the main database name fails before handing ownership to SQLite.
|
||||
- See [GitLab merge request #100](https://gitlab.com/cznic/sqlite/-/merge_requests/100), thanks Josh Bleecher Snyder!
|
||||
- Fix `(*conn).Deserialize` to explicitly reject `nil` or empty byte slices.
|
||||
- Prevent silent database disconnection and connection pool corruption caused by SQLite's default behavior when `sqlite3_deserialize` receives a 0-length buffer.
|
||||
- See [GitLab merge request #101](https://gitlab.com/cznic/sqlite/-/merge_requests/101), thanks Josh Bleecher Snyder!
|
||||
- Fix `commitHookTrampoline` and `rollbackHookTrampoline` signatures by removing the unused `pCsr` parameter.
|
||||
- Aligns internal hook callbacks accurately with the underlying SQLite C API, cleaning up the code to prevent potential future confusion or bugs.
|
||||
- See [GitLab merge request #102](https://gitlab.com/cznic/sqlite/-/merge_requests/102), thanks Josh Bleecher Snyder!
|
||||
- Fix `checkptr` instrumentation failures during `go test -race` when registering and using virtual tables (`vtab`).
|
||||
- Allocate `sqlite3_module` instances using the C allocator (`libc.Xcalloc`) instead of the Go heap. This ensures transpiled C code can safely perform pointer operations on the struct without tripping Go's pointer checks.
|
||||
- See [GitLab merge request #103](https://gitlab.com/cznic/sqlite/-/merge_requests/103), thanks Josh Bleecher Snyder!
|
||||
- Fix data race on `mutex.id` in the `mutexTry` non-recursive path.
|
||||
- Ensure consistent atomic writes (`atomic.StoreInt32`) to prevent data races with atomic loads in `mutexHeld` and `mutexNotheld` during concurrent execution.
|
||||
- See [GitLab merge request #104](https://gitlab.com/cznic/sqlite/-/merge_requests/104), thanks Josh Bleecher Snyder!
|
||||
- Fix resource leak in `(*Backup).Commit` where the destination connection was not closed on error.
|
||||
- Ensure `dstConn` is properly closed when `sqlite3_backup_finish` fails, preventing file descriptor, TLS, and memory leaks.
|
||||
- See [GitLab merge request #105](https://gitlab.com/cznic/sqlite/-/merge_requests/105), thanks Josh Bleecher Snyder!
|
||||
- Fix `Exec` to fully drain rows when encountering `SQLITE_ROW`, preventing silent data loss in DML statements.
|
||||
- Previously, `Exec` aborted after the first row, meaning `INSERT`, `UPDATE`, or `DELETE` statements with a `RETURNING` clause would fail to process subsequent rows. The execution path now correctly loops until `SQLITE_DONE` and properly respects context cancellations during the drain loop, fully aligning with native C `sqlite3_exec` semantics.
|
||||
- See [GitLab merge request #106](https://gitlab.com/cznic/sqlite/-/merge_requests/106), thanks Josh Bleecher Snyder!
|
||||
- Fix "Shadowed err value (stmt.go)".
|
||||
- See [GitLab issue #249](https://gitlab.com/cznic/sqlite/-/work_items/249), thanks Emrecan BATI!
|
||||
- Fix silent omission of virtual table savepoint callbacks by correctly setting the sqlite3_module version.
|
||||
- See [GitLab merge request #107](https://gitlab.com/cznic/sqlite/-/merge_requests/107), thanks Josh Bleecher Snyder!
|
||||
- Fix `vfsRead` to properly handle partial and fragmented reads from `io.Reader`.
|
||||
- Replace `f.Read` with `io.ReadFull` to ensure the buffer is fully populated, preventing premature `SQLITE_IOERR_SHORT_READ` errors on valid mid-stream partial reads. Unread tail bytes at EOF are now efficiently zero-filled using the built-in `clear` function.
|
||||
- See [GitLab merge request #108](https://gitlab.com/cznic/sqlite/-/merge_requests/108), thanks Josh Bleecher Snyder!
|
||||
- Refactor internal error formatting to safely handle uninitialized or closed database pointers.
|
||||
- Prevent a misleading "out of memory" error message when an operation fails and the underlying SQLite database handle is `NULL` (`db == 0`).
|
||||
- See [GitLab merge request #109](https://gitlab.com/cznic/sqlite/-/merge_requests/109), thanks Josh Bleecher Snyder!
|
||||
- Fix error handling in database backup and restore initialization (`sqlite3_backup_init`).
|
||||
- Ensure error codes and messages are accurately read from the destination database handle rather than hardcoding the source or remote handle. This prevents swallowed errors or mismatched "not an error" messages when a backup or restore operation fails to start.
|
||||
- See [GitLab merge request #111](https://gitlab.com/cznic/sqlite/-/merge_requests/111), thanks Josh Bleecher Snyder!
|
||||
- Fix database handle and C-heap memory leaks when `sqlite3_open_v2` fails.
|
||||
- Ensure `sqlite3_close_v2` is called on the partially allocated database handle during a failed open, and explicitly close `libc.TLS` in `newConn` to prevent resource leakage.
|
||||
- Prevent misleading "out of memory" error messages on failed connections by correctly extracting the exact error string from the allocated handle before it is closed.
|
||||
- See [GitLab merge request #112](https://gitlab.com/cznic/sqlite/-/merge_requests/112), thanks Josh Bleecher Snyder!
|
||||
|
||||
- 2026-04-03 v1.48.1:
|
||||
- Fix memory leaks and double-free vulnerabilities in the multi-statement query execution path.
|
||||
- Ensure bind-parameter allocations are reliably freed via strict ownership transfer if an error occurs mid-loop or if multiple statements bind parameters.
|
||||
- Fix a resource leak where a subsequent statement's error could orphan a previously generated `rows` object without closing it, leaking the prepared statement handle.
|
||||
- See [GitLab merge request #96](https://gitlab.com/cznic/sqlite/-/merge_requests/96), thanks Josh Bleecher Snyder!
|
||||
|
||||
- 2026-03-27 v1.48.0:
|
||||
- Add `_timezone` DSN query parameter to apply IANA timezones (e.g., "America/New_York") to both reads and writes.
|
||||
- Writes will convert `time.Time` values to the target timezone before formatting as a string.
|
||||
- Reads will interpret timezone-less strings as being in the target timezone.
|
||||
- Does not impact `_inttotime` integer values, which will always safely evaluate as UTC.
|
||||
- Add support for `_time_format=datetime` URI parameter to format `time.Time` values identically to SQLite's native `datetime()` function and `CURRENT_TIMESTAMP` (`YYYY-MM-DD HH:MM:SS`).
|
||||
- See [GitLab merge request #94](https://gitlab.com/cznic/sqlite/-/merge_requests/94) and [GitLab merge request #95](https://gitlab.com/cznic/sqlite/-/merge_requests/95), thanks Josh Bleecher Snyder!
|
||||
|
||||
- 2026-03-17 v1.47.0: Add CGO-free version of the vector extensions from https://github.com/asg017/sqlite-vec. See `vec_test.go` for example usage. From the GitHub project page:
|
||||
- **Important:** sqlite-vec is a pre-v1, so expect breaking changes!
|
||||
- Store and query float, int8, and binary vectors in vec0 virtual tables
|
||||
- Written in pure C, no dependencies, runs anywhere SQLite runs (Linux/MacOS/Windows, in the browser with WASM, Raspberry Pis, etc.)
|
||||
- Store non-vector data in metadata, auxiliary, or partition key columns
|
||||
- See [GitLab merge request #93](https://gitlab.com/cznic/sqlite/-/merge_requests/93), thanks Zhenghao Zhang!
|
||||
|
||||
- 2026-03-16 v1.46.2: Upgrade to [SQLite 3.51.3](https://sqlite.org/releaselog/3_51_3.html).
|
||||
|
||||
- 2026-02-17 v1.46.1:
|
||||
- Ensure connection state is reset if Tx.Commit fails. Previously, errors like SQLITE_BUSY during COMMIT could leave the underlying connection inside a transaction, causing errors when the connection was reused by the database/sql pool. The driver now detects this state and forces a rollback internally.
|
||||
- Fixes [GitHub issue #2](https://github.com/modernc-org/sqlite/issues/2), thanks Edoardo Spadolini!
|
||||
|
||||
- 2026-02-17 v1.46.0:
|
||||
- Enable ColumnTypeScanType to report time.Time instead of string for TEXT columns declared as DATE, DATETIME, TIME, or TIMESTAMP via a new `_texttotime` URI parameter.
|
||||
- See [GitHub pull request #1](https://github.com/modernc-org/sqlite/pull/1), thanks devhaozi!
|
||||
|
||||
- 2026-02-09 v1.45.0:
|
||||
- Introduce vtab subpackage (modernc.org/sqlite/vtab) exposing Module, Table, Cursor, and IndexInfo API for Go virtual tables.
|
||||
- Wire vtab registration into the driver: vtab.RegisterModule installs modules globally and each new connection calls sqlite3_create_module_v2.
|
||||
- Implement vtab trampolines for xCreate/xConnect/xBestIndex/xDisconnect/xDestroy/xOpen/xClose/xFilter/xNext/xEof/xColumn/xRowid.
|
||||
- Map SQLite’s sqlite3_index_info into vtab.IndexInfo, including constraints, ORDER BY terms, and constraint usage (ArgIndex → xFilter argv[]).
|
||||
- Add an in‑repo dummy vtab module and test (module_test.go) that validates registration, basic scanning, and constraint visibility.
|
||||
- See [GitLab merge request #90](https://gitlab.com/cznic/sqlite/-/merge_requests/90), thanks Adrian Witas!
|
||||
|
||||
- 2026-01-19 v1.44.3: Resolves [GitLab issue #243](https://gitlab.com/cznic/sqlite/-/issues/243).
|
||||
|
||||
- 2026-01-18 v1.44.2: Upgrade to [SQLite 3.51.2](https://sqlite.org/releaselog/3_51_2.html).
|
||||
|
||||
- 2026-01-15 v1.44.1: Bump the pinned `modernc.org/libc` to v1.67.6. Its memory-safe `strlen` fixes the AddressSanitizer global-buffer-overflow in the transpiled window-function name arrays reported in [GitLab merge request #88](https://gitlab.com/cznic/sqlite/-/merge_requests/88), which was closed in favour of that upstream fix, thanks Matt Topol!
|
||||
|
||||
- 2026-01-13 v1.44.0: Upgrade to SQLite 3.51.1.
|
||||
|
||||
- 2026-01-08 v1.43.0:
|
||||
- Add `IsReadOnly(schema string) (bool, error)` on the driver connection, a wrapper around `sqlite3_db_readonly`, reachable through `(*sql.Conn).Raw()`. Resolves [GitLab issue #242](https://gitlab.com/cznic/sqlite/-/issues/242).
|
||||
- Honour `_time_integer_format=unix_micro` and `unix_nano` when reading integer time values back with `_inttotime=true`; previously only the seconds/milliseconds heuristic applied. Resolves [GitLab issue #240](https://gitlab.com/cznic/sqlite/-/issues/240).
|
||||
- Make the mutex implementation in `lib/mutex.go` more robust.
|
||||
- Re-vendor the transpiled library from `modernc.org/libsqlite3` v1.11.0; the SQLite version stays 3.50.4.
|
||||
- Add openbsd/amd64 and openbsd/arm64 to the targets exercised by the builders (see [GitLab issue #237](https://gitlab.com/cznic/sqlite/-/issues/237)).
|
||||
|
||||
- 2025-12-28 v1.42.2: Fix a TOCTOU race in query interruption: a cancelled context could interrupt an unrelated, later query on the same connection. Resolves [GitLab issue #241](https://gitlab.com/cznic/sqlite/-/issues/241). See [GitLab merge request #86](https://gitlab.com/cznic/sqlite/-/merge_requests/86), thanks Josh Bleecher Snyder!
|
||||
|
||||
- 2025-12-27 v1.42.1: Revert to the v1.41.0 state (SQLite 3.50.4) and retract v1.42.0 in `go.mod`.
|
||||
|
||||
- 2025-12-27 v1.42.0: Upgrade to SQLite 3.51.1. **Retracted** the same day as accidentally broken, see the `retract` directive in `go.mod`; v1.42.1 reverts it and v1.44.0 carries the working 3.51.1 upgrade.
|
||||
|
||||
- 2025-12-08 v1.41.0:
|
||||
- Add the `modernc.org/sqlite/vtab` subpackage, a Go virtual-table API (`Module`, `Table`, `Cursor`, `IndexInfo`, `vtab.RegisterModule`) bridged to the engine and validated by an in-tree dummy module. See [GitLab merge request #84](https://gitlab.com/cznic/sqlite/-/merge_requests/84), thanks Adrian Witas!
|
||||
- Optimize prepared statements: reuse the prepared SQLite statement handle across executions instead of preparing it again. Updates [GitLab issue #236](https://gitlab.com/cznic/sqlite/-/issues/236).
|
||||
- Fix the build on 32-bit targets.
|
||||
|
||||
- 2025-11-12 v1.40.1: Close the `Rows` of a query whose context was cancelled after the statement had already produced them; such `Rows` were previously leaked, which kept a read transaction open, starved WAL checkpoints and let the WAL grow without bound. See [GitLab merge request #81](https://gitlab.com/cznic/sqlite/-/merge_requests/81), thanks Silvio Moioli!
|
||||
|
||||
- 2025-10-17 v1.40.0: Add pre-update, commit and rollback hooks: `RegisterPreUpdateHook`, `RegisterCommitHook` and `RegisterRollbackHook` on the driver connection, plus the `SQLitePreUpdateData` type (`Depth`, `Count`, `Old`, `New`), reachable through `(*sql.Conn).Raw()`. Updates [GitLab issue #125](https://gitlab.com/cznic/sqlite/-/issues/125). See [GitLab merge request #80](https://gitlab.com/cznic/sqlite/-/merge_requests/80), thanks Walter Wanderley!
|
||||
|
||||
- 2025-10-10 v1.39.1: Upgrade to SQLite 3.50.4.
|
||||
|
||||
- 2025-08-11 v1.39.0:
|
||||
- Add the `_time_integer_format` DSN parameter (`unix`, `unix_milli`, `unix_micro`, `unix_nano`): `time.Time` values are bound as integers in that unit instead of as text, so timestamps fit `INTEGER` columns, `STRICT` tables included. Resolves [GitLab issue #216](https://gitlab.com/cznic/sqlite/-/issues/216). See [GitLab merge request #77](https://gitlab.com/cznic/sqlite/-/merge_requests/77), thanks Guénaël Muller!
|
||||
- Add the `_inttotime` DSN parameter: when enabled, `INTEGER` values read from columns declared `DATE`, `DATETIME` or `TIMESTAMP` are converted to `time.Time` (seconds, or milliseconds for magnitudes above 1e12), matching mattn/go-sqlite3, so scanning them into a `*time.Time` no longer fails. Resolves [GitLab issue #214](https://gitlab.com/cznic/sqlite/-/issues/214). See [GitLab merge request #76](https://gitlab.com/cznic/sqlite/-/merge_requests/76), thanks Harald Albrecht!
|
||||
- Add a VFS unit test. See [GitLab merge request #78](https://gitlab.com/cznic/sqlite/-/merge_requests/78), thanks Harald Albrecht!
|
||||
|
||||
- 2025-07-28 v1.38.2: Upgrade to SQLite 3.50.3, this time including the regenerated library that v1.38.1 lacked.
|
||||
|
||||
- 2025-07-25 v1.38.1: Update dependencies. Intended as the upgrade to SQLite 3.50.3, but the regenerated library was not included, so the shipped SQLite version is still 3.50.1. Superseded by v1.38.2.
|
||||
|
||||
- 2025-06-09 v1.38.0: Upgrade to SQLite 3.50.1.
|
||||
|
||||
- 2025-02-26 v1.36.0: Upgrade to SQLite 3.49.0.
|
||||
|
||||
- 2024-11-16 v1.34.0: Implement ResetSession and IsValid methods in connection
|
||||
|
||||
- 2024-07-22 v1.31.0: Support windows/386.
|
||||
|
||||
- 2024-06-04 v1.30.0: Upgrade to SQLite 3.46.0, release notes at
|
||||
https://sqlite.org/releaselog/3_46_0.html.
|
||||
|
||||
- 2024-02-13 v1.29.0: Upgrade to SQLite 3.45.1, release notes at
|
||||
https://sqlite.org/releaselog/3_45_1.html.
|
||||
|
||||
- 2023-12-14: v1.28.0: Add (*Driver).RegisterConnectionHook,
|
||||
ConnectionHookFn, ExecQuerierContext, RegisterConnectionHook.
|
||||
|
||||
- 2023-08-03 v1.25.0: enable SQLITE_ENABLE_DBSTAT_VTAB.
|
||||
|
||||
- 2023-07-11 v1.24.0: Add
|
||||
(*conn).{Serialize,Deserialize,NewBackup,NewRestore} methods, add Backup
|
||||
type.
|
||||
|
||||
- 2023-06-01 v1.23.0: Allow registering aggregate functions.
|
||||
|
||||
- 2023-04-22 v1.22.0: Support linux/s390x.
|
||||
|
||||
- 2023-02-23 v1.21.0: Upgrade to SQLite 3.41.0, release notes at
|
||||
https://sqlite.org/releaselog/3_41_0.html.
|
||||
|
||||
- 2022-11-28 v1.20.0: Support linux/ppc64le.
|
||||
|
||||
- 2022-09-16 v1.19.0: Support frebsd/arm64.
|
||||
|
||||
- 2022-07-26 v1.18.0: Add support for Go fs.FS based SQLite virtual
|
||||
filesystems, see function New in modernc.org/sqlite/vfs and/or TestVFS in
|
||||
all_test.go
|
||||
|
||||
- 2022-04-24 v1.17.0: Support windows/arm64.
|
||||
|
||||
- 2022-04-04 v1.16.0: Support scalar application defined functions written
|
||||
in Go. See https://www.sqlite.org/appfunc.html
|
||||
|
||||
- 2022-03-13 v1.15.0: Support linux/riscv64.
|
||||
|
||||
- 2021-11-13 v1.14.0: Support windows/amd64. This target had previously
|
||||
only experimental status because of a now resolved memory leak.
|
||||
|
||||
- 2021-09-07 v1.13.0: Support freebsd/amd64.
|
||||
|
||||
- 2021-06-23 v1.11.0: Upgrade to use sqlite 3.36.0, release notes at
|
||||
https://www.sqlite.org/releaselog/3_36_0.html.
|
||||
|
||||
- 2021-05-06 v1.10.6: Fixes a memory corruption issue
|
||||
(https://gitlab.com/cznic/sqlite/-/issues/53). Versions since v1.8.6 were
|
||||
affected and should be updated to v1.10.6.
|
||||
|
||||
- 2021-03-14 v1.10.0: Update to use sqlite 3.35.0, release notes at
|
||||
https://www.sqlite.org/releaselog/3_35_0.html.
|
||||
|
||||
- 2021-03-11 v1.9.0: Support darwin/arm64.
|
||||
|
||||
- 2021-01-08 v1.8.0: Support darwin/amd64.
|
||||
|
||||
- 2020-09-13 v1.7.0: Support linux/arm and linux/arm64.
|
||||
|
||||
- 2020-09-08 v1.6.0: Support linux/386.
|
||||
|
||||
- 2020-09-03 v1.5.0: This project is now completely CGo-free, including
|
||||
the Tcl tests.
|
||||
|
||||
- 2020-08-26 v1.4.0: First stable release for linux/amd64. The
|
||||
database/sql driver and its tests are CGo free. Tests of the translated
|
||||
sqlite3.c library still require CGo.
|
||||
|
||||
- 2020-07-26 v1.4.0-beta1: The project has reached beta status while
|
||||
supporting linux/amd64 only at the moment. The 'extraquick' Tcl testsuite
|
||||
reports
|
||||
|
||||
- 2019-12-28 v1.2.0-alpha.3: Third alpha fixes issue #19.
|
||||
|
||||
- 2019-12-26 v1.1.0-alpha.2: Second alpha release adds support for
|
||||
accessing a database concurrently by multiple goroutines and/or processes.
|
||||
v1.1.0 is now considered feature-complete. Next planed release should be a
|
||||
beta with a proper test suite.
|
||||
|
||||
- 2019-12-18 v1.1.0-alpha.1: First alpha release using the new cc/v3,
|
||||
gocc, qbe toolchain. Some primitive tests pass on linux_{amd64,386}. Not
|
||||
yet safe for concurrent access by multiple goroutines. Next alpha release
|
||||
is planed to arrive before the end of this year.
|
||||
|
||||
- 2017-06-10: Windows/Intel no more uses the VM (thanks Steffen Butzer).
|
||||
|
||||
- 2017-06-05 Linux/Intel no more uses the VM (cznic/virtual).
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## What this package is
|
||||
|
||||
`modernc.org/sqlite` is a pure-Go `database/sql/driver` for SQLite — **CGo-free**. The SQLite C amalgamation is transpiled to Go via `modernc.org/ccgo`; the generated code lives in this repo as per-`GOOS`/`GOARCH` files under `lib/` (SQLite itself), `vec/` (the `sqlite-vec` extension), and `vfs/` (the C side of the Go-fs VFS bridge). Runtime support — `malloc`, `pthread`, syscalls, etc. — is provided by `modernc.org/libc`.
|
||||
|
||||
The hand-written Go on top of that transpiled core implements the `database/sql/driver` shim and additional Go-facing APIs (virtual tables, VFS, hooks, UDFs).
|
||||
|
||||
## Repository layout (the parts that aren't self-evident)
|
||||
|
||||
- `sqlite.go`, `conn.go`, `driver.go`, `stmt.go`, `rows.go`, `tx.go`, `backup.go`, `error.go`, `result.go`, `convert.go` — hand-written `database/sql/driver` implementation calling into `lib/`.
|
||||
- `vtab.go`, `pre_update_hook.go`, `fcntl.go`, `mutex.go`, `ofd.go` — Go-facing extensions wired to SQLite hooks/trampolines (`ofd.go`: the process-wide opt-in switch to Linux OFD locks, backed by `modernc_ofd_locking()` in the transpiled library; the C side lives in `../libsqlite3/internal/sqlite_issue255.patch{,2}`).
|
||||
- `lib/` — transpiled SQLite 3.53.4. One `sqlite_<goos>_<goarch>.go` per supported triple plus build-tagged `sqlite_g_*.go` files holding declarations `modernc.org/undup` deduplicated across triples (so to check what code a target compiles, resolve its full GoFiles via `go list`, not by filename); `defs.go`, `hooks.go`, `hooks_linux_arm64.go`, `mutex.go`, plus `libsqlite3_freebsd.go`/`libsqlite3_windows.go` hold hand-written patches that augment the generated code. Import as `sqlite3 "modernc.org/sqlite/lib"`.
|
||||
- `vec/` — transpiled `sqlite-vec` v0.1.9, auto-registers via `sqlite3_auto_extension` in `patches.go` on package init. Activate by blank-importing: `_ "modernc.org/sqlite/vec"`. Covers the same 19 targets `lib/` does; `vec_test.go`'s `//go:build` constrains by GOOS only.
|
||||
- `vfs/` — exposes a Go `fs.FS` as a read-only SQLite VFS. `vfs.New(fsys)` returns a registered VFS name; open with `?vfs=<name>`. C side is transpiled per platform from `vfs/c/vfs.c` via the `vfs/Makefile`.
|
||||
- `vtab/` — Go-facing virtual-table API (no dependency on the transpiled C). `vtab.RegisterModule(db, name, module)` registers modules on **new connections only**; a nil `db` targets the driver registered as `sqlite`, a non-nil `db` the driver backing it (via `vtab.ModuleRegisterer`). The bridge to C lives in the top-level `vtab.go`. See `vtab/doc.go` for the contract (Updater/Renamer/Transactional optional interfaces, re-entrancy rules, ArgIndex/Omit semantics).
|
||||
- `vendor_libs/main.go` (build tag `none`) — regeneration tool. Reads transpiled `ccgo_<goos>_<goarch>.go` from sibling repos `../libsqlite3` and `../libsqlite_vec`, rewrites package names and imports, and writes `lib/sqlite_*.go` / `vec/vec_*.go`. Invoked by `make vendor`.
|
||||
- `examples/` — runnable samples: `example1`, `connector`, `vtab_basic`, `vtab_csv`, `vtab_match`, `vtab_regexp`.
|
||||
- `addport.go`, `issue198/`, `issue120.diff` — porting/regression scaffolding kept around for reference; not built.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
make editor # quick local check: go test -c + go build ./... + vendor_libs build
|
||||
make test # go test -v -timeout 24h (the full suite is long)
|
||||
make build_all_targets # cross-build every supported GOOS/GOARCH
|
||||
make vendor # regenerate lib/ and vec/ from sibling ../libsqlite3 + ../libsqlite_vec
|
||||
make all # editor + golint + staticcheck
|
||||
make work # set up go.work pointing at sibling cc/ccgo/libc/libtcl8.6/libsqlite3/libz repos
|
||||
make clean # removes log-*, *.test, *.out, go.work*
|
||||
```
|
||||
|
||||
Single test: `go test -v -run TestScalar` (pattern is a regexp; tests live in `all_test.go`, `module_test.go`, `func_test.go`, `pre_update_hook_test.go`, `vec_test.go`, `leak_test.go`, `fcntl_test.go`, `backup_test.go`, `null_test.go`). VFS tests: `go test ./vfs/...`.
|
||||
|
||||
Build/debug tags:
|
||||
- `-tags=sqlite.dmesg` — enables this package's `dmesg(...)` (writes to `/tmp/libc.log`); see `dmesg.go` / `nodmesg.go`.
|
||||
- `-tags=libc.dmesg` — enables debug logs from `modernc.org/libc` (must be combined with patching `libc` itself — see the worked example in `doc.go`).
|
||||
|
||||
There is no `go generate` in this repo — `generator.go` lives in `../libsqlite3`, which owns the transpilation and its SQLite compile-time options. To produce a debug-instrumented transpilation, change the options there, `make generate` in that repo, then `make vendor` here.
|
||||
|
||||
## Fragile `modernc.org/libc` coupling
|
||||
|
||||
Downstream `go.mod` files **must pin the exact `modernc.org/libc` version that this repo's `go.mod` pins** — the transpiled code in `lib/` is closely tied to that specific `libc`. This is documented in `doc.go` and tracked in [issue #177](https://gitlab.com/cznic/sqlite/-/issues/177). Bumping `libc` here without re-transpiling (or vice-versa) breaks consumers; that's why `v1.33.0`, `v1.34.3`, and `v1.42.0` are retracted in `go.mod`.
|
||||
|
||||
When debugging into `libc`, use `make work` (or a manual `go work init && go work use . <path-to-libc>`) — `doc.go` has a worked example showing how to enable `Xwrite` dmesg logging in a local `libc` checkout.
|
||||
|
||||
## Repository / release workflow
|
||||
|
||||
- The canonical repo is GitLab `cznic/sqlite`. The GitHub `modernc-org/sqlite` mirror **does accept** issues and PRs, but PRs land via a manual cross-merge into GitLab — there can be a delay. The PRs listed in `CHANGELOG.md` (e.g. "merge request #113") are GitLab MR numbers, not GitHub PRs.
|
||||
- Per `HACKING.md`: this repo is **not** auto-tagged — `builder.json` has `"autotag": "<none>"` because too many projects depend on `modernc.org/sqlite` to risk bot tagging. Releases are tagged **manually by the maintainer**; don't tag unless asked, and only once [the builder dashboard](https://modern-c.appspot.com/-/builder/?importpath=modernc.org%2fsqlite) is green for all platforms listed in `builder.json`.
|
||||
- `go.mod` `retract` directives encode known-broken versions; treat them as load-bearing — don't remove entries when bumping the module.
|
||||
|
||||
## Driver registration model
|
||||
|
||||
`init()` in `sqlite.go` calls `sql.Register("sqlite", defaultDriver())` with a single package-level `*Driver` (`var d` in `driver.go`). The package-level registration functions (`RegisterFunction`, `RegisterScalarFunction`, `RegisterDeterministicScalarFunction`, `RegisterCollationUtf8`, `RegisterConnectionHook`) attach to that driver alone; its vtab modules — `vtab.RegisterModule` with a nil `db` — are the one category held process-globally and reach every driver's connections. A caller-constructed `Driver` carries its own registrations through the mirroring `*Driver` methods (`RegisterFunction`, `RegisterScalarFunction`, `RegisterDeterministicScalarFunction`, `RegisterCollationUtf8`, `RegisterConnectionHook`, `RegisterModule`, plus `Must*` variants), and `vtab.RegisterModule` with a non-nil `db` lands on the driver backing that `db`. Same-name module on both: the package-level implementation wins on that driver's connections. All registration applies to connections opened **afterwards**; registrations made after a connection is open do not affect it — open a new one. See the `Driver` type doc in `driver.go` and `vtab/doc.go`.
|
||||
|
||||
DSN query params are parsed in `conn.go`/`driver.go`: `_pragma`, `_time_format`, `_time_integer_format`, `_inttotime`, `_texttotime`, `_timezone`, `_txlock`, plus `vfs=<name>` to select a VFS registered via `vfs.New`.
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
# This file lists people who contributed code to this repository. The AUTHORS
|
||||
# file lists the copyright holders; this file lists people.
|
||||
#
|
||||
# Names should be added to this file like so:
|
||||
# Name <email address>
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Adrian Witas <adrianwit@gmail.com>
|
||||
Alexander Menzhinsky <amenzhinsky@gmail.com>
|
||||
Alexey Palazhchenko <alexey.palazhchenko@gmail.com>
|
||||
Angus Dippenaar <angusdippenaar@gmail.com>
|
||||
Artyom Pervukhin <github@artyom.dev>
|
||||
Dan Kortschak <dan@kortschak.io>
|
||||
Dan Peterson <danp@danp.net>
|
||||
David Skinner <skinner.david@gmail.com>
|
||||
David Walton <david@davidwalton.com>
|
||||
Elle Mouton <elle.mouton@gmail.com>
|
||||
FlyingOnion <731677080@qq.com>
|
||||
Gleb Sakhnov <gleb.sakhnov@gmail.com>
|
||||
Guénaël Muller <inkey@inkey-art.net>
|
||||
HaoZi <haozi@loli.email>
|
||||
Harald Albrecht <thediveo@gmx.eu>
|
||||
Ian Chechin <ian00chechin@gmail.com>
|
||||
Jaap Aarts <jaap.aarts1@gmail.com>
|
||||
Jan Mercl <0xjnml@gmail.com>
|
||||
Josh Bleecher Snyder <josharian@gmail.com>
|
||||
Josh Klein <josh.klein@outlook.com>
|
||||
Kim <grufwub@gmail.com>
|
||||
Logan Snow <logansnow@protonmail.com>
|
||||
Mario Salgado <mariozalgo@gmail.com>
|
||||
Mark Summerfield <mark@qtrac.eu>
|
||||
Matthew Gabeler-Lee <fastcat@gmail.com>
|
||||
Michael Hoffmann <mhoffm@posteo.de>
|
||||
Michael Rykov <mrykov@gmail.com>
|
||||
Morgan Bazalgette <morgan@howl.moe>
|
||||
Nathan Herring <nherring@google.com>
|
||||
Prathyush PV <prathyush.pv@temporal.io>
|
||||
Romain Le Disez <r.gitlab@ledisez.net>
|
||||
Ross Light <ross@zombiezen.com>
|
||||
SUSE LLC <legal@suse.de>
|
||||
Saed SayedAhmed <saadmtsa@gmail.com>
|
||||
Sean McGivern <sean@mcgivern.me.uk>
|
||||
Steffen Butzer <steffen(dot)butzer@outlook.com>
|
||||
Toni Spets <toni.spets@beeper.com>
|
||||
W. Michael Petullo <mike@flyn.org>
|
||||
Walter Wanderley <walterwanderley@gmail.com>
|
||||
Yaacov Akiba Slama <ya@slamail.org>
|
||||
Zhenghao Zhang zhangzhenghao@hotmail.com
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# Governance & Contribution
|
||||
|
||||
* **Primary Maintainer:** Jan Mercl, GitLab @cznic, GitHub @j-modernc-org
|
||||
|
||||
* **Maintainer:** Ian Chechin, GitLab @Deln0r, GitHub @Deln0r
|
||||
|
||||
* **Canonical Source:** GitLab ([cznic/sqlite](https://gitlab.com/cznic/sqlite))
|
||||
|
||||
* **Community Hub:** GitHub ([modernc-org/sqlite](https://github.com/modernc-org/sqlite))
|
||||
|
||||
* **Security Policy:** We utilize GitHub Security Advisories for vulnerability reporting. Security patches are developed on GitLab and prioritized for immediate mirroring to GitHub to ensure downstream users are protected via Dependabot.
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
## Tagging and releases
|
||||
|
||||
Please do not tag commits unless all builders at
|
||||
https://modern-c.appspot.com/-/builder/?importpath=modernc.org%2fsqlite are
|
||||
happy.
|
||||
|
||||
Unlike most modernc.org repositories, this one is deliberately NOT
|
||||
auto-tagged: builder.json sets "autotag": "<none>". Many projects depend on
|
||||
modernc.org/sqlite, so letting the build bots tag it automatically is too
|
||||
risky. Releases here are tagged manually by the maintainer, once all the
|
||||
builders above are green.
|
||||
|
||||
## CHANGELOG
|
||||
|
||||
Because releases are tagged manually (see above), the top of CHANGELOG.md can
|
||||
run ahead of the actual git tags: a version section may be written and dated
|
||||
when the work lands on master while the tag itself is pushed later. Before
|
||||
assuming a version is released, check the real latest tag with
|
||||
|
||||
git ls-remote --tags origin
|
||||
|
||||
Keep all not-yet-tagged work in a SINGLE pending section at the top of
|
||||
CHANGELOG.md. Do not open a new "vX.Y.Z" header per merge request - that splits
|
||||
one pending release across several version numbers. Add each merge request's
|
||||
entry to the existing pending section, grouped with related work, and let the
|
||||
maintainer set the final version number and date when the release is actually
|
||||
tagged. The next version is the one after the latest tag reported by the
|
||||
command above, not after whatever header currently sits at the top of the file.
|
||||
|
||||
## Integrating merge requests
|
||||
|
||||
The canonical repository is GitLab cznic/sqlite; the GitHub mirror does not
|
||||
auto-sync merge requests, and the "merge request !NNN" references in
|
||||
CHANGELOG.md are GitLab MR numbers.
|
||||
|
||||
Land a contributor MR by fetching its head ref and merging it with a merge
|
||||
commit:
|
||||
|
||||
git fetch origin refs/merge-requests/<iid>/head
|
||||
git merge --no-ff FETCH_HEAD
|
||||
|
||||
GitLab publishes every MR's commits at refs/merge-requests/<iid>/head
|
||||
regardless of which fork the source branch lives on. Merging --no-ff keeps the
|
||||
contributor's original commit SHAs and author metadata, and because the MR's
|
||||
head commit becomes reachable from master, GitLab automatically flips the MR to
|
||||
"Merged" once master is pushed.
|
||||
|
||||
Do NOT land an MR by downloading its .patch and running git am: that rewrites
|
||||
the committer and the commit date, producing a new SHA that GitLab cannot match
|
||||
against the MR's source branch. The MR then has to be closed by hand and shows
|
||||
as "Closed" rather than "Merged", which reads as "rejected" to anyone scanning
|
||||
the list.
|
||||
|
||||
Match the merge-commit message GitLab itself uses:
|
||||
|
||||
Merge branch '<source-branch>' into 'master'
|
||||
|
||||
<substantive subject> (#<issue>)
|
||||
|
||||
[Closes #<issue>]
|
||||
See merge request cznic/sqlite!<NNN>
|
||||
|
||||
Include the "Closes #<issue>" line only when the MR actually closes an issue;
|
||||
omit it for follow-ups. <source-branch> is the contributor's branch name on
|
||||
their fork.
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2017 The Sqlite Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
SQLite Is Public Domain
|
||||
|
||||
All of the code and documentation in SQLite has been dedicated to the public
|
||||
domain by the authors. All code authors, and representatives of the companies
|
||||
they work for, have signed affidavits dedicating their contributions to the
|
||||
public domain and originals of those signed affidavits are stored in a firesafe
|
||||
at the main offices of Hwaci. Anyone is free to copy, modify, publish, use,
|
||||
compile, sell, or distribute the original SQLite code, either in source code
|
||||
form or as a compiled binary, for any purpose, commercial or non-commercial,
|
||||
and by any means.
|
||||
|
||||
The previous paragraph applies to the deliverable code and documentation in
|
||||
SQLite - those parts of the SQLite library that you actually bundle and ship
|
||||
with a larger application. Some scripts used as part of the build process (for
|
||||
example the "configure" scripts generated by autoconf) might fall under other
|
||||
open-source licenses. Nothing from these build scripts ever reaches the final
|
||||
deliverable SQLite library, however, and so the licenses associated with those
|
||||
scripts should not be a factor in assessing your rights to copy and use the
|
||||
SQLite library.
|
||||
|
||||
All of the deliverable code in SQLite has been written from scratch. No code
|
||||
has been taken from other projects or from the open internet. Every line of
|
||||
code can be traced back to its original author, and all of those authors have
|
||||
public domain dedications on file. So the SQLite code base is clean and is
|
||||
uncontaminated with licensed code from other projects.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Alex Garcia
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
# Copyright 2024 The Sqlite Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
.PHONY: all build_all_targets clean edit editor test vendor work
|
||||
|
||||
# Pinned deduplicator. undup folds byte-identical declarations shared across the
|
||||
# per-target generated files in lib/ and vec/ into build-tagged shared files,
|
||||
# keeping each tag's module download under Go's 500MB cap. Bump deliberately.
|
||||
UNDUP = modernc.org/undup@v0.0.5
|
||||
|
||||
all: editor
|
||||
golint 2>&1
|
||||
staticcheck 2>&1
|
||||
|
||||
build_all_targets:
|
||||
GOOS=darwin GOARCH=amd64 go test -c -o /dev/null
|
||||
GOOS=darwin GOARCH=amd64 go build -v ./...
|
||||
GOOS=darwin GOARCH=arm64 go test -c -o /dev/null
|
||||
GOOS=darwin GOARCH=arm64 go build -v ./...
|
||||
GOOS=freebsd GOARCH=amd64 go test -c -o /dev/null
|
||||
GOOS=freebsd GOARCH=amd64 go build -v ./...
|
||||
GOOS=freebsd GOARCH=386 go test -c -o /dev/null
|
||||
GOOS=freebsd GOARCH=386 go build -v ./...
|
||||
GOOS=freebsd GOARCH=arm go test -c -o /dev/null
|
||||
GOOS=freebsd GOARCH=arm go build -v ./...
|
||||
GOOS=freebsd GOARCH=arm64 go test -c -o /dev/null
|
||||
GOOS=freebsd GOARCH=arm64 go build -v ./...
|
||||
GOOS=linux GOARCH=386 go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=386 go build -v ./...
|
||||
GOOS=linux GOARCH=amd64 go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=amd64 go build -v ./...
|
||||
GOOS=linux GOARCH=arm go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=arm go build -v ./...
|
||||
GOOS=linux GOARCH=arm64 go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=arm64 go build -v ./...
|
||||
GOOS=linux GOARCH=loong64 go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=loong64 go build -v ./...
|
||||
GOOS=linux GOARCH=ppc64le go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=ppc64le go build -v ./...
|
||||
GOOS=linux GOARCH=riscv64 go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=riscv64 go build -v ./...
|
||||
GOOS=linux GOARCH=s390x go test -c -o /dev/null
|
||||
GOOS=linux GOARCH=s390x go build -v ./...
|
||||
GOOS=netbsd GOARCH=amd64 go test -c -o /dev/null
|
||||
GOOS=netbsd GOARCH=amd64 go build -v ./...
|
||||
GOOS=openbsd GOARCH=amd64 go test -c -o /dev/null
|
||||
GOOS=openbsd GOARCH=amd64 go build -v ./...
|
||||
GOOS=openbsd GOARCH=arm64 go test -c -o /dev/null
|
||||
GOOS=openbsd GOARCH=arm64 go build -v ./...
|
||||
GOOS=windows GOARCH=386 go test -c -o /dev/null
|
||||
GOOS=windows GOARCH=386 go build -v ./...
|
||||
GOOS=windows GOARCH=amd64 go test -c -o /dev/null
|
||||
GOOS=windows GOARCH=amd64 go build -v ./...
|
||||
GOOS=windows GOARCH=arm64 go test -c -o /dev/null
|
||||
GOOS=windows GOARCH=arm64 go build -v ./...
|
||||
echo done
|
||||
|
||||
clean:
|
||||
rm -f log-* cpu.test mem.test *.out go.work*
|
||||
go clean
|
||||
|
||||
edit:
|
||||
@if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile go.mod builder.json all_test.go & fi
|
||||
|
||||
editor:
|
||||
go test -c -o /dev/null
|
||||
go build -v -o /dev/null ./...
|
||||
cd vendor_libs && go build -o /dev/null main.go
|
||||
|
||||
test:
|
||||
go test -v -timeout 24h
|
||||
|
||||
vendor:
|
||||
# Reconstruct full per-target files (a no-op the first time), so the freshly
|
||||
# vendored transpiles overwrite a clean tree with no stale shared files.
|
||||
go run $(UNDUP) -expand -dir lib
|
||||
go run $(UNDUP) -expand -dir vec
|
||||
cd vendor_libs && go build -o ../vendor main.go
|
||||
# ../libsqlite3 and ../libsqlite_vec are read one full per-target file at a
|
||||
# time. They ship expanded today, but either may adopt the deduplicated
|
||||
# layout (modernc.org/builder's NW autogen); the tool detects that and
|
||||
# expands a temporary copy, leaving those checkouts untouched. Hence the pin:
|
||||
# one version of record for this repo, wherever undup is invoked.
|
||||
./vendor -undup=$(UNDUP)
|
||||
rm -f vendor
|
||||
# Fold byte-identical declarations back into build-tagged shared files. undup
|
||||
# only touches files carrying the generated-code marker, never hand-written
|
||||
# platform files (libsqlite3_*.go, hooks_*.go, ...).
|
||||
go run $(UNDUP) -dir lib
|
||||
go run $(UNDUP) -dir vec
|
||||
gofmt -s -w lib/sqlite*.go vec/vec*.go
|
||||
make build_all_targets
|
||||
|
||||
work:
|
||||
rm -f go.work*
|
||||
go work init
|
||||
go work use .
|
||||
go work use ../cc/v4
|
||||
go work use ../ccgo/v3
|
||||
go work use ../ccgo/v4
|
||||
go work use ../libc
|
||||
go work use ../libtcl8.6
|
||||
go work use ../libsqlite3
|
||||
go work use ../libz
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
### Pure-Go SQLite, no cgo
|
||||
|
||||
The repository you are currently viewing might be a mirror. Please review the guidelines below based on where you are viewing this:
|
||||
|
||||
| Platform | Role | Contributing Guidelines |
|
||||
| :--- | :--- | :--- |
|
||||
| **GitLab** | **Primary Source** | This is the canonical repository (`cznic/sqlite`). CI pipelines and main development happen here. |
|
||||
| **GitHub** | **Mirror** | This is a mirror (`modernc-org/sqlite`). We **do accept** Issues and Pull Requests here for your convenience! <br> *Note: PRs submitted here will be manually merged into the GitLab source, so please allow extra time for processing.* |
|
||||
|
||||
[](https://pkg.go.dev/modernc.org/sqlite)
|
||||
[](https://liberapay.com/jnml/donate)
|
||||
[](https://liberapay.com/jnml/donate)
|
||||
[](https://liberapay.com/jnml/donate)
|
||||
|
||||
---
|
||||
|
||||

|
||||
[Github Sponsors Account](https://github.com/sponsors/j-modernc-org) / j-modernc-org
|
||||
|
||||
### Enterprise Infrastructure Tier Sponsor
|
||||
|
||||
 [Tailscale](https://tailscale.com/)
|
||||
|
||||
### Startup / Small Business Tier Sponsor
|
||||
|
||||
 [exe.dev](https://exe.dev)
|
||||
|
||||
 [October Swimmer](https://www.octoberswimmer.com/)
|
||||
|
||||
---
|
||||
|
||||
 [The SQLite Drivers Benchmarks Game]
|
||||
|
||||
[The SQLite Drivers Benchmarks Game]: https://pkg.go.dev/modernc.org/sqlite-bench#readme-tl-dr-scorecard
|
||||
|
||||
---
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
Release notes are kept in [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
Virtual Tables (vtab)
|
||||
---------------------
|
||||
|
||||
The driver exposes a Go API to implement SQLite virtual table modules in pure Go via the `modernc.org/sqlite/vtab` package. This lets you back SQL tables with arbitrary data sources (e.g., vector indexes, CSV files, remote APIs) and integrate with SQLite’s planner.
|
||||
|
||||
- Register: `vtab.RegisterModule(db, name, module)`. A nil `db` registers on the driver this package registers as `sqlite`, whose modules reach every connection in the process; a non-nil `db` registers on the driver backing it, so a `db` opened on a caller-constructed `sqlite.Driver` keeps its modules to that driver's connections. Registration applies to new connections only.
|
||||
- Schema declaration: Call `ctx.Declare("CREATE TABLE <name>(<cols...>)")` within `Create` or `Connect`. The driver does not auto-declare schemas, enabling dynamic schemas.
|
||||
- Module arguments: `args []string` passed to `Create/Connect` are configuration parsed from `USING module(...)`. They are not treated as columns unless your module chooses to.
|
||||
- Planning (BestIndex):
|
||||
- Inspect `info.Constraints` (with `Column`, `Op`, `Usable`, 0-based `ArgIndex`, and `Omit`), `info.OrderBy`, and `info.ColUsed` (bitmask of referenced columns).
|
||||
- Set `ArgIndex` (0-based) to populate `Filter`’s `vals` in the chosen order; set `Omit` to ask SQLite not to re-check a constraint you fully handle.
|
||||
- Execution: `Cursor.Filter(idxNum, idxStr, vals)` receives arguments in the order implied by `ArgIndex`.
|
||||
- Operators: Common SQLite operators map to `ConstraintOp` (EQ/NE/GT/GE/LT/LE/MATCH/IS/ISNOT/ISNULL/ISNOTNULL/LIKE/GLOB/REGEXP/FUNCTION/LIMIT/OFFSET). Unknown operators map to `OpUnknown`.
|
||||
- Errors: Returning an error from vtab methods surfaces a descriptive message to SQLite (e.g., `zErrMsg` for xCreate/xConnect/xBestIndex/xFilter; `sqlite3_result_error` for xColumn).
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
- Vector search (sqlite-vec style):
|
||||
- `CREATE VIRTUAL TABLE vec_docs USING vec(dim=128, metric="cosine")`
|
||||
- Module reads args (e.g., `dim`, `metric`), calls `ctx.Declare("CREATE TABLE vec_docs(id, embedding, content HIDDEN)")`, and implements search via `BestIndex`/`Filter`.
|
||||
|
||||
- CSV loader:
|
||||
- `CREATE VIRTUAL TABLE csv_users USING csv(filename="/tmp/users.csv", delimiter=",", header=true)`
|
||||
- Module reads the file header to compute columns, declares them via `ctx.Declare("CREATE TABLE csv_users(name, email, ...)")`, and streams rows via a cursor.
|
||||
|
||||
See `vtab` package docs for full API details.
|
||||
|
||||
Generated sources (deduplication)
|
||||
---------------------------------
|
||||
|
||||
The transpiled SQLite C amalgamation in `lib/` and the `sqlite-vec` extension in
|
||||
`vec/` ship one generated Go file per `GOOS`/`GOARCH`. Declarations that are
|
||||
byte-identical across targets are folded into build-tagged shared files —
|
||||
`lib/sqlite.go` plus `lib/sqlite_g_<hex>.go` (and `vec/vec.go` plus
|
||||
`vec/vec_g_<hex>.go`) — by [`modernc.org/undup`](https://gitlab.com/cznic/undup),
|
||||
wired into `make vendor`. Go's build constraints make every target compile exactly
|
||||
the same set of declarations as before, so this is purely a packaging change: it
|
||||
keeps each tag's module download well under Go's 500 MB cap and does not
|
||||
affect the public API or behavior.
|
||||
|
||||
To read or debug a single target's full, self-contained generated source, expand
|
||||
the tree back to one complete file per target:
|
||||
|
||||
```sh
|
||||
go run modernc.org/undup@v0.0.5 -expand -dir lib # writes full lib/sqlite_<goos>_<goarch>.go
|
||||
go run modernc.org/undup@v0.0.5 -expand -dir vec # writes full vec/vec_<goos>_<goarch>.go
|
||||
```
|
||||
|
||||
This removes the shared `*_g_*.go` files and rewrites each
|
||||
`*_<goos>_<goarch>.go` as a standalone file — convenient for grepping, reading, or
|
||||
stepping through one platform's code. Restore the committed, deduplicated form
|
||||
with `git checkout -- lib vec`, or re-fold in place with
|
||||
`go run modernc.org/undup@v0.0.5 -dir lib` (and `-dir vec`). Hand-written platform
|
||||
files (`libsqlite3_*.go`, `hooks_*.go`, …) carry no generated-code marker and are
|
||||
never touched by either step.
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
// Copyright 2025 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
|
||||
sqlite3 "modernc.org/sqlite/lib"
|
||||
)
|
||||
|
||||
// Backup object is used to manage progress and cleanup an online backup. It
|
||||
// is returned by NewBackup or NewRestore.
|
||||
type Backup struct {
|
||||
srcConn *conn // source database connection
|
||||
dstConn *conn // destination database connection
|
||||
pBackup uintptr // sqlite3_backup object pointer
|
||||
}
|
||||
|
||||
// Step will copy up to n pages between the source and destination databases
|
||||
// specified by the backup object. If n is negative, all remaining source
|
||||
// pages are copied.
|
||||
// If it successfully copies n pages and there are still more pages to be
|
||||
// copied, then the function returns true with no error. If it successfully
|
||||
// finishes copying all pages from source to destination, then it returns
|
||||
// false with no error. If an error occurs while running, then an error is
|
||||
// returned.
|
||||
func (b *Backup) Step(n int32) (bool, error) {
|
||||
rc := sqlite3.Xsqlite3_backup_step(b.srcConn.tls, b.pBackup, n)
|
||||
if rc == sqlite3.SQLITE_OK {
|
||||
return true, nil
|
||||
} else if rc == sqlite3.SQLITE_DONE {
|
||||
return false, nil
|
||||
} else {
|
||||
return false, b.srcConn.errstr(rc)
|
||||
}
|
||||
}
|
||||
|
||||
// Finish releases all resources associated with the Backup object. The Backup
|
||||
// object is invalid and may not be used following a call to Finish.
|
||||
func (b *Backup) Finish() error {
|
||||
rc := sqlite3.Xsqlite3_backup_finish(b.srcConn.tls, b.pBackup)
|
||||
b.dstConn.Close()
|
||||
if rc == sqlite3.SQLITE_OK {
|
||||
return nil
|
||||
} else {
|
||||
return b.srcConn.errstr(rc)
|
||||
}
|
||||
}
|
||||
|
||||
// Remaining returns the number of source-database pages still to be backed
|
||||
// up at the conclusion of the most recent [Backup.Step] call. The value is
|
||||
// useful for driving progress UIs that need to estimate how much work is
|
||||
// left.
|
||||
//
|
||||
// If Step has not yet been called on this Backup, or if the most recent
|
||||
// Step returned false (SQLITE_DONE), Remaining returns 0.
|
||||
//
|
||||
// See https://www.sqlite.org/c3ref/backup_finish.html.
|
||||
func (b *Backup) Remaining() int {
|
||||
return int(sqlite3.Xsqlite3_backup_remaining(b.srcConn.tls, b.pBackup))
|
||||
}
|
||||
|
||||
// PageCount returns the total number of pages in the source database at the
|
||||
// conclusion of the most recent [Backup.Step] call. Pair with [Backup.Remaining]
|
||||
// to compute progress as a fraction (PageCount - Remaining) / PageCount.
|
||||
//
|
||||
// See https://www.sqlite.org/c3ref/backup_finish.html.
|
||||
func (b *Backup) PageCount() int {
|
||||
return int(sqlite3.Xsqlite3_backup_pagecount(b.srcConn.tls, b.pBackup))
|
||||
}
|
||||
|
||||
// Commit releases all resources associated with the Backup object but does not
|
||||
// close the destination database connection.
|
||||
//
|
||||
// The destination database connection is returned to the caller or an error if raised.
|
||||
// It is the responsibility of the caller to handle the connection closure.
|
||||
func (b *Backup) Commit() (driver.Conn, error) {
|
||||
rc := sqlite3.Xsqlite3_backup_finish(b.srcConn.tls, b.pBackup)
|
||||
|
||||
if rc == sqlite3.SQLITE_OK {
|
||||
return b.dstConn, nil
|
||||
} else {
|
||||
b.dstConn.Close()
|
||||
return nil, b.srcConn.errstr(rc)
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"autogen": "<none>",
|
||||
"autotag": "<none>",
|
||||
"autoupdate": "<none>",
|
||||
"test": "darwin/(amd64|arm64)|freebsd/(amd64|arm64|386|arm$)|linux/(386|amd64|arm|arm64|loong64|ppc64le|riscv64|s390x)|netbsd/amd64|openbsd/(amd64|arm64)|windows/(amd64|arm64|386)"
|
||||
}
|
||||
+1377
File diff suppressed because it is too large
Load Diff
+113
@@ -0,0 +1,113 @@
|
||||
// Copyright 2026 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NewConnector returns a driver.Connector that opens connections to dsn using
|
||||
// the driver this package registers as "sqlite" -- the one carrying every
|
||||
// function, collation, connection hook and virtual table module registered
|
||||
// through RegisterFunction, RegisterScalarFunction,
|
||||
// RegisterDeterministicScalarFunction, RegisterCollationUtf8,
|
||||
// RegisterConnectionHook and vtab.RegisterModule. The dsn syntax and the
|
||||
// supported query parameters are documented on Driver.Open.
|
||||
//
|
||||
// The returned value is intended for sql.OpenDB:
|
||||
//
|
||||
// c, err := sqlite.NewConnector("file:app.db?_pragma=foreign_keys(1)")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// db := sql.OpenDB(c)
|
||||
// defer db.Close()
|
||||
//
|
||||
// For opening a database this is equivalent to sql.Open("sqlite", dsn). It
|
||||
// exists for callers that need to interpose on the physical connections
|
||||
// database/sql opens -- tracing, metrics, or connection-scoped setup. Such a
|
||||
// caller can embed the returned Connector, override Connect, and pass its own
|
||||
// wrapper to sql.OpenDB:
|
||||
//
|
||||
// type tracer struct{ driver.Connector }
|
||||
//
|
||||
// func (t tracer) Connect(ctx context.Context) (driver.Conn, error) {
|
||||
// conn, err := t.Connector.Connect(ctx)
|
||||
// // ... wrap conn ...
|
||||
// return conn, err
|
||||
// }
|
||||
//
|
||||
// base, err := sqlite.NewConnector(dsn)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// db := sql.OpenDB(tracer{base})
|
||||
//
|
||||
// Reaching the same driver through sql.Open requires sql.Register, which is
|
||||
// process-global, rejects a name it has already seen with a panic, and offers
|
||||
// no way to undo a registration; a library doing the above would have to
|
||||
// invent a unique name per configuration. sql.OpenDB registers nothing.
|
||||
//
|
||||
// The dsn is checked here only as far as it can be without opening a database:
|
||||
// a query string that does not parse, such as one carrying an invalid
|
||||
// percent-escape, and conflicting vfs parameters are reported immediately.
|
||||
// Everything else is validated when the connection is opened, so an unknown
|
||||
// parameter or an out-of-range value is reported by Connect, and hence by the
|
||||
// first use of the sql.DB, rather than by NewConnector.
|
||||
//
|
||||
// The returned Connector is safe for concurrent use; database/sql calls
|
||||
// Connect from multiple goroutines as it grows the pool. As with sql.Open, it
|
||||
// does not itself open a connection.
|
||||
func NewConnector(dsn string) (driver.Connector, error) {
|
||||
// getVFSName is the first thing newConn does with the query string: it
|
||||
// parses it, which rejects a malformed query, and it rejects conflicting
|
||||
// vfs parameters. Calling that same function rather than repeating its
|
||||
// parse here keeps what NewConnector rejects aligned with what opening a
|
||||
// connection rejects, by construction.
|
||||
if _, err := getVFSName(dsnQuery(dsn)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &connector{dsn: dsn}, nil
|
||||
}
|
||||
|
||||
// connector implements driver.Connector on top of the package-level driver. It
|
||||
// holds no mutable state, so the concurrent Connect calls database/sql makes
|
||||
// need no synchronization here.
|
||||
type connector struct {
|
||||
dsn string
|
||||
}
|
||||
|
||||
// Connect implements driver.Connector.
|
||||
//
|
||||
// ctx is honored only up to the point the open begins: sqlite3_open_v2 is a
|
||||
// blocking call with no cancellation hook, so a cancellation arriving once it
|
||||
// is under way takes effect no earlier than the first statement run on the
|
||||
// returned connection.
|
||||
func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return d.Open(c.dsn)
|
||||
}
|
||||
|
||||
// Driver implements driver.Connector. It returns the driver registered as
|
||||
// "sqlite", so (*sql.DB).Driver() reports the same value for a database opened
|
||||
// through this Connector as for one opened with sql.Open("sqlite", dsn).
|
||||
func (c *connector) Driver() driver.Driver { return d }
|
||||
|
||||
// dsnQuery returns the query-parameter portion of dsn, or "" when it has none.
|
||||
// It must agree with the split newConn performs, which likewise ignores a '?'
|
||||
// in the first position; TestConnectorDSNSplitMatchesOpen guards that.
|
||||
func dsnQuery(dsn string) string {
|
||||
if pos := strings.IndexRune(dsn, '?'); pos >= 1 {
|
||||
return dsn[pos+1:]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
// Extracted from Go database/sql source code
|
||||
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Type conversions for Scan.
|
||||
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
|
||||
|
||||
// convertAssign copies to dest the value in src, converting it if possible.
|
||||
// An error is returned if the copy would result in loss of information.
|
||||
// dest should be a pointer type.
|
||||
func convertAssign(dest, src interface{}) error {
|
||||
// Common cases, without reflect.
|
||||
switch s := src.(type) {
|
||||
case string:
|
||||
switch d := dest.(type) {
|
||||
case *string:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = s
|
||||
return nil
|
||||
case *[]byte:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = []byte(s)
|
||||
return nil
|
||||
case *sql.RawBytes:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = append((*d)[:0], s...)
|
||||
return nil
|
||||
}
|
||||
case []byte:
|
||||
switch d := dest.(type) {
|
||||
case *string:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = string(s)
|
||||
return nil
|
||||
case *interface{}:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = cloneBytes(s)
|
||||
return nil
|
||||
case *[]byte:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = cloneBytes(s)
|
||||
return nil
|
||||
case *sql.RawBytes:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = s
|
||||
return nil
|
||||
}
|
||||
case time.Time:
|
||||
switch d := dest.(type) {
|
||||
case *time.Time:
|
||||
*d = s
|
||||
return nil
|
||||
case *string:
|
||||
*d = s.Format(time.RFC3339Nano)
|
||||
return nil
|
||||
case *[]byte:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = []byte(s.Format(time.RFC3339Nano))
|
||||
return nil
|
||||
case *sql.RawBytes:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
|
||||
return nil
|
||||
}
|
||||
case nil:
|
||||
switch d := dest.(type) {
|
||||
case *interface{}:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = nil
|
||||
return nil
|
||||
case *[]byte:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = nil
|
||||
return nil
|
||||
case *sql.RawBytes:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = nil
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var sv reflect.Value
|
||||
|
||||
switch d := dest.(type) {
|
||||
case *string:
|
||||
sv = reflect.ValueOf(src)
|
||||
switch sv.Kind() {
|
||||
case reflect.Bool,
|
||||
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Float32, reflect.Float64:
|
||||
*d = asString(src)
|
||||
return nil
|
||||
}
|
||||
case *[]byte:
|
||||
sv = reflect.ValueOf(src)
|
||||
if b, ok := asBytes(nil, sv); ok {
|
||||
*d = b
|
||||
return nil
|
||||
}
|
||||
case *sql.RawBytes:
|
||||
sv = reflect.ValueOf(src)
|
||||
if b, ok := asBytes([]byte(*d)[:0], sv); ok {
|
||||
*d = sql.RawBytes(b)
|
||||
return nil
|
||||
}
|
||||
case *bool:
|
||||
bv, err := driver.Bool.ConvertValue(src)
|
||||
if err == nil {
|
||||
*d = bv.(bool)
|
||||
}
|
||||
return err
|
||||
case *interface{}:
|
||||
*d = src
|
||||
return nil
|
||||
}
|
||||
|
||||
if scanner, ok := dest.(sql.Scanner); ok {
|
||||
return scanner.Scan(src)
|
||||
}
|
||||
|
||||
dpv := reflect.ValueOf(dest)
|
||||
if dpv.Kind() != reflect.Ptr {
|
||||
return errors.New("destination not a pointer")
|
||||
}
|
||||
if dpv.IsNil() {
|
||||
return errNilPtr
|
||||
}
|
||||
|
||||
if !sv.IsValid() {
|
||||
sv = reflect.ValueOf(src)
|
||||
}
|
||||
|
||||
dv := reflect.Indirect(dpv)
|
||||
if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
|
||||
switch b := src.(type) {
|
||||
case []byte:
|
||||
dv.Set(reflect.ValueOf(cloneBytes(b)))
|
||||
default:
|
||||
dv.Set(sv)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
|
||||
dv.Set(sv.Convert(dv.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
// The following conversions use a string value as an intermediate representation
|
||||
// to convert between various numeric types.
|
||||
//
|
||||
// This also allows scanning into user defined types such as "type Int int64".
|
||||
// For symmetry, also check for string destination types.
|
||||
switch dv.Kind() {
|
||||
case reflect.Ptr:
|
||||
if src == nil {
|
||||
dv.Set(reflect.Zero(dv.Type()))
|
||||
return nil
|
||||
}
|
||||
dv.Set(reflect.New(dv.Type().Elem()))
|
||||
return convertAssign(dv.Interface(), src)
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
s := asString(src)
|
||||
i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
|
||||
if err != nil {
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
|
||||
}
|
||||
dv.SetInt(i64)
|
||||
return nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
s := asString(src)
|
||||
u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
|
||||
if err != nil {
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
|
||||
}
|
||||
dv.SetUint(u64)
|
||||
return nil
|
||||
case reflect.Float32, reflect.Float64:
|
||||
s := asString(src)
|
||||
f64, err := strconv.ParseFloat(s, dv.Type().Bits())
|
||||
if err != nil {
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
|
||||
}
|
||||
dv.SetFloat(f64)
|
||||
return nil
|
||||
case reflect.String:
|
||||
switch v := src.(type) {
|
||||
case string:
|
||||
dv.SetString(v)
|
||||
return nil
|
||||
case []byte:
|
||||
dv.SetString(string(v))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
|
||||
}
|
||||
|
||||
func strconvErr(err error) error {
|
||||
if ne, ok := err.(*strconv.NumError); ok {
|
||||
return ne.Err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func cloneBytes(b []byte) []byte {
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
c := make([]byte, len(b))
|
||||
copy(c, b)
|
||||
return c
|
||||
}
|
||||
|
||||
func asString(src interface{}) string {
|
||||
switch v := src.(type) {
|
||||
case string:
|
||||
return v
|
||||
case []byte:
|
||||
return string(v)
|
||||
}
|
||||
rv := reflect.ValueOf(src)
|
||||
switch rv.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return strconv.FormatInt(rv.Int(), 10)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return strconv.FormatUint(rv.Uint(), 10)
|
||||
case reflect.Float64:
|
||||
return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
|
||||
case reflect.Float32:
|
||||
return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
|
||||
case reflect.Bool:
|
||||
return strconv.FormatBool(rv.Bool())
|
||||
}
|
||||
return fmt.Sprintf("%v", src)
|
||||
}
|
||||
|
||||
func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
|
||||
switch rv.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return strconv.AppendInt(buf, rv.Int(), 10), true
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return strconv.AppendUint(buf, rv.Uint(), 10), true
|
||||
case reflect.Float32:
|
||||
return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
|
||||
case reflect.Float64:
|
||||
return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
|
||||
case reflect.Bool:
|
||||
return strconv.AppendBool(buf, rv.Bool()), true
|
||||
case reflect.String:
|
||||
s := rv.String()
|
||||
return append(buf, s...), true
|
||||
}
|
||||
return
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// Copyright 2026 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
sqlite3 "modernc.org/sqlite/lib"
|
||||
)
|
||||
|
||||
// DBStatusOp identifies a per-connection runtime counter readable through
|
||||
// [DBStatus.Status]. The values mirror the SQLITE_DBSTATUS_* verbs of the C
|
||||
// API; the distinct type keeps a counter from a different family (for example
|
||||
// a file-control or db-config op) from compiling in its place.
|
||||
//
|
||||
// See https://www.sqlite.org/c3ref/c_dbstatus_options.html for the per-op
|
||||
// semantics.
|
||||
type DBStatusOp int32
|
||||
|
||||
// DBStatus* are the operations accepted by [DBStatus.Status]. They report
|
||||
// their value differently depending on the op:
|
||||
//
|
||||
// - DBStatusLookasideUsed: current is the lookaside memory in use now; high
|
||||
// is its high-water mark. The reset flag rebases the high-water mark to
|
||||
// current. This is the only op that maintains a high-water mark.
|
||||
// - Memory-usage ops (DBStatusCacheUsed, DBStatusSchemaUsed,
|
||||
// DBStatusStmtUsed, DBStatusCacheUsedShared): current is the bytes in use
|
||||
// now; high is always 0; the reset flag is ignored.
|
||||
// - Running-counter ops (DBStatusCacheHit, DBStatusCacheMiss,
|
||||
// DBStatusCacheWrite, DBStatusCacheSpill, DBStatusTempbufSpill): current
|
||||
// is the cumulative count (bytes spilled, for DBStatusTempbufSpill); high
|
||||
// is always 0. The reset flag zeroes current.
|
||||
// - Lookaside event ops (DBStatusLookasideHit, DBStatusLookasideMissSize,
|
||||
// DBStatusLookasideMissFull): the count is reported in high, not current
|
||||
// (current is always 0). The reset flag zeroes high.
|
||||
// - DBStatusDeferredFKs: current is 1 if the connection has unresolved
|
||||
// deferred foreign-key constraints, else 0; high is always 0; the reset
|
||||
// flag is ignored.
|
||||
const (
|
||||
DBStatusLookasideUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_USED)
|
||||
DBStatusCacheUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_USED)
|
||||
DBStatusSchemaUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_SCHEMA_USED)
|
||||
DBStatusStmtUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_STMT_USED)
|
||||
DBStatusLookasideHit = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_HIT)
|
||||
DBStatusLookasideMissSize = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE)
|
||||
DBStatusLookasideMissFull = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL)
|
||||
DBStatusCacheHit = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_HIT)
|
||||
DBStatusCacheMiss = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_MISS)
|
||||
DBStatusCacheWrite = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_WRITE)
|
||||
DBStatusDeferredFKs = DBStatusOp(sqlite3.SQLITE_DBSTATUS_DEFERRED_FKS)
|
||||
DBStatusCacheUsedShared = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_USED_SHARED)
|
||||
DBStatusCacheSpill = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_SPILL)
|
||||
DBStatusTempbufSpill = DBStatusOp(sqlite3.SQLITE_DBSTATUS_TEMPBUF_SPILL)
|
||||
)
|
||||
|
||||
// DBStatus exposes sqlite3_db_status, the per-connection runtime counters
|
||||
// (cache hit/miss/write/spill rates, schema and prepared-statement memory,
|
||||
// lookaside usage, deferred foreign keys). Reach it through the
|
||||
// database/sql escape hatch, the same way as [FileControl]:
|
||||
//
|
||||
// err := sqlConn.Raw(func(dc any) error {
|
||||
// cur, _, err := dc.(sqlite.DBStatus).Status(sqlite.DBStatusCacheSpill, false)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// // use cur
|
||||
// return nil
|
||||
// })
|
||||
type DBStatus interface {
|
||||
// Status returns the current and high-water values of the per-connection
|
||||
// counter identified by op. When reset is true the counter is reset after
|
||||
// the read; which value the reset affects depends on the op's family, see
|
||||
// the DBStatus* constant documentation. The returned error is non-nil only
|
||||
// when SQLite rejects op as out of range.
|
||||
Status(op DBStatusOp, reset bool) (current, high int, err error)
|
||||
}
|
||||
|
||||
var _ DBStatus = (*conn)(nil)
|
||||
|
||||
func (c *conn) Status(op DBStatusOp, reset bool) (current, high int, err error) {
|
||||
// Two int32 out-params: pCurrent, pHighwater. sqlite3_db_status writes
|
||||
// C int (32-bit) through both, so a single 8-byte buffer holds the pair.
|
||||
p := c.tls.Alloc(8)
|
||||
defer c.tls.Free(8)
|
||||
|
||||
pCur, pHi := p, p+4
|
||||
resetFlag := int32(0)
|
||||
if reset {
|
||||
resetFlag = 1
|
||||
}
|
||||
if rc := sqlite3.Xsqlite3_db_status(c.tls, c.db, int32(op), pCur, pHi, resetFlag); rc != sqlite3.SQLITE_OK {
|
||||
return 0, 0, c.errstr(rc)
|
||||
}
|
||||
|
||||
return int(*(*int32)(unsafe.Pointer(pCur))), int(*(*int32)(unsafe.Pointer(pHi))), nil
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright 2023 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build sqlite.dmesg
|
||||
// +build sqlite.dmesg
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const dmesgs = true
|
||||
|
||||
var (
|
||||
pid = fmt.Sprintf("[%v %v] ", os.Getpid(), filepath.Base(os.Args[0]))
|
||||
logf *os.File
|
||||
)
|
||||
|
||||
func init() {
|
||||
t := time.Now()
|
||||
// 01/02 03:04:05PM '06 -0700
|
||||
dn := t.Format("sqlite-dmesg-2006-01-02-03-150405")
|
||||
dn = filepath.Join(os.TempDir(), fmt.Sprintf("%s.%d", dn, os.Getpid()))
|
||||
if err := os.Mkdir(dn, 0770); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fn := filepath.Join(dn, "dmesg.log")
|
||||
var err error
|
||||
if logf, err = os.OpenFile(fn, os.O_APPEND|os.O_CREATE|os.O_WRONLY|os.O_SYNC, 0644); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
dmesg("%v", time.Now())
|
||||
fmt.Fprintf(os.Stderr, "debug messages in %s\n", fn)
|
||||
}
|
||||
|
||||
func dmesg(s string, args ...interface{}) {
|
||||
if s == "" {
|
||||
s = strings.Repeat("%v ", len(args))
|
||||
}
|
||||
s = fmt.Sprintf(pid+s, args...)
|
||||
s += fmt.Sprintf(" (%v: %v:)", origin(3), origin(2))
|
||||
switch {
|
||||
case len(s) != 0 && s[len(s)-1] == '\n':
|
||||
fmt.Fprint(logf, s)
|
||||
default:
|
||||
fmt.Fprintln(logf, s)
|
||||
}
|
||||
}
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package sqlite is a sql/database driver using a CGo-free port of the C
|
||||
// SQLite3 library.
|
||||
//
|
||||
// SQLite is an in-process implementation of a self-contained, serverless,
|
||||
// zero-configuration, transactional SQL database engine.
|
||||
//
|
||||
// # Pluggable page cache
|
||||
//
|
||||
// The package exposes a Go-facing wrapper for SQLite's
|
||||
// SQLITE_CONFIG_PCACHE2 mechanism. Applications can supply their own
|
||||
// page cache implementation by registering a [PageCache] before the
|
||||
// first [sql.Open] via [RegisterPageCache]. See the docstrings
|
||||
// on [PageCache], [Cache], and [Page] for the contract; the binding
|
||||
// owns the sqlite3_pcache_page stub on behalf of the implementation
|
||||
// and re-consults Cache.Fetch on every SQLite request, so a bounded
|
||||
// and evicting purgeable cache works as the C contract intends.
|
||||
//
|
||||
// # OFD locking (Linux)
|
||||
//
|
||||
// On Linux the library can take Open File Description (OFD) locks instead of
|
||||
// POSIX record locks on database files, which stops an unrelated os.File
|
||||
// close anywhere in the process from silently stripping SQLite's transaction
|
||||
// locks. The switch is process-wide, off by default, and must happen before
|
||||
// the first connection is opened: set MODERNC_SQLITE_OFD_LOCK=1 in the
|
||||
// environment the process starts with, or call [OFDLocking] from Go. See the
|
||||
// [OFDLocking] documentation for the full contract.
|
||||
//
|
||||
// # Fragile modernc.org/libc dependency
|
||||
//
|
||||
// When you import this package you should use in your go.mod file the exact
|
||||
// same version of modernc.org/libc as seen in the go.mod file of this
|
||||
// repository.
|
||||
//
|
||||
// See the discussion at https://gitlab.com/cznic/sqlite/-/issues/177 for more details.
|
||||
//
|
||||
// # Changelog
|
||||
//
|
||||
// Release notes are kept in CHANGELOG.md in the repository root, see
|
||||
// https://gitlab.com/cznic/sqlite/-/blob/master/CHANGELOG.md.
|
||||
//
|
||||
// # Thanks
|
||||
//
|
||||
// This project is sponsored by Schleibinger Geräte Teubert u. Greim GmbH by
|
||||
// allowing one of the maintainers to work on it also in office hours.
|
||||
//
|
||||
// # Supported platforms and architectures
|
||||
//
|
||||
// These combinations of GOOS and GOARCH are currently supported
|
||||
//
|
||||
// OS Arch SQLite version
|
||||
// ------------------------------
|
||||
// darwin amd64 3.53.4
|
||||
// darwin arm64 3.53.4
|
||||
// freebsd 386 3.53.4
|
||||
// freebsd amd64 3.53.4
|
||||
// freebsd arm 3.53.4
|
||||
// freebsd arm64 3.53.4
|
||||
// linux 386 3.53.4
|
||||
// linux amd64 3.53.4
|
||||
// linux arm 3.53.4
|
||||
// linux arm64 3.53.4
|
||||
// linux loong64 3.53.4
|
||||
// linux ppc64le 3.53.4
|
||||
// linux riscv64 3.53.4
|
||||
// linux s390x 3.53.4
|
||||
// netbsd amd64 3.53.4
|
||||
// openbsd amd64 3.53.4
|
||||
// openbsd arm64 3.53.4
|
||||
// windows 386 3.53.4
|
||||
// windows amd64 3.53.4
|
||||
// windows arm64 3.53.4
|
||||
//
|
||||
// # Benchmarks
|
||||
//
|
||||
// [The SQLite Drivers Benchmarks Game]
|
||||
//
|
||||
// # Performance
|
||||
//
|
||||
// The transpiled SQLite core runs slower than the same C compiled natively.
|
||||
// The gap is in CPU-bound work: the bytecode interpreter loop, b-tree page
|
||||
// balancing and record building. I/O-bound work is dominated by the operating
|
||||
// system either way. The ratios below are CPU time per query, measured in
|
||||
// September 2026 on linux/amd64 with Go 1.27 and modernc.org/libc v1.75.7,
|
||||
// against SQLite 3.53.4 compiled with the same compile-time options this
|
||||
// package uses:
|
||||
//
|
||||
// Workload Driver vs C
|
||||
// -------------------------------------------------------------------------
|
||||
// Unindexed ORDER BY ... LIMIT 100 over 584k rows of 23 columns 2.0x
|
||||
// GROUP BY aggregate over the same table 1.9x
|
||||
// Correlated subquery walking an index with text comparisons 1.3x
|
||||
//
|
||||
// Throughput across four connections scaled at least as well as the C build
|
||||
// did, so the ratios hold under concurrency.
|
||||
//
|
||||
// Two things follow. First, this package uses the same query planner as C
|
||||
// SQLite, so a query that is slow in C is slower here by the ratio above and
|
||||
// no more; but a missing index costs the same ratio more, and a query that is
|
||||
// merely sluggish in C can cross a deadline here. Check EXPLAIN QUERY PLAN for
|
||||
// USE TEMP B-TREE and index the columns that ORDER BY, GROUP BY and WHERE use.
|
||||
// Second, database/sql opens connections without limit by default. Each
|
||||
// connection carries its own page cache and its own libc thread state, and a
|
||||
// periodic query that takes longer than its period piles up without bound.
|
||||
// Bound the pool with [sql.DB.SetMaxOpenConns] and do not issue a periodic
|
||||
// query before the previous one has returned.
|
||||
//
|
||||
// Part of the gap is in modernc.org/libc rather than in the transpiled SQLite.
|
||||
// On Linux, libc versions before v1.75.7 implemented memcpy, memmove, memset
|
||||
// and memcmp as transpiled musl loops moving at most four bytes per step;
|
||||
// v1.75.7 replaced them with native Go routines backed by the runtime's
|
||||
// vectorized memmove, and the three workloads above went from 3.0x, 2.2x and
|
||||
// 1.6x to the figures shown. The libc version this package is validated
|
||||
// against is the one pinned in its go.mod, see "Fragile modernc.org/libc
|
||||
// dependency" above. On the non-Linux targets memcpy and memmove are native Go
|
||||
// copies already; memcmp there is still a byte loop.
|
||||
//
|
||||
// Because everything is Go, the usual Go tooling reaches into the SQLite core:
|
||||
// a CPU profile taken with runtime/pprof attributes time to the transpiled
|
||||
// SQLite functions under their C names, for example lib._balance_nonroot or
|
||||
// lib.Xsqlite3_step, and to the libc routines they call.
|
||||
//
|
||||
// # Builders
|
||||
//
|
||||
// Builder results available at:
|
||||
//
|
||||
// https://modern-c.appspot.com/-/builder/?importpath=modernc.org%2fsqlite
|
||||
//
|
||||
// # Connecting to a database
|
||||
//
|
||||
// To access a Sqlite database do something like
|
||||
//
|
||||
// import (
|
||||
// "database/sql"
|
||||
//
|
||||
// _ "modernc.org/sqlite"
|
||||
// )
|
||||
//
|
||||
// ...
|
||||
//
|
||||
//
|
||||
// db, err := sql.Open("sqlite", dsnURI)
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// [NewConnector] is an alternative entry point returning a
|
||||
// [driver.Connector] for use with [sql.OpenDB]. It opens the same
|
||||
// connections sql.Open does, from the same driver, and exists for callers that
|
||||
// need to interpose on them -- tracing, metrics, or connection-scoped setup --
|
||||
// which sql.Open gives no access to. See its docstring for an example.
|
||||
//
|
||||
// # Debug and development versions
|
||||
//
|
||||
// The transpiled SQLite sources under lib/, and the sqlite-vec sources under
|
||||
// vec/, are not generated in this repository. They are produced by
|
||||
// modernc.org/libsqlite3 and modernc.org/libsqlite_vec respectively, which own
|
||||
// the transpilation and the SQLite compile-time options it uses, and are
|
||||
// copied here by
|
||||
//
|
||||
// $ make vendor
|
||||
//
|
||||
// which reads them from checkouts of those two repositories placed next to
|
||||
// this one. To build a debug or otherwise modified version, adjust the
|
||||
// compile-time options in modernc.org/libsqlite3, regenerate there with 'make
|
||||
// generate', and vendor the result here.
|
||||
//
|
||||
// # Hacking
|
||||
//
|
||||
// This is an example of how to use the debug logs in modernc.org/libc when hunting a bug.
|
||||
//
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ git status
|
||||
// On branch master
|
||||
// Your branch is up to date with 'origin/master'.
|
||||
//
|
||||
// nothing to commit, working tree clean
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ git log -1
|
||||
// commit df33b8d15107f3cc777799c0fe105f74ef499e62 (HEAD -> master, tag: v1.21.1, origin/master, origin/HEAD, wips, ok)
|
||||
// Author: Jan Mercl <0xjnml@gmail.com>
|
||||
// Date: Mon Mar 27 16:18:28 2023 +0200
|
||||
//
|
||||
// upgrade to SQLite 3.41.2
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ rm -f /tmp/libc.log ; go test -v -tags=libc.dmesg -run TestScalar ; ls -l /tmp/libc.log
|
||||
// test binary compiled for linux/amd64
|
||||
// === RUN TestScalar
|
||||
// --- PASS: TestScalar (0.09s)
|
||||
// PASS
|
||||
// ok modernc.org/sqlite 0.128s
|
||||
// -rw-r--r-- 1 jnml jnml 76 Apr 6 11:22 /tmp/libc.log
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ cat /tmp/libc.log
|
||||
// [10723 sqlite.test] 2023-04-06 11:22:48.288066057 +0200 CEST m=+0.000707150
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$
|
||||
//
|
||||
// The /tmp/libc.log file is created as requested. No useful messages there because none are enabled in libc. Let's try to enable Xwrite as an example.
|
||||
//
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/libc$ git status
|
||||
// On branch master
|
||||
// Your branch is up to date with 'origin/master'.
|
||||
//
|
||||
// Changes not staged for commit:
|
||||
// (use "git add <file>..." to update what will be committed)
|
||||
// (use "git restore <file>..." to discard changes in working directory)
|
||||
// modified: libc_linux.go
|
||||
//
|
||||
// no changes added to commit (use "git add" and/or "git commit -a")
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/libc$ git log -1
|
||||
// commit 1e22c18cf2de8aa86d5b19b165f354f99c70479c (HEAD -> master, tag: v1.22.3, origin/master, origin/HEAD)
|
||||
// Author: Jan Mercl <0xjnml@gmail.com>
|
||||
// Date: Wed Feb 22 20:27:45 2023 +0100
|
||||
//
|
||||
// support sqlite 3.41 on linux targets
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/libc$ git diff
|
||||
// diff --git a/libc_linux.go b/libc_linux.go
|
||||
// index 1c2f482..ac1f08d 100644
|
||||
// --- a/libc_linux.go
|
||||
// +++ b/libc_linux.go
|
||||
// @@ -332,19 +332,19 @@ func Xwrite(t *TLS, fd int32, buf uintptr, count types.Size_t) types.Ssize_t {
|
||||
// var n uintptr
|
||||
// switch n, _, err = unix.Syscall(unix.SYS_WRITE, uintptr(fd), buf, uintptr(count)); err {
|
||||
// case 0:
|
||||
// - // if dmesgs {
|
||||
// - // // dmesg("%v: %d %#x: %#x\n%s", origin(1), fd, count, n, hex.Dump(GoBytes(buf, int(n))))
|
||||
// - // dmesg("%v: %d %#x: %#x", origin(1), fd, count, n)
|
||||
// - // }
|
||||
// + if dmesgs {
|
||||
// + // dmesg("%v: %d %#x: %#x\n%s", origin(1), fd, count, n, hex.Dump(GoBytes(buf, int(n))))
|
||||
// + dmesg("%v: %d %#x: %#x", origin(1), fd, count, n)
|
||||
// + }
|
||||
// return types.Ssize_t(n)
|
||||
// case errno.EAGAIN:
|
||||
// // nop
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// - // if dmesgs {
|
||||
// - // dmesg("%v: fd %v, count %#x: %v", origin(1), fd, count, err)
|
||||
// - // }
|
||||
// + if dmesgs {
|
||||
// + dmesg("%v: fd %v, count %#x: %v", origin(1), fd, count, err)
|
||||
// + }
|
||||
// t.setErrno(err)
|
||||
// return -1
|
||||
// }
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/libc$
|
||||
//
|
||||
// We need to tell the Go build system to use our local, patched/debug libc.
|
||||
// 'make work' sets up a go.work covering this and the sibling repositories;
|
||||
// by hand it is:
|
||||
//
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ go work use $(go env GOPATH)/src/modernc.org/libc
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ go work use .
|
||||
//
|
||||
// And run the test again:
|
||||
//
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ rm -f /tmp/libc.log ; go test -v -tags=libc.dmesg -run TestScalar ; ls -l /tmp/libc.log
|
||||
// test binary compiled for linux/amd64
|
||||
// === RUN TestScalar
|
||||
// --- PASS: TestScalar (0.26s)
|
||||
// PASS
|
||||
// ok modernc.org/sqlite 0.285s
|
||||
// -rw-r--r-- 1 jnml jnml 918 Apr 6 11:29 /tmp/libc.log
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$ cat /tmp/libc.log
|
||||
// [11910 sqlite.test] 2023-04-06 11:29:13.143589542 +0200 CEST m=+0.000689270
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x200: 0x200
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0xc: 0xc
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 7 0x1000: 0x1000
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 7 0x1000: 0x1000
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x200: 0x200
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x4: 0x4
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x1000: 0x1000
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x4: 0x4
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x4: 0x4
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x1000: 0x1000
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0x4: 0x4
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 8 0xc: 0xc
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 7 0x1000: 0x1000
|
||||
// [11910 sqlite.test] libc_linux.go:337:Xwrite: 7 0x1000: 0x1000
|
||||
// 0:jnml@e5-1650:~/src/modernc.org/sqlite$
|
||||
//
|
||||
// # Sqlite documentation
|
||||
//
|
||||
// See https://sqlite.org/docs.html
|
||||
//
|
||||
// [The SQLite Drivers Benchmarks Game]: https://pkg.go.dev/modernc.org/sqlite-bench#readme-tl-dr-scorecard
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
+403
@@ -0,0 +1,403 @@
|
||||
// Copyright 2025 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
sqlite3 "modernc.org/sqlite/lib"
|
||||
"modernc.org/sqlite/vtab"
|
||||
)
|
||||
|
||||
// Driver implements database/sql/driver.Driver.
|
||||
//
|
||||
// Registration functions and methods must be called before the first call to
|
||||
// Open. The methods are safe to call concurrently with each other, so a
|
||||
// *Driver can be handed out for several packages to fill from their init
|
||||
// functions; the ordering requirement against Open still stands.
|
||||
//
|
||||
// Most code has no use for this type. sql.Open("sqlite", dsn) and
|
||||
// [NewConnector] both go through the driver this package registers as
|
||||
// "sqlite", which carries everything registered with [RegisterFunction],
|
||||
// [RegisterScalarFunction], [RegisterDeterministicScalarFunction],
|
||||
// [RegisterCollationUtf8], [RegisterConnectionHook] and
|
||||
// [vtab.RegisterModule].
|
||||
//
|
||||
// A Driver a caller constructs is not equivalent to that one. It starts out
|
||||
// empty, and the package-level registration functions always apply to the
|
||||
// registered driver, never to a constructed one. Connections it opens
|
||||
// therefore run without the package-level functions and collations -- and
|
||||
// where such a registration overrides a SQLite built-in of the same name, they
|
||||
// run with SQLite's built-in in force instead. Virtual table modules are the
|
||||
// one exception: those registered through the package-level path are held
|
||||
// process-globally and reach every Driver.
|
||||
//
|
||||
// A constructed Driver is filled in through its own methods, each of which
|
||||
// registers on that Driver alone: [Driver.RegisterFunction],
|
||||
// [Driver.RegisterScalarFunction],
|
||||
// [Driver.RegisterDeterministicScalarFunction],
|
||||
// [Driver.RegisterCollationUtf8], [Driver.RegisterConnectionHook] and
|
||||
// [Driver.RegisterModule]. The zero Driver is ready to use; there is no
|
||||
// constructor. What it registers stays on it, so two constructed Drivers do
|
||||
// not see each other's registrations and neither leaks into the package-level
|
||||
// driver. Modules it registers itself are installed in addition to the
|
||||
// process-global ones, not instead of them, and where both registered the
|
||||
// same name the package-level implementation wins on its connections.
|
||||
//
|
||||
// Constructing one is supported for the private-registration pattern: a driver
|
||||
// registered under a name of its own with sql.Register, so that its functions,
|
||||
// collations, modules and connection hooks apply to its own connections rather
|
||||
// than to every connection in the process. Prefer sql.Open or NewConnector for
|
||||
// anything else.
|
||||
type Driver struct {
|
||||
// mu guards the registration state below against concurrent
|
||||
// registrations. Open reads that state without it, which the ordering
|
||||
// requirement in the type documentation makes safe.
|
||||
mu sync.Mutex
|
||||
// user defined functions that are added to every new connection on Open
|
||||
udfs map[string]*userDefinedFunction
|
||||
// collations that are added to every new connection on Open
|
||||
collations map[string]*collation
|
||||
// connection hooks are called after a connection is opened
|
||||
connectionHooks []ConnectionHookFn
|
||||
// modules holds registered virtual table modules that should be added to
|
||||
// every new connection on Open.
|
||||
modules map[string]vtab.Module
|
||||
}
|
||||
|
||||
var d = &Driver{
|
||||
udfs: make(map[string]*userDefinedFunction, 0),
|
||||
collations: make(map[string]*collation, 0),
|
||||
connectionHooks: make([]ConnectionHookFn, 0),
|
||||
modules: make(map[string]vtab.Module, 0),
|
||||
}
|
||||
|
||||
func defaultDriver() *Driver { return d }
|
||||
|
||||
// Open returns a new connection to the database. The name is a string in a
|
||||
// driver-specific format.
|
||||
//
|
||||
// Open may return a cached connection (one previously closed), but doing so is
|
||||
// unnecessary; the sql package maintains a pool of idle connections for
|
||||
// efficient re-use.
|
||||
//
|
||||
// The returned connection is only used by one goroutine at a time.
|
||||
//
|
||||
// The name may be a filename, e.g., "/tmp/mydata.sqlite", or a URI, in which
|
||||
// case it may include a '?' followed by one or more query parameters.
|
||||
// For example, "file:///tmp/mydata.sqlite?_pragma=foreign_keys(1)&_time_format=sqlite".
|
||||
// The supported query parameters are:
|
||||
//
|
||||
// _pragma: Each value will be run as a "PRAGMA ..." statement (with the PRAGMA
|
||||
// keyword added for you). May be specified more than once, '&'-separated. For more
|
||||
// information on supported PRAGMAs see: https://www.sqlite.org/pragma.html
|
||||
//
|
||||
// The following shorthand keys set common PRAGMAs for easier DSN compatibility
|
||||
// when migrating from github.com/mattn/go-sqlite3. Each value is validated
|
||||
// against the same set github.com/mattn/go-sqlite3 accepts (case-insensitive);
|
||||
// an unrecognized value fails the connection with an error instead of being
|
||||
// silently ignored. The keys are applied in a fixed order, independent of the
|
||||
// order they appear in the DSN: _busy_timeout and _auto_vacuum first (auto_vacuum
|
||||
// must be set before the database is first written), then the _pragma values,
|
||||
// then the remaining keys, and _query_only last. Where a shorthand key and a
|
||||
// _pragma set the same PRAGMA, whichever is applied later in that order wins. If
|
||||
// a key and its alias are both supplied, the alias (the second name below) wins,
|
||||
// matching github.com/mattn/go-sqlite3; supplying the alias with an empty value
|
||||
// therefore suppresses the PRAGMA rather than deferring to the primary key.
|
||||
// Accepted values:
|
||||
//
|
||||
// _busy_timeout, _timeout -> PRAGMA busy_timeout (an integer)
|
||||
// _foreign_keys, _fk -> PRAGMA foreign_keys (0 1 false true no yes off on)
|
||||
// _journal_mode, _journal -> PRAGMA journal_mode (DELETE TRUNCATE PERSIST MEMORY WAL OFF)
|
||||
// _synchronous, _sync -> PRAGMA synchronous (0 OFF 1 NORMAL 2 FULL 3 EXTRA)
|
||||
// _auto_vacuum, _vacuum -> PRAGMA auto_vacuum (0 NONE 1 FULL 2 INCREMENTAL)
|
||||
// _query_only -> PRAGMA query_only (0 1 false true no yes off on)
|
||||
//
|
||||
// All DSN parameters that can be validated are validated before any of them is
|
||||
// applied, so a DSN carrying a typo fails without having executed the PRAGMAs
|
||||
// that precede it -- a rejected DSN does not leave the database converted to WAL
|
||||
// or with auto_vacuum already set.
|
||||
//
|
||||
// Unlike these validated shorthand keys, each _pragma value is executed verbatim
|
||||
// (with PRAGMA prepended) and is not validated, so a DSN that includes _pragma
|
||||
// must come from a trusted source. It is also the one case that can still fail
|
||||
// partway: a bad _pragma is only rejected by SQLite as it runs, after any
|
||||
// earlier _pragma in the list has taken effect.
|
||||
//
|
||||
// _time_format: The name of a format to use when writing time values to the database.
|
||||
// The currently supported values are (1) "sqlite" for YYYY-MM-DD HH:MM:SS.SSS[+-]HH:MM
|
||||
// (format 4 from https://www.sqlite.org/lang_datefunc.html#time_values with sub-second
|
||||
// precision and timezone specifier) and (2) "datetime" for YYYY-MM-DD HH:MM:SS
|
||||
// (format 3, matching the output of SQLite's datetime() function).
|
||||
// If this parameter is not specified, then the default String() format will be used.
|
||||
//
|
||||
// _time_integer_format: The name of a integer format to use when writing time values.
|
||||
// By default, the time is stored as string and the format can be set with _time_format
|
||||
// parameter. If _time_integer_format is set, the time will be stored as an integer and
|
||||
// the integer value will depend on the integer format.
|
||||
// If you decide to set both _time_format and _time_integer_format, the time will be
|
||||
// converted as integer and the _time_format value will be ignored.
|
||||
// Currently the supported value are "unix","unix_milli", "unix_micro" and "unix_nano",
|
||||
// which corresponds to seconds, milliseconds, microseconds or nanoseconds
|
||||
// since unixepoch (1 January 1970 00:00:00 UTC).
|
||||
//
|
||||
// _inttotime: Enable conversion of time column (DATE, DATETIME,TIMESTAMP) from integer
|
||||
// to time if the field contain integer (int64).
|
||||
//
|
||||
// _texttotime: Enable ColumnTypeScanType to report time.Time instead of string
|
||||
// for TEXT columns declared as DATE, DATETIME, TIME, or TIMESTAMP. It also
|
||||
// best-effort upgrades date-shaped TEXT values from columns SQLite reports with
|
||||
// an empty declared type (aggregates and expressions such as MAX(d) or
|
||||
// upper(d), subqueries, and typeless real columns) to time.Time, since the
|
||||
// declared-type test cannot catch those (#248). When that upgrade fires, a Scan
|
||||
// into interface{} yields a time.Time where it previously yielded a string, and
|
||||
// a Scan into *string receives the value reformatted to RFC3339Nano rather than
|
||||
// the raw stored text. A value that does not parse as a time is delivered
|
||||
// unchanged as the original string.
|
||||
//
|
||||
// _timezone: A timezone to use for all time reads and writes, such as "UTC".
|
||||
// The value is parsed by time.LoadLocation.
|
||||
// Writes will convert to the timezone before formatting as a string;
|
||||
// it does not impact _inttotime integer values, as they always use UTC.
|
||||
// Reads will interpret timezone-less strings as being in this timezone.
|
||||
// Values that are in a known timezone, such as a string with a timezone specifier
|
||||
// or an integer with _inttotime (specified to be in UTC), will be converted to this timezone.
|
||||
//
|
||||
// _txlock: The locking behavior to use when beginning a transaction. May be
|
||||
// "deferred" (the default), "immediate", or "exclusive" (case insensitive). See:
|
||||
// https://www.sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions
|
||||
//
|
||||
// _dqs: Opt-in toggle for SQLite's double-quoted string literal
|
||||
// compatibility quirk on the connection. Accepts the values strconv.ParseBool
|
||||
// understands ("0"/"1", "false"/"true", "f"/"t", case-insensitive). When
|
||||
// absent or set to a true value, SQLite's built-in behavior is unchanged:
|
||||
// a double-quoted identifier that fails to resolve is silently
|
||||
// re-interpreted as a string literal. When set to a false value,
|
||||
// SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML are both turned
|
||||
// off via sqlite3_db_config so that mistakes hidden by the legacy
|
||||
// fallback surface as a parse error instead. See:
|
||||
// https://www.sqlite.org/quirks.html#dblquote and
|
||||
// https://gitlab.com/cznic/sqlite/-/issues/61
|
||||
//
|
||||
// _defensive: Opt-in toggle for SQLite's defensive connection mode, which
|
||||
// disables the SQL-level features that let ordinary statements deliberately
|
||||
// corrupt the database file. Accepts the values strconv.ParseBool understands
|
||||
// ("0"/"1", "false"/"true", "f"/"t", case-insensitive). When absent or set to
|
||||
// a false value SQLite's default is unchanged. When set to a true value the
|
||||
// driver calls sqlite3_db_config(SQLITE_DBCONFIG_DEFENSIVE) immediately after
|
||||
// sqlite3_open_v2 and before any other parameter is applied, so the PRAGMAs
|
||||
// this driver runs, the _pragma list, and every statement the caller prepares
|
||||
// are all subject to it. The parameter is parsed before sqlite3_open_v2, so an
|
||||
// invalid value fails the connection without creating the database file, and
|
||||
// it must appear at most once: a repeated _defensive is an error rather than
|
||||
// letting the first value silently win.
|
||||
//
|
||||
// On such a connection PRAGMA writable_schema=ON, PRAGMA journal_mode=OFF and
|
||||
// PRAGMA schema_version=N become silent no-ops, and writes to a virtual
|
||||
// table's shadow tables (fts5's _data, _idx and so on) and to sqlite_dbpage
|
||||
// fail with "table ... may not be modified". Reading those tables, ordinary
|
||||
// use of the virtual tables that own them, and VACUUM are unaffected.
|
||||
//
|
||||
// Because journal_mode=OFF is one of the operations defensive mode suppresses,
|
||||
// a true _defensive combined with _journal_mode=OFF (or _journal=OFF) is
|
||||
// rejected rather than silently honouring neither. The unvalidated _pragma
|
||||
// list is the exception, as always: _pragma=journal_mode(OFF) alongside
|
||||
// _defensive=1 runs and is silently ignored by SQLite.
|
||||
//
|
||||
// Defensive mode is a hardening measure, not a sandbox for hostile database
|
||||
// files. It is one of several steps SQLite recommends for that purpose (see
|
||||
// https://www.sqlite.org/security.html); this build compiles with neither
|
||||
// SQLITE_TRUSTED_SCHEMA=0 nor SQLITE_DQS=0 and the driver exposes no
|
||||
// authorizer, so _defensive=1 alone does not make opening an untrusted file
|
||||
// safe. It is also a property of the connection, not of the database: another
|
||||
// connection to the same file, opened without the parameter, is unrestricted.
|
||||
// See: https://www.sqlite.org/c3ref/c_dbconfig_defensive.html
|
||||
//
|
||||
// _error_rc: Opt-in error-string reporting mode for synthesised errors.
|
||||
// Accepts the values strconv.ParseBool understands ("0"/"1",
|
||||
// "false"/"true", "f"/"t", case-insensitive). When absent or set to a
|
||||
// false value, the legacy "errstr: errmsg (rc)" form is preserved
|
||||
// byte-for-byte: the canonical sqlite3_errstr(rc) and the connection's
|
||||
// sqlite3_errmsg(db) are concatenated even when the latter belongs to a
|
||||
// different operation, which can read as misleading on open-time
|
||||
// failures such as SQLITE_CANTOPEN reporting "out of memory". When set
|
||||
// to a true value, the appended errmsg is suppressed if
|
||||
// sqlite3_extended_errcode(db) is inconsistent with the operation rc
|
||||
// (full match first, primary code as fallback); in that case the
|
||||
// canonical errstr(rc) is used alone. The Code() returned by the
|
||||
// driver's *Error is unchanged in either mode. The parameter is parsed
|
||||
// before sqlite3_open_v2 so open-time errors are covered. See
|
||||
// https://gitlab.com/cznic/sqlite/-/issues/230.
|
||||
//
|
||||
// vfs: The name of the SQLite VFS to open the database with. Note the absent
|
||||
// underscore prefix: this is the same parameter SQLite recognizes in a file:
|
||||
// URI, and its value is passed on as the sqlite3_open_v2 zVfs argument. It
|
||||
// selects any VFS registered with SQLite, in particular one returned by
|
||||
// [modernc.org/sqlite/vfs.New], which exposes a Go fs.FS as a read-only VFS.
|
||||
// When absent or empty the default VFS is used. Supplying the parameter more
|
||||
// than once with values that differ is an error.
|
||||
func (d *Driver) Open(name string) (conn driver.Conn, err error) {
|
||||
if dmesgs {
|
||||
defer func() {
|
||||
dmesg("name %q: (driver.Conn %p, err %v)", name, conn, err)
|
||||
}()
|
||||
}
|
||||
c, err := newConn(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, udf := range d.udfs {
|
||||
if err = c.createFunctionInternal(udf); err != nil {
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, coll := range d.collations {
|
||||
if err = c.createCollationInternal(coll); err != nil {
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, connHookFn := range d.connectionHooks {
|
||||
if err = connHookFn(c, name); err != nil {
|
||||
c.Close()
|
||||
return nil, fmt.Errorf("connection hook: %w", err)
|
||||
}
|
||||
}
|
||||
// Register any vtab modules with this connection.
|
||||
// Note: vtab module registration applies to new connections only. If a
|
||||
// module is registered after a connection has been opened, that existing
|
||||
// connection will not see the module; open a new connection to use it.
|
||||
if err := c.registerModules(d); err != nil {
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// RegisterConnectionHook registers a function to be called after each connection
|
||||
// is opened. This is called after all the connection has been set up.
|
||||
//
|
||||
// The hook applies only to connections opened by d. To register one on the
|
||||
// driver this package registers as "sqlite", and so on the connections
|
||||
// sql.Open and [NewConnector] hand out, use the package-level
|
||||
// [RegisterConnectionHook].
|
||||
func (d *Driver) RegisterConnectionHook(fn ConnectionHookFn) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
d.connectionHooks = append(d.connectionHooks, fn)
|
||||
}
|
||||
|
||||
// RegisterFunction is like the package-level [RegisterFunction] but registers
|
||||
// the function on d alone, so it reaches only the connections d opens. See
|
||||
// [Driver] for when to prefer this over the package-level form.
|
||||
func (d *Driver) RegisterFunction(
|
||||
zFuncName string,
|
||||
impl *FunctionImpl,
|
||||
) (err error) {
|
||||
if dmesgs {
|
||||
defer func() {
|
||||
dmesg("d %p, zFuncName %q, impl %p: err %v", d, zFuncName, impl, err)
|
||||
}()
|
||||
}
|
||||
return d.registerFunction(zFuncName, impl)
|
||||
}
|
||||
|
||||
// MustRegisterFunction is like [Driver.RegisterFunction] but panics on error.
|
||||
func (d *Driver) MustRegisterFunction(
|
||||
zFuncName string,
|
||||
impl *FunctionImpl,
|
||||
) {
|
||||
if err := d.RegisterFunction(zFuncName, impl); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterScalarFunction is like the package-level [RegisterScalarFunction]
|
||||
// but registers the function on d alone, so it reaches only the connections d
|
||||
// opens. See [Driver] for when to prefer this over the package-level form.
|
||||
func (d *Driver) RegisterScalarFunction(
|
||||
zFuncName string,
|
||||
nArg int32,
|
||||
xFunc func(ctx *FunctionContext, args []driver.Value) (driver.Value, error),
|
||||
) (err error) {
|
||||
if dmesgs {
|
||||
defer func() {
|
||||
dmesg("d %p, zFuncName %q, nArg %v, xFunc %p: err %v", d, zFuncName, nArg, xFunc, err)
|
||||
}()
|
||||
}
|
||||
return d.registerFunction(zFuncName, &FunctionImpl{NArgs: nArg, Scalar: xFunc, Deterministic: false})
|
||||
}
|
||||
|
||||
// MustRegisterScalarFunction is like [Driver.RegisterScalarFunction] but
|
||||
// panics on error.
|
||||
func (d *Driver) MustRegisterScalarFunction(
|
||||
zFuncName string,
|
||||
nArg int32,
|
||||
xFunc func(ctx *FunctionContext, args []driver.Value) (driver.Value, error),
|
||||
) {
|
||||
if err := d.RegisterScalarFunction(zFuncName, nArg, xFunc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterDeterministicScalarFunction is like the package-level
|
||||
// [RegisterDeterministicScalarFunction] but registers the function on d alone,
|
||||
// so it reaches only the connections d opens. See [Driver] for when to prefer
|
||||
// this over the package-level form.
|
||||
func (d *Driver) RegisterDeterministicScalarFunction(
|
||||
zFuncName string,
|
||||
nArg int32,
|
||||
xFunc func(ctx *FunctionContext, args []driver.Value) (driver.Value, error),
|
||||
) (err error) {
|
||||
if dmesgs {
|
||||
defer func() {
|
||||
dmesg("d %p, zFuncName %q, nArg %v, xFunc %p: err %v", d, zFuncName, nArg, xFunc, err)
|
||||
}()
|
||||
}
|
||||
return d.registerFunction(zFuncName, &FunctionImpl{NArgs: nArg, Scalar: xFunc, Deterministic: true})
|
||||
}
|
||||
|
||||
// MustRegisterDeterministicScalarFunction is like
|
||||
// [Driver.RegisterDeterministicScalarFunction] but panics on error.
|
||||
func (d *Driver) MustRegisterDeterministicScalarFunction(
|
||||
zFuncName string,
|
||||
nArg int32,
|
||||
xFunc func(ctx *FunctionContext, args []driver.Value) (driver.Value, error),
|
||||
) {
|
||||
if err := d.RegisterDeterministicScalarFunction(zFuncName, nArg, xFunc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCollationUtf8 is like the package-level [RegisterCollationUtf8] but
|
||||
// registers the collation on d alone, so it reaches only the connections d
|
||||
// opens. See [Driver] for when to prefer this over the package-level form.
|
||||
func (d *Driver) RegisterCollationUtf8(
|
||||
zName string,
|
||||
impl func(left, right string) int,
|
||||
) (err error) {
|
||||
if dmesgs {
|
||||
defer func() {
|
||||
dmesg("d %p, zName %q, impl %p: err %v", d, zName, impl, err)
|
||||
}()
|
||||
}
|
||||
return d.registerCollation(zName, impl, sqlite3.SQLITE_UTF8)
|
||||
}
|
||||
|
||||
// MustRegisterCollationUtf8 is like [Driver.RegisterCollationUtf8] but panics
|
||||
// on error.
|
||||
func (d *Driver) MustRegisterCollationUtf8(
|
||||
zName string,
|
||||
impl func(left, right string) int,
|
||||
) {
|
||||
if err := d.RegisterCollationUtf8(zName, impl); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+75
@@ -0,0 +1,75 @@
|
||||
// Copyright 2025 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
sqlite3 "modernc.org/sqlite/lib"
|
||||
)
|
||||
|
||||
// Error represents sqlite library error code.
|
||||
type Error struct {
|
||||
msg string
|
||||
code int
|
||||
}
|
||||
|
||||
// Error implements error.
|
||||
func (e *Error) Error() string { return e.msg }
|
||||
|
||||
// Code returns the sqlite result code for this error.
|
||||
func (e *Error) Code() int { return e.code }
|
||||
|
||||
var (
|
||||
// ErrorCodeString maps Error.Code() to its string representation.
|
||||
ErrorCodeString = map[int]string{
|
||||
sqlite3.SQLITE_ABORT: "Callback routine requested an abort (SQLITE_ABORT)",
|
||||
sqlite3.SQLITE_AUTH: "Authorization denied (SQLITE_AUTH)",
|
||||
sqlite3.SQLITE_BUSY: "The database file is locked (SQLITE_BUSY)",
|
||||
sqlite3.SQLITE_CANTOPEN: "Unable to open the database file (SQLITE_CANTOPEN)",
|
||||
sqlite3.SQLITE_CONSTRAINT: "Abort due to constraint violation (SQLITE_CONSTRAINT)",
|
||||
sqlite3.SQLITE_CORRUPT: "The database disk image is malformed (SQLITE_CORRUPT)",
|
||||
sqlite3.SQLITE_DONE: "sqlite3_step() has finished executing (SQLITE_DONE)",
|
||||
sqlite3.SQLITE_EMPTY: "Internal use only (SQLITE_EMPTY)",
|
||||
sqlite3.SQLITE_ERROR: "Generic error (SQLITE_ERROR)",
|
||||
sqlite3.SQLITE_FORMAT: "Not used (SQLITE_FORMAT)",
|
||||
sqlite3.SQLITE_FULL: "Insertion failed because database is full (SQLITE_FULL)",
|
||||
sqlite3.SQLITE_INTERNAL: "Internal logic error in SQLite (SQLITE_INTERNAL)",
|
||||
sqlite3.SQLITE_INTERRUPT: "Operation terminated by sqlite3_interrupt()(SQLITE_INTERRUPT)",
|
||||
sqlite3.SQLITE_IOERR | (1 << 8): "(SQLITE_IOERR_READ)",
|
||||
sqlite3.SQLITE_IOERR | (10 << 8): "(SQLITE_IOERR_DELETE)",
|
||||
sqlite3.SQLITE_IOERR | (11 << 8): "(SQLITE_IOERR_BLOCKED)",
|
||||
sqlite3.SQLITE_IOERR | (12 << 8): "(SQLITE_IOERR_NOMEM)",
|
||||
sqlite3.SQLITE_IOERR | (13 << 8): "(SQLITE_IOERR_ACCESS)",
|
||||
sqlite3.SQLITE_IOERR | (14 << 8): "(SQLITE_IOERR_CHECKRESERVEDLOCK)",
|
||||
sqlite3.SQLITE_IOERR | (15 << 8): "(SQLITE_IOERR_LOCK)",
|
||||
sqlite3.SQLITE_IOERR | (16 << 8): "(SQLITE_IOERR_CLOSE)",
|
||||
sqlite3.SQLITE_IOERR | (17 << 8): "(SQLITE_IOERR_DIR_CLOSE)",
|
||||
sqlite3.SQLITE_IOERR | (2 << 8): "(SQLITE_IOERR_SHORT_READ)",
|
||||
sqlite3.SQLITE_IOERR | (3 << 8): "(SQLITE_IOERR_WRITE)",
|
||||
sqlite3.SQLITE_IOERR | (4 << 8): "(SQLITE_IOERR_FSYNC)",
|
||||
sqlite3.SQLITE_IOERR | (5 << 8): "(SQLITE_IOERR_DIR_FSYNC)",
|
||||
sqlite3.SQLITE_IOERR | (6 << 8): "(SQLITE_IOERR_TRUNCATE)",
|
||||
sqlite3.SQLITE_IOERR | (7 << 8): "(SQLITE_IOERR_FSTAT)",
|
||||
sqlite3.SQLITE_IOERR | (8 << 8): "(SQLITE_IOERR_UNLOCK)",
|
||||
sqlite3.SQLITE_IOERR | (9 << 8): "(SQLITE_IOERR_RDLOCK)",
|
||||
sqlite3.SQLITE_IOERR: "Some kind of disk I/O error occurred (SQLITE_IOERR)",
|
||||
sqlite3.SQLITE_LOCKED | (1 << 8): "(SQLITE_LOCKED_SHAREDCACHE)",
|
||||
sqlite3.SQLITE_LOCKED: "A table in the database is locked (SQLITE_LOCKED)",
|
||||
sqlite3.SQLITE_MISMATCH: "Data type mismatch (SQLITE_MISMATCH)",
|
||||
sqlite3.SQLITE_MISUSE: "Library used incorrectly (SQLITE_MISUSE)",
|
||||
sqlite3.SQLITE_NOLFS: "Uses OS features not supported on host (SQLITE_NOLFS)",
|
||||
sqlite3.SQLITE_NOMEM: "A malloc() failed (SQLITE_NOMEM)",
|
||||
sqlite3.SQLITE_NOTADB: "File opened that is not a database file (SQLITE_NOTADB)",
|
||||
sqlite3.SQLITE_NOTFOUND: "Unknown opcode in sqlite3_file_control() (SQLITE_NOTFOUND)",
|
||||
sqlite3.SQLITE_NOTICE: "Notifications from sqlite3_log() (SQLITE_NOTICE)",
|
||||
sqlite3.SQLITE_PERM: "Access permission denied (SQLITE_PERM)",
|
||||
sqlite3.SQLITE_PROTOCOL: "Database lock protocol error (SQLITE_PROTOCOL)",
|
||||
sqlite3.SQLITE_RANGE: "2nd parameter to sqlite3_bind out of range (SQLITE_RANGE)",
|
||||
sqlite3.SQLITE_READONLY: "Attempt to write a readonly database (SQLITE_READONLY)",
|
||||
sqlite3.SQLITE_ROW: "sqlite3_step() has another row ready (SQLITE_ROW)",
|
||||
sqlite3.SQLITE_SCHEMA: "The database schema changed (SQLITE_SCHEMA)",
|
||||
sqlite3.SQLITE_TOOBIG: "String or BLOB exceeds size limit (SQLITE_TOOBIG)",
|
||||
sqlite3.SQLITE_WARNING: "Warnings from sqlite3_log() (SQLITE_WARNING)",
|
||||
}
|
||||
)
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// Copyright 2024 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite // import "modernc.org/sqlite"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
sqlite3 "modernc.org/sqlite/lib"
|
||||
)
|
||||
|
||||
// Access to sqlite3_file_control
|
||||
type FileControl interface {
|
||||
// Set or query SQLITE_FCNTL_PERSIST_WAL, returns set mode or query result
|
||||
FileControlPersistWAL(dbName string, mode int) (int, error)
|
||||
// Query SQLITE_FCNTL_DATA_VERSION, returns the pager-cache data version
|
||||
// for dbName. The value changes whenever the contents of the database
|
||||
// file change, which makes it suitable for cache-invalidation use cases.
|
||||
// See
|
||||
// https://www.sqlite.org/c3ref/c_fcntl_begin_atomic_write.html#sqlitefcntldataversion.
|
||||
FileControlDataVersion(dbName string) (uint32, error)
|
||||
}
|
||||
|
||||
var _ FileControl = (*conn)(nil)
|
||||
|
||||
func (c *conn) FileControlPersistWAL(dbName string, mode int) (int, error) {
|
||||
pi32 := c.tls.Alloc(4)
|
||||
defer c.tls.Free(4)
|
||||
|
||||
*(*int32)(unsafe.Pointer(pi32)) = int32(mode)
|
||||
err := c.fileControl(dbName, sqlite3.SQLITE_FCNTL_PERSIST_WAL, pi32)
|
||||
return int(*(*int32)(unsafe.Pointer(pi32))), err
|
||||
}
|
||||
|
||||
func (c *conn) FileControlDataVersion(dbName string) (uint32, error) {
|
||||
pu32 := c.tls.Alloc(4)
|
||||
defer c.tls.Free(4)
|
||||
|
||||
*(*uint32)(unsafe.Pointer(pu32)) = 0
|
||||
err := c.fileControl(dbName, sqlite3.SQLITE_FCNTL_DATA_VERSION, pu32)
|
||||
return *(*uint32)(unsafe.Pointer(pu32)), err
|
||||
}
|
||||
|
||||
func (c *conn) fileControl(dbName string, op int, pArg uintptr) error {
|
||||
zDbName, err := libc.CString(dbName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.free(zDbName)
|
||||
|
||||
if rc := sqlite3.Xsqlite3_file_control(c.tls, c.db, zDbName, int32(op), pArg); rc != sqlite3.SQLITE_OK {
|
||||
return c.errstr(rc)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
--- /home/jnml/tmp/test_syscall.c 2023-04-21 16:26:44.302689709 +0200
|
||||
+++ testdata/sqlite-src-3410200/src/test_syscall.c 2023-04-21 16:29:28.000869993 +0200
|
||||
@@ -110,15 +110,15 @@
|
||||
static int ts_fstat(int fd, struct stat *p);
|
||||
static int ts_ftruncate(int fd, off_t n);
|
||||
static int ts_fcntl(int fd, int cmd, ... );
|
||||
-static int ts_read(int fd, void *aBuf, size_t nBuf);
|
||||
-static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off);
|
||||
+static ssize_t ts_read(int fd, void *aBuf, size_t nBuf);
|
||||
+static ssize_t ts_pread(int fd, void *aBuf, size_t nBuf, off_t off);
|
||||
/* Note: pread64() and pwrite64() actually use off64_t as the type on their
|
||||
** last parameter. But that datatype is not defined on many systems
|
||||
** (ex: Mac, OpenBSD). So substitute a likely equivalent: sqlite3_uint64 */
|
||||
-static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off);
|
||||
-static int ts_write(int fd, const void *aBuf, size_t nBuf);
|
||||
-static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off);
|
||||
-static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off);
|
||||
+static ssize_t ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off);
|
||||
+static ssize_t ts_write(int fd, const void *aBuf, size_t nBuf);
|
||||
+static ssize_t ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off);
|
||||
+static ssize_t ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off);
|
||||
static int ts_fchmod(int fd, mode_t mode);
|
||||
static int ts_fallocate(int fd, off_t off, off_t len);
|
||||
static void *ts_mmap(void *, size_t, int, int, int, off_t);
|
||||
@@ -313,7 +313,7 @@
|
||||
/*
|
||||
** A wrapper around read().
|
||||
*/
|
||||
-static int ts_read(int fd, void *aBuf, size_t nBuf){
|
||||
+static ssize_t ts_read(int fd, void *aBuf, size_t nBuf){
|
||||
if( tsIsFailErrno("read") ){
|
||||
return -1;
|
||||
}
|
||||
@@ -323,7 +323,7 @@
|
||||
/*
|
||||
** A wrapper around pread().
|
||||
*/
|
||||
-static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off){
|
||||
+static ssize_t ts_pread(int fd, void *aBuf, size_t nBuf, off_t off){
|
||||
if( tsIsFailErrno("pread") ){
|
||||
return -1;
|
||||
}
|
||||
@@ -333,7 +333,7 @@
|
||||
/*
|
||||
** A wrapper around pread64().
|
||||
*/
|
||||
-static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off){
|
||||
+static ssize_t ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off){
|
||||
if( tsIsFailErrno("pread64") ){
|
||||
return -1;
|
||||
}
|
||||
@@ -343,7 +343,7 @@
|
||||
/*
|
||||
** A wrapper around write().
|
||||
*/
|
||||
-static int ts_write(int fd, const void *aBuf, size_t nBuf){
|
||||
+static ssize_t ts_write(int fd, const void *aBuf, size_t nBuf){
|
||||
if( tsIsFailErrno("write") ){
|
||||
if( tsErrno("write")==EINTR ) orig_write(fd, aBuf, nBuf/2);
|
||||
return -1;
|
||||
@@ -354,7 +354,7 @@
|
||||
/*
|
||||
** A wrapper around pwrite().
|
||||
*/
|
||||
-static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off){
|
||||
+static ssize_t ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off){
|
||||
if( tsIsFailErrno("pwrite") ){
|
||||
return -1;
|
||||
}
|
||||
@@ -364,7 +364,7 @@
|
||||
/*
|
||||
** A wrapper around pwrite64().
|
||||
*/
|
||||
-static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off){
|
||||
+static ssize_t ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off){
|
||||
if( tsIsFailErrno("pwrite64") ){
|
||||
return -1;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2022 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite3
|
||||
|
||||
const (
|
||||
SQLITE_STATIC = uintptr(0) // ((sqlite3_destructor_type)0)
|
||||
SQLITE_TRANSIENT = ^uintptr(0) // ((sqlite3_destructor_type)-1)
|
||||
)
|
||||
|
||||
type (
|
||||
Sqlite3_index_constraint = sqlite3_index_constraint
|
||||
Sqlite3_index_orderby = sqlite3_index_orderby
|
||||
Sqlite3_index_constraint_usage = sqlite3_index_constraint_usage
|
||||
)
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// Copyright 2019 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !(linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// Format and write a message to the log if logging is enabled.
|
||||
func X__ccgo_sqlite3_log(t *libc.TLS, iErrCode int32, zFormat uintptr, va uintptr) { /* sqlite3.c:29405:17: */
|
||||
libc.X__ccgo_sqlite3_log(t, iErrCode, zFormat, va)
|
||||
}
|
||||
|
||||
func PatchIssue199() {
|
||||
// nop
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// Copyright 2019 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// Format and write a message to the log if logging is enabled.
|
||||
func X__ccgo_sqlite3_log(t *libc.TLS, iErrCode int32, zFormat uintptr, va uintptr) { /* sqlite3.c:29405:17: */
|
||||
libc.X__ccgo_sqlite3_log(t, iErrCode, zFormat, va)
|
||||
}
|
||||
|
||||
// https://gitlab.com/cznic/sqlite/-/issues/199
|
||||
//
|
||||
// The transpiled getpagesize entry of _aSyscall does not report the kernel page
|
||||
// size on linux/arm64, so SQLite misaligns the mmap of its WAL shm regions on a
|
||||
// 64 KB page kernel and reports a disk I/O error. Substitute a Go implementation
|
||||
// at run time; sqlite.go calls this from its init.
|
||||
func PatchIssue199() {
|
||||
p := unsafe.Pointer(&_aSyscall)
|
||||
*(*uintptr)(unsafe.Add(p, 608)) = __ccgo_fp(_unixGetpagesizeIssue199)
|
||||
}
|
||||
|
||||
func _unixGetpagesizeIssue199(tls *libc.TLS) (r int32) {
|
||||
return int32(syscall.Getpagesize())
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2026 The libsqlite3-go Authors. All rights reserved.
|
||||
// Use of the source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
func ___inline_isnanf(tls *libc.TLS, f float32) int32 {
|
||||
return libc.X__inline_isnanf(tls, f)
|
||||
}
|
||||
|
||||
func ___inline_isnan(tls *libc.TLS, f float64) int32 {
|
||||
return libc.X__inline_isnand(tls, f)
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2026 The libsqlite3-go Authors. All rights reserved.
|
||||
// Use of the source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
func ___umulh(tls *libc.TLS, a, b uint64) uint64 {
|
||||
hi, _ := bits.Mul64(a, b)
|
||||
return hi
|
||||
}
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
// Copyright 2021 The Sqlite Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !linux
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
"modernc.org/libc/sys/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tls := libc.NewTLS()
|
||||
if Xsqlite3_threadsafe(tls) == 0 {
|
||||
panic(fmt.Errorf("sqlite: thread safety configuration error"))
|
||||
}
|
||||
|
||||
varArgs := libc.Xmalloc(tls, types.Size_t(unsafe.Sizeof(uintptr(0))))
|
||||
if varArgs == 0 {
|
||||
panic(fmt.Errorf("cannot allocate memory"))
|
||||
}
|
||||
|
||||
// int sqlite3_config(int, ...);
|
||||
if rc := Xsqlite3_config(tls, SQLITE_CONFIG_MUTEX, libc.VaList(varArgs, uintptr(unsafe.Pointer(&mutexMethods)))); rc != SQLITE_OK {
|
||||
p := Xsqlite3_errstr(tls, rc)
|
||||
str := libc.GoString(p)
|
||||
panic(fmt.Errorf("sqlite: failed to configure mutex methods: %v", str))
|
||||
}
|
||||
|
||||
libc.Xfree(tls, varArgs)
|
||||
tls.Close()
|
||||
}
|
||||
|
||||
var (
|
||||
mutexMethods = Sqlite3_mutex_methods{
|
||||
FxMutexInit: *(*uintptr)(unsafe.Pointer(&struct{ f func(*libc.TLS) int32 }{mutexInit})),
|
||||
FxMutexEnd: *(*uintptr)(unsafe.Pointer(&struct{ f func(*libc.TLS) int32 }{mutexEnd})),
|
||||
FxMutexAlloc: *(*uintptr)(unsafe.Pointer(&struct {
|
||||
f func(*libc.TLS, int32) uintptr
|
||||
}{mutexAlloc})),
|
||||
FxMutexFree: *(*uintptr)(unsafe.Pointer(&struct{ f func(*libc.TLS, uintptr) }{mutexFree})),
|
||||
FxMutexEnter: *(*uintptr)(unsafe.Pointer(&struct{ f func(*libc.TLS, uintptr) }{mutexEnter})),
|
||||
FxMutexTry: *(*uintptr)(unsafe.Pointer(&struct {
|
||||
f func(*libc.TLS, uintptr) int32
|
||||
}{mutexTry})),
|
||||
FxMutexLeave: *(*uintptr)(unsafe.Pointer(&struct{ f func(*libc.TLS, uintptr) }{mutexLeave})),
|
||||
FxMutexHeld: *(*uintptr)(unsafe.Pointer(&struct {
|
||||
f func(*libc.TLS, uintptr) int32
|
||||
}{mutexHeld})),
|
||||
FxMutexNotheld: *(*uintptr)(unsafe.Pointer(&struct {
|
||||
f func(*libc.TLS, uintptr) int32
|
||||
}{mutexNotheld})),
|
||||
}
|
||||
|
||||
mutexApp10 mutex
|
||||
mutexApp20 mutex
|
||||
mutexApp30 mutex
|
||||
mutexLRU0 mutex
|
||||
mutexMaster0 mutex
|
||||
mutexMem0 mutex
|
||||
mutexOpen0 mutex
|
||||
mutexPMem0 mutex
|
||||
mutexPRNG0 mutex
|
||||
mutexVFS10 mutex
|
||||
mutexVFS20 mutex
|
||||
mutexVFS30 mutex
|
||||
|
||||
mutexApp1 = uintptr(unsafe.Pointer(&mutexApp10))
|
||||
mutexApp2 = uintptr(unsafe.Pointer(&mutexApp20))
|
||||
mutexApp3 = uintptr(unsafe.Pointer(&mutexApp30))
|
||||
mutexLRU = uintptr(unsafe.Pointer(&mutexLRU0))
|
||||
mutexMaster = uintptr(unsafe.Pointer(&mutexMaster0))
|
||||
mutexMem = uintptr(unsafe.Pointer(&mutexMem0))
|
||||
mutexOpen = uintptr(unsafe.Pointer(&mutexOpen0))
|
||||
mutexPMem = uintptr(unsafe.Pointer(&mutexPMem0))
|
||||
mutexPRNG = uintptr(unsafe.Pointer(&mutexPRNG0))
|
||||
mutexVFS1 = uintptr(unsafe.Pointer(&mutexVFS10))
|
||||
mutexVFS2 = uintptr(unsafe.Pointer(&mutexVFS20))
|
||||
mutexVFS3 = uintptr(unsafe.Pointer(&mutexVFS30))
|
||||
)
|
||||
|
||||
type mutex struct {
|
||||
sync.Mutex
|
||||
cnt int32
|
||||
id int32 // tls.ID
|
||||
recursive bool
|
||||
}
|
||||
|
||||
// int (*xMutexInit)(void);
|
||||
//
|
||||
// The xMutexInit method defined by this structure is invoked as part of system
|
||||
// initialization by the sqlite3_initialize() function. The xMutexInit routine
|
||||
// is called by SQLite exactly once for each effective call to
|
||||
// sqlite3_initialize().
|
||||
//
|
||||
// The xMutexInit() method must be threadsafe. It must be harmless to invoke
|
||||
// xMutexInit() multiple times within the same process and without intervening
|
||||
// calls to xMutexEnd(). Second and subsequent calls to xMutexInit() must be
|
||||
// no-ops. xMutexInit() must not use SQLite memory allocation (sqlite3_malloc()
|
||||
// and its associates).
|
||||
//
|
||||
// If xMutexInit fails in any way, it is expected to clean up after itself
|
||||
// prior to returning.
|
||||
func mutexInit(tls *libc.TLS) int32 { return SQLITE_OK }
|
||||
|
||||
// int (*xMutexEnd)(void);
|
||||
func mutexEnd(tls *libc.TLS) int32 { return SQLITE_OK }
|
||||
|
||||
// sqlite3_mutex *(*xMutexAlloc)(int);
|
||||
//
|
||||
// The sqlite3_mutex_alloc() routine allocates a new mutex and returns a
|
||||
// pointer to it. The sqlite3_mutex_alloc() routine returns NULL if it is
|
||||
// unable to allocate the requested mutex. The argument to
|
||||
// sqlite3_mutex_alloc() must one of these integer constants:
|
||||
//
|
||||
// SQLITE_MUTEX_FAST
|
||||
// SQLITE_MUTEX_RECURSIVE
|
||||
// SQLITE_MUTEX_STATIC_MASTER
|
||||
// SQLITE_MUTEX_STATIC_MEM
|
||||
// SQLITE_MUTEX_STATIC_OPEN
|
||||
// SQLITE_MUTEX_STATIC_PRNG
|
||||
// SQLITE_MUTEX_STATIC_LRU
|
||||
// SQLITE_MUTEX_STATIC_PMEM
|
||||
// SQLITE_MUTEX_STATIC_APP1
|
||||
// SQLITE_MUTEX_STATIC_APP2
|
||||
// SQLITE_MUTEX_STATIC_APP3
|
||||
// SQLITE_MUTEX_STATIC_VFS1
|
||||
// SQLITE_MUTEX_STATIC_VFS2
|
||||
// SQLITE_MUTEX_STATIC_VFS3
|
||||
//
|
||||
// The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) cause
|
||||
// sqlite3_mutex_alloc() to create a new mutex. The new mutex is recursive when
|
||||
// SQLITE_MUTEX_RECURSIVE is used but not necessarily so when SQLITE_MUTEX_FAST
|
||||
// is used. The mutex implementation does not need to make a distinction
|
||||
// between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does not want to.
|
||||
// SQLite will only request a recursive mutex in cases where it really needs
|
||||
// one. If a faster non-recursive mutex implementation is available on the host
|
||||
// platform, the mutex subsystem might return such a mutex in response to
|
||||
// SQLITE_MUTEX_FAST.
|
||||
//
|
||||
// The other allowed parameters to sqlite3_mutex_alloc() (anything other than
|
||||
// SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return a pointer to a
|
||||
// static preexisting mutex. Nine static mutexes are used by the current
|
||||
// version of SQLite. Future versions of SQLite may add additional static
|
||||
// mutexes. Static mutexes are for internal use by SQLite only. Applications
|
||||
// that use SQLite mutexes should use only the dynamic mutexes returned by
|
||||
// SQLITE_MUTEX_FAST or SQLITE_MUTEX_RECURSIVE.
|
||||
//
|
||||
// Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST or
|
||||
// SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() returns a
|
||||
// different mutex on every call. For the static mutex types, the same mutex is
|
||||
// returned on every call that has the same type number.
|
||||
func mutexAlloc(tls *libc.TLS, typ int32) (r uintptr) {
|
||||
switch typ {
|
||||
case SQLITE_MUTEX_FAST:
|
||||
r = libc.Xcalloc(tls, 1, types.Size_t(unsafe.Sizeof(mutex{})))
|
||||
return r
|
||||
case SQLITE_MUTEX_RECURSIVE:
|
||||
r = libc.Xcalloc(tls, 1, types.Size_t(unsafe.Sizeof(mutex{})))
|
||||
(*mutex)(unsafe.Pointer(r)).recursive = true
|
||||
return r
|
||||
case SQLITE_MUTEX_STATIC_MASTER:
|
||||
return mutexMaster
|
||||
case SQLITE_MUTEX_STATIC_MEM:
|
||||
return mutexMem
|
||||
case SQLITE_MUTEX_STATIC_OPEN:
|
||||
return mutexOpen
|
||||
case SQLITE_MUTEX_STATIC_PRNG:
|
||||
return mutexPRNG
|
||||
case SQLITE_MUTEX_STATIC_LRU:
|
||||
return mutexLRU
|
||||
case SQLITE_MUTEX_STATIC_PMEM:
|
||||
return mutexPMem
|
||||
case SQLITE_MUTEX_STATIC_APP1:
|
||||
return mutexApp1
|
||||
case SQLITE_MUTEX_STATIC_APP2:
|
||||
return mutexApp2
|
||||
case SQLITE_MUTEX_STATIC_APP3:
|
||||
return mutexApp3
|
||||
case SQLITE_MUTEX_STATIC_VFS1:
|
||||
return mutexVFS1
|
||||
case SQLITE_MUTEX_STATIC_VFS2:
|
||||
return mutexVFS2
|
||||
case SQLITE_MUTEX_STATIC_VFS3:
|
||||
return mutexVFS3
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// void (*xMutexFree)(sqlite3_mutex *);
|
||||
func mutexFree(tls *libc.TLS, m uintptr) {
|
||||
libc.Xfree(tls, m)
|
||||
}
|
||||
|
||||
// The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt to enter
|
||||
// a mutex. If another thread is already within the mutex,
|
||||
// sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
|
||||
// SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK upon
|
||||
// successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can be
|
||||
// entered multiple times by the same thread. In such cases, the mutex must be
|
||||
// exited an equal number of times before another thread can enter. If the same
|
||||
// thread tries to enter any mutex other than an SQLITE_MUTEX_RECURSIVE more
|
||||
// than once, the behavior is undefined.
|
||||
//
|
||||
// If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
|
||||
// sqlite3_mutex_leave() is a NULL pointer, then all three routines behave as
|
||||
// no-ops.
|
||||
|
||||
// void (*xMutexEnter)(sqlite3_mutex *);
|
||||
func mutexEnter(tls *libc.TLS, m uintptr) {
|
||||
if m == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Non-recursive mutex: Standard Go lock
|
||||
if !(*mutex)(unsafe.Pointer(m)).recursive {
|
||||
(*mutex)(unsafe.Pointer(m)).Lock()
|
||||
atomic.StoreInt32(&(*mutex)(unsafe.Pointer(m)).id, tls.ID)
|
||||
return
|
||||
}
|
||||
|
||||
// Recursive mutex: Check if we already own it (Fast Path)
|
||||
// We can safely read ptr.id without a lock here because if it equals tls.ID,
|
||||
// WE are the writer, so no other thread can be changing it.
|
||||
if atomic.LoadInt32(&(*mutex)(unsafe.Pointer(m)).id) == tls.ID {
|
||||
(*mutex)(unsafe.Pointer(m)).cnt++
|
||||
return
|
||||
}
|
||||
|
||||
// We don't own it. Acquire physical lock (Slow Path).
|
||||
// This blocks until the mutex is free.
|
||||
(*mutex)(unsafe.Pointer(m)).Lock()
|
||||
|
||||
// Now that we have the lock, claim ownership.
|
||||
atomic.StoreInt32(&(*mutex)(unsafe.Pointer(m)).id, tls.ID)
|
||||
(*mutex)(unsafe.Pointer(m)).cnt = 1
|
||||
}
|
||||
|
||||
// int (*xMutexTry)(sqlite3_mutex *);
|
||||
func mutexTry(tls *libc.TLS, m uintptr) int32 {
|
||||
if m == 0 {
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// Non-recursive mutex
|
||||
if !(*mutex)(unsafe.Pointer(m)).recursive {
|
||||
if (*mutex)(unsafe.Pointer(m)).TryLock() {
|
||||
atomic.StoreInt32(&(*mutex)(unsafe.Pointer(m)).id, tls.ID)
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
return SQLITE_BUSY
|
||||
}
|
||||
|
||||
// Recursive mutex: Check if we already own it (Fast Path)
|
||||
if atomic.LoadInt32(&(*mutex)(unsafe.Pointer(m)).id) == tls.ID {
|
||||
(*mutex)(unsafe.Pointer(m)).cnt++
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// Try to acquire physical lock
|
||||
if (*mutex)(unsafe.Pointer(m)).TryLock() {
|
||||
atomic.StoreInt32(&(*mutex)(unsafe.Pointer(m)).id, tls.ID)
|
||||
(*mutex)(unsafe.Pointer(m)).cnt = 1
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
return SQLITE_BUSY
|
||||
}
|
||||
|
||||
// void (*xMutexLeave)(sqlite3_mutex *);
|
||||
func mutexLeave(tls *libc.TLS, m uintptr) {
|
||||
if m == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Non-recursive mutex
|
||||
if !(*mutex)(unsafe.Pointer(m)).recursive {
|
||||
atomic.StoreInt32(&(*mutex)(unsafe.Pointer(m)).id, 0)
|
||||
(*mutex)(unsafe.Pointer(m)).Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Recursive mutex: Decrement count
|
||||
(*mutex)(unsafe.Pointer(m)).cnt--
|
||||
|
||||
// If count reaches zero, we are fully releasing the mutex.
|
||||
if (*mutex)(unsafe.Pointer(m)).cnt == 0 {
|
||||
atomic.StoreInt32(&(*mutex)(unsafe.Pointer(m)).id, 0)
|
||||
(*mutex)(unsafe.Pointer(m)).Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines are intended
|
||||
// for use inside assert() statements. The SQLite core never uses these
|
||||
// routines except inside an assert() and applications are advised to follow
|
||||
// the lead of the core. The SQLite core only provides implementations for
|
||||
// these routines when it is compiled with the SQLITE_DEBUG flag. External
|
||||
// mutex implementations are only required to provide these routines if
|
||||
// SQLITE_DEBUG is defined and if NDEBUG is not defined.
|
||||
//
|
||||
// These routines should return true if the mutex in their argument is held or
|
||||
// not held, respectively, by the calling thread.
|
||||
//
|
||||
// The implementation is not required to provide versions of these routines
|
||||
// that actually work. If the implementation does not provide working versions
|
||||
// of these routines, it should at least provide stubs that always return true
|
||||
// so that one does not get spurious assertion failures.
|
||||
//
|
||||
// If the argument to sqlite3_mutex_held() is a NULL pointer then the routine
|
||||
// should return 1. This seems counter-intuitive since clearly the mutex cannot
|
||||
// be held if it does not exist. But the reason the mutex does not exist is
|
||||
// because the build is not using mutexes. And we do not want the assert()
|
||||
// containing the call to sqlite3_mutex_held() to fail, so a non-zero return is
|
||||
// the appropriate thing to do. The sqlite3_mutex_notheld() interface should
|
||||
// also return 1 when given a NULL pointer.
|
||||
|
||||
// int (*xMutexHeld)(sqlite3_mutex *);
|
||||
func mutexHeld(tls *libc.TLS, m uintptr) int32 {
|
||||
if m == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// atomic.Load is required because we might be checking a mutex
|
||||
// that we do not own (and thus another thread might be writing to).
|
||||
return libc.Bool32(atomic.LoadInt32(&(*mutex)(unsafe.Pointer(m)).id) == tls.ID)
|
||||
}
|
||||
|
||||
// int (*xMutexNotheld)(sqlite3_mutex *);
|
||||
func mutexNotheld(tls *libc.TLS, m uintptr) int32 {
|
||||
if m == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Returns True if ID is Zero (unheld) OR ID is some other thread's ID.
|
||||
return libc.Bool32(atomic.LoadInt32(&(*mutex)(unsafe.Pointer(m)).id) != tls.ID)
|
||||
}
|
||||
+49185
File diff suppressed because it is too large
Load Diff
+658
@@ -0,0 +1,658 @@
|
||||
// Code generated for darwin/amd64 by 'generator -D_GCC_NULLPTR_T -D_Float16=short -D__bf16=short -mlong-double-64 --package-name libsqlite3 --prefix-enumerator=_ --prefix-external=x_ --prefix-field=F --prefix-static-internal=_ --prefix-static-none=_ --prefix-tagged-enum=_ --prefix-tagged-struct=T --prefix-tagged-union=T --prefix-typename=T --prefix-undefined=_ -ignore-unsupported-alignment -ignore-link-errors -import=sync -DHAVE_USLEEP -DLONGDOUBLE_TYPE=double -DNDEBUG -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DISABLE_INTRINSIC -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_GEOPOLY -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_RBU -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_SNAPSHOT -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_HAVE_ZLIB=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_SOUNDEX -DSQLITE_THREADSAFE=1 -DSQLITE_WITHOUT_ZONEMALLOC -D_LARGEFILE64_SOURCE -I /Users/jnml/src/modernc.org/builder/.exclude/modernc.org/libc/include/darwin/amd64 -I /Users/jnml/src/modernc.org/builder/.exclude/modernc.org/libz/include/darwin/amd64 -I /Users/jnml/src/modernc.org/builder/.exclude/modernc.org/libtcl8.6/include/darwin/amd64 -extended-errors -o sqlite3.go sqlite3.c -DSQLITE_MUTEX_NOOP -DSQLITE_OS_UNIX=1 -eval-all-macros', DO NOT EDIT.
|
||||
|
||||
//go:build darwin && amd64
|
||||
|
||||
package sqlite3
|
||||
|
||||
const FP_CHOP = 3
|
||||
|
||||
const FP_PREC_24B = 0
|
||||
|
||||
const FP_PREC_53B = 2
|
||||
|
||||
const FP_PREC_64B = 3
|
||||
|
||||
const FP_RND_DOWN = 1
|
||||
|
||||
const FP_RND_NEAR = 0
|
||||
|
||||
const FP_RND_UP = 2
|
||||
|
||||
const FP_STATE_BYTES = 512
|
||||
|
||||
const MAXPHYS = 131072
|
||||
|
||||
const MAXPHYSIO = 131072
|
||||
|
||||
const NMBCLUSTERS = 512
|
||||
|
||||
const TARGET_ABI_USES_IOS_VALUES = 0
|
||||
|
||||
const TARGET_CPU_ARM64 = 0
|
||||
|
||||
const TARGET_CPU_X86_64 = 1
|
||||
|
||||
const TARGET_OS_ARROW = 0
|
||||
|
||||
type Tboolean_t = uint32
|
||||
|
||||
type Tstat64 = struct {
|
||||
Fst_dev Tdev_t
|
||||
Fst_mode Tmode_t
|
||||
Fst_nlink Tnlink_t
|
||||
Fst_ino t__darwin_ino64_t
|
||||
Fst_uid Tuid_t
|
||||
Fst_gid Tgid_t
|
||||
Fst_rdev Tdev_t
|
||||
Fst_atimespec Ttimespec
|
||||
Fst_mtimespec Ttimespec
|
||||
Fst_ctimespec Ttimespec
|
||||
Fst_birthtimespec Ttimespec
|
||||
Fst_size Toff_t
|
||||
Fst_blocks Tblkcnt_t
|
||||
Fst_blksize Tblksize_t
|
||||
Fst_flags t__uint32_t
|
||||
Fst_gen t__uint32_t
|
||||
Fst_lspare t__int32_t
|
||||
Fst_qspare [2]t__int64_t
|
||||
}
|
||||
|
||||
type Tstatfs64 = struct {
|
||||
Ff_bsize Tuint32_t
|
||||
Ff_iosize Tint32_t
|
||||
Ff_blocks Tuint64_t
|
||||
Ff_bfree Tuint64_t
|
||||
Ff_bavail Tuint64_t
|
||||
Ff_files Tuint64_t
|
||||
Ff_ffree Tuint64_t
|
||||
Ff_fsid Tfsid_t
|
||||
Ff_owner Tuid_t
|
||||
Ff_type Tuint32_t
|
||||
Ff_flags Tuint32_t
|
||||
Ff_fssubtype Tuint32_t
|
||||
Ff_fstypename [16]int8
|
||||
Ff_mntonname [1024]int8
|
||||
Ff_mntfromname [1024]int8
|
||||
Ff_flags_ext Tuint32_t
|
||||
Ff_reserved [7]Tuint32_t
|
||||
}
|
||||
|
||||
const _I386_SIGNAL_H_ = 1
|
||||
|
||||
const _X86_INSTRUCTION_STATE_CACHELINE_SIZE = 64
|
||||
|
||||
const _X86_INSTRUCTION_STATE_MAX_INSN_BYTES = 2380
|
||||
|
||||
const __DARWIN_ONLY_64_BIT_INO_T = 0
|
||||
|
||||
const __DARWIN_ONLY_VERS_1050 = 0
|
||||
|
||||
const __DARWIN_SUF_1050 = "$1050"
|
||||
|
||||
const __DARWIN_SUF_64_BIT_INO_T = "$INODE64"
|
||||
|
||||
const __LASTBRANCH_MAX = 32
|
||||
|
||||
const __SSE3__ = 1
|
||||
|
||||
const __SSE4_1__ = 1
|
||||
|
||||
const __SSSE3__ = 1
|
||||
|
||||
const __core2 = 1
|
||||
|
||||
const __core2__ = 1
|
||||
|
||||
const __tune_core2__ = 1
|
||||
|
||||
type stat64 = Tstat64
|
||||
|
||||
type statfs64 = Tstatfs64
|
||||
|
||||
type t__darwin_fp_control = struct {
|
||||
F__ccgo0 uint16
|
||||
}
|
||||
|
||||
type t__darwin_fp_control_t = struct {
|
||||
F__ccgo0 uint16
|
||||
}
|
||||
|
||||
type t__darwin_fp_status = struct {
|
||||
F__ccgo0 uint16
|
||||
}
|
||||
|
||||
type t__darwin_fp_status_t = struct {
|
||||
F__ccgo0 uint16
|
||||
}
|
||||
|
||||
type t__darwin_i386_avx512_state = struct {
|
||||
F__fpu_reserved [2]int32
|
||||
F__fpu_fcw t__darwin_fp_control
|
||||
F__fpu_fsw t__darwin_fp_status
|
||||
F__fpu_ftw t__uint8_t
|
||||
F__fpu_rsrv1 t__uint8_t
|
||||
F__fpu_fop t__uint16_t
|
||||
F__fpu_ip t__uint32_t
|
||||
F__fpu_cs t__uint16_t
|
||||
F__fpu_rsrv2 t__uint16_t
|
||||
F__fpu_dp t__uint32_t
|
||||
F__fpu_ds t__uint16_t
|
||||
F__fpu_rsrv3 t__uint16_t
|
||||
F__fpu_mxcsr t__uint32_t
|
||||
F__fpu_mxcsrmask t__uint32_t
|
||||
F__fpu_stmm0 t__darwin_mmst_reg
|
||||
F__fpu_stmm1 t__darwin_mmst_reg
|
||||
F__fpu_stmm2 t__darwin_mmst_reg
|
||||
F__fpu_stmm3 t__darwin_mmst_reg
|
||||
F__fpu_stmm4 t__darwin_mmst_reg
|
||||
F__fpu_stmm5 t__darwin_mmst_reg
|
||||
F__fpu_stmm6 t__darwin_mmst_reg
|
||||
F__fpu_stmm7 t__darwin_mmst_reg
|
||||
F__fpu_xmm0 t__darwin_xmm_reg
|
||||
F__fpu_xmm1 t__darwin_xmm_reg
|
||||
F__fpu_xmm2 t__darwin_xmm_reg
|
||||
F__fpu_xmm3 t__darwin_xmm_reg
|
||||
F__fpu_xmm4 t__darwin_xmm_reg
|
||||
F__fpu_xmm5 t__darwin_xmm_reg
|
||||
F__fpu_xmm6 t__darwin_xmm_reg
|
||||
F__fpu_xmm7 t__darwin_xmm_reg
|
||||
F__fpu_rsrv4 [224]int8
|
||||
F__fpu_reserved1 int32
|
||||
F__avx_reserved1 [64]int8
|
||||
F__fpu_ymmh0 t__darwin_xmm_reg
|
||||
F__fpu_ymmh1 t__darwin_xmm_reg
|
||||
F__fpu_ymmh2 t__darwin_xmm_reg
|
||||
F__fpu_ymmh3 t__darwin_xmm_reg
|
||||
F__fpu_ymmh4 t__darwin_xmm_reg
|
||||
F__fpu_ymmh5 t__darwin_xmm_reg
|
||||
F__fpu_ymmh6 t__darwin_xmm_reg
|
||||
F__fpu_ymmh7 t__darwin_xmm_reg
|
||||
F__fpu_k0 t__darwin_opmask_reg
|
||||
F__fpu_k1 t__darwin_opmask_reg
|
||||
F__fpu_k2 t__darwin_opmask_reg
|
||||
F__fpu_k3 t__darwin_opmask_reg
|
||||
F__fpu_k4 t__darwin_opmask_reg
|
||||
F__fpu_k5 t__darwin_opmask_reg
|
||||
F__fpu_k6 t__darwin_opmask_reg
|
||||
F__fpu_k7 t__darwin_opmask_reg
|
||||
F__fpu_zmmh0 t__darwin_ymm_reg
|
||||
F__fpu_zmmh1 t__darwin_ymm_reg
|
||||
F__fpu_zmmh2 t__darwin_ymm_reg
|
||||
F__fpu_zmmh3 t__darwin_ymm_reg
|
||||
F__fpu_zmmh4 t__darwin_ymm_reg
|
||||
F__fpu_zmmh5 t__darwin_ymm_reg
|
||||
F__fpu_zmmh6 t__darwin_ymm_reg
|
||||
F__fpu_zmmh7 t__darwin_ymm_reg
|
||||
}
|
||||
|
||||
type t__darwin_i386_avx_state = struct {
|
||||
F__fpu_reserved [2]int32
|
||||
F__fpu_fcw t__darwin_fp_control
|
||||
F__fpu_fsw t__darwin_fp_status
|
||||
F__fpu_ftw t__uint8_t
|
||||
F__fpu_rsrv1 t__uint8_t
|
||||
F__fpu_fop t__uint16_t
|
||||
F__fpu_ip t__uint32_t
|
||||
F__fpu_cs t__uint16_t
|
||||
F__fpu_rsrv2 t__uint16_t
|
||||
F__fpu_dp t__uint32_t
|
||||
F__fpu_ds t__uint16_t
|
||||
F__fpu_rsrv3 t__uint16_t
|
||||
F__fpu_mxcsr t__uint32_t
|
||||
F__fpu_mxcsrmask t__uint32_t
|
||||
F__fpu_stmm0 t__darwin_mmst_reg
|
||||
F__fpu_stmm1 t__darwin_mmst_reg
|
||||
F__fpu_stmm2 t__darwin_mmst_reg
|
||||
F__fpu_stmm3 t__darwin_mmst_reg
|
||||
F__fpu_stmm4 t__darwin_mmst_reg
|
||||
F__fpu_stmm5 t__darwin_mmst_reg
|
||||
F__fpu_stmm6 t__darwin_mmst_reg
|
||||
F__fpu_stmm7 t__darwin_mmst_reg
|
||||
F__fpu_xmm0 t__darwin_xmm_reg
|
||||
F__fpu_xmm1 t__darwin_xmm_reg
|
||||
F__fpu_xmm2 t__darwin_xmm_reg
|
||||
F__fpu_xmm3 t__darwin_xmm_reg
|
||||
F__fpu_xmm4 t__darwin_xmm_reg
|
||||
F__fpu_xmm5 t__darwin_xmm_reg
|
||||
F__fpu_xmm6 t__darwin_xmm_reg
|
||||
F__fpu_xmm7 t__darwin_xmm_reg
|
||||
F__fpu_rsrv4 [224]int8
|
||||
F__fpu_reserved1 int32
|
||||
F__avx_reserved1 [64]int8
|
||||
F__fpu_ymmh0 t__darwin_xmm_reg
|
||||
F__fpu_ymmh1 t__darwin_xmm_reg
|
||||
F__fpu_ymmh2 t__darwin_xmm_reg
|
||||
F__fpu_ymmh3 t__darwin_xmm_reg
|
||||
F__fpu_ymmh4 t__darwin_xmm_reg
|
||||
F__fpu_ymmh5 t__darwin_xmm_reg
|
||||
F__fpu_ymmh6 t__darwin_xmm_reg
|
||||
F__fpu_ymmh7 t__darwin_xmm_reg
|
||||
}
|
||||
|
||||
type t__darwin_i386_exception_state = struct {
|
||||
F__trapno t__uint16_t
|
||||
F__cpu t__uint16_t
|
||||
F__err t__uint32_t
|
||||
F__faultvaddr t__uint32_t
|
||||
}
|
||||
|
||||
type t__darwin_i386_float_state = struct {
|
||||
F__fpu_reserved [2]int32
|
||||
F__fpu_fcw t__darwin_fp_control
|
||||
F__fpu_fsw t__darwin_fp_status
|
||||
F__fpu_ftw t__uint8_t
|
||||
F__fpu_rsrv1 t__uint8_t
|
||||
F__fpu_fop t__uint16_t
|
||||
F__fpu_ip t__uint32_t
|
||||
F__fpu_cs t__uint16_t
|
||||
F__fpu_rsrv2 t__uint16_t
|
||||
F__fpu_dp t__uint32_t
|
||||
F__fpu_ds t__uint16_t
|
||||
F__fpu_rsrv3 t__uint16_t
|
||||
F__fpu_mxcsr t__uint32_t
|
||||
F__fpu_mxcsrmask t__uint32_t
|
||||
F__fpu_stmm0 t__darwin_mmst_reg
|
||||
F__fpu_stmm1 t__darwin_mmst_reg
|
||||
F__fpu_stmm2 t__darwin_mmst_reg
|
||||
F__fpu_stmm3 t__darwin_mmst_reg
|
||||
F__fpu_stmm4 t__darwin_mmst_reg
|
||||
F__fpu_stmm5 t__darwin_mmst_reg
|
||||
F__fpu_stmm6 t__darwin_mmst_reg
|
||||
F__fpu_stmm7 t__darwin_mmst_reg
|
||||
F__fpu_xmm0 t__darwin_xmm_reg
|
||||
F__fpu_xmm1 t__darwin_xmm_reg
|
||||
F__fpu_xmm2 t__darwin_xmm_reg
|
||||
F__fpu_xmm3 t__darwin_xmm_reg
|
||||
F__fpu_xmm4 t__darwin_xmm_reg
|
||||
F__fpu_xmm5 t__darwin_xmm_reg
|
||||
F__fpu_xmm6 t__darwin_xmm_reg
|
||||
F__fpu_xmm7 t__darwin_xmm_reg
|
||||
F__fpu_rsrv4 [224]int8
|
||||
F__fpu_reserved1 int32
|
||||
}
|
||||
|
||||
type t__darwin_i386_thread_state = struct {
|
||||
F__eax uint32
|
||||
F__ebx uint32
|
||||
F__ecx uint32
|
||||
F__edx uint32
|
||||
F__edi uint32
|
||||
F__esi uint32
|
||||
F__ebp uint32
|
||||
F__esp uint32
|
||||
F__ss uint32
|
||||
F__eflags uint32
|
||||
F__eip uint32
|
||||
F__cs uint32
|
||||
F__ds uint32
|
||||
F__es uint32
|
||||
F__fs uint32
|
||||
F__gs uint32
|
||||
}
|
||||
|
||||
type t__darwin_mcontext32 = struct {
|
||||
F__es t__darwin_i386_exception_state
|
||||
F__ss t__darwin_i386_thread_state
|
||||
F__fs t__darwin_i386_float_state
|
||||
}
|
||||
|
||||
type t__darwin_mcontext64 = struct {
|
||||
F__es t__darwin_x86_exception_state64
|
||||
F__ss t__darwin_x86_thread_state64
|
||||
F__fs t__darwin_x86_float_state64
|
||||
}
|
||||
|
||||
type t__darwin_mcontext64_full = struct {
|
||||
F__es t__darwin_x86_exception_state64
|
||||
F__ss t__darwin_x86_thread_full_state64
|
||||
F__fs t__darwin_x86_float_state64
|
||||
}
|
||||
|
||||
type t__darwin_mcontext_avx32 = struct {
|
||||
F__es t__darwin_i386_exception_state
|
||||
F__ss t__darwin_i386_thread_state
|
||||
F__fs t__darwin_i386_avx_state
|
||||
}
|
||||
|
||||
type t__darwin_mcontext_avx512_32 = struct {
|
||||
F__es t__darwin_i386_exception_state
|
||||
F__ss t__darwin_i386_thread_state
|
||||
F__fs t__darwin_i386_avx512_state
|
||||
}
|
||||
|
||||
type t__darwin_mcontext_avx512_64 = struct {
|
||||
F__es t__darwin_x86_exception_state64
|
||||
F__ss t__darwin_x86_thread_state64
|
||||
F__fs t__darwin_x86_avx512_state64
|
||||
}
|
||||
|
||||
type t__darwin_mcontext_avx512_64_full = struct {
|
||||
F__es t__darwin_x86_exception_state64
|
||||
F__ss t__darwin_x86_thread_full_state64
|
||||
F__fs t__darwin_x86_avx512_state64
|
||||
}
|
||||
|
||||
type t__darwin_mcontext_avx64 = struct {
|
||||
F__es t__darwin_x86_exception_state64
|
||||
F__ss t__darwin_x86_thread_state64
|
||||
F__fs t__darwin_x86_avx_state64
|
||||
}
|
||||
|
||||
type t__darwin_mcontext_avx64_full = struct {
|
||||
F__es t__darwin_x86_exception_state64
|
||||
F__ss t__darwin_x86_thread_full_state64
|
||||
F__fs t__darwin_x86_avx_state64
|
||||
}
|
||||
|
||||
type t__darwin_mmst_reg = struct {
|
||||
F__mmst_reg [10]int8
|
||||
F__mmst_rsrv [6]int8
|
||||
}
|
||||
|
||||
type t__darwin_opmask_reg = struct {
|
||||
F__opmask_reg [8]int8
|
||||
}
|
||||
|
||||
type t__darwin_x86_avx512_state64 = struct {
|
||||
F__fpu_reserved [2]int32
|
||||
F__fpu_fcw t__darwin_fp_control
|
||||
F__fpu_fsw t__darwin_fp_status
|
||||
F__fpu_ftw t__uint8_t
|
||||
F__fpu_rsrv1 t__uint8_t
|
||||
F__fpu_fop t__uint16_t
|
||||
F__fpu_ip t__uint32_t
|
||||
F__fpu_cs t__uint16_t
|
||||
F__fpu_rsrv2 t__uint16_t
|
||||
F__fpu_dp t__uint32_t
|
||||
F__fpu_ds t__uint16_t
|
||||
F__fpu_rsrv3 t__uint16_t
|
||||
F__fpu_mxcsr t__uint32_t
|
||||
F__fpu_mxcsrmask t__uint32_t
|
||||
F__fpu_stmm0 t__darwin_mmst_reg
|
||||
F__fpu_stmm1 t__darwin_mmst_reg
|
||||
F__fpu_stmm2 t__darwin_mmst_reg
|
||||
F__fpu_stmm3 t__darwin_mmst_reg
|
||||
F__fpu_stmm4 t__darwin_mmst_reg
|
||||
F__fpu_stmm5 t__darwin_mmst_reg
|
||||
F__fpu_stmm6 t__darwin_mmst_reg
|
||||
F__fpu_stmm7 t__darwin_mmst_reg
|
||||
F__fpu_xmm0 t__darwin_xmm_reg
|
||||
F__fpu_xmm1 t__darwin_xmm_reg
|
||||
F__fpu_xmm2 t__darwin_xmm_reg
|
||||
F__fpu_xmm3 t__darwin_xmm_reg
|
||||
F__fpu_xmm4 t__darwin_xmm_reg
|
||||
F__fpu_xmm5 t__darwin_xmm_reg
|
||||
F__fpu_xmm6 t__darwin_xmm_reg
|
||||
F__fpu_xmm7 t__darwin_xmm_reg
|
||||
F__fpu_xmm8 t__darwin_xmm_reg
|
||||
F__fpu_xmm9 t__darwin_xmm_reg
|
||||
F__fpu_xmm10 t__darwin_xmm_reg
|
||||
F__fpu_xmm11 t__darwin_xmm_reg
|
||||
F__fpu_xmm12 t__darwin_xmm_reg
|
||||
F__fpu_xmm13 t__darwin_xmm_reg
|
||||
F__fpu_xmm14 t__darwin_xmm_reg
|
||||
F__fpu_xmm15 t__darwin_xmm_reg
|
||||
F__fpu_rsrv4 [96]int8
|
||||
F__fpu_reserved1 int32
|
||||
F__avx_reserved1 [64]int8
|
||||
F__fpu_ymmh0 t__darwin_xmm_reg
|
||||
F__fpu_ymmh1 t__darwin_xmm_reg
|
||||
F__fpu_ymmh2 t__darwin_xmm_reg
|
||||
F__fpu_ymmh3 t__darwin_xmm_reg
|
||||
F__fpu_ymmh4 t__darwin_xmm_reg
|
||||
F__fpu_ymmh5 t__darwin_xmm_reg
|
||||
F__fpu_ymmh6 t__darwin_xmm_reg
|
||||
F__fpu_ymmh7 t__darwin_xmm_reg
|
||||
F__fpu_ymmh8 t__darwin_xmm_reg
|
||||
F__fpu_ymmh9 t__darwin_xmm_reg
|
||||
F__fpu_ymmh10 t__darwin_xmm_reg
|
||||
F__fpu_ymmh11 t__darwin_xmm_reg
|
||||
F__fpu_ymmh12 t__darwin_xmm_reg
|
||||
F__fpu_ymmh13 t__darwin_xmm_reg
|
||||
F__fpu_ymmh14 t__darwin_xmm_reg
|
||||
F__fpu_ymmh15 t__darwin_xmm_reg
|
||||
F__fpu_k0 t__darwin_opmask_reg
|
||||
F__fpu_k1 t__darwin_opmask_reg
|
||||
F__fpu_k2 t__darwin_opmask_reg
|
||||
F__fpu_k3 t__darwin_opmask_reg
|
||||
F__fpu_k4 t__darwin_opmask_reg
|
||||
F__fpu_k5 t__darwin_opmask_reg
|
||||
F__fpu_k6 t__darwin_opmask_reg
|
||||
F__fpu_k7 t__darwin_opmask_reg
|
||||
F__fpu_zmmh0 t__darwin_ymm_reg
|
||||
F__fpu_zmmh1 t__darwin_ymm_reg
|
||||
F__fpu_zmmh2 t__darwin_ymm_reg
|
||||
F__fpu_zmmh3 t__darwin_ymm_reg
|
||||
F__fpu_zmmh4 t__darwin_ymm_reg
|
||||
F__fpu_zmmh5 t__darwin_ymm_reg
|
||||
F__fpu_zmmh6 t__darwin_ymm_reg
|
||||
F__fpu_zmmh7 t__darwin_ymm_reg
|
||||
F__fpu_zmmh8 t__darwin_ymm_reg
|
||||
F__fpu_zmmh9 t__darwin_ymm_reg
|
||||
F__fpu_zmmh10 t__darwin_ymm_reg
|
||||
F__fpu_zmmh11 t__darwin_ymm_reg
|
||||
F__fpu_zmmh12 t__darwin_ymm_reg
|
||||
F__fpu_zmmh13 t__darwin_ymm_reg
|
||||
F__fpu_zmmh14 t__darwin_ymm_reg
|
||||
F__fpu_zmmh15 t__darwin_ymm_reg
|
||||
F__fpu_zmm16 t__darwin_zmm_reg
|
||||
F__fpu_zmm17 t__darwin_zmm_reg
|
||||
F__fpu_zmm18 t__darwin_zmm_reg
|
||||
F__fpu_zmm19 t__darwin_zmm_reg
|
||||
F__fpu_zmm20 t__darwin_zmm_reg
|
||||
F__fpu_zmm21 t__darwin_zmm_reg
|
||||
F__fpu_zmm22 t__darwin_zmm_reg
|
||||
F__fpu_zmm23 t__darwin_zmm_reg
|
||||
F__fpu_zmm24 t__darwin_zmm_reg
|
||||
F__fpu_zmm25 t__darwin_zmm_reg
|
||||
F__fpu_zmm26 t__darwin_zmm_reg
|
||||
F__fpu_zmm27 t__darwin_zmm_reg
|
||||
F__fpu_zmm28 t__darwin_zmm_reg
|
||||
F__fpu_zmm29 t__darwin_zmm_reg
|
||||
F__fpu_zmm30 t__darwin_zmm_reg
|
||||
F__fpu_zmm31 t__darwin_zmm_reg
|
||||
}
|
||||
|
||||
type t__darwin_x86_avx_state64 = struct {
|
||||
F__fpu_reserved [2]int32
|
||||
F__fpu_fcw t__darwin_fp_control
|
||||
F__fpu_fsw t__darwin_fp_status
|
||||
F__fpu_ftw t__uint8_t
|
||||
F__fpu_rsrv1 t__uint8_t
|
||||
F__fpu_fop t__uint16_t
|
||||
F__fpu_ip t__uint32_t
|
||||
F__fpu_cs t__uint16_t
|
||||
F__fpu_rsrv2 t__uint16_t
|
||||
F__fpu_dp t__uint32_t
|
||||
F__fpu_ds t__uint16_t
|
||||
F__fpu_rsrv3 t__uint16_t
|
||||
F__fpu_mxcsr t__uint32_t
|
||||
F__fpu_mxcsrmask t__uint32_t
|
||||
F__fpu_stmm0 t__darwin_mmst_reg
|
||||
F__fpu_stmm1 t__darwin_mmst_reg
|
||||
F__fpu_stmm2 t__darwin_mmst_reg
|
||||
F__fpu_stmm3 t__darwin_mmst_reg
|
||||
F__fpu_stmm4 t__darwin_mmst_reg
|
||||
F__fpu_stmm5 t__darwin_mmst_reg
|
||||
F__fpu_stmm6 t__darwin_mmst_reg
|
||||
F__fpu_stmm7 t__darwin_mmst_reg
|
||||
F__fpu_xmm0 t__darwin_xmm_reg
|
||||
F__fpu_xmm1 t__darwin_xmm_reg
|
||||
F__fpu_xmm2 t__darwin_xmm_reg
|
||||
F__fpu_xmm3 t__darwin_xmm_reg
|
||||
F__fpu_xmm4 t__darwin_xmm_reg
|
||||
F__fpu_xmm5 t__darwin_xmm_reg
|
||||
F__fpu_xmm6 t__darwin_xmm_reg
|
||||
F__fpu_xmm7 t__darwin_xmm_reg
|
||||
F__fpu_xmm8 t__darwin_xmm_reg
|
||||
F__fpu_xmm9 t__darwin_xmm_reg
|
||||
F__fpu_xmm10 t__darwin_xmm_reg
|
||||
F__fpu_xmm11 t__darwin_xmm_reg
|
||||
F__fpu_xmm12 t__darwin_xmm_reg
|
||||
F__fpu_xmm13 t__darwin_xmm_reg
|
||||
F__fpu_xmm14 t__darwin_xmm_reg
|
||||
F__fpu_xmm15 t__darwin_xmm_reg
|
||||
F__fpu_rsrv4 [96]int8
|
||||
F__fpu_reserved1 int32
|
||||
F__avx_reserved1 [64]int8
|
||||
F__fpu_ymmh0 t__darwin_xmm_reg
|
||||
F__fpu_ymmh1 t__darwin_xmm_reg
|
||||
F__fpu_ymmh2 t__darwin_xmm_reg
|
||||
F__fpu_ymmh3 t__darwin_xmm_reg
|
||||
F__fpu_ymmh4 t__darwin_xmm_reg
|
||||
F__fpu_ymmh5 t__darwin_xmm_reg
|
||||
F__fpu_ymmh6 t__darwin_xmm_reg
|
||||
F__fpu_ymmh7 t__darwin_xmm_reg
|
||||
F__fpu_ymmh8 t__darwin_xmm_reg
|
||||
F__fpu_ymmh9 t__darwin_xmm_reg
|
||||
F__fpu_ymmh10 t__darwin_xmm_reg
|
||||
F__fpu_ymmh11 t__darwin_xmm_reg
|
||||
F__fpu_ymmh12 t__darwin_xmm_reg
|
||||
F__fpu_ymmh13 t__darwin_xmm_reg
|
||||
F__fpu_ymmh14 t__darwin_xmm_reg
|
||||
F__fpu_ymmh15 t__darwin_xmm_reg
|
||||
}
|
||||
|
||||
type t__darwin_x86_cpmu_state64 = struct {
|
||||
F__ctrs [16]t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_x86_debug_state32 = struct {
|
||||
F__dr0 uint32
|
||||
F__dr1 uint32
|
||||
F__dr2 uint32
|
||||
F__dr3 uint32
|
||||
F__dr4 uint32
|
||||
F__dr5 uint32
|
||||
F__dr6 uint32
|
||||
F__dr7 uint32
|
||||
}
|
||||
|
||||
type t__darwin_x86_debug_state64 = struct {
|
||||
F__dr0 t__uint64_t
|
||||
F__dr1 t__uint64_t
|
||||
F__dr2 t__uint64_t
|
||||
F__dr3 t__uint64_t
|
||||
F__dr4 t__uint64_t
|
||||
F__dr5 t__uint64_t
|
||||
F__dr6 t__uint64_t
|
||||
F__dr7 t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_x86_exception_state64 = struct {
|
||||
F__trapno t__uint16_t
|
||||
F__cpu t__uint16_t
|
||||
F__err t__uint32_t
|
||||
F__faultvaddr t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_x86_float_state64 = struct {
|
||||
F__fpu_reserved [2]int32
|
||||
F__fpu_fcw t__darwin_fp_control
|
||||
F__fpu_fsw t__darwin_fp_status
|
||||
F__fpu_ftw t__uint8_t
|
||||
F__fpu_rsrv1 t__uint8_t
|
||||
F__fpu_fop t__uint16_t
|
||||
F__fpu_ip t__uint32_t
|
||||
F__fpu_cs t__uint16_t
|
||||
F__fpu_rsrv2 t__uint16_t
|
||||
F__fpu_dp t__uint32_t
|
||||
F__fpu_ds t__uint16_t
|
||||
F__fpu_rsrv3 t__uint16_t
|
||||
F__fpu_mxcsr t__uint32_t
|
||||
F__fpu_mxcsrmask t__uint32_t
|
||||
F__fpu_stmm0 t__darwin_mmst_reg
|
||||
F__fpu_stmm1 t__darwin_mmst_reg
|
||||
F__fpu_stmm2 t__darwin_mmst_reg
|
||||
F__fpu_stmm3 t__darwin_mmst_reg
|
||||
F__fpu_stmm4 t__darwin_mmst_reg
|
||||
F__fpu_stmm5 t__darwin_mmst_reg
|
||||
F__fpu_stmm6 t__darwin_mmst_reg
|
||||
F__fpu_stmm7 t__darwin_mmst_reg
|
||||
F__fpu_xmm0 t__darwin_xmm_reg
|
||||
F__fpu_xmm1 t__darwin_xmm_reg
|
||||
F__fpu_xmm2 t__darwin_xmm_reg
|
||||
F__fpu_xmm3 t__darwin_xmm_reg
|
||||
F__fpu_xmm4 t__darwin_xmm_reg
|
||||
F__fpu_xmm5 t__darwin_xmm_reg
|
||||
F__fpu_xmm6 t__darwin_xmm_reg
|
||||
F__fpu_xmm7 t__darwin_xmm_reg
|
||||
F__fpu_xmm8 t__darwin_xmm_reg
|
||||
F__fpu_xmm9 t__darwin_xmm_reg
|
||||
F__fpu_xmm10 t__darwin_xmm_reg
|
||||
F__fpu_xmm11 t__darwin_xmm_reg
|
||||
F__fpu_xmm12 t__darwin_xmm_reg
|
||||
F__fpu_xmm13 t__darwin_xmm_reg
|
||||
F__fpu_xmm14 t__darwin_xmm_reg
|
||||
F__fpu_xmm15 t__darwin_xmm_reg
|
||||
F__fpu_rsrv4 [96]int8
|
||||
F__fpu_reserved1 int32
|
||||
}
|
||||
|
||||
type t__darwin_x86_thread_full_state64 = struct {
|
||||
F__ss64 t__darwin_x86_thread_state64
|
||||
F__ds t__uint64_t
|
||||
F__es t__uint64_t
|
||||
F__ss t__uint64_t
|
||||
F__gsbase t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_x86_thread_state64 = struct {
|
||||
F__rax t__uint64_t
|
||||
F__rbx t__uint64_t
|
||||
F__rcx t__uint64_t
|
||||
F__rdx t__uint64_t
|
||||
F__rdi t__uint64_t
|
||||
F__rsi t__uint64_t
|
||||
F__rbp t__uint64_t
|
||||
F__rsp t__uint64_t
|
||||
F__r8 t__uint64_t
|
||||
F__r9 t__uint64_t
|
||||
F__r10 t__uint64_t
|
||||
F__r11 t__uint64_t
|
||||
F__r12 t__uint64_t
|
||||
F__r13 t__uint64_t
|
||||
F__r14 t__uint64_t
|
||||
F__r15 t__uint64_t
|
||||
F__rip t__uint64_t
|
||||
F__rflags t__uint64_t
|
||||
F__cs t__uint64_t
|
||||
F__fs t__uint64_t
|
||||
F__gs t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_xmm_reg = struct {
|
||||
F__xmm_reg [16]int8
|
||||
}
|
||||
|
||||
type t__darwin_ymm_reg = struct {
|
||||
F__ymm_reg [32]int8
|
||||
}
|
||||
|
||||
type t__darwin_zmm_reg = struct {
|
||||
F__zmm_reg [64]int8
|
||||
}
|
||||
|
||||
type t__last_branch_record = struct {
|
||||
F__from_ip t__uint64_t
|
||||
F__to_ip t__uint64_t
|
||||
F__ccgo16 uint32
|
||||
}
|
||||
|
||||
type t__last_branch_state = struct {
|
||||
F__lbr_count int32
|
||||
F__ccgo4 uint32
|
||||
F__lbrs [32]t__last_branch_record
|
||||
}
|
||||
|
||||
type t__x86_instruction_state = struct {
|
||||
F__insn_stream_valid_bytes int32
|
||||
F__insn_offset int32
|
||||
F__out_of_synch int32
|
||||
F__insn_bytes [2380]t__uint8_t
|
||||
F__insn_cacheline [64]t__uint8_t
|
||||
}
|
||||
|
||||
type t__x86_pagein_state = struct {
|
||||
F__pagein_error int32
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
// Code generated for darwin/arm64 by 'generator -D_GCC_NULLPTR_T -D_Float16=short -D__bf16=short --package-name libsqlite3 --prefix-enumerator=_ --prefix-external=x_ --prefix-field=F --prefix-static-internal=_ --prefix-static-none=_ --prefix-tagged-enum=_ --prefix-tagged-struct=T --prefix-tagged-union=T --prefix-typename=T --prefix-undefined=_ -ignore-unsupported-alignment -ignore-link-errors -import=sync -DHAVE_USLEEP -DLONGDOUBLE_TYPE=double -DNDEBUG -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DISABLE_INTRINSIC -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_GEOPOLY -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_RBU -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_SNAPSHOT -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_HAVE_ZLIB=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_SOUNDEX -DSQLITE_THREADSAFE=1 -DSQLITE_WITHOUT_ZONEMALLOC -D_LARGEFILE64_SOURCE -I /Users/jnml/src/modernc.org/builder/.exclude/modernc.org/libc/include/darwin/arm64 -I /Users/jnml/src/modernc.org/builder/.exclude/modernc.org/libz/include/darwin/arm64 -I /Users/jnml/src/modernc.org/builder/.exclude/modernc.org/libtcl8.6/include/darwin/arm64 -extended-errors -o sqlite3.go sqlite3.c -DSQLITE_MUTEX_NOOP -DSQLITE_OS_UNIX=1 -eval-all-macros', DO NOT EDIT.
|
||||
|
||||
//go:build darwin && arm64
|
||||
|
||||
package sqlite3
|
||||
|
||||
const MAXPHYS = 65536
|
||||
|
||||
const MAXPHYSIO = 65536
|
||||
|
||||
const NMBCLUSTERS = 0
|
||||
|
||||
const TARGET_ABI_USES_IOS_VALUES = 1
|
||||
|
||||
const TARGET_CPU_ARM64 = 1
|
||||
|
||||
const TARGET_CPU_X86_64 = 0
|
||||
|
||||
const TARGET_OS_ARROW = 1
|
||||
|
||||
type Tboolean_t = int32
|
||||
|
||||
type Tvm32_address_t = uint32
|
||||
|
||||
type Tvm32_offset_t = uint32
|
||||
|
||||
type Tvm32_size_t = uint32
|
||||
|
||||
const _ARM_SIGNAL_ = 1
|
||||
|
||||
const _DARWIN_FEATURE_ONLY_64_BIT_INODE = 1
|
||||
|
||||
const _DARWIN_FEATURE_ONLY_VERS_1050 = 1
|
||||
|
||||
const __AARCH64_SIMD__ = 1
|
||||
|
||||
const __ARM64_ARCH_8__ = 1
|
||||
|
||||
const __ARM_ACLE = 202420
|
||||
|
||||
const __ARM_ARCH_8_2__ = 1
|
||||
|
||||
const __ARM_ARCH_8_3__ = 1
|
||||
|
||||
const __ARM_ARCH_8_4__ = 1
|
||||
|
||||
const __ARM_ARCH_8_5__ = 1
|
||||
|
||||
const __ARM_FEATURE_AES = 1
|
||||
|
||||
const __ARM_FEATURE_ATOMICS = 1
|
||||
|
||||
const __ARM_FEATURE_BTI = 1
|
||||
|
||||
const __ARM_FEATURE_COMPLEX = 1
|
||||
|
||||
const __ARM_FEATURE_CRC32 = 1
|
||||
|
||||
const __ARM_FEATURE_CRYPTO = 1
|
||||
|
||||
const __ARM_FEATURE_DOTPROD = 1
|
||||
|
||||
const __ARM_FEATURE_FP16_FML = 1
|
||||
|
||||
const __ARM_FEATURE_FP16_SCALAR_ARITHMETIC = 1
|
||||
|
||||
const __ARM_FEATURE_FP16_VECTOR_ARITHMETIC = 1
|
||||
|
||||
const __ARM_FEATURE_FRINT = 1
|
||||
|
||||
const __ARM_FEATURE_JCVT = 1
|
||||
|
||||
const __ARM_FEATURE_PAUTH = 1
|
||||
|
||||
const __ARM_FEATURE_QRDMX = 1
|
||||
|
||||
const __ARM_FEATURE_RCPC = 1
|
||||
|
||||
const __ARM_FEATURE_SHA2 = 1
|
||||
|
||||
const __ARM_FEATURE_SHA3 = 1
|
||||
|
||||
const __ARM_FEATURE_SHA512 = 1
|
||||
|
||||
const __ARM_NEON_SVE_BRIDGE = 1
|
||||
|
||||
const __DARWIN_ONLY_64_BIT_INO_T = 1
|
||||
|
||||
const __DARWIN_ONLY_VERS_1050 = 1
|
||||
|
||||
const __DARWIN_OPAQUE_ARM_THREAD_STATE64 = 0
|
||||
|
||||
const __FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL = 202430
|
||||
|
||||
const __OBJC_BOOL_IS_BOOL = 1
|
||||
|
||||
const __arm64 = 1
|
||||
|
||||
const __arm64__ = 1
|
||||
|
||||
type t__arm_legacy_debug_state = struct {
|
||||
F__bvr [16]t__uint32_t
|
||||
F__bcr [16]t__uint32_t
|
||||
F__wvr [16]t__uint32_t
|
||||
F__wcr [16]t__uint32_t
|
||||
}
|
||||
|
||||
type t__arm_pagein_state = struct {
|
||||
F__pagein_error int32
|
||||
}
|
||||
|
||||
type t__darwin_arm_cpmu_state64 = struct {
|
||||
F__ctrs [16]t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_debug_state32 = struct {
|
||||
F__bvr [16]t__uint32_t
|
||||
F__bcr [16]t__uint32_t
|
||||
F__wvr [16]t__uint32_t
|
||||
F__wcr [16]t__uint32_t
|
||||
F__mdscr_el1 t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_debug_state64 = struct {
|
||||
F__bvr [16]t__uint64_t
|
||||
F__bcr [16]t__uint64_t
|
||||
F__wvr [16]t__uint64_t
|
||||
F__wcr [16]t__uint64_t
|
||||
F__mdscr_el1 t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_exception_state = struct {
|
||||
F__exception t__uint32_t
|
||||
F__fsr t__uint32_t
|
||||
F__far t__uint32_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_exception_state64 = struct {
|
||||
F__far t__uint64_t
|
||||
F__esr t__uint32_t
|
||||
F__exception t__uint32_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_exception_state64_v2 = struct {
|
||||
F__far t__uint64_t
|
||||
F__esr t__uint64_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_neon_state = struct {
|
||||
F__ccgo_align [0]uint64
|
||||
F__v [16][2]uint64
|
||||
F__fpsr t__uint32_t
|
||||
F__fpcr t__uint32_t
|
||||
F__ccgo_pad3 [8]byte
|
||||
}
|
||||
|
||||
type t__darwin_arm_neon_state64 = struct {
|
||||
F__ccgo_align [0]uint64
|
||||
F__v [32][2]uint64
|
||||
F__fpsr t__uint32_t
|
||||
F__fpcr t__uint32_t
|
||||
F__ccgo_pad3 [8]byte
|
||||
}
|
||||
|
||||
type t__darwin_arm_sme2_state = struct {
|
||||
F__ccgo_align [0]uint32
|
||||
F__zt0 [64]int8
|
||||
}
|
||||
|
||||
type t__darwin_arm_sme_state = struct {
|
||||
F__svcr t__uint64_t
|
||||
F__tpidr2_el0 t__uint64_t
|
||||
F__svl_b t__uint16_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_sme_za_state = struct {
|
||||
F__ccgo_align [0]uint32
|
||||
F__za [4096]int8
|
||||
}
|
||||
|
||||
type t__darwin_arm_sve_p_state = struct {
|
||||
F__ccgo_align [0]uint32
|
||||
F__p [16][32]int8
|
||||
}
|
||||
|
||||
type t__darwin_arm_sve_z_state = struct {
|
||||
F__ccgo_align [0]uint32
|
||||
F__z [16][256]int8
|
||||
}
|
||||
|
||||
type t__darwin_arm_thread_state = struct {
|
||||
F__r [13]t__uint32_t
|
||||
F__sp t__uint32_t
|
||||
F__lr t__uint32_t
|
||||
F__pc t__uint32_t
|
||||
F__cpsr t__uint32_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_thread_state64 = struct {
|
||||
F__x [29]t__uint64_t
|
||||
F__fp t__uint64_t
|
||||
F__lr t__uint64_t
|
||||
F__sp t__uint64_t
|
||||
F__pc t__uint64_t
|
||||
F__cpsr t__uint32_t
|
||||
F__pad t__uint32_t
|
||||
}
|
||||
|
||||
type t__darwin_arm_vfp_state = struct {
|
||||
F__r [64]t__uint32_t
|
||||
F__fpscr t__uint32_t
|
||||
}
|
||||
|
||||
type t__darwin_mcontext32 = struct {
|
||||
F__es t__darwin_arm_exception_state
|
||||
F__ss t__darwin_arm_thread_state
|
||||
F__fs t__darwin_arm_vfp_state
|
||||
}
|
||||
|
||||
type t__darwin_mcontext64 = struct {
|
||||
F__ccgo_align [0]uint64
|
||||
F__es t__darwin_arm_exception_state64
|
||||
F__ss t__darwin_arm_thread_state64
|
||||
F__ns t__darwin_arm_neon_state64
|
||||
}
|
||||
|
||||
type vm32_address_t = Tvm32_address_t
|
||||
|
||||
type vm32_offset_t = Tvm32_offset_t
|
||||
|
||||
type vm32_size_t = Tvm32_size_t
|
||||
+41343
File diff suppressed because it is too large
Load Diff
+29598
File diff suppressed because it is too large
Load Diff
+41294
File diff suppressed because it is too large
Load Diff
+31371
File diff suppressed because it is too large
Load Diff
+106224
File diff suppressed because one or more lines are too long
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && 386)
|
||||
|
||||
package sqlite3
|
||||
|
||||
type Trune_t = int32
|
||||
|
||||
type rune_t = Trune_t
|
||||
+658
@@ -0,0 +1,658 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && amd64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Execute SQL code. Return one of the SQLITE_ success/failure
|
||||
// ** codes. Also write an error message into memory obtained from
|
||||
// ** malloc() and make *pzErrMsg point to that message.
|
||||
// **
|
||||
// ** If the SQL is a query, then for each row in the query result
|
||||
// ** the xCallback() function is called. pArg becomes the first
|
||||
// ** argument to xCallback(). If xCallback=NULL then no callback
|
||||
// ** is invoked, even for queries.
|
||||
// */
|
||||
func Xsqlite3_exec(tls *libc.TLS, db uintptr, zSql uintptr, __ccgo_fp_xCallback Tsqlite3_callback, pArg uintptr, pzErrMsg uintptr) (r int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var azCols, azVals uintptr
|
||||
var callbackIsInit, i, nCol, rc int32
|
||||
var _ /* pStmt at bp+8 */ uintptr
|
||||
var _ /* zLeftover at bp+0 */ uintptr
|
||||
_, _, _, _, _, _ = azCols, azVals, callbackIsInit, i, nCol, rc
|
||||
rc = SQLITE_OK /* Tail of unprocessed SQL */
|
||||
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0) /* The current SQL statement */
|
||||
azCols = uintptr(0) /* True if callback data is initialized */
|
||||
if !(_sqlite3SafetyCheckOk(tls, db) != 0) {
|
||||
return _sqlite3MisuseError(tls, int32(142492))
|
||||
}
|
||||
if zSql == uintptr(0) {
|
||||
zSql = __ccgo_ts + 1702
|
||||
}
|
||||
Xsqlite3_mutex_enter(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
||||
_sqlite3Error(tls, db, SQLITE_OK)
|
||||
for rc == SQLITE_OK && **(**int8)(__ccgo_up(zSql)) != 0 {
|
||||
nCol = 0
|
||||
azVals = uintptr(0)
|
||||
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
||||
rc = Xsqlite3_prepare_v2(tls, db, zSql, -int32(1), bp+8, bp)
|
||||
if rc != SQLITE_OK {
|
||||
continue
|
||||
}
|
||||
if !(**(**uintptr)(__ccgo_up(bp + 8)) != 0) {
|
||||
/* this happens for a comment or white-space */
|
||||
zSql = **(**uintptr)(__ccgo_up(bp))
|
||||
continue
|
||||
}
|
||||
callbackIsInit = 0
|
||||
for int32(1) != 0 {
|
||||
rc = Xsqlite3_step(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
||||
/* Invoke the callback function if required */
|
||||
if __ccgo_fp_xCallback != 0 && (int32(SQLITE_ROW) == rc || int32(SQLITE_DONE) == rc && !(callbackIsInit != 0) && (*Tsqlite3)(unsafe.Pointer(db)).Fflags&uint64(SQLITE_NullCallback) != 0) {
|
||||
if !(callbackIsInit != 0) {
|
||||
nCol = Xsqlite3_column_count(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
||||
azCols = _sqlite3DbMallocRaw(tls, db, uint64(libc.Uint64FromInt32(libc.Int32FromInt32(2)*nCol+libc.Int32FromInt32(1))*uint64(8)))
|
||||
if azCols == uintptr(0) {
|
||||
goto exec_out
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(i < nCol) {
|
||||
break
|
||||
}
|
||||
**(**uintptr)(__ccgo_up(azCols + uintptr(i)*8)) = Xsqlite3_column_name(tls, **(**uintptr)(__ccgo_up(bp + 8)), i)
|
||||
/* sqlite3VdbeSetColName() installs column names as UTF8
|
||||
** strings so there is no way for sqlite3_column_name() to fail. */
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
callbackIsInit = int32(1)
|
||||
}
|
||||
if rc == int32(SQLITE_ROW) {
|
||||
azVals = azCols + uintptr(nCol)*8
|
||||
i = 0
|
||||
for {
|
||||
if !(i < nCol) {
|
||||
break
|
||||
}
|
||||
**(**uintptr)(__ccgo_up(azVals + uintptr(i)*8)) = Xsqlite3_column_text(tls, **(**uintptr)(__ccgo_up(bp + 8)), i)
|
||||
if !(**(**uintptr)(__ccgo_up(azVals + uintptr(i)*8)) != 0) && Xsqlite3_column_type(tls, **(**uintptr)(__ccgo_up(bp + 8)), i) != int32(SQLITE_NULL) {
|
||||
_sqlite3OomFault(tls, db)
|
||||
goto exec_out
|
||||
}
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
**(**uintptr)(__ccgo_up(azVals + uintptr(i)*8)) = uintptr(0)
|
||||
}
|
||||
if (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{__ccgo_fp_xCallback})))(tls, pArg, nCol, azVals, azCols) != 0 {
|
||||
/* EVIDENCE-OF: R-38229-40159 If the callback function to
|
||||
** sqlite3_exec() returns non-zero, then sqlite3_exec() will
|
||||
** return SQLITE_ABORT. */
|
||||
rc = int32(SQLITE_ABORT)
|
||||
_sqlite3VdbeFinalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
||||
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
||||
_sqlite3Error(tls, db, int32(SQLITE_ABORT))
|
||||
goto exec_out
|
||||
}
|
||||
}
|
||||
if rc != int32(SQLITE_ROW) {
|
||||
rc = _sqlite3VdbeFinalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
||||
**(**uintptr)(__ccgo_up(bp + 8)) = uintptr(0)
|
||||
zSql = **(**uintptr)(__ccgo_up(bp))
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zSql)))])&int32(0x01) != 0 {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
_sqlite3DbFree(tls, db, azCols)
|
||||
azCols = uintptr(0)
|
||||
}
|
||||
goto exec_out
|
||||
exec_out:
|
||||
;
|
||||
if **(**uintptr)(__ccgo_up(bp + 8)) != 0 {
|
||||
_sqlite3VdbeFinalize(tls, **(**uintptr)(__ccgo_up(bp + 8)))
|
||||
}
|
||||
_sqlite3DbFree(tls, db, azCols)
|
||||
rc = _sqlite3ApiExit(tls, db, rc)
|
||||
if rc != SQLITE_OK && pzErrMsg != 0 {
|
||||
**(**uintptr)(__ccgo_up(pzErrMsg)) = _sqlite3DbStrDup(tls, uintptr(0), Xsqlite3_errmsg(tls, db))
|
||||
if **(**uintptr)(__ccgo_up(pzErrMsg)) == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
_sqlite3Error(tls, db, int32(SQLITE_NOMEM))
|
||||
}
|
||||
} else {
|
||||
if pzErrMsg != 0 {
|
||||
**(**uintptr)(__ccgo_up(pzErrMsg)) = uintptr(0)
|
||||
}
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, (*Tsqlite3)(unsafe.Pointer(db)).Fmutex)
|
||||
return rc
|
||||
}
|
||||
|
||||
func _fts5ConfigSkipLiteral(tls *libc.TLS, pIn uintptr) (r uintptr) {
|
||||
var p uintptr
|
||||
_ = p
|
||||
p = pIn
|
||||
switch int32(**(**int8)(__ccgo_up(p))) {
|
||||
case int32('n'):
|
||||
fallthrough
|
||||
case int32('N'):
|
||||
if Xsqlite3_strnicmp(tls, __ccgo_ts+1688, p, int32(4)) == 0 {
|
||||
p = p + 4
|
||||
} else {
|
||||
p = uintptr(0)
|
||||
}
|
||||
case int32('x'):
|
||||
fallthrough
|
||||
case int32('X'):
|
||||
p = p + 1
|
||||
if int32(**(**int8)(__ccgo_up(p))) == int32('\'') {
|
||||
p = p + 1
|
||||
for int32(**(**int8)(__ccgo_up(p))) >= int32('a') && int32(**(**int8)(__ccgo_up(p))) <= int32('f') || int32(**(**int8)(__ccgo_up(p))) >= int32('A') && int32(**(**int8)(__ccgo_up(p))) <= int32('F') || int32(**(**int8)(__ccgo_up(p))) >= int32('0') && int32(**(**int8)(__ccgo_up(p))) <= int32('9') {
|
||||
p = p + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(p))) == int32('\'') && 0 == (int64(p)-int64(pIn))%int64(2) {
|
||||
p = p + 1
|
||||
} else {
|
||||
p = uintptr(0)
|
||||
}
|
||||
} else {
|
||||
p = uintptr(0)
|
||||
}
|
||||
case int32('\''):
|
||||
p = p + 1
|
||||
for p != 0 {
|
||||
if int32(**(**int8)(__ccgo_up(p))) == int32('\'') {
|
||||
p = p + 1
|
||||
if int32(**(**int8)(__ccgo_up(p))) != int32('\'') {
|
||||
break
|
||||
}
|
||||
}
|
||||
p = p + 1
|
||||
if int32(**(**int8)(__ccgo_up(p))) == 0 {
|
||||
p = uintptr(0)
|
||||
}
|
||||
}
|
||||
default:
|
||||
/* maybe a number */
|
||||
if int32(**(**int8)(__ccgo_up(p))) == int32('+') || int32(**(**int8)(__ccgo_up(p))) == int32('-') {
|
||||
p = p + 1
|
||||
}
|
||||
for _fts5_isdigit(tls, **(**int8)(__ccgo_up(p))) != 0 {
|
||||
p = p + 1
|
||||
}
|
||||
/* At this point, if the literal was an integer, the parse is
|
||||
** finished. Or, if it is a floating point value, it may continue
|
||||
** with either a decimal point or an 'E' character. */
|
||||
if int32(**(**int8)(__ccgo_up(p))) == int32('.') && _fts5_isdigit(tls, **(**int8)(__ccgo_up(p + 1))) != 0 {
|
||||
p = p + uintptr(2)
|
||||
for _fts5_isdigit(tls, **(**int8)(__ccgo_up(p))) != 0 {
|
||||
p = p + 1
|
||||
}
|
||||
}
|
||||
if p == pIn {
|
||||
p = uintptr(0)
|
||||
}
|
||||
break
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /* c is a control character. Append the canonical JSON representation
|
||||
// ** of that control character to p.
|
||||
// **
|
||||
// ** This routine assumes that the output buffer has already been enlarged
|
||||
// ** sufficiently to hold the worst-case encoding plus a nul terminator.
|
||||
// */
|
||||
func _jsonAppendControlChar(tls *libc.TLS, p uintptr, c Tu8) {
|
||||
if _aSpecial[c] != 0 {
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed))) = int8('\\')
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(1)))) = _aSpecial[c]
|
||||
**(**Tu64)(__ccgo_up(p + 24)) += uint64(2)
|
||||
} else {
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed))) = int8('\\')
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(1)))) = int8('u')
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(2)))) = int8('0')
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(3)))) = int8('0')
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(4)))) = **(**int8)(__ccgo_up(__ccgo_ts + 1724 + uintptr(libc.Int32FromUint8(c)>>int32(4))))
|
||||
**(**int8)(__ccgo_up((*TJsonString)(unsafe.Pointer(p)).FzBuf + uintptr((*TJsonString)(unsafe.Pointer(p)).FnUsed+uint64(5)))) = **(**int8)(__ccgo_up(__ccgo_ts + 1724 + uintptr(libc.Int32FromUint8(c)&int32(0xf))))
|
||||
**(**Tu64)(__ccgo_up(p + 24)) += uint64(6)
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken
|
||||
// ** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those
|
||||
// ** that contain '_' characters that must be removed before further processing.
|
||||
// */
|
||||
func _sqlite3DequoteNumber(tls *libc.TLS, pParse uintptr, p uintptr) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var bHex int32
|
||||
var pIn, pOut, v1, v3 uintptr
|
||||
var _ /* iValue at bp+0 */ int32
|
||||
_, _, _, _, _ = bHex, pIn, pOut, v1, v3
|
||||
if p != 0 {
|
||||
pIn = *(*uintptr)(unsafe.Pointer(p + 8))
|
||||
pOut = *(*uintptr)(unsafe.Pointer(p + 8))
|
||||
bHex = libc.BoolInt32(int32(**(**int8)(__ccgo_up(pIn))) == int32('0') && (int32(**(**int8)(__ccgo_up(pIn + 1))) == int32('x') || int32(**(**int8)(__ccgo_up(pIn + 1))) == int32('X')))
|
||||
(*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_INTEGER)
|
||||
for {
|
||||
if int32(**(**int8)(__ccgo_up(pIn))) != int32('_') {
|
||||
v3 = pOut
|
||||
pOut = pOut + 1
|
||||
**(**int8)(__ccgo_up(v3)) = **(**int8)(__ccgo_up(pIn))
|
||||
if int32(**(**int8)(__ccgo_up(pIn))) == int32('e') || int32(**(**int8)(__ccgo_up(pIn))) == int32('E') || int32(**(**int8)(__ccgo_up(pIn))) == int32('.') {
|
||||
(*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_FLOAT)
|
||||
}
|
||||
} else {
|
||||
if bHex == 0 && (!(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(pIn + uintptr(-libc.Int32FromInt32(1)))))])&libc.Int32FromInt32(0x04) != 0) || !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(pIn + 1)))])&libc.Int32FromInt32(0x04) != 0)) || bHex == int32(1) && (!(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(pIn + uintptr(-libc.Int32FromInt32(1)))))])&libc.Int32FromInt32(0x08) != 0) || !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(pIn + 1)))])&libc.Int32FromInt32(0x08) != 0)) {
|
||||
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+1788, libc.VaList(bp+16, *(*uintptr)(unsafe.Pointer(p + 8))))
|
||||
}
|
||||
}
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
v1 = pIn
|
||||
pIn = pIn + 1
|
||||
if !(**(**int8)(__ccgo_up(v1)) != 0) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if bHex != 0 {
|
||||
(*TExpr)(unsafe.Pointer(p)).Fop = uint8(TK_INTEGER)
|
||||
}
|
||||
/* tag-20240227-a: If after dequoting, the number is an integer that
|
||||
** fits in 32 bits, then it must be converted into EP_IntValue. Other
|
||||
** parts of the code expect this. See also tag-20240227-b. */
|
||||
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(p)).Fop) == int32(TK_INTEGER) && _sqlite3GetInt32(tls, *(*uintptr)(unsafe.Pointer(p + 8)), bp) != 0 {
|
||||
*(*int32)(unsafe.Pointer(&(*TExpr)(unsafe.Pointer(p)).Fu)) = **(**int32)(__ccgo_up(bp))
|
||||
**(**Tu32)(__ccgo_up(p + 4)) |= uint32(EP_IntValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
|
||||
// **
|
||||
// ** Return a string described by FORMAT. Conversions as follows:
|
||||
// **
|
||||
// ** %d day of month 01-31
|
||||
// ** %e day of month 1-31
|
||||
// ** %f ** fractional seconds SS.SSS
|
||||
// ** %F ISO date. YYYY-MM-DD
|
||||
// ** %G ISO year corresponding to %V 0000-9999.
|
||||
// ** %g 2-digit ISO year corresponding to %V 00-99
|
||||
// ** %H hour 00-24
|
||||
// ** %k hour 0-24 (leading zero converted to space)
|
||||
// ** %I hour 01-12
|
||||
// ** %j day of year 001-366
|
||||
// ** %J ** julian day number
|
||||
// ** %l hour 1-12 (leading zero converted to space)
|
||||
// ** %m month 01-12
|
||||
// ** %M minute 00-59
|
||||
// ** %p "AM" or "PM"
|
||||
// ** %P "am" or "pm"
|
||||
// ** %R time as HH:MM
|
||||
// ** %s seconds since 1970-01-01
|
||||
// ** %S seconds 00-59
|
||||
// ** %T time as HH:MM:SS
|
||||
// ** %u day of week 1-7 Monday==1, Sunday==7
|
||||
// ** %w day of week 0-6 Sunday==0, Monday==1
|
||||
// ** %U week of year 00-53 (First Sunday is start of week 01)
|
||||
// ** %V week of year 01-53 (First week containing Thursday is week 01)
|
||||
// ** %W week of year 00-53 (First Monday is start of week 01)
|
||||
// ** %Y year 0000-9999
|
||||
// ** %% %
|
||||
// */
|
||||
func _strftimeFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
||||
bp := tls.Alloc(208)
|
||||
defer tls.Free(208)
|
||||
var c, cf int8
|
||||
var db, zFmt, v3 uintptr
|
||||
var h int32
|
||||
var i, j, v2 Tsize_t
|
||||
var iS Ti64
|
||||
var s float64
|
||||
var _ /* sRes at bp+48 */ Tsqlite3_str
|
||||
var _ /* x at bp+0 */ TDateTime
|
||||
var _ /* y at bp+128 */ TDateTime
|
||||
var _ /* y at bp+80 */ TDateTime
|
||||
_, _, _, _, _, _, _, _, _, _, _ = c, cf, db, h, i, iS, j, s, zFmt, v2, v3
|
||||
if argc == 0 {
|
||||
return
|
||||
}
|
||||
zFmt = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
if zFmt == uintptr(0) || _isDate(tls, context, argc-int32(1), argv+uintptr(1)*8, bp) != 0 {
|
||||
return
|
||||
}
|
||||
db = Xsqlite3_context_db_handle(tls, context)
|
||||
_sqlite3StrAccumInit(tls, bp+48, uintptr(0), uintptr(0), 0, **(**int32)(__ccgo_up(db + 136)))
|
||||
_computeJD(tls, bp)
|
||||
_computeYMD_HMS(tls, bp)
|
||||
v2 = libc.Uint64FromInt32(0)
|
||||
j = v2
|
||||
i = v2
|
||||
for {
|
||||
if !(**(**int8)(__ccgo_up(zFmt + uintptr(i))) != 0) {
|
||||
break
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zFmt + uintptr(i)))) != int32('%') {
|
||||
goto _1
|
||||
}
|
||||
if j < i {
|
||||
Xsqlite3_str_append(tls, bp+48, zFmt+uintptr(j), libc.Int32FromUint64(i-j))
|
||||
}
|
||||
i = i + 1
|
||||
j = i + uint64(1)
|
||||
cf = **(**int8)(__ccgo_up(zFmt + uintptr(i)))
|
||||
switch int32(cf) {
|
||||
case int32('d'): /* Fall thru */
|
||||
fallthrough
|
||||
case int32('e'):
|
||||
if int32(cf) == int32('d') {
|
||||
v3 = __ccgo_ts + 1389
|
||||
} else {
|
||||
v3 = __ccgo_ts + 1394
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, bp+48, v3, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).FD))
|
||||
case int32('f'): /* Fractional seconds. (Non-standard) */
|
||||
s = (**(**TDateTime)(__ccgo_up(bp))).Fs
|
||||
if s > float64(59.999) {
|
||||
s = float64(59.999)
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1398, libc.VaList(bp+184, s))
|
||||
case int32('F'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1405, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).FY, (**(**TDateTime)(__ccgo_up(bp))).FM, (**(**TDateTime)(__ccgo_up(bp))).FD))
|
||||
case int32('G'): /* Fall thru */
|
||||
fallthrough
|
||||
case int32('g'):
|
||||
**(**TDateTime)(__ccgo_up(bp + 80)) = **(**TDateTime)(__ccgo_up(bp))
|
||||
/* Move y so that it is the Thursday in the same week as x */
|
||||
(**(**TDateTime)(__ccgo_up(bp + 80))).FiJD += int64((int32(3) - _daysAfterMonday(tls, bp)) * int32(86400000))
|
||||
(**(**TDateTime)(__ccgo_up(bp + 80))).FvalidYMD = 0
|
||||
_computeYMD(tls, bp+80)
|
||||
if int32(cf) == int32('g') {
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp + 80))).FY%int32(100)))
|
||||
} else {
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1420, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp + 80))).FY))
|
||||
}
|
||||
case int32('H'):
|
||||
fallthrough
|
||||
case int32('k'):
|
||||
if int32(cf) == int32('H') {
|
||||
v3 = __ccgo_ts + 1389
|
||||
} else {
|
||||
v3 = __ccgo_ts + 1394
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, bp+48, v3, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).Fh))
|
||||
case int32('I'): /* Fall thru */
|
||||
fallthrough
|
||||
case int32('l'):
|
||||
h = (**(**TDateTime)(__ccgo_up(bp))).Fh
|
||||
if h > int32(12) {
|
||||
h = h - int32(12)
|
||||
}
|
||||
if h == 0 {
|
||||
h = int32(12)
|
||||
}
|
||||
if int32(cf) == int32('I') {
|
||||
v3 = __ccgo_ts + 1389
|
||||
} else {
|
||||
v3 = __ccgo_ts + 1394
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, bp+48, v3, libc.VaList(bp+184, h))
|
||||
case int32('j'): /* Day of year. Jan01==1, Jan02==2, and so forth */
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1425, libc.VaList(bp+184, _daysAfterJan01(tls, bp)+int32(1)))
|
||||
case int32('J'): /* Julian day number. (Non-standard) */
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1430, libc.VaList(bp+184, float64((**(**TDateTime)(__ccgo_up(bp))).FiJD)/float64(8.64e+07)))
|
||||
case int32('m'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).FM))
|
||||
case int32('M'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).Fm))
|
||||
case int32('p'): /* Fall thru */
|
||||
fallthrough
|
||||
case int32('P'):
|
||||
if (**(**TDateTime)(__ccgo_up(bp))).Fh >= int32(12) {
|
||||
if int32(cf) == int32('p') {
|
||||
v3 = __ccgo_ts + 1436
|
||||
} else {
|
||||
v3 = __ccgo_ts + 1439
|
||||
}
|
||||
Xsqlite3_str_append(tls, bp+48, v3, int32(2))
|
||||
} else {
|
||||
if int32(cf) == int32('p') {
|
||||
v3 = __ccgo_ts + 1442
|
||||
} else {
|
||||
v3 = __ccgo_ts + 1445
|
||||
}
|
||||
Xsqlite3_str_append(tls, bp+48, v3, int32(2))
|
||||
}
|
||||
case int32('R'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1448, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).Fh, (**(**TDateTime)(__ccgo_up(bp))).Fm))
|
||||
case int32('s'):
|
||||
if int32(uint32(*(*uint8)(unsafe.Pointer(bp + 44))&0x4>>2)) != 0 {
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1458, libc.VaList(bp+184, float64((**(**TDateTime)(__ccgo_up(bp))).FiJD-libc.Int64FromInt32(21086676)*libc.Int64FromInt32(10000000))/float64(1000)))
|
||||
} else {
|
||||
iS = (**(**TDateTime)(__ccgo_up(bp))).FiJD/libc.Int64FromInt32(1000) - libc.Int64FromInt32(21086676)*libc.Int64FromInt32(10000)
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1463, libc.VaList(bp+184, iS))
|
||||
}
|
||||
case int32('S'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, int32((**(**TDateTime)(__ccgo_up(bp))).Fs)))
|
||||
case int32('T'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1468, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).Fh, (**(**TDateTime)(__ccgo_up(bp))).Fm, int32((**(**TDateTime)(__ccgo_up(bp))).Fs)))
|
||||
case int32('u'): /* Day of week. 1 to 7. Monday==1, Sunday==7 */
|
||||
fallthrough
|
||||
case int32('w'): /* Day of week. 0 to 6. Sunday==0, Monday==1 */
|
||||
c = int8(int32(int8(_daysAfterSunday(tls, bp))) + int32('0'))
|
||||
if int32(c) == int32('0') && int32(cf) == int32('u') {
|
||||
c = int8('7')
|
||||
}
|
||||
Xsqlite3_str_appendchar(tls, bp+48, int32(1), c)
|
||||
case int32('U'): /* Week num. 00-53. First Sun of the year is week 01 */
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, (_daysAfterJan01(tls, bp)-_daysAfterSunday(tls, bp)+int32(7))/int32(7)))
|
||||
case int32('V'): /* Week num. 01-53. First week with a Thur is week 01 */
|
||||
**(**TDateTime)(__ccgo_up(bp + 128)) = **(**TDateTime)(__ccgo_up(bp))
|
||||
/* Adjust y so that is the Thursday in the same week as x */
|
||||
(**(**TDateTime)(__ccgo_up(bp + 128))).FiJD += int64((int32(3) - _daysAfterMonday(tls, bp)) * int32(86400000))
|
||||
(**(**TDateTime)(__ccgo_up(bp + 128))).FvalidYMD = 0
|
||||
_computeYMD(tls, bp+128)
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, _daysAfterJan01(tls, bp+128)/int32(7)+int32(1)))
|
||||
case int32('W'): /* Week num. 00-53. First Mon of the year is week 01 */
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1389, libc.VaList(bp+184, (_daysAfterJan01(tls, bp)-_daysAfterMonday(tls, bp)+int32(7))/int32(7)))
|
||||
case int32('Y'):
|
||||
Xsqlite3_str_appendf(tls, bp+48, __ccgo_ts+1420, libc.VaList(bp+184, (**(**TDateTime)(__ccgo_up(bp))).FY))
|
||||
case int32('%'):
|
||||
Xsqlite3_str_appendchar(tls, bp+48, int32(1), int8('%'))
|
||||
default:
|
||||
Xsqlite3_str_reset(tls, bp+48)
|
||||
return
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if j < i {
|
||||
Xsqlite3_str_append(tls, bp+48, zFmt+uintptr(j), libc.Int32FromUint64(i-j))
|
||||
}
|
||||
_sqlite3ResultStrAccum(tls, context, bp+48)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** timediff(DATE1, DATE2)
|
||||
// **
|
||||
// ** Return the amount of time that must be added to DATE2 in order to
|
||||
// ** convert it into DATE2. The time difference format is:
|
||||
// **
|
||||
// ** +YYYY-MM-DD HH:MM:SS.SSS
|
||||
// **
|
||||
// ** The initial "+" becomes "-" if DATE1 occurs before DATE2. For
|
||||
// ** date/time values A and B, the following invariant should hold:
|
||||
// **
|
||||
// ** datetime(A) == (datetime(B, timediff(A,B))
|
||||
// **
|
||||
// ** Both DATE arguments must be either a julian day number, or an
|
||||
// ** ISO-8601 string. The unix timestamps are not supported by this
|
||||
// ** routine.
|
||||
// */
|
||||
func _timediffFunc(tls *libc.TLS, context uintptr, NotUsed1 int32, argv uintptr) {
|
||||
bp := tls.Alloc(192)
|
||||
defer tls.Free(192)
|
||||
var M, Y int32
|
||||
var sign int8
|
||||
var v1 uintptr
|
||||
var _ /* d1 at bp+0 */ TDateTime
|
||||
var _ /* d2 at bp+48 */ TDateTime
|
||||
var _ /* sRes at bp+96 */ Tsqlite3_str
|
||||
_, _, _, _ = M, Y, sign, v1
|
||||
_ = NotUsed1
|
||||
if _isDate(tls, context, int32(1), argv, bp) != 0 {
|
||||
return
|
||||
}
|
||||
if _isDate(tls, context, int32(1), argv+1*8, bp+48) != 0 {
|
||||
return
|
||||
}
|
||||
_computeYMD_HMS(tls, bp)
|
||||
_computeYMD_HMS(tls, bp+48)
|
||||
if (**(**TDateTime)(__ccgo_up(bp))).FiJD >= (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD {
|
||||
sign = int8('+')
|
||||
Y = (**(**TDateTime)(__ccgo_up(bp))).FY - (**(**TDateTime)(__ccgo_up(bp + 48))).FY
|
||||
if Y != 0 {
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp))).FY
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = 0
|
||||
_computeJD(tls, bp+48)
|
||||
}
|
||||
M = (**(**TDateTime)(__ccgo_up(bp))).FM - (**(**TDateTime)(__ccgo_up(bp + 48))).FM
|
||||
if M < 0 {
|
||||
Y = Y - 1
|
||||
M = M + int32(12)
|
||||
}
|
||||
if M != 0 {
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp))).FM
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = 0
|
||||
_computeJD(tls, bp+48)
|
||||
}
|
||||
for (**(**TDateTime)(__ccgo_up(bp))).FiJD < (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD {
|
||||
M = M - 1
|
||||
if M < 0 {
|
||||
M = int32(11)
|
||||
Y = Y - 1
|
||||
}
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp + 48))).FM - 1
|
||||
if (**(**TDateTime)(__ccgo_up(bp + 48))).FM < int32(1) {
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FM = int32(12)
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp + 48))).FY - 1
|
||||
}
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = 0
|
||||
_computeJD(tls, bp+48)
|
||||
}
|
||||
(**(**TDateTime)(__ccgo_up(bp))).FiJD -= (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD
|
||||
v1 = bp
|
||||
*(*Tsqlite3_int64)(unsafe.Pointer(v1)) = Tsqlite3_int64(uint64(*(*Tsqlite3_int64)(unsafe.Pointer(v1))) + libc.Uint64FromInt32(1486995408)*libc.Uint64FromInt32(100000))
|
||||
} else { /* d1<d2 */
|
||||
sign = int8('-')
|
||||
Y = (**(**TDateTime)(__ccgo_up(bp + 48))).FY - (**(**TDateTime)(__ccgo_up(bp))).FY
|
||||
if Y != 0 {
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp))).FY
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = 0
|
||||
_computeJD(tls, bp+48)
|
||||
}
|
||||
M = (**(**TDateTime)(__ccgo_up(bp + 48))).FM - (**(**TDateTime)(__ccgo_up(bp))).FM
|
||||
if M < 0 {
|
||||
Y = Y - 1
|
||||
M = M + int32(12)
|
||||
}
|
||||
if M != 0 {
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp))).FM
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = 0
|
||||
_computeJD(tls, bp+48)
|
||||
}
|
||||
for (**(**TDateTime)(__ccgo_up(bp))).FiJD > (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD {
|
||||
M = M - 1
|
||||
if M < 0 {
|
||||
M = int32(11)
|
||||
Y = Y - 1
|
||||
}
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FM = (**(**TDateTime)(__ccgo_up(bp + 48))).FM + 1
|
||||
if (**(**TDateTime)(__ccgo_up(bp + 48))).FM > int32(12) {
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FM = int32(1)
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FY = (**(**TDateTime)(__ccgo_up(bp + 48))).FY + 1
|
||||
}
|
||||
(**(**TDateTime)(__ccgo_up(bp + 48))).FvalidJD = 0
|
||||
_computeJD(tls, bp+48)
|
||||
}
|
||||
(**(**TDateTime)(__ccgo_up(bp))).FiJD = (**(**TDateTime)(__ccgo_up(bp + 48))).FiJD - (**(**TDateTime)(__ccgo_up(bp))).FiJD
|
||||
v1 = bp
|
||||
*(*Tsqlite3_int64)(unsafe.Pointer(v1)) = Tsqlite3_int64(uint64(*(*Tsqlite3_int64)(unsafe.Pointer(v1))) + libc.Uint64FromInt32(1486995408)*libc.Uint64FromInt32(100000))
|
||||
}
|
||||
_clearYMD_HMS_TZ(tls, bp)
|
||||
_computeYMD_HMS(tls, bp)
|
||||
_sqlite3StrAccumInit(tls, bp+96, uintptr(0), uintptr(0), 0, int32(100))
|
||||
Xsqlite3_str_appendf(tls, bp+96, __ccgo_ts+1483, libc.VaList(bp+136, int32(sign), Y, M, (**(**TDateTime)(__ccgo_up(bp))).FD-int32(1), (**(**TDateTime)(__ccgo_up(bp))).Fh, (**(**TDateTime)(__ccgo_up(bp))).Fm, (**(**TDateTime)(__ccgo_up(bp))).Fs))
|
||||
_sqlite3ResultStrAccum(tls, context, bp+96)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Turn a relative pathname into a full pathname. The relative path
|
||||
// ** is stored as a nul-terminated string in the buffer pointed to by
|
||||
// ** zPath.
|
||||
// **
|
||||
// ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes
|
||||
// ** (in this case, MAX_PATHNAME bytes). The full-path is written to
|
||||
// ** this buffer before returning.
|
||||
// */
|
||||
func _unixFullPathname(tls *libc.TLS, pVfs uintptr, zPath uintptr, nOut int32, zOut uintptr) (r int32) {
|
||||
bp := tls.Alloc(1056)
|
||||
defer tls.Free(1056)
|
||||
var _ /* path at bp+0 */ TDbPath
|
||||
var _ /* zPwd at bp+24 */ [1026]int8
|
||||
_ = pVfs
|
||||
(**(**TDbPath)(__ccgo_up(bp))).Frc = 0
|
||||
(**(**TDbPath)(__ccgo_up(bp))).FnUsed = 0
|
||||
(**(**TDbPath)(__ccgo_up(bp))).FnSymlink = 0
|
||||
(**(**TDbPath)(__ccgo_up(bp))).FnOut = nOut
|
||||
(**(**TDbPath)(__ccgo_up(bp))).FzOut = zOut
|
||||
if int32(**(**int8)(__ccgo_up(zPath))) != int32('/') {
|
||||
if (*(*func(*libc.TLS, uintptr, Tsize_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(3)].FpCurrent})))(tls, bp+24, libc.Uint64FromInt64(1026)-libc.Uint64FromInt32(2)) == uintptr(0) {
|
||||
return _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47366)), __ccgo_ts+3558, zPath, int32(47366))
|
||||
}
|
||||
_appendAllPathElements(tls, bp, bp+24)
|
||||
}
|
||||
_appendAllPathElements(tls, bp, zPath)
|
||||
**(**int8)(__ccgo_up(zOut + uintptr((**(**TDbPath)(__ccgo_up(bp))).FnUsed))) = 0
|
||||
if (**(**TDbPath)(__ccgo_up(bp))).Frc != 0 || (**(**TDbPath)(__ccgo_up(bp))).FnUsed < int32(2) {
|
||||
return _sqlite3CantopenError(tls, int32(47372))
|
||||
}
|
||||
if (**(**TDbPath)(__ccgo_up(bp))).FnSymlink != 0 {
|
||||
return libc.Int32FromInt32(SQLITE_OK) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
+676
@@ -0,0 +1,676 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && 386) || (freebsd && amd64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type T___wchar_t = int32
|
||||
|
||||
type Tcrypt_data = struct {
|
||||
Finitialized int32
|
||||
F__buf [256]int8
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if the given SQL string ends in a semicolon.
|
||||
// **
|
||||
// ** Special handling is require for CREATE TRIGGER statements.
|
||||
// ** Whenever the CREATE TRIGGER keywords are seen, the statement
|
||||
// ** must end with ";END;".
|
||||
// **
|
||||
// ** This implementation uses a state machine with 8 states:
|
||||
// **
|
||||
// ** (0) INVALID We have not yet seen a non-whitespace character.
|
||||
// **
|
||||
// ** (1) START At the beginning or end of an SQL statement. This routine
|
||||
// ** returns 1 if it ends in the START state and 0 if it ends
|
||||
// ** in any other state.
|
||||
// **
|
||||
// ** (2) NORMAL We are in the middle of statement which ends with a single
|
||||
// ** semicolon.
|
||||
// **
|
||||
// ** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
|
||||
// ** a statement.
|
||||
// **
|
||||
// ** (4) CREATE The keyword CREATE has been seen at the beginning of a
|
||||
// ** statement, possibly preceded by EXPLAIN and/or followed by
|
||||
// ** TEMP or TEMPORARY
|
||||
// **
|
||||
// ** (5) TRIGGER We are in the middle of a trigger definition that must be
|
||||
// ** ended by a semicolon, the keyword END, and another semicolon.
|
||||
// **
|
||||
// ** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
|
||||
// ** the end of a trigger definition.
|
||||
// **
|
||||
// ** (7) END We've seen the ";END" of the ";END;" that occurs at the end
|
||||
// ** of a trigger definition.
|
||||
// **
|
||||
// ** Transitions between states above are determined by tokens extracted
|
||||
// ** from the input. The following tokens are significant:
|
||||
// **
|
||||
// ** (0) tkSEMI A semicolon.
|
||||
// ** (1) tkWS Whitespace.
|
||||
// ** (2) tkOTHER Any other SQL token.
|
||||
// ** (3) tkEXPLAIN The "explain" keyword.
|
||||
// ** (4) tkCREATE The "create" keyword.
|
||||
// ** (5) tkTEMP The "temp" or "temporary" keyword.
|
||||
// ** (6) tkTRIGGER The "trigger" keyword.
|
||||
// ** (7) tkEND The "end" keyword.
|
||||
// **
|
||||
// ** Whitespace never causes a state transition and is always ignored.
|
||||
// ** This means that a SQL string of all whitespace is invalid.
|
||||
// **
|
||||
// ** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
|
||||
// ** to recognize the end of a trigger can be omitted. All we have to do
|
||||
// ** is look for a semicolon that is not part of an string or comment.
|
||||
// */
|
||||
func Xsqlite3_complete(tls *libc.TLS, zSql uintptr) (r int32) {
|
||||
var c, nId int32
|
||||
var state, token Tu8
|
||||
_, _, _, _ = c, nId, state, token
|
||||
state = uint8(0) /* Value of the next token */
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 {
|
||||
switch int32(**(**int8)(__ccgo_up(zSql))) {
|
||||
case int32(';'): /* A semicolon */
|
||||
token = uint8(tkSEMI)
|
||||
case int32(' '):
|
||||
fallthrough
|
||||
case int32('\r'):
|
||||
fallthrough
|
||||
case int32('\t'):
|
||||
fallthrough
|
||||
case int32('\n'):
|
||||
fallthrough
|
||||
case int32('\f'): /* White space is ignored */
|
||||
token = uint8(tkWS)
|
||||
case int32('/'): /* C-style comments */
|
||||
if int32(**(**int8)(__ccgo_up(zSql + 1))) != int32('*') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(2)
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && (int32(**(**int8)(__ccgo_up(zSql))) != int32('*') || int32(**(**int8)(__ccgo_up(zSql + 1))) != int32('/')) {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
zSql = zSql + 1
|
||||
token = uint8(tkWS)
|
||||
case int32('-'): /* SQL-style comments from "--" to end of line */
|
||||
if int32(**(**int8)(__ccgo_up(zSql + 1))) != int32('-') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && int32(**(**int8)(__ccgo_up(zSql))) != int32('\n') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
token = uint8(tkWS)
|
||||
case int32('['): /* Microsoft-style identifiers in [...] */
|
||||
zSql = zSql + 1
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && int32(**(**int8)(__ccgo_up(zSql))) != int32(']') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
case int32('`'): /* Grave-accent quoted symbols used by MySQL */
|
||||
fallthrough
|
||||
case int32('"'): /* single- and double-quoted strings */
|
||||
fallthrough
|
||||
case int32('\''):
|
||||
c = int32(**(**int8)(__ccgo_up(zSql)))
|
||||
zSql = zSql + 1
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && int32(**(**int8)(__ccgo_up(zSql))) != c {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
default:
|
||||
if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zSql)))])&int32(0x46) != 0 {
|
||||
nId = int32(1)
|
||||
for {
|
||||
if !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zSql + uintptr(nId))))])&int32(0x46) != 0) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
nId = nId + 1
|
||||
}
|
||||
switch int32(**(**int8)(__ccgo_up(zSql))) {
|
||||
case int32('c'):
|
||||
fallthrough
|
||||
case int32('C'):
|
||||
if nId == int32(6) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25255, int32(6)) == 0 {
|
||||
token = uint8(tkCREATE)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
case int32('t'):
|
||||
fallthrough
|
||||
case int32('T'):
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+21884, int32(7)) == 0 {
|
||||
token = uint8(tkTRIGGER)
|
||||
} else {
|
||||
if nId == int32(4) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25262, int32(4)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
if nId == int32(9) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25267, int32(9)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
case int32('e'):
|
||||
fallthrough
|
||||
case int32('E'):
|
||||
if nId == int32(3) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25277, int32(3)) == 0 {
|
||||
token = uint8(tkEND)
|
||||
} else {
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25281, int32(7)) == 0 {
|
||||
token = uint8(tkEXPLAIN)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
default:
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(nId-int32(1))
|
||||
} else {
|
||||
/* Operators and special symbols */
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
break
|
||||
}
|
||||
state = **(**Tu8)(__ccgo_up(uintptr(unsafe.Pointer(&_trans)) + uintptr(state)*8 + uintptr(token)))
|
||||
zSql = zSql + 1
|
||||
}
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
|
||||
const __MINSIGSTKSZ = 2048
|
||||
|
||||
const __WCHAR_MAX = 2147483647
|
||||
|
||||
const __WCHAR_MIN = -2147483648
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Extra floating-point literals to allow in JSON.
|
||||
// */
|
||||
var _aNanInfName = [5]TNanInfName{
|
||||
0: {
|
||||
Fc1: int8('i'),
|
||||
Fc2: int8('I'),
|
||||
Fn: int8(3),
|
||||
FeType: int8(JSONB_FLOAT),
|
||||
FnRepl: int8(7),
|
||||
FzMatch: __ccgo_ts + 26475,
|
||||
FzRepl: __ccgo_ts + 26479,
|
||||
},
|
||||
1: {
|
||||
Fc1: int8('i'),
|
||||
Fc2: int8('I'),
|
||||
Fn: int8(8),
|
||||
FeType: int8(JSONB_FLOAT),
|
||||
FnRepl: int8(7),
|
||||
FzMatch: __ccgo_ts + 26487,
|
||||
FzRepl: __ccgo_ts + 26479,
|
||||
},
|
||||
2: {
|
||||
Fc1: int8('n'),
|
||||
Fc2: int8('N'),
|
||||
Fn: int8(3),
|
||||
FnRepl: int8(4),
|
||||
FzMatch: __ccgo_ts + 1693,
|
||||
FzRepl: __ccgo_ts + 1688,
|
||||
},
|
||||
3: {
|
||||
Fc1: int8('q'),
|
||||
Fc2: int8('Q'),
|
||||
Fn: int8(4),
|
||||
FnRepl: int8(4),
|
||||
FzMatch: __ccgo_ts + 26496,
|
||||
FzRepl: __ccgo_ts + 1688,
|
||||
},
|
||||
4: {
|
||||
Fc1: int8('s'),
|
||||
Fc2: int8('S'),
|
||||
Fn: int8(4),
|
||||
FnRepl: int8(4),
|
||||
FzMatch: __ccgo_ts + 26501,
|
||||
FzRepl: __ccgo_ts + 1688,
|
||||
},
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Process a "special" query. A special query is identified as one with a
|
||||
// ** MATCH expression that begins with a '*' character. The remainder of
|
||||
// ** the text passed to the MATCH operator are used as the special query
|
||||
// ** parameters.
|
||||
// */
|
||||
func _fts5SpecialMatch(tls *libc.TLS, pTab uintptr, pCsr uintptr, zQuery uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var n, rc int32
|
||||
var z uintptr
|
||||
_, _, _ = n, rc, z
|
||||
rc = SQLITE_OK /* Return code */
|
||||
z = zQuery /* Number of bytes in text at z */
|
||||
for int32(**(**int8)(__ccgo_up(z))) == int32(' ') {
|
||||
z = z + 1
|
||||
}
|
||||
n = 0
|
||||
for {
|
||||
if !(**(**int8)(__ccgo_up(z + uintptr(n))) != 0 && int32(**(**int8)(__ccgo_up(z + uintptr(n)))) != int32(' ')) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
n = n + 1
|
||||
}
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_SPECIAL)
|
||||
if n == int32(5) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+39817, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = int64(_sqlite3Fts5IndexReads(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex))
|
||||
} else {
|
||||
if n == int32(2) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+5650, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiCsrId
|
||||
} else {
|
||||
/* An unrecognized directive. Return an error message. */
|
||||
(*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39823, libc.VaList(bp+8, n, z))
|
||||
rc = int32(SQLITE_ERROR)
|
||||
}
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Interpret the given string as a temp db location. Return 1 for file
|
||||
// ** backed temporary databases, 2 for the Red-Black tree in memory database
|
||||
// ** and 0 to use the compile-time default.
|
||||
// */
|
||||
func _getTempStore(tls *libc.TLS, z uintptr) (r int32) {
|
||||
if int32(**(**int8)(__ccgo_up(z))) >= int32('0') && int32(**(**int8)(__ccgo_up(z))) <= int32('2') {
|
||||
return int32(**(**int8)(__ccgo_up(z))) - int32('0')
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+17994) == 0 {
|
||||
return int32(1)
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+19035) == 0 {
|
||||
return int32(2)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a complete JSON string. Return 0 on success or non-zero if there
|
||||
// ** are any errors. If an error occurs, free all memory held by pParse,
|
||||
// ** but not pParse itself.
|
||||
// **
|
||||
// ** pParse must be initialized to an empty parse object prior to calling
|
||||
// ** this routine.
|
||||
// */
|
||||
func _jsonConvertTextToBlob(tls *libc.TLS, pParse uintptr, pCtx uintptr) (r int32) {
|
||||
var i int32
|
||||
var zJson uintptr
|
||||
_, _ = i, zJson
|
||||
zJson = (*TJsonParse)(unsafe.Pointer(pParse)).FzJson
|
||||
i = _jsonTranslateTextToBlob(tls, pParse, uint32(0))
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
i = -int32(1)
|
||||
}
|
||||
if i > 0 {
|
||||
for _jsonIsSpace[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zJson + uintptr(i))))] != 0 {
|
||||
i = i + 1
|
||||
}
|
||||
if **(**int8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
i = i + _json5Whitespace(tls, zJson+uintptr(i))
|
||||
if **(**int8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
if pCtx != 0 {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26460, -int32(1))
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
(*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1)
|
||||
}
|
||||
}
|
||||
if i <= 0 {
|
||||
if pCtx != uintptr(0) {
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
Xsqlite3_result_error_nomem(tls, pCtx)
|
||||
} else {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26460, -int32(1))
|
||||
}
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Allocate a private rbu VFS for the rbu handle passed as the only
|
||||
// ** argument. This VFS will be used unless the call to sqlite3rbu_open()
|
||||
// ** specified a URI with a vfs=? option in place of a target database
|
||||
// ** file name.
|
||||
// */
|
||||
func _rbuCreateVfs(tls *libc.TLS, p uintptr) {
|
||||
bp := tls.Alloc(96)
|
||||
defer tls.Free(96)
|
||||
var pVfs uintptr
|
||||
var _ /* rnd at bp+0 */ int32
|
||||
var _ /* zRnd at bp+4 */ [64]int8
|
||||
_ = pVfs
|
||||
Xsqlite3_randomness(tls, int32(4), bp)
|
||||
Xsqlite3_snprintf(tls, int32(64), bp+4, __ccgo_ts+34328, libc.VaList(bp+80, **(**int32)(__ccgo_up(bp))))
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3rbu_create_vfs(tls, bp+4, uintptr(0))
|
||||
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
||||
pVfs = Xsqlite3_vfs_find(tls, bp+4)
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzVfsName = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FzName
|
||||
(*Trbu_vfs)(unsafe.Pointer(pVfs)).FpRbu = p
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** An error occurred while parsing or otherwise processing a database
|
||||
// ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
|
||||
// ** ALTER TABLE RENAME COLUMN program. The error message emitted by the
|
||||
// ** sub-routine is currently stored in pParse->zErrMsg. This function
|
||||
// ** adds context to the error message and then stores it in pCtx.
|
||||
// */
|
||||
func _renameColumnParseError(tls *libc.TLS, pCtx uintptr, zWhen uintptr, pType uintptr, pObject uintptr, pParse uintptr) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var zErr, zN, zT, v1 uintptr
|
||||
_, _, _, _ = zErr, zN, zT, v1
|
||||
zT = Xsqlite3_value_text(tls, pType)
|
||||
zN = Xsqlite3_value_text(tls, pObject)
|
||||
if **(**int8)(__ccgo_up(zWhen)) != 0 {
|
||||
v1 = __ccgo_ts + 11543
|
||||
} else {
|
||||
v1 = __ccgo_ts + 1702
|
||||
}
|
||||
zErr = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+11545, libc.VaList(bp+8, zT, zN, v1, zWhen, (*TParse)(unsafe.Pointer(pParse)).FzErrMsg))
|
||||
Xsqlite3_result_error(tls, pCtx, zErr, -int32(1))
|
||||
_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zErr)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /* IMP: R-25361-16150 This function is omitted from SQLite by default. It
|
||||
// ** is only available if the SQLITE_SOUNDEX compile-time option is used
|
||||
// ** when SQLite is built.
|
||||
// */
|
||||
// /*
|
||||
// ** Compute the soundex encoding of a word.
|
||||
// **
|
||||
// ** IMP: R-59782-00072 The soundex(X) function returns a string that is the
|
||||
// ** soundex encoding of the string X.
|
||||
// */
|
||||
func _soundexFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var code, i, j, v3 int32
|
||||
var prevcode Tu8
|
||||
var zIn uintptr
|
||||
var _ /* zResult at bp+0 */ [8]int8
|
||||
_, _, _, _, _, _ = code, i, j, prevcode, zIn, v3
|
||||
zIn = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
if zIn == uintptr(0) {
|
||||
zIn = __ccgo_ts + 1702
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(**(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))])&libc.Int32FromInt32(0x02) != 0)) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 {
|
||||
prevcode = _iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)]
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[0] = int8(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i)))) & ^(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))]) & libc.Int32FromInt32(0x20)))
|
||||
j = int32(1)
|
||||
for {
|
||||
if !(j < int32(4) && **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0) {
|
||||
break
|
||||
}
|
||||
code = libc.Int32FromUint8(_iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)])
|
||||
if code > 0 {
|
||||
if code != libc.Int32FromUint8(prevcode) {
|
||||
prevcode = libc.Uint8FromInt32(code)
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[v3] = int8(code + int32('0'))
|
||||
}
|
||||
} else {
|
||||
prevcode = uint8(0)
|
||||
}
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
for j < int32(4) {
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[v3] = int8('0')
|
||||
}
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[j] = 0
|
||||
Xsqlite3_result_text(tls, context, bp, int32(4), uintptr(-libc.Int32FromInt32(1)))
|
||||
} else {
|
||||
/* IMP: R-64894-50321 The string "?000" is returned if the argument
|
||||
** is NULL or contains no ASCII alphabetic characters. */
|
||||
Xsqlite3_result_text(tls, context, __ccgo_ts+16596, int32(4), libc.UintptrFromInt32(0))
|
||||
}
|
||||
}
|
||||
|
||||
func _sqlite3Fts5ParseSetDistance(tls *libc.TLS, pParse uintptr, pNear uintptr, p uintptr) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c int8
|
||||
var i, nNear int32
|
||||
_, _, _ = c, i, nNear
|
||||
if pNear != 0 {
|
||||
nNear = 0
|
||||
if (*TFts5Token)(unsafe.Pointer(p)).Fn != 0 {
|
||||
i = 0
|
||||
for {
|
||||
if !(i < (*TFts5Token)(unsafe.Pointer(p)).Fn) {
|
||||
break
|
||||
}
|
||||
c = **(**int8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))
|
||||
if int32(c) < int32('0') || int32(c) > int32('9') {
|
||||
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38608, libc.VaList(bp+8, (*TFts5Token)(unsafe.Pointer(p)).Fn, (*TFts5Token)(unsafe.Pointer(p)).Fp))
|
||||
return
|
||||
}
|
||||
if nNear < int32(214748363) {
|
||||
nNear = nNear*int32(10) + (int32(**(**int8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))) - int32('0'))
|
||||
}
|
||||
/* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
} else {
|
||||
nNear = int32(FTS5_DEFAULT_NEARDIST)
|
||||
}
|
||||
(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnNear = nNear
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Append to pStr text that is the SQL literal representation of the
|
||||
// ** value contained in pValue.
|
||||
// */
|
||||
func _sqlite3QuoteValue(tls *libc.TLS, pStr uintptr, pValue uintptr, bEscape int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var i int32
|
||||
var nBlob Ti64
|
||||
var zArg, zBlob, zText, v2 uintptr
|
||||
_, _, _, _, _, _ = i, nBlob, zArg, zBlob, zText, v2
|
||||
/* As currently implemented, the string must be initially empty.
|
||||
** we might relax this requirement in the future, but that will
|
||||
** require enhancements to the implementation. */
|
||||
switch Xsqlite3_value_type(tls, pValue) {
|
||||
case int32(SQLITE_FLOAT):
|
||||
/* ,--- Show infinity as 9.0e+999
|
||||
** |
|
||||
** | ,--- 17 precision guarantees round-trip
|
||||
** v v */
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+16561, libc.VaList(bp+8, Xsqlite3_value_double(tls, pValue)))
|
||||
case int32(SQLITE_INTEGER):
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+1463, libc.VaList(bp+8, Xsqlite3_value_int64(tls, pValue)))
|
||||
case int32(SQLITE_BLOB):
|
||||
zBlob = Xsqlite3_value_blob(tls, pValue)
|
||||
nBlob = int64(Xsqlite3_value_bytes(tls, pValue))
|
||||
/* No encoding change */
|
||||
_sqlite3StrAccumEnlarge(tls, pStr, nBlob*int64(2)+int64(4))
|
||||
if libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(pStr)).FaccError) == 0 {
|
||||
zText = (*TStrAccum)(unsafe.Pointer(pStr)).FzText
|
||||
i = 0
|
||||
for {
|
||||
if !(int64(i) < nBlob) {
|
||||
break
|
||||
}
|
||||
**(**int8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(2)))) = _hexdigits[int32(**(**int8)(__ccgo_up(zBlob + uintptr(i))))>>int32(4)&int32(0x0F)]
|
||||
**(**int8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(3)))) = _hexdigits[int32(**(**int8)(__ccgo_up(zBlob + uintptr(i))))&int32(0x0F)]
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
**(**int8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(2)))) = int8('\'')
|
||||
**(**int8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(3)))) = int8('\000')
|
||||
**(**int8)(__ccgo_up(zText)) = int8('X')
|
||||
**(**int8)(__ccgo_up(zText + 1)) = int8('\'')
|
||||
(*TStrAccum)(unsafe.Pointer(pStr)).FnChar = libc.Uint32FromInt64(nBlob*int64(2) + int64(3))
|
||||
}
|
||||
case int32(SQLITE_TEXT):
|
||||
zArg = Xsqlite3_value_text(tls, pValue)
|
||||
if bEscape != 0 {
|
||||
v2 = __ccgo_ts + 16569
|
||||
} else {
|
||||
v2 = __ccgo_ts + 11927
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, pStr, v2, libc.VaList(bp+8, zArg))
|
||||
default:
|
||||
Xsqlite3_str_append(tls, pStr, __ccgo_ts+1703, int32(4))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Create a temporary file name in zBuf. zBuf must be allocated
|
||||
// ** by the calling process and must be big enough to hold at least
|
||||
// ** pVfs->mxPathname bytes.
|
||||
// */
|
||||
func _unixGetTempname(tls *libc.TLS, nBuf int32, zBuf uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var iLimit, rc, v1 int32
|
||||
var zDir uintptr
|
||||
var v2 bool
|
||||
var _ /* r at bp+0 */ Tu64
|
||||
_, _, _, _, _ = iLimit, rc, zDir, v1, v2
|
||||
iLimit = 0
|
||||
rc = SQLITE_OK
|
||||
/* It's odd to simulate an io-error here, but really this is just
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
** function failing.
|
||||
*/
|
||||
**(**int8)(__ccgo_up(zBuf)) = 0
|
||||
Xsqlite3_mutex_enter(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
zDir = _unixTempFileDir(tls)
|
||||
if zDir == uintptr(0) {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(25)<<libc.Int32FromInt32(8)
|
||||
} else {
|
||||
for cond := true; cond; cond = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zBuf, 0) == 0 {
|
||||
Xsqlite3_randomness(tls, int32(8), bp)
|
||||
**(**int8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2)))) = 0
|
||||
Xsqlite3_snprintf(tls, nBuf, zBuf, __ccgo_ts+4043, libc.VaList(bp+16, zDir, **(**Tu64)(__ccgo_up(bp)), 0))
|
||||
if v2 = int32(**(**int8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2))))) != 0; !v2 {
|
||||
v1 = iLimit
|
||||
iLimit = iLimit + 1
|
||||
}
|
||||
if v2 || v1 > int32(10) {
|
||||
rc = int32(SQLITE_ERROR)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** The following code executes when a syntax error first occurs.
|
||||
// */
|
||||
func _yy_syntax_error(tls *libc.TLS, yypParser uintptr, yymajor int32, _yyminor TToken) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
*(*TToken)(unsafe.Pointer(bp)) = _yyminor
|
||||
var pParse uintptr
|
||||
_ = pParse
|
||||
pParse = (*TyyParser)(unsafe.Pointer(yypParser)).FpParse
|
||||
/************ Begin %syntax_error code ****************************************/
|
||||
_ = yymajor /* Silence some compiler warnings */
|
||||
if **(**int8)(__ccgo_up((**(**TToken)(__ccgo_up(bp))).Fz)) != 0 {
|
||||
_parserSyntaxError(tls, pParse, bp)
|
||||
} else {
|
||||
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+25202, 0)
|
||||
}
|
||||
/************ End %syntax_error code ******************************************/
|
||||
/* Suppress warning about unused %extra_argument variable */
|
||||
(*TyyParser)(unsafe.Pointer(yypParser)).FpParse = pParse
|
||||
}
|
||||
|
||||
type t__mbstate_t = struct {
|
||||
F_mbstateL [0]t__int64_t
|
||||
F__mbstate8 [128]int8
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && 386) || (freebsd && amd64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Compare the 19-character string zNum against the text representation
|
||||
// ** value 2^63: 9223372036854775808. Return negative, zero, or positive
|
||||
// ** if zNum is less than, equal to, or greater than the string.
|
||||
// ** Note that zNum must contain exactly 19 characters.
|
||||
// **
|
||||
// ** Unlike memcmp() this routine is guaranteed to return the difference
|
||||
// ** in the values of the last digit if the only difference is in the
|
||||
// ** last digit. So, for example,
|
||||
// **
|
||||
// ** compare2pow63("9223372036854775800", 1)
|
||||
// **
|
||||
// ** will return -8.
|
||||
// */
|
||||
func _compare2pow63(tls *libc.TLS, zNum uintptr, incr int32) (r int32) {
|
||||
var c, i int32
|
||||
var pow63 uintptr
|
||||
_, _, _ = c, i, pow63
|
||||
c = 0
|
||||
/* 012345678901234567 */
|
||||
pow63 = __ccgo_ts + 1813
|
||||
i = 0
|
||||
for {
|
||||
if !(c == 0 && i < int32(18)) {
|
||||
break
|
||||
}
|
||||
c = (int32(**(**int8)(__ccgo_up(zNum + uintptr(i*incr)))) - int32(**(**int8)(__ccgo_up(pow63 + uintptr(i))))) * int32(10)
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if c == 0 {
|
||||
c = int32(**(**int8)(__ccgo_up(zNum + uintptr(int32(18)*incr)))) - int32('8')
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
|
||||
// ** The HH, MM, and SS must each be exactly 2 digits. The
|
||||
// ** fractional seconds FFFF can be one or more digits.
|
||||
// **
|
||||
// ** Return 1 if there is a parsing error and 0 on success.
|
||||
// */
|
||||
func _parseHhMmSs(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var ms, rScale float64
|
||||
var _ /* h at bp+0 */ int32
|
||||
var _ /* m at bp+4 */ int32
|
||||
var _ /* s at bp+8 */ int32
|
||||
_, _ = ms, rScale
|
||||
ms = float64(0)
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1202, libc.VaList(bp+24, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == int32(':') {
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1210, libc.VaList(bp+24, bp+8)) != int32(1) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(2)
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == int32('.') && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate + 1)))])&int32(0x04) != 0 {
|
||||
rScale = float64(1)
|
||||
zDate = zDate + 1
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x04) != 0 {
|
||||
ms = float64(ms*float64(10)) + float64(**(**int8)(__ccgo_up(zDate))) - libc.Float64FromUint8('0')
|
||||
rScale = rScale * float64(10)
|
||||
zDate = zDate + 1
|
||||
}
|
||||
ms = ms / rScale
|
||||
/* Truncate to avoid problems with sub-milliseconds
|
||||
** rounding. https://sqlite.org/forum/forumpost/766a2c9231 */
|
||||
if ms > float64(0.999) {
|
||||
ms = float64(0.999)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(bp + 8)) = 0
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = 0
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 0, 0x1)
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = int8(1)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fh = **(**int32)(__ccgo_up(bp))
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fm = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fs = float64(**(**int32)(__ccgo_up(bp + 8))) + ms
|
||||
if _parseTimezone(tls, zDate, p) != 0 {
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a timezone extension on the end of a date-time.
|
||||
// ** The extension is of the form:
|
||||
// **
|
||||
// ** (+/-)HH:MM
|
||||
// **
|
||||
// ** Or the "zulu" notation:
|
||||
// **
|
||||
// ** Z
|
||||
// **
|
||||
// ** If the parse is successful, write the number of minutes
|
||||
// ** of change in p->tz and return 0. If a parser error occurs,
|
||||
// ** return non-zero.
|
||||
// **
|
||||
// ** A missing specifier is not considered an error.
|
||||
// */
|
||||
func _parseTimezone(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c, sgn int32
|
||||
var _ /* nHr at bp+0 */ int32
|
||||
var _ /* nMn at bp+4 */ int32
|
||||
_, _ = c, sgn
|
||||
sgn = 0
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = 0
|
||||
c = int32(**(**int8)(__ccgo_up(zDate)))
|
||||
if c == int32('-') {
|
||||
sgn = -int32(1)
|
||||
} else {
|
||||
if c == int32('+') {
|
||||
sgn = +libc.Int32FromInt32(1)
|
||||
} else {
|
||||
if c == int32('Z') || c == int32('z') {
|
||||
zDate = zDate + 1
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
goto zulu_time
|
||||
} else {
|
||||
return libc.BoolInt32(c != 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1194, libc.VaList(bp+16, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = sgn * (**(**int32)(__ccgo_up(bp + 4)) + **(**int32)(__ccgo_up(bp))*int32(60))
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz == 0 { /* Forum post 2025-09-17T10:12:14z */
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
}
|
||||
goto zulu_time
|
||||
zulu_time:
|
||||
;
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
return libc.BoolInt32(int32(**(**int8)(__ccgo_up(zDate))) != 0)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse dates of the form
|
||||
// **
|
||||
// ** YYYY-MM-DD HH:MM:SS.FFF
|
||||
// ** YYYY-MM-DD HH:MM:SS
|
||||
// ** YYYY-MM-DD HH:MM
|
||||
// ** YYYY-MM-DD
|
||||
// **
|
||||
// ** Write the result into the DateTime structure and return 0
|
||||
// ** on success and 1 if the input string is not a well-formed
|
||||
// ** date.
|
||||
// */
|
||||
func _parseYyyyMmDd(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var neg, v1 int32
|
||||
var _ /* D at bp+8 */ int32
|
||||
var _ /* M at bp+4 */ int32
|
||||
var _ /* Y at bp+0 */ int32
|
||||
_, _ = neg, v1
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == int32('-') {
|
||||
zDate = zDate + 1
|
||||
neg = int32(1)
|
||||
} else {
|
||||
neg = 0
|
||||
}
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1214, libc.VaList(bp+24, bp, bp+4, bp+8)) != int32(3) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(10)
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x01) != 0 || int32('T') == libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zDate))) {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
if _parseHhMmSs(tls, zDate, p) == 0 {
|
||||
/* We got the time */
|
||||
} else {
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == 0 {
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = 0
|
||||
} else {
|
||||
return int32(1)
|
||||
}
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = 0
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidYMD = int8(1)
|
||||
if neg != 0 {
|
||||
v1 = -**(**int32)(__ccgo_up(bp))
|
||||
} else {
|
||||
v1 = **(**int32)(__ccgo_up(bp))
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FY = v1
|
||||
(*TDateTime)(unsafe.Pointer(p)).FM = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).FD = **(**int32)(__ccgo_up(bp + 8))
|
||||
_computeFloor(tls, p)
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz != 0 {
|
||||
_computeJD(tls, p)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && arm64) || (freebsd && arm)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __ARM_NEON__ = 1
|
||||
+22933
File diff suppressed because it is too large
Load Diff
+29
@@ -0,0 +1,29 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && 386) || (freebsd && arm)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __INT_FAST64_FMTd__ = "lld"
|
||||
|
||||
const __INT_FAST64_FMTi__ = "lli"
|
||||
|
||||
const __INT_LEAST64_FMTd__ = "lld"
|
||||
|
||||
const __INT_LEAST64_FMTi__ = "lli"
|
||||
|
||||
const __UINT_FAST64_FMTX__ = "llX"
|
||||
|
||||
const __UINT_FAST64_FMTo__ = "llo"
|
||||
|
||||
const __UINT_FAST64_FMTu__ = "llu"
|
||||
|
||||
const __UINT_FAST64_FMTx__ = "llx"
|
||||
|
||||
const __UINT_LEAST64_FMTX__ = "llX"
|
||||
|
||||
const __UINT_LEAST64_FMTo__ = "llo"
|
||||
|
||||
const __UINT_LEAST64_FMTu__ = "llu"
|
||||
|
||||
const __UINT_LEAST64_FMTx__ = "llx"
|
||||
+32779
File diff suppressed because it is too large
Load Diff
+721
@@ -0,0 +1,721 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && amd64) || (freebsd && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type Tvm_offset_t = uint64
|
||||
|
||||
type Tvm_size_t = uint64
|
||||
|
||||
const __INTMAX_FMTd__ = "ld"
|
||||
|
||||
const __INTMAX_FMTi__ = "li"
|
||||
|
||||
const __UINTMAX_FMTX__ = "lX"
|
||||
|
||||
const __UINTMAX_FMTo__ = "lo"
|
||||
|
||||
const __UINTMAX_FMTu__ = "lu"
|
||||
|
||||
const __UINTMAX_FMTx__ = "lx"
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Allocate and populate an sqlite3_index_info structure. It is the
|
||||
// ** responsibility of the caller to eventually release the structure
|
||||
// ** by passing the pointer returned by this function to freeIndexInfo().
|
||||
// */
|
||||
func _allocateIndexInfo(tls *libc.TLS, pWInfo uintptr, pWC uintptr, mUnusable TBitmask, pSrc uintptr, pmNoOmit uintptr) (r uintptr) {
|
||||
var bSortByGroup, eDistinct, i, iCol, j, n, nLast, nOrderBy, nTerm, v10 int32
|
||||
var mNoOmit, op Tu16
|
||||
var p, pE2, pExpr, pExpr1, pHidden, pIdxCons, pIdxInfo, pIdxOrderBy, pOrderBy, pParse, pPk, pTab, pTerm, pUsage, zColl, v3 uintptr
|
||||
var v12 uint32
|
||||
var v7 bool
|
||||
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = bSortByGroup, eDistinct, i, iCol, j, mNoOmit, n, nLast, nOrderBy, nTerm, op, p, pE2, pExpr, pExpr1, pHidden, pIdxCons, pIdxInfo, pIdxOrderBy, pOrderBy, pParse, pPk, pTab, pTerm, pUsage, zColl, v10, v12, v3, v7
|
||||
pParse = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpParse
|
||||
mNoOmit = uint16(0)
|
||||
eDistinct = 0
|
||||
pOrderBy = (*TWhereInfo)(unsafe.Pointer(pWInfo)).FpOrderBy
|
||||
pTab = (*TSrcItem)(unsafe.Pointer(pSrc)).FpSTab
|
||||
/* Find all WHERE clause constraints referring to this virtual table.
|
||||
** Mark each term with the TERM_OK flag. Set nTerm to the number of
|
||||
** terms found.
|
||||
*/
|
||||
p = pWC
|
||||
nTerm = libc.Int32FromInt32(0)
|
||||
for {
|
||||
if !(p != 0) {
|
||||
break
|
||||
}
|
||||
i = 0
|
||||
pTerm = (*TWhereClause)(unsafe.Pointer(p)).Fa
|
||||
for {
|
||||
if !(i < (*TWhereClause)(unsafe.Pointer(p)).FnTerm) {
|
||||
break
|
||||
}
|
||||
v3 = pTerm + 18
|
||||
*(*Tu16)(unsafe.Pointer(v3)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v3))) & ^libc.Int32FromInt32(TERM_OK))
|
||||
if (*TWhereTerm)(unsafe.Pointer(pTerm)).FleftCursor != (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor {
|
||||
goto _2
|
||||
}
|
||||
if (*TWhereTerm)(unsafe.Pointer(pTerm)).FprereqRight&mUnusable != 0 {
|
||||
goto _2
|
||||
}
|
||||
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator) & ^libc.Int32FromInt32(WO_EQUIV) == 0 {
|
||||
goto _2
|
||||
}
|
||||
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags)&int32(TERM_VNULL) != 0 {
|
||||
goto _2
|
||||
}
|
||||
if libc.Int32FromUint8((*TSrcItem)(unsafe.Pointer(pSrc)).Ffg.Fjointype)&(libc.Int32FromInt32(JT_LEFT)|libc.Int32FromInt32(JT_LTORJ)|libc.Int32FromInt32(JT_RIGHT)) != 0 && !(_constraintCompatibleWithOuterJoin(tls, pTerm, pSrc) != 0) {
|
||||
goto _2
|
||||
}
|
||||
nTerm = nTerm + 1
|
||||
v3 = pTerm + 18
|
||||
*(*Tu16)(unsafe.Pointer(v3)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v3))) | libc.Int32FromInt32(TERM_OK))
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
i = i + 1
|
||||
pTerm += 56
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
p = (*TWhereClause)(unsafe.Pointer(p)).FpOuter
|
||||
}
|
||||
/* If the ORDER BY clause contains only columns in the current
|
||||
** virtual table then allocate space for the aOrderBy part of
|
||||
** the sqlite3_index_info structure.
|
||||
*/
|
||||
nOrderBy = 0
|
||||
if pOrderBy != 0 {
|
||||
n = (*TExprList)(unsafe.Pointer(pOrderBy)).FnExpr
|
||||
i = 0
|
||||
for {
|
||||
if !(i < n) {
|
||||
break
|
||||
}
|
||||
pExpr = (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*32))).FpExpr
|
||||
/* Skip over constant terms in the ORDER BY clause */
|
||||
if _sqlite3ExprIsConstant(tls, uintptr(0), pExpr) != 0 {
|
||||
goto _5
|
||||
}
|
||||
/* Virtual tables are unable to deal with NULLS FIRST */
|
||||
if libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*32))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_BIGNULL) != 0 {
|
||||
break
|
||||
}
|
||||
/* First case - a direct column references without a COLLATE operator */
|
||||
if libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_COLUMN) && (*TExpr)(unsafe.Pointer(pExpr)).FiTable == (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor {
|
||||
goto _5
|
||||
}
|
||||
/* 2nd case - a column reference with a COLLATE operator. Only match
|
||||
** of the COLLATE operator matches the collation of the column. */
|
||||
if v7 = libc.Int32FromUint8((*TExpr)(unsafe.Pointer(pExpr)).Fop) == int32(TK_COLLATE); v7 {
|
||||
v3 = (*TExpr)(unsafe.Pointer(pExpr)).FpLeft
|
||||
pE2 = v3
|
||||
}
|
||||
if v7 && libc.Int32FromUint8((*TExpr)(unsafe.Pointer(v3)).Fop) == int32(TK_COLUMN) && (*TExpr)(unsafe.Pointer(pE2)).FiTable == (*TSrcItem)(unsafe.Pointer(pSrc)).FiCursor { /* The collating sequence name */
|
||||
(*TExpr)(unsafe.Pointer(pExpr)).FiColumn = (*TExpr)(unsafe.Pointer(pE2)).FiColumn
|
||||
if int32((*TExpr)(unsafe.Pointer(pE2)).FiColumn) < 0 {
|
||||
goto _5
|
||||
} /* Collseq does not matter for rowid */
|
||||
zColl = _sqlite3ColumnColl(tls, (*TTable)(unsafe.Pointer(pTab)).FaCol+uintptr((*TExpr)(unsafe.Pointer(pE2)).FiColumn)*16)
|
||||
if zColl == uintptr(0) {
|
||||
zColl = uintptr(unsafe.Pointer(&_sqlite3StrBINARY))
|
||||
}
|
||||
if Xsqlite3_stricmp(tls, *(*uintptr)(unsafe.Pointer(pExpr + 8)), zColl) == 0 {
|
||||
goto _5
|
||||
}
|
||||
}
|
||||
/* No matches cause a break out of the loop */
|
||||
break
|
||||
goto _5
|
||||
_5:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if i == n {
|
||||
bSortByGroup = libc.BoolInt32(libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_SORTBYGROUP) != 0)
|
||||
nOrderBy = n
|
||||
if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_DISTINCTBY) != 0 && !(int32(*(*uint32)(unsafe.Pointer(pSrc + 24 + 4))&0x8000>>15) != 0) {
|
||||
eDistinct = int32(2) + bSortByGroup
|
||||
} else {
|
||||
if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_GROUPBY) != 0 {
|
||||
eDistinct = int32(1) - bSortByGroup
|
||||
} else {
|
||||
if libc.Int32FromUint16((*TWhereInfo)(unsafe.Pointer(pWInfo)).FwctrlFlags)&int32(WHERE_WANT_DISTINCT) != 0 {
|
||||
eDistinct = int32(3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Allocate the sqlite3_index_info structure
|
||||
*/
|
||||
pIdxInfo = _sqlite3DbMallocZero(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, uint64(uint64(96)+(libc.Uint64FromInt64(12)+libc.Uint64FromInt64(8))*libc.Uint64FromInt32(nTerm)+uint64(8)*libc.Uint64FromInt32(nOrderBy)+(uint64(libc.UintptrFromInt32(0)+32)+libc.Uint64FromInt32(nTerm)*uint64(8))))
|
||||
if pIdxInfo == uintptr(0) {
|
||||
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+1672, 0)
|
||||
return uintptr(0)
|
||||
}
|
||||
pHidden = pIdxInfo + 1*96
|
||||
pIdxCons = pHidden + 32 + uintptr(nTerm)*8
|
||||
pIdxOrderBy = pIdxCons + uintptr(nTerm)*12
|
||||
pUsage = pIdxOrderBy + uintptr(nOrderBy)*8
|
||||
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraint = pIdxCons
|
||||
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaOrderBy = pIdxOrderBy
|
||||
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FaConstraintUsage = pUsage
|
||||
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FcolUsed = libc.Uint64FromInt64(libc.Int64FromUint64((*TSrcItem)(unsafe.Pointer(pSrc)).FcolUsed))
|
||||
if libc.BoolInt32((*TTable)(unsafe.Pointer(pTab)).FtabFlags&uint32(TF_WithoutRowid) == uint32(0)) == 0 {
|
||||
/* Ensure that all bits associated with PK columns are set. This is to
|
||||
** ensure they are available for cases like RIGHT joins or OR loops. */
|
||||
pPk = _sqlite3PrimaryKeyIndex(tls, pTab)
|
||||
i = 0
|
||||
for {
|
||||
if !(i < libc.Int32FromUint16((*TIndex)(unsafe.Pointer(pPk)).FnKeyCol)) {
|
||||
break
|
||||
}
|
||||
iCol = int32(**(**Ti16)(__ccgo_up((*TIndex)(unsafe.Pointer(pPk)).FaiColumn + uintptr(i)*2)))
|
||||
if iCol >= libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8))-libc.Int32FromInt32(1) {
|
||||
iCol = libc.Int32FromUint64(libc.Uint64FromInt64(8)*libc.Uint64FromInt32(8)) - libc.Int32FromInt32(1)
|
||||
}
|
||||
**(**Tsqlite3_uint64)(__ccgo_up(pIdxInfo + 88)) |= libc.Uint64FromInt32(1) << iCol
|
||||
goto _8
|
||||
_8:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
(*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FpWC = pWC
|
||||
(*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FpParse = pParse
|
||||
(*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FeDistinct = eDistinct
|
||||
(*THiddenIndexInfo)(unsafe.Pointer(pHidden)).FmIn = uint32(0)
|
||||
p = pWC
|
||||
v10 = libc.Int32FromInt32(0)
|
||||
j = v10
|
||||
i = v10
|
||||
for {
|
||||
if !(p != 0) {
|
||||
break
|
||||
}
|
||||
nLast = i + (*TWhereClause)(unsafe.Pointer(p)).FnTerm
|
||||
pTerm = (*TWhereClause)(unsafe.Pointer(p)).Fa
|
||||
for {
|
||||
if !(i < nLast) {
|
||||
break
|
||||
}
|
||||
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags)&int32(TERM_OK) == 0 {
|
||||
goto _11
|
||||
}
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).FiColumn = (*(*struct {
|
||||
FleftColumn int32
|
||||
FiField int32
|
||||
})(unsafe.Pointer(pTerm + 32))).FleftColumn
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).FiTermOffset = i
|
||||
op = libc.Uint16FromInt32(libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FeOperator) & int32(WO_ALL))
|
||||
if libc.Int32FromUint16(op) == int32(WO_IN) {
|
||||
if libc.Int32FromUint16((*TWhereTerm)(unsafe.Pointer(pTerm)).FwtFlags)&int32(TERM_SLICE) == 0 {
|
||||
if j <= int32(31) {
|
||||
v12 = libc.Uint32FromInt32(1) << j
|
||||
} else {
|
||||
v12 = uint32(0)
|
||||
}
|
||||
**(**Tu32)(__ccgo_up(pHidden + 20)) |= v12
|
||||
}
|
||||
op = uint16(WO_EQ)
|
||||
}
|
||||
if libc.Int32FromUint16(op) == int32(WO_AUX) {
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).Fop = (*TWhereTerm)(unsafe.Pointer(pTerm)).FeMatchOp
|
||||
} else {
|
||||
if libc.Int32FromUint16(op)&(libc.Int32FromInt32(WO_ISNULL)|libc.Int32FromInt32(WO_IS)) != 0 {
|
||||
if libc.Int32FromUint16(op) == int32(WO_ISNULL) {
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).Fop = uint8(SQLITE_INDEX_CONSTRAINT_ISNULL)
|
||||
} else {
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).Fop = uint8(SQLITE_INDEX_CONSTRAINT_IS)
|
||||
}
|
||||
} else {
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).Fop = uint8(op)
|
||||
/* The direct assignment in the previous line is possible only because
|
||||
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
|
||||
** following asserts verify this fact. */
|
||||
if libc.Int32FromUint16(op)&(libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LE)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ))|libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GE)-libc.Int32FromInt32(TK_EQ))) != 0 && _sqlite3ExprIsVector(tls, (*TExpr)(unsafe.Pointer((*TWhereTerm)(unsafe.Pointer(pTerm)).FpExpr)).FpRight) != 0 {
|
||||
if j < int32(16) {
|
||||
mNoOmit = libc.Uint16FromInt32(int32(mNoOmit) | libc.Int32FromInt32(1)<<j)
|
||||
}
|
||||
if libc.Int32FromUint16(op) == libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_LT)-libc.Int32FromInt32(TK_EQ)) {
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).Fop = libc.Uint8FromInt32(libc.Int32FromInt32(WO_EQ) << (libc.Int32FromInt32(TK_LE) - libc.Int32FromInt32(TK_EQ)))
|
||||
}
|
||||
if libc.Int32FromUint16(op) == libc.Int32FromInt32(WO_EQ)<<(libc.Int32FromInt32(TK_GT)-libc.Int32FromInt32(TK_EQ)) {
|
||||
(**(**Tsqlite3_index_constraint)(__ccgo_up(pIdxCons + uintptr(j)*12))).Fop = libc.Uint8FromInt32(libc.Int32FromInt32(WO_EQ) << (libc.Int32FromInt32(TK_GE) - libc.Int32FromInt32(TK_EQ)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j = j + 1
|
||||
goto _11
|
||||
_11:
|
||||
;
|
||||
i = i + 1
|
||||
pTerm += 56
|
||||
}
|
||||
goto _9
|
||||
_9:
|
||||
;
|
||||
p = (*TWhereClause)(unsafe.Pointer(p)).FpOuter
|
||||
}
|
||||
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnConstraint = j
|
||||
v10 = libc.Int32FromInt32(0)
|
||||
j = v10
|
||||
i = v10
|
||||
for {
|
||||
if !(i < nOrderBy) {
|
||||
break
|
||||
}
|
||||
pExpr1 = (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*32))).FpExpr
|
||||
if _sqlite3ExprIsConstant(tls, uintptr(0), pExpr1) != 0 {
|
||||
goto _13
|
||||
}
|
||||
(**(**Tsqlite3_index_orderby)(__ccgo_up(pIdxOrderBy + uintptr(j)*8))).FiColumn = int32((*TExpr)(unsafe.Pointer(pExpr1)).FiColumn)
|
||||
(**(**Tsqlite3_index_orderby)(__ccgo_up(pIdxOrderBy + uintptr(j)*8))).Fdesc = libc.Uint8FromInt32(libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8 + uintptr(i)*32))).Ffg.FsortFlags) & int32(KEYINFO_ORDER_DESC))
|
||||
j = j + 1
|
||||
goto _13
|
||||
_13:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
(*Tsqlite3_index_info)(unsafe.Pointer(pIdxInfo)).FnOrderBy = j
|
||||
**(**Tu16)(__ccgo_up(pmNoOmit)) = mNoOmit
|
||||
return pIdxInfo
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Like malloc(), but remember the size of the allocation
|
||||
// ** so that we can find it later using sqlite3MemSize().
|
||||
// **
|
||||
// ** For this low-level routine, we are guaranteed that nByte>0 because
|
||||
// ** cases of nByte<=0 will be intercepted and dealt with by higher level
|
||||
// ** routines.
|
||||
// */
|
||||
func _sqlite3MemMalloc(tls *libc.TLS, nByte int32) (r uintptr) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var p uintptr
|
||||
_ = p
|
||||
p = libc.Xmalloc(tls, libc.Uint64FromInt32(nByte+int32(8)))
|
||||
if p != 0 {
|
||||
**(**Tsqlite3_int64)(__ccgo_up(p)) = int64(nByte)
|
||||
p += 8
|
||||
} else {
|
||||
Xsqlite3_log(tls, int32(SQLITE_NOMEM), __ccgo_ts+1598, libc.VaList(bp+8, nByte))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Like realloc(). Resize an allocation previously obtained from
|
||||
// ** sqlite3MemMalloc().
|
||||
// **
|
||||
// ** For this low-level interface, we know that pPrior!=0. Cases where
|
||||
// ** pPrior==0 while have been intercepted by higher-level routine and
|
||||
// ** redirected to xMalloc. Similarly, we know that nByte>0 because
|
||||
// ** cases where nByte<=0 will have been intercepted by higher-level
|
||||
// ** routines and redirected to xFree.
|
||||
// */
|
||||
func _sqlite3MemRealloc(tls *libc.TLS, pPrior uintptr, nByte int32) (r uintptr) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var p uintptr
|
||||
_ = p
|
||||
p = pPrior
|
||||
/* EV: R-46199-30249 */
|
||||
p -= 8
|
||||
p = libc.Xrealloc(tls, p, libc.Uint64FromInt32(nByte+libc.Int32FromInt32(8)))
|
||||
if p != 0 {
|
||||
**(**Tsqlite3_int64)(__ccgo_up(p)) = int64(nByte)
|
||||
p += 8
|
||||
} else {
|
||||
Xsqlite3_log(tls, int32(SQLITE_NOMEM), __ccgo_ts+1636, libc.VaList(bp+8, _sqlite3MemSize(tls, pPrior), nByte))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Call this routine to record the fact that an OOM (out-of-memory) error
|
||||
// ** has happened. This routine will set db->mallocFailed, and also
|
||||
// ** temporarily disable the lookaside memory allocator and interrupt
|
||||
// ** any running VDBEs.
|
||||
// **
|
||||
// ** Always return a NULL pointer so that this routine can be invoked using
|
||||
// **
|
||||
// ** return sqlite3OomFault(db);
|
||||
// **
|
||||
// ** and thereby avoid unnecessary stack frame allocations for the overwhelmingly
|
||||
// ** common case where no OOM occurs.
|
||||
// */
|
||||
func _sqlite3OomFault(tls *libc.TLS, db uintptr) (r uintptr) {
|
||||
var pParse uintptr
|
||||
_ = pParse
|
||||
if libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed) == 0 && libc.Int32FromUint8((*Tsqlite3)(unsafe.Pointer(db)).FbBenignMalloc) == 0 {
|
||||
(*Tsqlite3)(unsafe.Pointer(db)).FmallocFailed = uint8(1)
|
||||
if (*Tsqlite3)(unsafe.Pointer(db)).FnVdbeExec > 0 {
|
||||
libc.AtomicStoreNInt32(db+432, libc.Int32FromInt32(1), libc.Int32FromInt32(__ATOMIC_RELAXED))
|
||||
}
|
||||
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable = (*Tsqlite3)(unsafe.Pointer(db)).Flookaside.FbDisable + 1
|
||||
(*Tsqlite3)(unsafe.Pointer(db)).Flookaside.Fsz = uint16(0)
|
||||
if (*Tsqlite3)(unsafe.Pointer(db)).FpParse != 0 {
|
||||
_sqlite3ErrorMsg(tls, (*Tsqlite3)(unsafe.Pointer(db)).FpParse, __ccgo_ts+1672, 0)
|
||||
(*TParse)(unsafe.Pointer((*Tsqlite3)(unsafe.Pointer(db)).FpParse)).Frc = int32(SQLITE_NOMEM)
|
||||
pParse = (*TParse)(unsafe.Pointer((*Tsqlite3)(unsafe.Pointer(db)).FpParse)).FpOuterParse
|
||||
for {
|
||||
if !(pParse != 0) {
|
||||
break
|
||||
}
|
||||
(*TParse)(unsafe.Pointer(pParse)).FnErr = (*TParse)(unsafe.Pointer(pParse)).FnErr + 1
|
||||
(*TParse)(unsafe.Pointer(pParse)).Frc = int32(SQLITE_NOMEM)
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
pParse = (*TParse)(unsafe.Pointer(pParse)).FpOuterParse
|
||||
}
|
||||
}
|
||||
}
|
||||
return uintptr(0)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Set the value stored in *pMem should already be a NULL.
|
||||
// ** Also store a pointer to go with it.
|
||||
// */
|
||||
func _sqlite3VdbeMemSetPointer(tls *libc.TLS, pMem uintptr, pPtr uintptr, zPType uintptr, __ccgo_fp_xDestructor uintptr) {
|
||||
var v1 uintptr
|
||||
_ = v1
|
||||
_vdbeMemClear(tls, pMem)
|
||||
if zPType != 0 {
|
||||
v1 = zPType
|
||||
} else {
|
||||
v1 = __ccgo_ts + 1702
|
||||
}
|
||||
*(*uintptr)(unsafe.Pointer(pMem)) = v1
|
||||
(*TMem)(unsafe.Pointer(pMem)).Fz = pPtr
|
||||
(*TMem)(unsafe.Pointer(pMem)).Fflags = libc.Uint16FromInt32(libc.Int32FromInt32(MEM_Null) | libc.Int32FromInt32(MEM_Dyn) | libc.Int32FromInt32(MEM_Subtype) | libc.Int32FromInt32(MEM_Term))
|
||||
(*TMem)(unsafe.Pointer(pMem)).FeSubtype = uint8('p')
|
||||
if __ccgo_fp_xDestructor != 0 {
|
||||
v1 = __ccgo_fp_xDestructor
|
||||
} else {
|
||||
v1 = __ccgo_fp(_sqlite3NoopDestructor)
|
||||
}
|
||||
(*TMem)(unsafe.Pointer(pMem)).FxDel = v1
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** The unhex() function. This function may be invoked with either one or
|
||||
// ** two arguments. In both cases the first argument is interpreted as text
|
||||
// ** a text value containing a set of pairs of hexadecimal digits which are
|
||||
// ** decoded and returned as a blob.
|
||||
// **
|
||||
// ** If there is only a single argument, then it must consist only of an
|
||||
// ** even number of hexadecimal digits. Otherwise, return NULL.
|
||||
// **
|
||||
// ** Or, if there is a second argument, then any character that appears in
|
||||
// ** the second argument is also allowed to appear between pairs of hexadecimal
|
||||
// ** digits in the first argument. If any other character appears in the
|
||||
// ** first argument, or if one of the allowed characters appears between
|
||||
// ** two hexadecimal digits that make up a single byte, NULL is returned.
|
||||
// **
|
||||
// ** The following expressions are all true:
|
||||
// **
|
||||
// ** unhex('ABCD') IS x'ABCD'
|
||||
// ** unhex('AB CD') IS NULL
|
||||
// ** unhex('AB CD', ' ') IS x'ABCD'
|
||||
// ** unhex('A BCD', ' ') IS NULL
|
||||
// */
|
||||
func _unhexFunc(tls *libc.TLS, pCtx uintptr, argc int32, argv uintptr) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var c, d, v2 Tu8
|
||||
var ch Tu32
|
||||
var nHex, nPass int32
|
||||
var p, pBlob, zPass, v1 uintptr
|
||||
var v3 uint32
|
||||
var _ /* zHex at bp+0 */ uintptr
|
||||
_, _, _, _, _, _, _, _, _, _, _ = c, ch, d, nHex, nPass, p, pBlob, zPass, v1, v2, v3
|
||||
zPass = __ccgo_ts + 1702
|
||||
nPass = 0
|
||||
**(**uintptr)(__ccgo_up(bp)) = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
nHex = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
pBlob = uintptr(0)
|
||||
p = uintptr(0)
|
||||
if argc == int32(2) {
|
||||
zPass = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
||||
nPass = Xsqlite3_value_bytes(tls, **(**uintptr)(__ccgo_up(argv + 1*8)))
|
||||
}
|
||||
if !(**(**uintptr)(__ccgo_up(bp)) != 0) || !(zPass != 0) {
|
||||
return
|
||||
}
|
||||
v1 = _contextMalloc(tls, pCtx, int64(nHex/int32(2)+int32(1)))
|
||||
pBlob = v1
|
||||
p = v1
|
||||
if pBlob != 0 { /* Least significant digit of next byte */
|
||||
for {
|
||||
v2 = **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))
|
||||
c = v2
|
||||
if !(libc.Int32FromUint8(v2) != 0x00) {
|
||||
break
|
||||
}
|
||||
for !(libc.Int32FromUint8(_sqlite3CtypeMap[c])&libc.Int32FromInt32(0x08) != 0) {
|
||||
if libc.Int32FromUint8(**(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))) < int32(0x80) {
|
||||
v1 = **(**uintptr)(__ccgo_up(bp))
|
||||
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
|
||||
v3 = uint32(**(**Tu8)(__ccgo_up(v1)))
|
||||
} else {
|
||||
v3 = _sqlite3Utf8Read(tls, bp)
|
||||
}
|
||||
ch = v3
|
||||
if !(_strContainsChar(tls, zPass, nPass, ch) != 0) {
|
||||
goto unhex_null
|
||||
}
|
||||
c = **(**Tu8)(__ccgo_up(**(**uintptr)(__ccgo_up(bp))))
|
||||
if libc.Int32FromUint8(c) == 0x00 {
|
||||
goto unhex_done
|
||||
}
|
||||
}
|
||||
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
|
||||
v1 = **(**uintptr)(__ccgo_up(bp))
|
||||
**(**uintptr)(__ccgo_up(bp)) = **(**uintptr)(__ccgo_up(bp)) + 1
|
||||
d = **(**Tu8)(__ccgo_up(v1))
|
||||
if !(libc.Int32FromUint8(_sqlite3CtypeMap[d])&libc.Int32FromInt32(0x08) != 0) {
|
||||
goto unhex_null
|
||||
}
|
||||
v1 = p
|
||||
p = p + 1
|
||||
**(**Tu8)(__ccgo_up(v1)) = libc.Uint8FromInt32(libc.Int32FromUint8(_sqlite3HexToInt(tls, libc.Int32FromUint8(c)))<<int32(4) | libc.Int32FromUint8(_sqlite3HexToInt(tls, libc.Int32FromUint8(d))))
|
||||
}
|
||||
}
|
||||
goto unhex_done
|
||||
unhex_done:
|
||||
;
|
||||
Xsqlite3_result_blob(tls, pCtx, pBlob, int32(int64(p)-int64(pBlob)), __ccgo_fp(Xsqlite3_free))
|
||||
return
|
||||
goto unhex_null
|
||||
unhex_null:
|
||||
;
|
||||
Xsqlite3_free(tls, pBlob)
|
||||
return
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Attempt to set the size of the memory mapping maintained by file
|
||||
// ** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
||||
// **
|
||||
// ** If successful, this function sets the following variables:
|
||||
// **
|
||||
// ** unixFile.pMapRegion
|
||||
// ** unixFile.mmapSize
|
||||
// ** unixFile.mmapSizeActual
|
||||
// **
|
||||
// ** If unsuccessful, an error message is logged via sqlite3_log() and
|
||||
// ** the three variables above are zeroed. In this case SQLite should
|
||||
// ** continue accessing the database using the xRead() and xWrite()
|
||||
// ** methods.
|
||||
// */
|
||||
func _unixRemapfile(tls *libc.TLS, pFd uintptr, nNew Ti64) {
|
||||
var flags, h, szSyspage int32
|
||||
var nOrig, nReuse Ti64
|
||||
var pNew, pOrig, pReq, zErr uintptr
|
||||
var v1 Tsqlite3_int64
|
||||
_, _, _, _, _, _, _, _, _, _ = flags, h, nOrig, nReuse, pNew, pOrig, pReq, szSyspage, zErr, v1
|
||||
zErr = __ccgo_ts + 3698
|
||||
h = (*TunixFile)(unsafe.Pointer(pFd)).Fh /* File descriptor open on db file */
|
||||
pOrig = (*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion /* Pointer to current file mapping */
|
||||
nOrig = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeActual /* Size of pOrig region in bytes */
|
||||
pNew = uintptr(0) /* Location of new mapping */
|
||||
flags = int32(PROT_READ) /* Flags to pass to mmap() */
|
||||
if pOrig != 0 {
|
||||
szSyspage = (*(*func(*libc.TLS) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(25)].FpCurrent})))(tls)
|
||||
nReuse = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSize & int64(^(szSyspage - libc.Int32FromInt32(1)))
|
||||
pReq = pOrig + uintptr(nReuse)
|
||||
/* Unmap any pages of the existing mapping that cannot be reused. */
|
||||
if nReuse != nOrig {
|
||||
(*(*func(*libc.TLS, uintptr, Tsize_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(23)].FpCurrent})))(tls, pReq, libc.Uint64FromInt64(nOrig-nReuse))
|
||||
}
|
||||
pNew = (*(*func(*libc.TLS, uintptr, Tsize_t, int32, int32, int32, Toff_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(22)].FpCurrent})))(tls, pReq, libc.Uint64FromInt64(nNew-nReuse), flags, int32(MAP_SHARED), h, nReuse)
|
||||
if pNew != uintptr(-libc.Int32FromInt32(1)) {
|
||||
if pNew != pReq {
|
||||
(*(*func(*libc.TLS, uintptr, Tsize_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(23)].FpCurrent})))(tls, pNew, libc.Uint64FromInt64(nNew-nReuse))
|
||||
pNew = uintptr(0)
|
||||
} else {
|
||||
pNew = pOrig
|
||||
}
|
||||
}
|
||||
/* The attempt to extend the existing mapping failed. Free it. */
|
||||
if pNew == uintptr(-libc.Int32FromInt32(1)) || pNew == uintptr(0) {
|
||||
(*(*func(*libc.TLS, uintptr, Tsize_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(23)].FpCurrent})))(tls, pOrig, libc.Uint64FromInt64(nReuse))
|
||||
}
|
||||
}
|
||||
/* If pNew is still NULL, try to create an entirely new mapping. */
|
||||
if pNew == uintptr(0) {
|
||||
pNew = (*(*func(*libc.TLS, uintptr, Tsize_t, int32, int32, int32, Toff_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(22)].FpCurrent})))(tls, uintptr(0), libc.Uint64FromInt64(nNew), flags, int32(MAP_SHARED), h, 0)
|
||||
}
|
||||
if pNew == uintptr(-libc.Int32FromInt32(1)) {
|
||||
pNew = uintptr(0)
|
||||
nNew = 0
|
||||
_unixLogErrorAtLine(tls, SQLITE_OK, zErr, (*TunixFile)(unsafe.Pointer(pFd)).FzPath, int32(45992))
|
||||
/* If the mmap() above failed, assume that all subsequent mmap() calls
|
||||
** will probably fail too. Fall back to using xRead/xWrite exclusively
|
||||
** in this case. */
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax = 0
|
||||
}
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion = pNew
|
||||
v1 = nNew
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeActual = v1
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSize = v1
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called as part of generating VM programs for RANGE
|
||||
// ** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
|
||||
// ** the ORDER BY term in the window, and that argument op is OP_Ge, it generates
|
||||
// ** code equivalent to:
|
||||
// **
|
||||
// ** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
|
||||
// **
|
||||
// ** The value of parameter op may also be OP_Gt or OP_Le. In these cases the
|
||||
// ** operator in the above pseudo-code is replaced with ">" or "<=", respectively.
|
||||
// **
|
||||
// ** If the sort-order for the ORDER BY term in the window is DESC, then the
|
||||
// ** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is
|
||||
// ** subtracted. And the comparison operator is inverted to - ">=" becomes "<=",
|
||||
// ** ">" becomes "<", and so on. So, with DESC sort order, if the argument op
|
||||
// ** is OP_Ge, the generated code is equivalent to:
|
||||
// **
|
||||
// ** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl;
|
||||
// **
|
||||
// ** A special type of arithmetic is used such that if csr1.peerVal is not
|
||||
// ** a numeric type (real or integer), then the result of the addition
|
||||
// ** or subtraction is a a copy of csr1.peerVal.
|
||||
// */
|
||||
func _windowCodeRangeTest(tls *libc.TLS, p uintptr, op int32, csr1 int32, regVal int32, csr2 int32, lbl int32) {
|
||||
var addr, addrDone, addrGe, arith, reg1, reg2, regString, v1 int32
|
||||
var pColl, pOrderBy, pParse, v, v2 uintptr
|
||||
_, _, _, _, _, _, _, _, _, _, _, _, _ = addr, addrDone, addrGe, arith, pColl, pOrderBy, pParse, reg1, reg2, regString, v, v1, v2
|
||||
pParse = (*TWindowCodeArg)(unsafe.Pointer(p)).FpParse
|
||||
v = _sqlite3GetVdbe(tls, pParse)
|
||||
pOrderBy = (*TWindow)(unsafe.Pointer((*TWindowCodeArg)(unsafe.Pointer(p)).FpMWin)).FpOrderBy /* ORDER BY clause for window */
|
||||
reg1 = _sqlite3GetTempReg(tls, pParse) /* Reg. for csr1.peerVal+regVal */
|
||||
reg2 = _sqlite3GetTempReg(tls, pParse)
|
||||
v2 = pParse + 60
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
||||
v1 = *(*int32)(unsafe.Pointer(v2)) /* Reg. for csr2.peerVal */
|
||||
regString = v1 /* Reg. for constant value '' */
|
||||
arith = int32(OP_Add) /* Jump destination */
|
||||
addrDone = _sqlite3VdbeMakeLabel(tls, pParse)
|
||||
/* Read the peer-value from each cursor into a register */
|
||||
_windowReadPeerValues(tls, p, csr1, reg1)
|
||||
_windowReadPeerValues(tls, p, csr2, reg2)
|
||||
if libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_DESC) != 0 {
|
||||
switch op {
|
||||
case int32(OP_Ge):
|
||||
op = int32(OP_Le)
|
||||
case int32(OP_Gt):
|
||||
op = int32(OP_Lt)
|
||||
default:
|
||||
op = int32(OP_Ge)
|
||||
break
|
||||
}
|
||||
arith = int32(OP_Subtract)
|
||||
}
|
||||
/* If the BIGNULL flag is set for the ORDER BY, then it is required to
|
||||
** consider NULL values to be larger than all other values, instead of
|
||||
** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this
|
||||
** (and adding that capability causes a performance regression), so
|
||||
** instead if the BIGNULL flag is set then cases where either reg1 or
|
||||
** reg2 are NULL are handled separately in the following block. The code
|
||||
** generated is equivalent to:
|
||||
**
|
||||
** if( reg1 IS NULL ){
|
||||
** if( op==OP_Ge ) goto lbl;
|
||||
** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl;
|
||||
** if( op==OP_Le && reg2 IS NULL ) goto lbl;
|
||||
** }else if( reg2 IS NULL ){
|
||||
** if( op==OP_Le ) goto lbl;
|
||||
** }
|
||||
**
|
||||
** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is
|
||||
** not taken, control jumps over the comparison operator coded below this
|
||||
** block. */
|
||||
if libc.Int32FromUint8((*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).Ffg.FsortFlags)&int32(KEYINFO_ORDER_BIGNULL) != 0 {
|
||||
/* This block runs if reg1 contains a NULL. */
|
||||
addr = _sqlite3VdbeAddOp1(tls, v, int32(OP_NotNull), reg1)
|
||||
switch op {
|
||||
case int32(OP_Ge):
|
||||
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, lbl)
|
||||
case int32(OP_Gt):
|
||||
_sqlite3VdbeAddOp2(tls, v, int32(OP_NotNull), reg2, lbl)
|
||||
case int32(OP_Le):
|
||||
_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), reg2, lbl)
|
||||
default: /* no-op */
|
||||
break
|
||||
}
|
||||
_sqlite3VdbeAddOp2(tls, v, int32(OP_Goto), 0, addrDone)
|
||||
/* This block runs if reg1 is not NULL, but reg2 is. */
|
||||
_sqlite3VdbeJumpHere(tls, v, addr)
|
||||
if op == int32(OP_Gt) || op == int32(OP_Ge) {
|
||||
v1 = addrDone
|
||||
} else {
|
||||
v1 = lbl
|
||||
}
|
||||
_sqlite3VdbeAddOp2(tls, v, int32(OP_IsNull), reg2, v1)
|
||||
}
|
||||
/* Register reg1 currently contains csr1.peerVal (the peer-value from csr1).
|
||||
** This block adds (or subtracts for DESC) the numeric value in regVal
|
||||
** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob),
|
||||
** then leave reg1 as it is. In pseudo-code, this is implemented as:
|
||||
**
|
||||
** if( reg1>='' ) goto addrGe;
|
||||
** reg1 = reg1 +/- regVal
|
||||
** addrGe:
|
||||
**
|
||||
** Since all strings and blobs are greater-than-or-equal-to an empty string,
|
||||
** the add/subtract is skipped for these, as required. If reg1 is a NULL,
|
||||
** then the arithmetic is performed, but since adding or subtracting from
|
||||
** NULL is always NULL anyway, this case is handled as required too. */
|
||||
_sqlite3VdbeAddOp4(tls, v, int32(OP_String8), 0, regString, 0, __ccgo_ts+1702, -int32(1))
|
||||
addrGe = _sqlite3VdbeAddOp3(tls, v, int32(OP_Ge), regString, 0, reg1)
|
||||
if op == int32(OP_Ge) && arith == int32(OP_Add) || op == int32(OP_Le) && arith == int32(OP_Subtract) {
|
||||
_sqlite3VdbeAddOp3(tls, v, op, reg2, lbl, reg1)
|
||||
}
|
||||
_sqlite3VdbeAddOp3(tls, v, arith, regVal, reg1, reg1)
|
||||
_sqlite3VdbeJumpHere(tls, v, addrGe)
|
||||
/* Compare registers reg2 and reg1, taking the jump if required. Note that
|
||||
** control skips over this test if the BIGNULL flag is set and either
|
||||
** reg1 or reg2 contain a NULL value. */
|
||||
_sqlite3VdbeAddOp3(tls, v, op, reg2, lbl, reg1)
|
||||
pColl = _sqlite3ExprNNCollSeq(tls, pParse, (*(*TExprList_item)(unsafe.Pointer(pOrderBy + 8))).FpExpr)
|
||||
_sqlite3VdbeAppendP4(tls, v, pColl, -int32(2))
|
||||
_sqlite3VdbeChangeP5(tls, v, uint16(SQLITE_NULLEQ))
|
||||
_sqlite3VdbeResolveLabel(tls, v, addrDone)
|
||||
_sqlite3ReleaseTempReg(tls, pParse, reg1)
|
||||
_sqlite3ReleaseTempReg(tls, pParse, reg2)
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && 386) || (freebsd && amd64) || (freebsd && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
type TFILE = struct {
|
||||
F_p uintptr
|
||||
F_r int32
|
||||
F_w int32
|
||||
F_flags int16
|
||||
F_file int16
|
||||
F_bf t__sbuf
|
||||
F_lbfsize int32
|
||||
F_cookie uintptr
|
||||
F_close uintptr
|
||||
F_read uintptr
|
||||
F_seek uintptr
|
||||
F_write uintptr
|
||||
F_ub t__sbuf
|
||||
F_up uintptr
|
||||
F_ur int32
|
||||
F_ubuf [3]uint8
|
||||
F_nbuf [1]uint8
|
||||
F_lb t__sbuf
|
||||
F_blksize int32
|
||||
F_offset Tfpos_t
|
||||
F_fl_mutex uintptr
|
||||
F_fl_owner uintptr
|
||||
F_fl_count int32
|
||||
F_orientation int32
|
||||
F_mbstate t__mbstate_t
|
||||
F_flags2 int32
|
||||
}
|
||||
|
||||
type Tfiobmap2_arg = struct {
|
||||
Fbn t__daddr_t
|
||||
Frunp int32
|
||||
Frunb int32
|
||||
}
|
||||
|
||||
type Tflock = struct {
|
||||
Fl_start Toff_t
|
||||
Fl_len Toff_t
|
||||
Fl_pid Tpid_t
|
||||
Fl_type int16
|
||||
Fl_whence int16
|
||||
Fl_sysid int32
|
||||
}
|
||||
|
||||
type Tmax_align_t = struct {
|
||||
F__max_align1 int64
|
||||
F__max_align2 float64
|
||||
}
|
||||
|
||||
type Tspacectl_range = struct {
|
||||
Fr_offset Toff_t
|
||||
Fr_len Toff_t
|
||||
}
|
||||
|
||||
type Tvm_paddr_t = uint64
|
||||
|
||||
type t__max_align_t = struct {
|
||||
F__max_align1 int64
|
||||
F__max_align2 float64
|
||||
}
|
||||
|
||||
type t__oflock = struct {
|
||||
Fl_start Toff_t
|
||||
Fl_len Toff_t
|
||||
Fl_pid Tpid_t
|
||||
Fl_type int16
|
||||
Fl_whence int16
|
||||
}
|
||||
|
||||
type t__sFILE = struct {
|
||||
F_p uintptr
|
||||
F_r int32
|
||||
F_w int32
|
||||
F_flags int16
|
||||
F_file int16
|
||||
F_bf t__sbuf
|
||||
F_lbfsize int32
|
||||
F_cookie uintptr
|
||||
F_close uintptr
|
||||
F_read uintptr
|
||||
F_seek uintptr
|
||||
F_write uintptr
|
||||
F_ub t__sbuf
|
||||
F_up uintptr
|
||||
F_ur int32
|
||||
F_ubuf [3]uint8
|
||||
F_nbuf [1]uint8
|
||||
F_lb t__sbuf
|
||||
F_blksize int32
|
||||
F_offset Tfpos_t
|
||||
F_fl_mutex uintptr
|
||||
F_fl_owner uintptr
|
||||
F_fl_count int32
|
||||
F_orientation int32
|
||||
F_mbstate t__mbstate_t
|
||||
F_flags2 int32
|
||||
}
|
||||
|
||||
type t__vm_paddr_t = uint64
|
||||
+844
@@ -0,0 +1,844 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && arm) || (freebsd && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type T___wchar_t = uint32
|
||||
|
||||
type Tcrypt_data = struct {
|
||||
Finitialized int32
|
||||
F__buf [256]uint8
|
||||
}
|
||||
|
||||
const WCHAR_MAX = 4294967295
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if the given SQL string ends in a semicolon.
|
||||
// **
|
||||
// ** Special handling is require for CREATE TRIGGER statements.
|
||||
// ** Whenever the CREATE TRIGGER keywords are seen, the statement
|
||||
// ** must end with ";END;".
|
||||
// **
|
||||
// ** This implementation uses a state machine with 8 states:
|
||||
// **
|
||||
// ** (0) INVALID We have not yet seen a non-whitespace character.
|
||||
// **
|
||||
// ** (1) START At the beginning or end of an SQL statement. This routine
|
||||
// ** returns 1 if it ends in the START state and 0 if it ends
|
||||
// ** in any other state.
|
||||
// **
|
||||
// ** (2) NORMAL We are in the middle of statement which ends with a single
|
||||
// ** semicolon.
|
||||
// **
|
||||
// ** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
|
||||
// ** a statement.
|
||||
// **
|
||||
// ** (4) CREATE The keyword CREATE has been seen at the beginning of a
|
||||
// ** statement, possibly preceded by EXPLAIN and/or followed by
|
||||
// ** TEMP or TEMPORARY
|
||||
// **
|
||||
// ** (5) TRIGGER We are in the middle of a trigger definition that must be
|
||||
// ** ended by a semicolon, the keyword END, and another semicolon.
|
||||
// **
|
||||
// ** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
|
||||
// ** the end of a trigger definition.
|
||||
// **
|
||||
// ** (7) END We've seen the ";END" of the ";END;" that occurs at the end
|
||||
// ** of a trigger definition.
|
||||
// **
|
||||
// ** Transitions between states above are determined by tokens extracted
|
||||
// ** from the input. The following tokens are significant:
|
||||
// **
|
||||
// ** (0) tkSEMI A semicolon.
|
||||
// ** (1) tkWS Whitespace.
|
||||
// ** (2) tkOTHER Any other SQL token.
|
||||
// ** (3) tkEXPLAIN The "explain" keyword.
|
||||
// ** (4) tkCREATE The "create" keyword.
|
||||
// ** (5) tkTEMP The "temp" or "temporary" keyword.
|
||||
// ** (6) tkTRIGGER The "trigger" keyword.
|
||||
// ** (7) tkEND The "end" keyword.
|
||||
// **
|
||||
// ** Whitespace never causes a state transition and is always ignored.
|
||||
// ** This means that a SQL string of all whitespace is invalid.
|
||||
// **
|
||||
// ** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
|
||||
// ** to recognize the end of a trigger can be omitted. All we have to do
|
||||
// ** is look for a semicolon that is not part of an string or comment.
|
||||
// */
|
||||
func Xsqlite3_complete(tls *libc.TLS, zSql uintptr) (r int32) {
|
||||
var c, nId int32
|
||||
var state, token Tu8
|
||||
_, _, _, _ = c, nId, state, token
|
||||
state = uint8(0) /* Value of the next token */
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 {
|
||||
switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) {
|
||||
case int32(';'): /* A semicolon */
|
||||
token = uint8(tkSEMI)
|
||||
case int32(' '):
|
||||
fallthrough
|
||||
case int32('\r'):
|
||||
fallthrough
|
||||
case int32('\t'):
|
||||
fallthrough
|
||||
case int32('\n'):
|
||||
fallthrough
|
||||
case int32('\f'): /* White space is ignored */
|
||||
token = uint8(tkWS)
|
||||
case int32('/'): /* C-style comments */
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + 1))) != int32('*') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(2)
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != int32('*') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + 1))) != int32('/')) {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
zSql = zSql + 1
|
||||
token = uint8(tkWS)
|
||||
case int32('-'): /* SQL-style comments from "--" to end of line */
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + 1))) != int32('-') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != int32('\n') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
token = uint8(tkWS)
|
||||
case int32('['): /* Microsoft-style identifiers in [...] */
|
||||
zSql = zSql + 1
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != int32(']') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
case int32('`'): /* Grave-accent quoted symbols used by MySQL */
|
||||
fallthrough
|
||||
case int32('"'): /* single- and double-quoted strings */
|
||||
fallthrough
|
||||
case int32('\''):
|
||||
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql)))
|
||||
zSql = zSql + 1
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != c {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
default:
|
||||
if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zSql)))])&int32(0x46) != 0 {
|
||||
nId = int32(1)
|
||||
for {
|
||||
if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zSql + uintptr(nId))))])&int32(0x46) != 0) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
nId = nId + 1
|
||||
}
|
||||
switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) {
|
||||
case int32('c'):
|
||||
fallthrough
|
||||
case int32('C'):
|
||||
if nId == int32(6) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25255, int32(6)) == 0 {
|
||||
token = uint8(tkCREATE)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
case int32('t'):
|
||||
fallthrough
|
||||
case int32('T'):
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+21884, int32(7)) == 0 {
|
||||
token = uint8(tkTRIGGER)
|
||||
} else {
|
||||
if nId == int32(4) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25262, int32(4)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
if nId == int32(9) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25267, int32(9)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
case int32('e'):
|
||||
fallthrough
|
||||
case int32('E'):
|
||||
if nId == int32(3) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25277, int32(3)) == 0 {
|
||||
token = uint8(tkEND)
|
||||
} else {
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25281, int32(7)) == 0 {
|
||||
token = uint8(tkEXPLAIN)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
default:
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(nId-int32(1))
|
||||
} else {
|
||||
/* Operators and special symbols */
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
break
|
||||
}
|
||||
state = **(**Tu8)(__ccgo_up(uintptr(unsafe.Pointer(&_trans)) + uintptr(state)*8 + uintptr(token)))
|
||||
zSql = zSql + 1
|
||||
}
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
|
||||
const __MINSIGSTKSZ = 4096
|
||||
|
||||
const __WCHAR_MAX = 4294967295
|
||||
|
||||
const __WCHAR_MIN = 0
|
||||
|
||||
const __WCHAR_UNSIGNED__ = 1
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Extra floating-point literals to allow in JSON.
|
||||
// */
|
||||
var _aNanInfName = [5]TNanInfName{
|
||||
0: {
|
||||
Fc1: uint8('i'),
|
||||
Fc2: uint8('I'),
|
||||
Fn: uint8(3),
|
||||
FeType: uint8(JSONB_FLOAT),
|
||||
FnRepl: uint8(7),
|
||||
FzMatch: __ccgo_ts + 26475,
|
||||
FzRepl: __ccgo_ts + 26479,
|
||||
},
|
||||
1: {
|
||||
Fc1: uint8('i'),
|
||||
Fc2: uint8('I'),
|
||||
Fn: uint8(8),
|
||||
FeType: uint8(JSONB_FLOAT),
|
||||
FnRepl: uint8(7),
|
||||
FzMatch: __ccgo_ts + 26487,
|
||||
FzRepl: __ccgo_ts + 26479,
|
||||
},
|
||||
2: {
|
||||
Fc1: uint8('n'),
|
||||
Fc2: uint8('N'),
|
||||
Fn: uint8(3),
|
||||
FnRepl: uint8(4),
|
||||
FzMatch: __ccgo_ts + 1693,
|
||||
FzRepl: __ccgo_ts + 1688,
|
||||
},
|
||||
3: {
|
||||
Fc1: uint8('q'),
|
||||
Fc2: uint8('Q'),
|
||||
Fn: uint8(4),
|
||||
FnRepl: uint8(4),
|
||||
FzMatch: __ccgo_ts + 26496,
|
||||
FzRepl: __ccgo_ts + 1688,
|
||||
},
|
||||
4: {
|
||||
Fc1: uint8('s'),
|
||||
Fc2: uint8('S'),
|
||||
Fn: uint8(4),
|
||||
FnRepl: uint8(4),
|
||||
FzMatch: __ccgo_ts + 26501,
|
||||
FzRepl: __ccgo_ts + 1688,
|
||||
},
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Compare the 19-character string zNum against the text representation
|
||||
// ** value 2^63: 9223372036854775808. Return negative, zero, or positive
|
||||
// ** if zNum is less than, equal to, or greater than the string.
|
||||
// ** Note that zNum must contain exactly 19 characters.
|
||||
// **
|
||||
// ** Unlike memcmp() this routine is guaranteed to return the difference
|
||||
// ** in the values of the last digit if the only difference is in the
|
||||
// ** last digit. So, for example,
|
||||
// **
|
||||
// ** compare2pow63("9223372036854775800", 1)
|
||||
// **
|
||||
// ** will return -8.
|
||||
// */
|
||||
func _compare2pow63(tls *libc.TLS, zNum uintptr, incr int32) (r int32) {
|
||||
var c, i int32
|
||||
var pow63 uintptr
|
||||
_, _, _ = c, i, pow63
|
||||
c = 0
|
||||
/* 012345678901234567 */
|
||||
pow63 = __ccgo_ts + 1813
|
||||
i = 0
|
||||
for {
|
||||
if !(c == 0 && i < int32(18)) {
|
||||
break
|
||||
}
|
||||
c = (libc.Int32FromUint8(**(**uint8)(__ccgo_up(zNum + uintptr(i*incr)))) - libc.Int32FromUint8(**(**uint8)(__ccgo_up(pow63 + uintptr(i))))) * int32(10)
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if c == 0 {
|
||||
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zNum + uintptr(int32(18)*incr)))) - int32('8')
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Process a "special" query. A special query is identified as one with a
|
||||
// ** MATCH expression that begins with a '*' character. The remainder of
|
||||
// ** the text passed to the MATCH operator are used as the special query
|
||||
// ** parameters.
|
||||
// */
|
||||
func _fts5SpecialMatch(tls *libc.TLS, pTab uintptr, pCsr uintptr, zQuery uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var n, rc int32
|
||||
var z uintptr
|
||||
_, _, _ = n, rc, z
|
||||
rc = SQLITE_OK /* Return code */
|
||||
z = zQuery /* Number of bytes in text at z */
|
||||
for libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32(' ') {
|
||||
z = z + 1
|
||||
}
|
||||
n = 0
|
||||
for {
|
||||
if !(**(**uint8)(__ccgo_up(z + uintptr(n))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(n)))) != int32(' ')) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
n = n + 1
|
||||
}
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_SPECIAL)
|
||||
if n == int32(5) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+39817, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = int64(_sqlite3Fts5IndexReads(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex))
|
||||
} else {
|
||||
if n == int32(2) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+5650, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiCsrId
|
||||
} else {
|
||||
/* An unrecognized directive. Return an error message. */
|
||||
(*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39823, libc.VaList(bp+8, n, z))
|
||||
rc = int32(SQLITE_ERROR)
|
||||
}
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Interpret the given string as a temp db location. Return 1 for file
|
||||
// ** backed temporary databases, 2 for the Red-Black tree in memory database
|
||||
// ** and 0 to use the compile-time default.
|
||||
// */
|
||||
func _getTempStore(tls *libc.TLS, z uintptr) (r int32) {
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) <= int32('2') {
|
||||
return libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) - int32('0')
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+17994) == 0 {
|
||||
return int32(1)
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+19035) == 0 {
|
||||
return int32(2)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a complete JSON string. Return 0 on success or non-zero if there
|
||||
// ** are any errors. If an error occurs, free all memory held by pParse,
|
||||
// ** but not pParse itself.
|
||||
// **
|
||||
// ** pParse must be initialized to an empty parse object prior to calling
|
||||
// ** this routine.
|
||||
// */
|
||||
func _jsonConvertTextToBlob(tls *libc.TLS, pParse uintptr, pCtx uintptr) (r int32) {
|
||||
var i int32
|
||||
var zJson uintptr
|
||||
_, _ = i, zJson
|
||||
zJson = (*TJsonParse)(unsafe.Pointer(pParse)).FzJson
|
||||
i = _jsonTranslateTextToBlob(tls, pParse, uint32(0))
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
i = -int32(1)
|
||||
}
|
||||
if i > 0 {
|
||||
for _jsonIsSpace[uint8(**(**uint8)(__ccgo_up(zJson + uintptr(i))))] != 0 {
|
||||
i = i + 1
|
||||
}
|
||||
if **(**uint8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
i = i + _json5Whitespace(tls, zJson+uintptr(i))
|
||||
if **(**uint8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
if pCtx != 0 {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26460, -int32(1))
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
(*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1)
|
||||
}
|
||||
}
|
||||
if i <= 0 {
|
||||
if pCtx != uintptr(0) {
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
Xsqlite3_result_error_nomem(tls, pCtx)
|
||||
} else {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26460, -int32(1))
|
||||
}
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a timezone extension on the end of a date-time.
|
||||
// ** The extension is of the form:
|
||||
// **
|
||||
// ** (+/-)HH:MM
|
||||
// **
|
||||
// ** Or the "zulu" notation:
|
||||
// **
|
||||
// ** Z
|
||||
// **
|
||||
// ** If the parse is successful, write the number of minutes
|
||||
// ** of change in p->tz and return 0. If a parser error occurs,
|
||||
// ** return non-zero.
|
||||
// **
|
||||
// ** A missing specifier is not considered an error.
|
||||
// */
|
||||
func _parseTimezone(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c, sgn int32
|
||||
var _ /* nHr at bp+0 */ int32
|
||||
var _ /* nMn at bp+4 */ int32
|
||||
_, _ = c, sgn
|
||||
sgn = 0
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = 0
|
||||
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate)))
|
||||
if c == int32('-') {
|
||||
sgn = -int32(1)
|
||||
} else {
|
||||
if c == int32('+') {
|
||||
sgn = +libc.Int32FromInt32(1)
|
||||
} else {
|
||||
if c == int32('Z') || c == int32('z') {
|
||||
zDate = zDate + 1
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
goto zulu_time
|
||||
} else {
|
||||
return libc.BoolInt32(c != 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1194, libc.VaList(bp+16, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = sgn * (**(**int32)(__ccgo_up(bp + 4)) + **(**int32)(__ccgo_up(bp))*int32(60))
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz == 0 { /* Forum post 2025-09-17T10:12:14z */
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
}
|
||||
goto zulu_time
|
||||
zulu_time:
|
||||
;
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
return libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) != 0)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse dates of the form
|
||||
// **
|
||||
// ** YYYY-MM-DD HH:MM:SS.FFF
|
||||
// ** YYYY-MM-DD HH:MM:SS
|
||||
// ** YYYY-MM-DD HH:MM
|
||||
// ** YYYY-MM-DD
|
||||
// **
|
||||
// ** Write the result into the DateTime structure and return 0
|
||||
// ** on success and 1 if the input string is not a well-formed
|
||||
// ** date.
|
||||
// */
|
||||
func _parseYyyyMmDd(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var neg, v1 int32
|
||||
var _ /* D at bp+8 */ int32
|
||||
var _ /* M at bp+4 */ int32
|
||||
var _ /* Y at bp+0 */ int32
|
||||
_, _ = neg, v1
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) == int32('-') {
|
||||
zDate = zDate + 1
|
||||
neg = int32(1)
|
||||
} else {
|
||||
neg = 0
|
||||
}
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1214, libc.VaList(bp+24, bp, bp+4, bp+8)) != int32(3) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(10)
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x01) != 0 || int32('T') == libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zDate))) {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
if _parseHhMmSs(tls, zDate, p) == 0 {
|
||||
/* We got the time */
|
||||
} else {
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) == 0 {
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = uint8(0)
|
||||
} else {
|
||||
return int32(1)
|
||||
}
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = uint8(0)
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidYMD = uint8(1)
|
||||
if neg != 0 {
|
||||
v1 = -**(**int32)(__ccgo_up(bp))
|
||||
} else {
|
||||
v1 = **(**int32)(__ccgo_up(bp))
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FY = v1
|
||||
(*TDateTime)(unsafe.Pointer(p)).FM = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).FD = **(**int32)(__ccgo_up(bp + 8))
|
||||
_computeFloor(tls, p)
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz != 0 {
|
||||
_computeJD(tls, p)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Allocate a private rbu VFS for the rbu handle passed as the only
|
||||
// ** argument. This VFS will be used unless the call to sqlite3rbu_open()
|
||||
// ** specified a URI with a vfs=? option in place of a target database
|
||||
// ** file name.
|
||||
// */
|
||||
func _rbuCreateVfs(tls *libc.TLS, p uintptr) {
|
||||
bp := tls.Alloc(96)
|
||||
defer tls.Free(96)
|
||||
var pVfs uintptr
|
||||
var _ /* rnd at bp+0 */ int32
|
||||
var _ /* zRnd at bp+4 */ [64]uint8
|
||||
_ = pVfs
|
||||
Xsqlite3_randomness(tls, int32(4), bp)
|
||||
Xsqlite3_snprintf(tls, int32(64), bp+4, __ccgo_ts+34328, libc.VaList(bp+80, **(**int32)(__ccgo_up(bp))))
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3rbu_create_vfs(tls, bp+4, uintptr(0))
|
||||
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
||||
pVfs = Xsqlite3_vfs_find(tls, bp+4)
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzVfsName = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FzName
|
||||
(*Trbu_vfs)(unsafe.Pointer(pVfs)).FpRbu = p
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** An error occurred while parsing or otherwise processing a database
|
||||
// ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
|
||||
// ** ALTER TABLE RENAME COLUMN program. The error message emitted by the
|
||||
// ** sub-routine is currently stored in pParse->zErrMsg. This function
|
||||
// ** adds context to the error message and then stores it in pCtx.
|
||||
// */
|
||||
func _renameColumnParseError(tls *libc.TLS, pCtx uintptr, zWhen uintptr, pType uintptr, pObject uintptr, pParse uintptr) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var zErr, zN, zT, v1 uintptr
|
||||
_, _, _, _ = zErr, zN, zT, v1
|
||||
zT = Xsqlite3_value_text(tls, pType)
|
||||
zN = Xsqlite3_value_text(tls, pObject)
|
||||
if **(**uint8)(__ccgo_up(zWhen)) != 0 {
|
||||
v1 = __ccgo_ts + 11543
|
||||
} else {
|
||||
v1 = __ccgo_ts + 1702
|
||||
}
|
||||
zErr = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+11545, libc.VaList(bp+8, zT, zN, v1, zWhen, (*TParse)(unsafe.Pointer(pParse)).FzErrMsg))
|
||||
Xsqlite3_result_error(tls, pCtx, zErr, -int32(1))
|
||||
_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zErr)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /* IMP: R-25361-16150 This function is omitted from SQLite by default. It
|
||||
// ** is only available if the SQLITE_SOUNDEX compile-time option is used
|
||||
// ** when SQLite is built.
|
||||
// */
|
||||
// /*
|
||||
// ** Compute the soundex encoding of a word.
|
||||
// **
|
||||
// ** IMP: R-59782-00072 The soundex(X) function returns a string that is the
|
||||
// ** soundex encoding of the string X.
|
||||
// */
|
||||
func _soundexFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var code, i, j, v3 int32
|
||||
var prevcode Tu8
|
||||
var zIn uintptr
|
||||
var _ /* zResult at bp+0 */ [8]uint8
|
||||
_, _, _, _, _, _ = code, i, j, prevcode, zIn, v3
|
||||
zIn = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
if zIn == uintptr(0) {
|
||||
zIn = __ccgo_ts + 1702
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(**(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))])&libc.Int32FromInt32(0x02) != 0)) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 {
|
||||
prevcode = _iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)]
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[0] = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i)))) & ^(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))]) & libc.Int32FromInt32(0x20)))
|
||||
j = int32(1)
|
||||
for {
|
||||
if !(j < int32(4) && **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0) {
|
||||
break
|
||||
}
|
||||
code = libc.Int32FromUint8(_iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)])
|
||||
if code > 0 {
|
||||
if code != libc.Int32FromUint8(prevcode) {
|
||||
prevcode = libc.Uint8FromInt32(code)
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[v3] = libc.Uint8FromInt32(code + int32('0'))
|
||||
}
|
||||
} else {
|
||||
prevcode = uint8(0)
|
||||
}
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
for j < int32(4) {
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[v3] = uint8('0')
|
||||
}
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[j] = uint8(0)
|
||||
Xsqlite3_result_text(tls, context, bp, int32(4), uintptr(-libc.Int32FromInt32(1)))
|
||||
} else {
|
||||
/* IMP: R-64894-50321 The string "?000" is returned if the argument
|
||||
** is NULL or contains no ASCII alphabetic characters. */
|
||||
Xsqlite3_result_text(tls, context, __ccgo_ts+16596, int32(4), libc.UintptrFromInt32(0))
|
||||
}
|
||||
}
|
||||
|
||||
func _sqlite3Fts5ParseSetDistance(tls *libc.TLS, pParse uintptr, pNear uintptr, p uintptr) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c uint8
|
||||
var i, nNear int32
|
||||
_, _, _ = c, i, nNear
|
||||
if pNear != 0 {
|
||||
nNear = 0
|
||||
if (*TFts5Token)(unsafe.Pointer(p)).Fn != 0 {
|
||||
i = 0
|
||||
for {
|
||||
if !(i < (*TFts5Token)(unsafe.Pointer(p)).Fn) {
|
||||
break
|
||||
}
|
||||
c = **(**uint8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))
|
||||
if libc.Int32FromUint8(c) < int32('0') || libc.Int32FromUint8(c) > int32('9') {
|
||||
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38608, libc.VaList(bp+8, (*TFts5Token)(unsafe.Pointer(p)).Fn, (*TFts5Token)(unsafe.Pointer(p)).Fp))
|
||||
return
|
||||
}
|
||||
if nNear < int32(214748363) {
|
||||
nNear = nNear*int32(10) + (libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))) - int32('0'))
|
||||
}
|
||||
/* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
} else {
|
||||
nNear = int32(FTS5_DEFAULT_NEARDIST)
|
||||
}
|
||||
(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnNear = nNear
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Append to pStr text that is the SQL literal representation of the
|
||||
// ** value contained in pValue.
|
||||
// */
|
||||
func _sqlite3QuoteValue(tls *libc.TLS, pStr uintptr, pValue uintptr, bEscape int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var i int32
|
||||
var nBlob Ti64
|
||||
var zArg, zBlob, zText, v2 uintptr
|
||||
_, _, _, _, _, _ = i, nBlob, zArg, zBlob, zText, v2
|
||||
/* As currently implemented, the string must be initially empty.
|
||||
** we might relax this requirement in the future, but that will
|
||||
** require enhancements to the implementation. */
|
||||
switch Xsqlite3_value_type(tls, pValue) {
|
||||
case int32(SQLITE_FLOAT):
|
||||
/* ,--- Show infinity as 9.0e+999
|
||||
** |
|
||||
** | ,--- 17 precision guarantees round-trip
|
||||
** v v */
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+16561, libc.VaList(bp+8, Xsqlite3_value_double(tls, pValue)))
|
||||
case int32(SQLITE_INTEGER):
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+1463, libc.VaList(bp+8, Xsqlite3_value_int64(tls, pValue)))
|
||||
case int32(SQLITE_BLOB):
|
||||
zBlob = Xsqlite3_value_blob(tls, pValue)
|
||||
nBlob = int64(Xsqlite3_value_bytes(tls, pValue))
|
||||
/* No encoding change */
|
||||
_sqlite3StrAccumEnlarge(tls, pStr, nBlob*int64(2)+int64(4))
|
||||
if libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(pStr)).FaccError) == 0 {
|
||||
zText = (*TStrAccum)(unsafe.Pointer(pStr)).FzText
|
||||
i = 0
|
||||
for {
|
||||
if !(int64(i) < nBlob) {
|
||||
break
|
||||
}
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(2)))) = _hexdigits[libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBlob + uintptr(i))))>>int32(4)&int32(0x0F)]
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(3)))) = _hexdigits[libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBlob + uintptr(i))))&int32(0x0F)]
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(2)))) = uint8('\'')
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(3)))) = uint8('\000')
|
||||
**(**uint8)(__ccgo_up(zText)) = uint8('X')
|
||||
**(**uint8)(__ccgo_up(zText + 1)) = uint8('\'')
|
||||
(*TStrAccum)(unsafe.Pointer(pStr)).FnChar = libc.Uint32FromInt64(nBlob*int64(2) + int64(3))
|
||||
}
|
||||
case int32(SQLITE_TEXT):
|
||||
zArg = Xsqlite3_value_text(tls, pValue)
|
||||
if bEscape != 0 {
|
||||
v2 = __ccgo_ts + 16569
|
||||
} else {
|
||||
v2 = __ccgo_ts + 11927
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, pStr, v2, libc.VaList(bp+8, zArg))
|
||||
default:
|
||||
Xsqlite3_str_append(tls, pStr, __ccgo_ts+1703, int32(4))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Create a temporary file name in zBuf. zBuf must be allocated
|
||||
// ** by the calling process and must be big enough to hold at least
|
||||
// ** pVfs->mxPathname bytes.
|
||||
// */
|
||||
func _unixGetTempname(tls *libc.TLS, nBuf int32, zBuf uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var iLimit, rc, v1 int32
|
||||
var zDir uintptr
|
||||
var v2 bool
|
||||
var _ /* r at bp+0 */ Tu64
|
||||
_, _, _, _, _ = iLimit, rc, zDir, v1, v2
|
||||
iLimit = 0
|
||||
rc = SQLITE_OK
|
||||
/* It's odd to simulate an io-error here, but really this is just
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
** function failing.
|
||||
*/
|
||||
**(**uint8)(__ccgo_up(zBuf)) = uint8(0)
|
||||
Xsqlite3_mutex_enter(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
zDir = _unixTempFileDir(tls)
|
||||
if zDir == uintptr(0) {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(25)<<libc.Int32FromInt32(8)
|
||||
} else {
|
||||
for cond := true; cond; cond = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zBuf, 0) == 0 {
|
||||
Xsqlite3_randomness(tls, int32(8), bp)
|
||||
**(**uint8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2)))) = uint8(0)
|
||||
Xsqlite3_snprintf(tls, nBuf, zBuf, __ccgo_ts+4043, libc.VaList(bp+16, zDir, **(**Tu64)(__ccgo_up(bp)), 0))
|
||||
if v2 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2))))) != 0; !v2 {
|
||||
v1 = iLimit
|
||||
iLimit = iLimit + 1
|
||||
}
|
||||
if v2 || v1 > int32(10) {
|
||||
rc = int32(SQLITE_ERROR)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** The following code executes when a syntax error first occurs.
|
||||
// */
|
||||
func _yy_syntax_error(tls *libc.TLS, yypParser uintptr, yymajor int32, _yyminor TToken) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
*(*TToken)(unsafe.Pointer(bp)) = _yyminor
|
||||
var pParse uintptr
|
||||
_ = pParse
|
||||
pParse = (*TyyParser)(unsafe.Pointer(yypParser)).FpParse
|
||||
/************ Begin %syntax_error code ****************************************/
|
||||
_ = yymajor /* Silence some compiler warnings */
|
||||
if **(**uint8)(__ccgo_up((**(**TToken)(__ccgo_up(bp))).Fz)) != 0 {
|
||||
_parserSyntaxError(tls, pParse, bp)
|
||||
} else {
|
||||
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+25202, 0)
|
||||
}
|
||||
/************ End %syntax_error code ******************************************/
|
||||
/* Suppress warning about unused %extra_argument variable */
|
||||
(*TyyParser)(unsafe.Pointer(yypParser)).FpParse = pParse
|
||||
}
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && amd64) || (freebsd && arm) || (freebsd && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
const CLOCK_BOOTTIME = 4
|
||||
|
||||
const CLOCK_TAI = 16
|
||||
|
||||
const CLOSE_RANGE_CLOFORK = 8
|
||||
|
||||
const COPY_FILE_RANGE_CLONE = 8388608
|
||||
|
||||
const COPY_FILE_RANGE_USERFLAGS = 8388608
|
||||
|
||||
const FD_RESOLVE_BENEATH = 2
|
||||
|
||||
const F_DUP3FD = 24
|
||||
|
||||
const F_DUP3FD_SHIFT = 16
|
||||
|
||||
const F_DUPFD_CLOFORK = 23
|
||||
|
||||
const MINCORE_PSIND_SHIFT = 5
|
||||
|
||||
const O_CLOFORK = 134217728
|
||||
|
||||
const O_NAMEDATTR = 67108864
|
||||
|
||||
const O_XATTR = 67108864
|
||||
|
||||
const PROT_CHERI0 = 8
|
||||
|
||||
const PROT_CHERI1 = 16
|
||||
|
||||
const _PC_CLONE_BLKSIZE = 69
|
||||
|
||||
const _PC_HAS_HIDDENSYSTEM = 68
|
||||
|
||||
const _PC_HAS_NAMEDATTR = 67
|
||||
|
||||
const _PC_NAMEDATTR_ENABLED = 66
|
||||
|
||||
const _PC_XATTR_ENABLED = 66
|
||||
|
||||
const _PC_XATTR_EXISTS = 67
|
||||
|
||||
const _SC_NSIG = 124
|
||||
|
||||
const _SC_UEXTERR_MAXLEN = 123
|
||||
|
||||
const __CC_SUPPORTS_SYMVER = 1
|
||||
|
||||
const __FreeBSD__ = 15
|
||||
|
||||
const __FreeBSD_cc_version = 1500000
|
||||
|
||||
const __SSP_FORTIFY_LEVEL = 0
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Find the mode, uid and gid of file zFile.
|
||||
// */
|
||||
func _getFileMode(tls *libc.TLS, zFile uintptr, pMode uintptr, pUid uintptr, pGid uintptr) (r int32) {
|
||||
bp := tls.Alloc(224)
|
||||
defer tls.Free(224)
|
||||
var rc int32
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
_ = rc /* Output of stat() on database file */
|
||||
rc = SQLITE_OK
|
||||
if 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zFile, bp) {
|
||||
**(**Tmode_t)(__ccgo_up(pMode)) = libc.Uint16FromInt32(libc.Int32FromUint16((**(**Tstat)(__ccgo_up(bp))).Fst_mode) & int32(0777))
|
||||
**(**Tuid_t)(__ccgo_up(pUid)) = (**(**Tstat)(__ccgo_up(bp))).Fst_uid
|
||||
**(**Tgid_t)(__ccgo_up(pGid)) = (**(**Tstat)(__ccgo_up(bp))).Fst_gid
|
||||
} else {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Invoke open(). Do so multiple times, until it either succeeds or
|
||||
// ** fails for some reason other than EINTR.
|
||||
// **
|
||||
// ** If the file creation mode "m" is 0 then set it to the default for
|
||||
// ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
|
||||
// ** 0644) as modified by the system umask. If m is not 0, then
|
||||
// ** make the file creation mode be exactly m ignoring the umask.
|
||||
// **
|
||||
// ** The m parameter will be non-zero only when creating -wal, -journal,
|
||||
// ** and -shm files. We want those files to have *exactly* the same
|
||||
// ** permissions as their original database, unadulterated by the umask.
|
||||
// ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
|
||||
// ** transaction crashes and leaves behind hot journals, then any
|
||||
// ** process that is able to write to the database will also be able to
|
||||
// ** recover the hot journals.
|
||||
// */
|
||||
func _robust_open(tls *libc.TLS, z uintptr, f int32, m Tmode_t) (r int32) {
|
||||
bp := tls.Alloc(256)
|
||||
defer tls.Free(256)
|
||||
var fd, v1 int32
|
||||
var m2 Tmode_t
|
||||
var _ /* statbuf at bp+0 */ Tstat
|
||||
_, _, _ = fd, m2, v1
|
||||
if m != 0 {
|
||||
v1 = libc.Int32FromUint16(m)
|
||||
} else {
|
||||
v1 = int32(SQLITE_DEFAULT_FILE_PERMISSIONS)
|
||||
}
|
||||
m2 = libc.Uint16FromInt32(v1)
|
||||
for int32(1) != 0 {
|
||||
fd = (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, z, f|int32(O_CLOEXEC), libc.Int32FromUint16(m2))
|
||||
if fd < 0 {
|
||||
if **(**int32)(__ccgo_up(libc.X__error(tls))) == int32(EINTR) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if fd >= int32(SQLITE_MINIMUM_FILE_DESCRIPTOR) {
|
||||
break
|
||||
}
|
||||
if f&(libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT)) == libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT) {
|
||||
(*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(16)].FpCurrent})))(tls, z)
|
||||
}
|
||||
(*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(1)].FpCurrent})))(tls, fd)
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3750, libc.VaList(bp+232, z, fd))
|
||||
fd = -int32(1)
|
||||
if (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, __ccgo_ts+3793, O_RDONLY, libc.Int32FromUint16(m)) < 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if fd >= 0 {
|
||||
if libc.Int32FromUint16(m) != 0 {
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, fd, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_size == 0 && libc.Int32FromUint16((**(**Tstat)(__ccgo_up(bp))).Fst_mode)&int32(0777) != libc.Int32FromUint16(m) {
|
||||
(*(*func(*libc.TLS, int32, Tmode_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(14)].FpCurrent})))(tls, fd, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return the fallback token corresponding to canonical token iToken, or
|
||||
// ** 0 if iToken has no fallback.
|
||||
// */
|
||||
func _sqlite3Fts5ParserFallback(tls *libc.TLS, iToken int32) (r int32) {
|
||||
_ = iToken
|
||||
return 0
|
||||
}
|
||||
|
||||
/*
|
||||
** 2014 May 31
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* #include "fts5Int.h" */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Test the existence of or access permissions of file zPath. The
|
||||
// ** test performed depends on the value of flags:
|
||||
// **
|
||||
// ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
|
||||
// ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
|
||||
// ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
|
||||
// **
|
||||
// ** Otherwise return 0.
|
||||
// */
|
||||
func _unixAccess(tls *libc.TLS, NotUsed uintptr, zPath uintptr, flags int32, pResOut uintptr) (r int32) {
|
||||
bp := tls.Alloc(224)
|
||||
defer tls.Free(224)
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = NotUsed
|
||||
/* The spec says there are three possible values for flags. But only
|
||||
** two of them are actually used */
|
||||
if flags == SQLITE_ACCESS_EXISTS {
|
||||
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32(0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zPath, bp) && (!(libc.Int32FromUint16((**(**Tstat)(__ccgo_up(bp))).Fst_mode)&libc.Int32FromInt32(0170000) == libc.Int32FromInt32(0100000)) || (**(**Tstat)(__ccgo_up(bp))).Fst_size > 0))
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32((*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zPath, libc.Int32FromInt32(W_OK)|libc.Int32FromInt32(R_OK)) == 0)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Check a unixFile that is a database. Verify the following:
|
||||
// **
|
||||
// ** (1) There is exactly one hard link on the file
|
||||
// ** (2) The file is not a symbolic link
|
||||
// ** (3) The file has not been renamed or unlinked
|
||||
// **
|
||||
// ** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
|
||||
// */
|
||||
func _verifyDbFile(tls *libc.TLS, pFile uintptr) {
|
||||
bp := tls.Alloc(240)
|
||||
defer tls.Free(240)
|
||||
var rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = rc
|
||||
/* These verifications occurs for the main database only */
|
||||
if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_NOLOCK) != 0 {
|
||||
return
|
||||
}
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp)
|
||||
if rc != 0 {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3834, libc.VaList(bp+232, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink == uint64(0) {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3858, libc.VaList(bp+232, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink > uint64(1) {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3887, libc.VaList(bp+232, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if _fileHasMoved(tls, pFile) != 0 {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3914, libc.VaList(bp+232, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type t__acl_entry_type_t = uint16
|
||||
|
||||
type t__acl_flag_t = uint16
|
||||
|
||||
type t__acl_flagset_t = uintptr
|
||||
|
||||
type t__acl_perm_t = uint32
|
||||
|
||||
type t__acl_permset_t = uintptr
|
||||
|
||||
type t__acl_tag_t = uint32
|
||||
|
||||
type t__acl_type_t = uint32
|
||||
+6700
File diff suppressed because one or more lines are too long
+1476
File diff suppressed because it is too large
Load Diff
+63
@@ -0,0 +1,63 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (linux && 386)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if pFile has been renamed or unlinked since it was first opened.
|
||||
// */
|
||||
func _fileHasMoved(tls *libc.TLS, pFile uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
return libc.BoolInt32((*TunixFile)(unsafe.Pointer(pFile)).FpInode != uintptr(0) && ((*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, bp) != 0 || (**(**Tstat)(__ccgo_up(bp))).Fst_ino != (*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FfileId.Fino))
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Memory map or remap the file opened by file-descriptor pFd (if the file
|
||||
// ** is already mapped, the existing mapping is replaced by the new). Or, if
|
||||
// ** there already exists a mapping for this file, and there are still
|
||||
// ** outstanding xFetch() references to it, this function is a no-op.
|
||||
// **
|
||||
// ** If parameter nByte is non-negative, then it is the requested size of
|
||||
// ** the mapping to create. Otherwise, if nByte is less than zero, then the
|
||||
// ** requested size is the size of the file on disk. The actual size of the
|
||||
// ** created mapping is either the requested size or the value configured
|
||||
// ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
|
||||
// **
|
||||
// ** SQLITE_OK is returned if no error occurs (even if the mapping is not
|
||||
// ** recreated as a result of outstanding references) or an SQLite error
|
||||
// ** code otherwise.
|
||||
// */
|
||||
func _unixMapfile(tls *libc.TLS, pFd uintptr, nMap Ti64) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var _ /* statbuf at bp+0 */ Tstat
|
||||
if (*TunixFile)(unsafe.Pointer(pFd)).FnFetchOut > 0 {
|
||||
return SQLITE_OK
|
||||
}
|
||||
if nMap < 0 { /* Low-level file information */
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFd)).Fh, bp) != 0 {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
nMap = (**(**Tstat)(__ccgo_up(bp))).Fst_size
|
||||
}
|
||||
if nMap > (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax {
|
||||
nMap = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax
|
||||
}
|
||||
if nMap != (*TunixFile)(unsafe.Pointer(pFd)).FmmapSize {
|
||||
_unixRemapfile(tls, pFd, nMap)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
+29823
File diff suppressed because it is too large
Load Diff
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const MAP_32BIT = 64
|
||||
+25398
File diff suppressed because it is too large
Load Diff
+23480
File diff suppressed because it is too large
Load Diff
+40
@@ -0,0 +1,40 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && arm) || (linux && 386) || (linux && arm)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Sleep for a little while. Return the amount of time slept.
|
||||
// ** The argument is the number of microseconds we want to sleep.
|
||||
// ** The return value is the number of microseconds of sleep actually
|
||||
// ** requested from the underlying operating system, a number which
|
||||
// ** might be greater than or equal to the argument, but not less
|
||||
// ** than the argument.
|
||||
// */
|
||||
func _unixSleep(tls *libc.TLS, NotUsed uintptr, microseconds int32) (r int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var _ /* sp at bp+0 */ Ttimespec
|
||||
(**(**Ttimespec)(__ccgo_up(bp))).Ftv_sec = int64(microseconds / int32(1000000))
|
||||
(**(**Ttimespec)(__ccgo_up(bp))).Ftv_nsec = microseconds % int32(1000000) * int32(1000)
|
||||
/* Almost all modern unix systems support nanosleep(). But if you are
|
||||
** compiling for one of the rare exceptions, you can use
|
||||
** -DHAVE_NANOSLEEP=0 (perhaps in conjunction with -DHAVE_USLEEP if
|
||||
** usleep() is available) in order to bypass the use of nanosleep() */
|
||||
libc.Xnanosleep(tls, bp, libc.UintptrFromInt32(0))
|
||||
_ = NotUsed
|
||||
return microseconds
|
||||
}
|
||||
|
||||
/*
|
||||
** The following variable, if set to a non-zero value, is interpreted as
|
||||
** the number of seconds since 1970 and is used to set the result of
|
||||
** sqlite3OsCurrentTime() during testing.
|
||||
*/
|
||||
+37893
File diff suppressed because it is too large
Load Diff
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && arm64) || (linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __GCC_DESTRUCTIVE_SIZE = 256
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && amd64) || (linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __FLT16_IS_IEC_60559__ = 2
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm) || (linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const O_LARGEFILE = 131072
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && arm) || (freebsd && arm64) || (linux && arm) || (linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
type Twchar_t = uint32
|
||||
|
||||
const __WCHAR_MAX__ = 4294967295
|
||||
|
||||
type t__predefined_wchar_t = uint32
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && arm64) || (freebsd && arm) || (freebsd && arm64) || (linux && arm) || (linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __ARM_FEATURE_UNALIGNED = 1
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && 386) || (freebsd && amd64) || (freebsd && arm) || (freebsd && arm64) || (linux && arm) || (linux && arm64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const O_DIRECT = 65536
|
||||
+30154
File diff suppressed because it is too large
Load Diff
+204
@@ -0,0 +1,204 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && amd64) || (linux && amd64) || (linux && loong64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called to obtain a shared lock on the database file.
|
||||
// ** It is illegal to call sqlite3PagerGet() until after this function
|
||||
// ** has been successfully called. If a shared-lock is already held when
|
||||
// ** this function is called, it is a no-op.
|
||||
// **
|
||||
// ** The following operations are also performed by this function.
|
||||
// **
|
||||
// ** 1) If the pager is currently in PAGER_OPEN state (no lock held
|
||||
// ** on the database file), then an attempt is made to obtain a
|
||||
// ** SHARED lock on the database file. Immediately after obtaining
|
||||
// ** the SHARED lock, the file-system is checked for a hot-journal,
|
||||
// ** which is played back if present. Following any hot-journal
|
||||
// ** rollback, the contents of the cache are validated by checking
|
||||
// ** the 'change-counter' field of the database file header and
|
||||
// ** discarded if they are found to be invalid.
|
||||
// **
|
||||
// ** 2) If the pager is running in exclusive-mode, and there are currently
|
||||
// ** no outstanding references to any pages, and is in the error state,
|
||||
// ** then an attempt is made to clear the error state by discarding
|
||||
// ** the contents of the page cache and rolling back any open journal
|
||||
// ** file.
|
||||
// **
|
||||
// ** If everything is successful, SQLITE_OK is returned. If an IO error
|
||||
// ** occurs while locking the database, checking for a hot-journal file or
|
||||
// ** rolling back a journal file, the IO error code is returned.
|
||||
// */
|
||||
func _sqlite3PagerSharedLock(tls *libc.TLS, pPager uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var f, rc int32
|
||||
var pVfs uintptr
|
||||
var _ /* bExists at bp+4 */ int32
|
||||
var _ /* bHotJournal at bp+0 */ int32
|
||||
var _ /* dbFileVers at bp+12 */ [16]int8
|
||||
var _ /* fout at bp+8 */ int32
|
||||
_, _, _ = f, pVfs, rc
|
||||
rc = SQLITE_OK /* Return code */
|
||||
/* This routine is only called from b-tree and only when there are no
|
||||
** outstanding pages. This implies that the pager state should either
|
||||
** be OPEN or READER. READER is only possible if the pager is or was in
|
||||
** exclusive access mode. */
|
||||
if !((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN {
|
||||
**(**int32)(__ccgo_up(bp)) = int32(1) /* True if there exists a hot journal-file */
|
||||
rc = _pager_wait_on_lock(tls, pPager, int32(SHARED_LOCK))
|
||||
if rc != SQLITE_OK {
|
||||
goto failed
|
||||
}
|
||||
/* If a journal file exists, and there is no RESERVED lock on the
|
||||
** database file, then it either needs to be played back or deleted.
|
||||
*/
|
||||
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) <= int32(SHARED_LOCK) {
|
||||
rc = _hasHotJournal(tls, pPager, bp)
|
||||
}
|
||||
if rc != SQLITE_OK {
|
||||
goto failed
|
||||
}
|
||||
if **(**int32)(__ccgo_up(bp)) != 0 {
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FreadOnly != 0 {
|
||||
rc = libc.Int32FromInt32(SQLITE_READONLY) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
|
||||
goto failed
|
||||
}
|
||||
/* Get an EXCLUSIVE lock on the database file. At this point it is
|
||||
** important that a RESERVED lock is not obtained on the way to the
|
||||
** EXCLUSIVE lock. If it were, another process might open the
|
||||
** database file, detect the RESERVED lock, and conclude that the
|
||||
** database is safe to read while this process is still rolling the
|
||||
** hot-journal back.
|
||||
**
|
||||
** Because the intermediate RESERVED lock is not requested, any
|
||||
** other process attempting to access the database file will get to
|
||||
** this point in the code and fail to obtain its own EXCLUSIVE lock
|
||||
** on the database file.
|
||||
**
|
||||
** Unless the pager is in locking_mode=exclusive mode, the lock is
|
||||
** downgraded to SHARED_LOCK before this function returns.
|
||||
*/
|
||||
rc = _pagerLockDb(tls, pPager, int32(EXCLUSIVE_LOCK))
|
||||
if rc != SQLITE_OK {
|
||||
goto failed
|
||||
}
|
||||
/* If it is not already open and the file exists on disk, open the
|
||||
** journal for read/write access. Write access is required because
|
||||
** in exclusive-access mode the file descriptor will be kept open
|
||||
** and possibly used for a transaction later on. Also, write-access
|
||||
** is usually required to finalize the journal in journal_mode=persist
|
||||
** mode (and also for journal_mode=truncate on some systems).
|
||||
**
|
||||
** If the journal does not exist, it usually means that some
|
||||
** other connection managed to get in and roll it back before
|
||||
** this connection obtained the exclusive lock above. Or, it
|
||||
** may mean that the pager was in the error-state when this
|
||||
** function was called and the journal file does not exist.
|
||||
*/
|
||||
if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_OFF) {
|
||||
pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs /* True if journal file exists */
|
||||
rc = _sqlite3OsAccess(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, SQLITE_ACCESS_EXISTS, bp+4)
|
||||
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 4)) != 0 {
|
||||
**(**int32)(__ccgo_up(bp + 8)) = 0
|
||||
f = libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_MAIN_JOURNAL)
|
||||
rc = _sqlite3OsOpen(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, (*TPager)(unsafe.Pointer(pPager)).Fjfd, f, bp+8)
|
||||
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 8))&int32(SQLITE_OPEN_READONLY) != 0 {
|
||||
rc = _sqlite3CantopenError(tls, int32(65169))
|
||||
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Playback and delete the journal. Drop the database write
|
||||
** lock and reacquire the read lock. Purge the cache before
|
||||
** playing back the hot-journal so that we don't end up with
|
||||
** an inconsistent cache. Sync the hot journal before playing
|
||||
** it back since the process that crashed and left the hot journal
|
||||
** probably did not sync it and we are required to always sync
|
||||
** the journal before playing it back.
|
||||
*/
|
||||
if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) {
|
||||
rc = _pagerSyncHotJournal(tls, pPager)
|
||||
if rc == SQLITE_OK {
|
||||
rc = _pager_playback(tls, pPager, libc.BoolInt32(!((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0)))
|
||||
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_OPEN)
|
||||
}
|
||||
} else {
|
||||
if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) {
|
||||
_pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
|
||||
}
|
||||
}
|
||||
if rc != SQLITE_OK {
|
||||
/* This branch is taken if an error occurs while trying to open
|
||||
** or roll back a hot-journal while holding an EXCLUSIVE lock. The
|
||||
** pager_unlock() routine will be called before returning to unlock
|
||||
** the file. If the unlock attempt fails, then Pager.eLock must be
|
||||
** set to UNKNOWN_LOCK (see the comment above the #define for
|
||||
** UNKNOWN_LOCK above for an explanation).
|
||||
**
|
||||
** In order to get pager_unlock() to do this, set Pager.eState to
|
||||
** PAGER_ERROR now. This is not actually counted as a transition
|
||||
** to ERROR state in the state diagram at the top of this file,
|
||||
** since we know that the same call to pager_unlock() will very
|
||||
** shortly transition the pager object to the OPEN state. Calling
|
||||
** assert_pager_state() would fail now, as it should not be possible
|
||||
** to be in ERROR state when there are zero outstanding page
|
||||
** references.
|
||||
*/
|
||||
_pager_error(tls, pPager, rc)
|
||||
goto failed
|
||||
}
|
||||
}
|
||||
if !((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0) && (*TPager)(unsafe.Pointer(pPager)).FhasHeldSharedLock != 0 {
|
||||
rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp+12, int32(16), int64(24))
|
||||
if rc != SQLITE_OK {
|
||||
if rc != libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
|
||||
goto failed
|
||||
}
|
||||
libc.Xmemset(tls, bp+12, 0, uint64(16))
|
||||
}
|
||||
if libc.Xmemcmp(tls, pPager+136, bp+12, uint64(16)) != 0 {
|
||||
_pager_reset(tls, pPager)
|
||||
/* Unmap the database file. It is possible that external processes
|
||||
** may have truncated the database file and then extended it back
|
||||
** to its original size while this process was not holding a lock.
|
||||
** In this case there may exist a Pager.pMap mapping that appears
|
||||
** to be the right size but is not actually valid. Avoid this
|
||||
** possibility by unmapping the db here. */
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FbUseFetch != 0 {
|
||||
_sqlite3OsUnfetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, 0, uintptr(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If there is a WAL file in the file-system, open this database in WAL
|
||||
** mode. Otherwise, the following function call is a no-op.
|
||||
*/
|
||||
rc = _pagerOpenWalIfPresent(tls, pPager)
|
||||
}
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
|
||||
rc = _pagerBeginReadTransaction(tls, pPager)
|
||||
}
|
||||
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FtempFile) == 0 && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN && rc == SQLITE_OK {
|
||||
rc = _pagerPagecount(tls, pPager, pPager+32)
|
||||
}
|
||||
goto failed
|
||||
failed:
|
||||
;
|
||||
if rc != SQLITE_OK {
|
||||
_pager_unlock(tls, pPager)
|
||||
} else {
|
||||
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_READER)
|
||||
(*TPager)(unsafe.Pointer(pPager)).FhasHeldSharedLock = uint8(1)
|
||||
}
|
||||
return rc
|
||||
}
|
||||
+907
@@ -0,0 +1,907 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64) || (linux && loong64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type Tfpos_t = struct {
|
||||
F__lldata [0]int64
|
||||
F__align [0]float64
|
||||
F__opaque [16]int8
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if the given SQL string ends in a semicolon.
|
||||
// **
|
||||
// ** Special handling is require for CREATE TRIGGER statements.
|
||||
// ** Whenever the CREATE TRIGGER keywords are seen, the statement
|
||||
// ** must end with ";END;".
|
||||
// **
|
||||
// ** This implementation uses a state machine with 8 states:
|
||||
// **
|
||||
// ** (0) INVALID We have not yet seen a non-whitespace character.
|
||||
// **
|
||||
// ** (1) START At the beginning or end of an SQL statement. This routine
|
||||
// ** returns 1 if it ends in the START state and 0 if it ends
|
||||
// ** in any other state.
|
||||
// **
|
||||
// ** (2) NORMAL We are in the middle of statement which ends with a single
|
||||
// ** semicolon.
|
||||
// **
|
||||
// ** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
|
||||
// ** a statement.
|
||||
// **
|
||||
// ** (4) CREATE The keyword CREATE has been seen at the beginning of a
|
||||
// ** statement, possibly preceded by EXPLAIN and/or followed by
|
||||
// ** TEMP or TEMPORARY
|
||||
// **
|
||||
// ** (5) TRIGGER We are in the middle of a trigger definition that must be
|
||||
// ** ended by a semicolon, the keyword END, and another semicolon.
|
||||
// **
|
||||
// ** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
|
||||
// ** the end of a trigger definition.
|
||||
// **
|
||||
// ** (7) END We've seen the ";END" of the ";END;" that occurs at the end
|
||||
// ** of a trigger definition.
|
||||
// **
|
||||
// ** Transitions between states above are determined by tokens extracted
|
||||
// ** from the input. The following tokens are significant:
|
||||
// **
|
||||
// ** (0) tkSEMI A semicolon.
|
||||
// ** (1) tkWS Whitespace.
|
||||
// ** (2) tkOTHER Any other SQL token.
|
||||
// ** (3) tkEXPLAIN The "explain" keyword.
|
||||
// ** (4) tkCREATE The "create" keyword.
|
||||
// ** (5) tkTEMP The "temp" or "temporary" keyword.
|
||||
// ** (6) tkTRIGGER The "trigger" keyword.
|
||||
// ** (7) tkEND The "end" keyword.
|
||||
// **
|
||||
// ** Whitespace never causes a state transition and is always ignored.
|
||||
// ** This means that a SQL string of all whitespace is invalid.
|
||||
// **
|
||||
// ** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
|
||||
// ** to recognize the end of a trigger can be omitted. All we have to do
|
||||
// ** is look for a semicolon that is not part of an string or comment.
|
||||
// */
|
||||
func Xsqlite3_complete(tls *libc.TLS, zSql uintptr) (r int32) {
|
||||
var c, nId int32
|
||||
var state, token Tu8
|
||||
_, _, _, _ = c, nId, state, token
|
||||
state = uint8(0) /* Value of the next token */
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 {
|
||||
switch int32(**(**int8)(__ccgo_up(zSql))) {
|
||||
case int32(';'): /* A semicolon */
|
||||
token = uint8(tkSEMI)
|
||||
case int32(' '):
|
||||
fallthrough
|
||||
case int32('\r'):
|
||||
fallthrough
|
||||
case int32('\t'):
|
||||
fallthrough
|
||||
case int32('\n'):
|
||||
fallthrough
|
||||
case int32('\f'): /* White space is ignored */
|
||||
token = uint8(tkWS)
|
||||
case int32('/'): /* C-style comments */
|
||||
if int32(**(**int8)(__ccgo_up(zSql + 1))) != int32('*') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(2)
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && (int32(**(**int8)(__ccgo_up(zSql))) != int32('*') || int32(**(**int8)(__ccgo_up(zSql + 1))) != int32('/')) {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
zSql = zSql + 1
|
||||
token = uint8(tkWS)
|
||||
case int32('-'): /* SQL-style comments from "--" to end of line */
|
||||
if int32(**(**int8)(__ccgo_up(zSql + 1))) != int32('-') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && int32(**(**int8)(__ccgo_up(zSql))) != int32('\n') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
token = uint8(tkWS)
|
||||
case int32('['): /* Microsoft-style identifiers in [...] */
|
||||
zSql = zSql + 1
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && int32(**(**int8)(__ccgo_up(zSql))) != int32(']') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
case int32('`'): /* Grave-accent quoted symbols used by MySQL */
|
||||
fallthrough
|
||||
case int32('"'): /* single- and double-quoted strings */
|
||||
fallthrough
|
||||
case int32('\''):
|
||||
c = int32(**(**int8)(__ccgo_up(zSql)))
|
||||
zSql = zSql + 1
|
||||
for **(**int8)(__ccgo_up(zSql)) != 0 && int32(**(**int8)(__ccgo_up(zSql))) != c {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if int32(**(**int8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
default:
|
||||
if libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zSql)))])&int32(0x46) != 0 {
|
||||
nId = int32(1)
|
||||
for {
|
||||
if !(libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zSql + uintptr(nId))))])&int32(0x46) != 0) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
nId = nId + 1
|
||||
}
|
||||
switch int32(**(**int8)(__ccgo_up(zSql))) {
|
||||
case int32('c'):
|
||||
fallthrough
|
||||
case int32('C'):
|
||||
if nId == int32(6) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25281, int32(6)) == 0 {
|
||||
token = uint8(tkCREATE)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
case int32('t'):
|
||||
fallthrough
|
||||
case int32('T'):
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+21910, int32(7)) == 0 {
|
||||
token = uint8(tkTRIGGER)
|
||||
} else {
|
||||
if nId == int32(4) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25288, int32(4)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
if nId == int32(9) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25293, int32(9)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
case int32('e'):
|
||||
fallthrough
|
||||
case int32('E'):
|
||||
if nId == int32(3) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25303, int32(3)) == 0 {
|
||||
token = uint8(tkEND)
|
||||
} else {
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25307, int32(7)) == 0 {
|
||||
token = uint8(tkEXPLAIN)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
default:
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(nId-int32(1))
|
||||
} else {
|
||||
/* Operators and special symbols */
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
break
|
||||
}
|
||||
state = **(**Tu8)(__ccgo_up(uintptr(unsafe.Pointer(&_trans)) + uintptr(state)*8 + uintptr(token)))
|
||||
zSql = zSql + 1
|
||||
}
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Extra floating-point literals to allow in JSON.
|
||||
// */
|
||||
var _aNanInfName = [5]TNanInfName{
|
||||
0: {
|
||||
Fc1: int8('i'),
|
||||
Fc2: int8('I'),
|
||||
Fn: int8(3),
|
||||
FeType: int8(JSONB_FLOAT),
|
||||
FnRepl: int8(7),
|
||||
FzMatch: __ccgo_ts + 26501,
|
||||
FzRepl: __ccgo_ts + 26505,
|
||||
},
|
||||
1: {
|
||||
Fc1: int8('i'),
|
||||
Fc2: int8('I'),
|
||||
Fn: int8(8),
|
||||
FeType: int8(JSONB_FLOAT),
|
||||
FnRepl: int8(7),
|
||||
FzMatch: __ccgo_ts + 26513,
|
||||
FzRepl: __ccgo_ts + 26505,
|
||||
},
|
||||
2: {
|
||||
Fc1: int8('n'),
|
||||
Fc2: int8('N'),
|
||||
Fn: int8(3),
|
||||
FnRepl: int8(4),
|
||||
FzMatch: __ccgo_ts + 1695,
|
||||
FzRepl: __ccgo_ts + 1690,
|
||||
},
|
||||
3: {
|
||||
Fc1: int8('q'),
|
||||
Fc2: int8('Q'),
|
||||
Fn: int8(4),
|
||||
FnRepl: int8(4),
|
||||
FzMatch: __ccgo_ts + 26522,
|
||||
FzRepl: __ccgo_ts + 1690,
|
||||
},
|
||||
4: {
|
||||
Fc1: int8('s'),
|
||||
Fc2: int8('S'),
|
||||
Fn: int8(4),
|
||||
FnRepl: int8(4),
|
||||
FzMatch: __ccgo_ts + 26527,
|
||||
FzRepl: __ccgo_ts + 1690,
|
||||
},
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Compare the 19-character string zNum against the text representation
|
||||
// ** value 2^63: 9223372036854775808. Return negative, zero, or positive
|
||||
// ** if zNum is less than, equal to, or greater than the string.
|
||||
// ** Note that zNum must contain exactly 19 characters.
|
||||
// **
|
||||
// ** Unlike memcmp() this routine is guaranteed to return the difference
|
||||
// ** in the values of the last digit if the only difference is in the
|
||||
// ** last digit. So, for example,
|
||||
// **
|
||||
// ** compare2pow63("9223372036854775800", 1)
|
||||
// **
|
||||
// ** will return -8.
|
||||
// */
|
||||
func _compare2pow63(tls *libc.TLS, zNum uintptr, incr int32) (r int32) {
|
||||
var c, i int32
|
||||
var pow63 uintptr
|
||||
_, _, _ = c, i, pow63
|
||||
c = 0
|
||||
/* 012345678901234567 */
|
||||
pow63 = __ccgo_ts + 1815
|
||||
i = 0
|
||||
for {
|
||||
if !(c == 0 && i < int32(18)) {
|
||||
break
|
||||
}
|
||||
c = (int32(**(**int8)(__ccgo_up(zNum + uintptr(i*incr)))) - int32(**(**int8)(__ccgo_up(pow63 + uintptr(i))))) * int32(10)
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if c == 0 {
|
||||
c = int32(**(**int8)(__ccgo_up(zNum + uintptr(int32(18)*incr)))) - int32('8')
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Process a "special" query. A special query is identified as one with a
|
||||
// ** MATCH expression that begins with a '*' character. The remainder of
|
||||
// ** the text passed to the MATCH operator are used as the special query
|
||||
// ** parameters.
|
||||
// */
|
||||
func _fts5SpecialMatch(tls *libc.TLS, pTab uintptr, pCsr uintptr, zQuery uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var n, rc int32
|
||||
var z uintptr
|
||||
_, _, _ = n, rc, z
|
||||
rc = SQLITE_OK /* Return code */
|
||||
z = zQuery /* Number of bytes in text at z */
|
||||
for int32(**(**int8)(__ccgo_up(z))) == int32(' ') {
|
||||
z = z + 1
|
||||
}
|
||||
n = 0
|
||||
for {
|
||||
if !(**(**int8)(__ccgo_up(z + uintptr(n))) != 0 && int32(**(**int8)(__ccgo_up(z + uintptr(n)))) != int32(' ')) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
n = n + 1
|
||||
}
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_SPECIAL)
|
||||
if n == int32(5) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+39843, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = int64(_sqlite3Fts5IndexReads(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex))
|
||||
} else {
|
||||
if n == int32(2) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+5676, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiCsrId
|
||||
} else {
|
||||
/* An unrecognized directive. Return an error message. */
|
||||
(*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39849, libc.VaList(bp+8, n, z))
|
||||
rc = int32(SQLITE_ERROR)
|
||||
}
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Interpret the given string as a temp db location. Return 1 for file
|
||||
// ** backed temporary databases, 2 for the Red-Black tree in memory database
|
||||
// ** and 0 to use the compile-time default.
|
||||
// */
|
||||
func _getTempStore(tls *libc.TLS, z uintptr) (r int32) {
|
||||
if int32(**(**int8)(__ccgo_up(z))) >= int32('0') && int32(**(**int8)(__ccgo_up(z))) <= int32('2') {
|
||||
return int32(**(**int8)(__ccgo_up(z))) - int32('0')
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+18020) == 0 {
|
||||
return int32(1)
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+19061) == 0 {
|
||||
return int32(2)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a complete JSON string. Return 0 on success or non-zero if there
|
||||
// ** are any errors. If an error occurs, free all memory held by pParse,
|
||||
// ** but not pParse itself.
|
||||
// **
|
||||
// ** pParse must be initialized to an empty parse object prior to calling
|
||||
// ** this routine.
|
||||
// */
|
||||
func _jsonConvertTextToBlob(tls *libc.TLS, pParse uintptr, pCtx uintptr) (r int32) {
|
||||
var i int32
|
||||
var zJson uintptr
|
||||
_, _ = i, zJson
|
||||
zJson = (*TJsonParse)(unsafe.Pointer(pParse)).FzJson
|
||||
i = _jsonTranslateTextToBlob(tls, pParse, uint32(0))
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
i = -int32(1)
|
||||
}
|
||||
if i > 0 {
|
||||
for _jsonIsSpace[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zJson + uintptr(i))))] != 0 {
|
||||
i = i + 1
|
||||
}
|
||||
if **(**int8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
i = i + _json5Whitespace(tls, zJson+uintptr(i))
|
||||
if **(**int8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
if pCtx != 0 {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26486, -int32(1))
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
(*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1)
|
||||
}
|
||||
}
|
||||
if i <= 0 {
|
||||
if pCtx != uintptr(0) {
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
Xsqlite3_result_error_nomem(tls, pCtx)
|
||||
} else {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26486, -int32(1))
|
||||
}
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Settle ofdEnabled from the environment, once. Called from sqlite3_os_init(),
|
||||
// ** before any file can be opened, so the mode is fixed before the first lock.
|
||||
// */
|
||||
func _ofdInitOnce(tls *libc.TLS) {
|
||||
var z uintptr
|
||||
_ = z
|
||||
if !(libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_ofdDecided))) != 0) {
|
||||
z = libc.Xgetenv(tls, __ccgo_ts+3805)
|
||||
libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_ofdEnabled)), libc.BoolInt32(z != uintptr(0) && int32(**(**int8)(__ccgo_up(z))) != 0 && int32(**(**int8)(__ccgo_up(z))) != int32('0')))
|
||||
libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_ofdDecided)), int32(1))
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
|
||||
// ** The HH, MM, and SS must each be exactly 2 digits. The
|
||||
// ** fractional seconds FFFF can be one or more digits.
|
||||
// **
|
||||
// ** Return 1 if there is a parsing error and 0 on success.
|
||||
// */
|
||||
func _parseHhMmSs(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var ms, rScale float64
|
||||
var _ /* h at bp+0 */ int32
|
||||
var _ /* m at bp+4 */ int32
|
||||
var _ /* s at bp+8 */ int32
|
||||
_, _ = ms, rScale
|
||||
ms = float64(0)
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1204, libc.VaList(bp+24, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == int32(':') {
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1212, libc.VaList(bp+24, bp+8)) != int32(1) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(2)
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == int32('.') && libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate + 1)))])&int32(0x04) != 0 {
|
||||
rScale = float64(1)
|
||||
zDate = zDate + 1
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x04) != 0 {
|
||||
ms = float64(ms*float64(10)) + float64(**(**int8)(__ccgo_up(zDate))) - libc.Float64FromUint8('0')
|
||||
rScale = rScale * float64(10)
|
||||
zDate = zDate + 1
|
||||
}
|
||||
ms = ms / rScale
|
||||
/* Truncate to avoid problems with sub-milliseconds
|
||||
** rounding. https://sqlite.org/forum/forumpost/766a2c9231 */
|
||||
if ms > float64(0.999) {
|
||||
ms = float64(0.999)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(bp + 8)) = 0
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = 0
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 0, 0x1)
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = int8(1)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fh = **(**int32)(__ccgo_up(bp))
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fm = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fs = float64(**(**int32)(__ccgo_up(bp + 8))) + ms
|
||||
if _parseTimezone(tls, zDate, p) != 0 {
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a timezone extension on the end of a date-time.
|
||||
// ** The extension is of the form:
|
||||
// **
|
||||
// ** (+/-)HH:MM
|
||||
// **
|
||||
// ** Or the "zulu" notation:
|
||||
// **
|
||||
// ** Z
|
||||
// **
|
||||
// ** If the parse is successful, write the number of minutes
|
||||
// ** of change in p->tz and return 0. If a parser error occurs,
|
||||
// ** return non-zero.
|
||||
// **
|
||||
// ** A missing specifier is not considered an error.
|
||||
// */
|
||||
func _parseTimezone(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c, sgn int32
|
||||
var _ /* nHr at bp+0 */ int32
|
||||
var _ /* nMn at bp+4 */ int32
|
||||
_, _ = c, sgn
|
||||
sgn = 0
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = 0
|
||||
c = int32(**(**int8)(__ccgo_up(zDate)))
|
||||
if c == int32('-') {
|
||||
sgn = -int32(1)
|
||||
} else {
|
||||
if c == int32('+') {
|
||||
sgn = +libc.Int32FromInt32(1)
|
||||
} else {
|
||||
if c == int32('Z') || c == int32('z') {
|
||||
zDate = zDate + 1
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
goto zulu_time
|
||||
} else {
|
||||
return libc.BoolInt32(c != 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1196, libc.VaList(bp+16, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = sgn * (**(**int32)(__ccgo_up(bp + 4)) + **(**int32)(__ccgo_up(bp))*int32(60))
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz == 0 { /* Forum post 2025-09-17T10:12:14z */
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
}
|
||||
goto zulu_time
|
||||
zulu_time:
|
||||
;
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
return libc.BoolInt32(int32(**(**int8)(__ccgo_up(zDate))) != 0)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse dates of the form
|
||||
// **
|
||||
// ** YYYY-MM-DD HH:MM:SS.FFF
|
||||
// ** YYYY-MM-DD HH:MM:SS
|
||||
// ** YYYY-MM-DD HH:MM
|
||||
// ** YYYY-MM-DD
|
||||
// **
|
||||
// ** Write the result into the DateTime structure and return 0
|
||||
// ** on success and 1 if the input string is not a well-formed
|
||||
// ** date.
|
||||
// */
|
||||
func _parseYyyyMmDd(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var neg, v1 int32
|
||||
var _ /* D at bp+8 */ int32
|
||||
var _ /* M at bp+4 */ int32
|
||||
var _ /* Y at bp+0 */ int32
|
||||
_, _ = neg, v1
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == int32('-') {
|
||||
zDate = zDate + 1
|
||||
neg = int32(1)
|
||||
} else {
|
||||
neg = 0
|
||||
}
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1216, libc.VaList(bp+24, bp, bp+4, bp+8)) != int32(3) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(10)
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[libc.Uint8FromInt8(**(**int8)(__ccgo_up(zDate)))])&int32(0x01) != 0 || int32('T') == libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zDate))) {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
if _parseHhMmSs(tls, zDate, p) == 0 {
|
||||
/* We got the time */
|
||||
} else {
|
||||
if int32(**(**int8)(__ccgo_up(zDate))) == 0 {
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = 0
|
||||
} else {
|
||||
return int32(1)
|
||||
}
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = 0
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidYMD = int8(1)
|
||||
if neg != 0 {
|
||||
v1 = -**(**int32)(__ccgo_up(bp))
|
||||
} else {
|
||||
v1 = **(**int32)(__ccgo_up(bp))
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FY = v1
|
||||
(*TDateTime)(unsafe.Pointer(p)).FM = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).FD = **(**int32)(__ccgo_up(bp + 8))
|
||||
_computeFloor(tls, p)
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz != 0 {
|
||||
_computeJD(tls, p)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Allocate a private rbu VFS for the rbu handle passed as the only
|
||||
// ** argument. This VFS will be used unless the call to sqlite3rbu_open()
|
||||
// ** specified a URI with a vfs=? option in place of a target database
|
||||
// ** file name.
|
||||
// */
|
||||
func _rbuCreateVfs(tls *libc.TLS, p uintptr) {
|
||||
bp := tls.Alloc(96)
|
||||
defer tls.Free(96)
|
||||
var pVfs uintptr
|
||||
var _ /* rnd at bp+0 */ int32
|
||||
var _ /* zRnd at bp+4 */ [64]int8
|
||||
_ = pVfs
|
||||
Xsqlite3_randomness(tls, int32(4), bp)
|
||||
Xsqlite3_snprintf(tls, int32(64), bp+4, __ccgo_ts+34354, libc.VaList(bp+80, **(**int32)(__ccgo_up(bp))))
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3rbu_create_vfs(tls, bp+4, uintptr(0))
|
||||
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
||||
pVfs = Xsqlite3_vfs_find(tls, bp+4)
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzVfsName = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FzName
|
||||
(*Trbu_vfs)(unsafe.Pointer(pVfs)).FpRbu = p
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** An error occurred while parsing or otherwise processing a database
|
||||
// ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
|
||||
// ** ALTER TABLE RENAME COLUMN program. The error message emitted by the
|
||||
// ** sub-routine is currently stored in pParse->zErrMsg. This function
|
||||
// ** adds context to the error message and then stores it in pCtx.
|
||||
// */
|
||||
func _renameColumnParseError(tls *libc.TLS, pCtx uintptr, zWhen uintptr, pType uintptr, pObject uintptr, pParse uintptr) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var zErr, zN, zT, v1 uintptr
|
||||
_, _, _, _ = zErr, zN, zT, v1
|
||||
zT = Xsqlite3_value_text(tls, pType)
|
||||
zN = Xsqlite3_value_text(tls, pObject)
|
||||
if **(**int8)(__ccgo_up(zWhen)) != 0 {
|
||||
v1 = __ccgo_ts + 11569
|
||||
} else {
|
||||
v1 = __ccgo_ts + 1704
|
||||
}
|
||||
zErr = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+11571, libc.VaList(bp+8, zT, zN, v1, zWhen, (*TParse)(unsafe.Pointer(pParse)).FzErrMsg))
|
||||
Xsqlite3_result_error(tls, pCtx, zErr, -int32(1))
|
||||
_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zErr)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /* IMP: R-25361-16150 This function is omitted from SQLite by default. It
|
||||
// ** is only available if the SQLITE_SOUNDEX compile-time option is used
|
||||
// ** when SQLite is built.
|
||||
// */
|
||||
// /*
|
||||
// ** Compute the soundex encoding of a word.
|
||||
// **
|
||||
// ** IMP: R-59782-00072 The soundex(X) function returns a string that is the
|
||||
// ** soundex encoding of the string X.
|
||||
// */
|
||||
func _soundexFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var code, i, j, v3 int32
|
||||
var prevcode Tu8
|
||||
var zIn uintptr
|
||||
var _ /* zResult at bp+0 */ [8]int8
|
||||
_, _, _, _, _, _ = code, i, j, prevcode, zIn, v3
|
||||
zIn = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
if zIn == uintptr(0) {
|
||||
zIn = __ccgo_ts + 1704
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(**(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))])&libc.Int32FromInt32(0x02) != 0)) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 {
|
||||
prevcode = _iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)]
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[0] = int8(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i)))) & ^(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))]) & libc.Int32FromInt32(0x20)))
|
||||
j = int32(1)
|
||||
for {
|
||||
if !(j < int32(4) && **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0) {
|
||||
break
|
||||
}
|
||||
code = libc.Int32FromUint8(_iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)])
|
||||
if code > 0 {
|
||||
if code != libc.Int32FromUint8(prevcode) {
|
||||
prevcode = libc.Uint8FromInt32(code)
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[v3] = int8(code + int32('0'))
|
||||
}
|
||||
} else {
|
||||
prevcode = uint8(0)
|
||||
}
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
for j < int32(4) {
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[v3] = int8('0')
|
||||
}
|
||||
(**(**[8]int8)(__ccgo_up(bp)))[j] = 0
|
||||
Xsqlite3_result_text(tls, context, bp, int32(4), uintptr(-libc.Int32FromInt32(1)))
|
||||
} else {
|
||||
/* IMP: R-64894-50321 The string "?000" is returned if the argument
|
||||
** is NULL or contains no ASCII alphabetic characters. */
|
||||
Xsqlite3_result_text(tls, context, __ccgo_ts+16622, int32(4), libc.UintptrFromInt32(0))
|
||||
}
|
||||
}
|
||||
|
||||
func _sqlite3Fts5ParseSetDistance(tls *libc.TLS, pParse uintptr, pNear uintptr, p uintptr) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c int8
|
||||
var i, nNear int32
|
||||
_, _, _ = c, i, nNear
|
||||
if pNear != 0 {
|
||||
nNear = 0
|
||||
if (*TFts5Token)(unsafe.Pointer(p)).Fn != 0 {
|
||||
i = 0
|
||||
for {
|
||||
if !(i < (*TFts5Token)(unsafe.Pointer(p)).Fn) {
|
||||
break
|
||||
}
|
||||
c = **(**int8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))
|
||||
if int32(c) < int32('0') || int32(c) > int32('9') {
|
||||
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38634, libc.VaList(bp+8, (*TFts5Token)(unsafe.Pointer(p)).Fn, (*TFts5Token)(unsafe.Pointer(p)).Fp))
|
||||
return
|
||||
}
|
||||
if nNear < int32(214748363) {
|
||||
nNear = nNear*int32(10) + (int32(**(**int8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))) - int32('0'))
|
||||
}
|
||||
/* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
} else {
|
||||
nNear = int32(FTS5_DEFAULT_NEARDIST)
|
||||
}
|
||||
(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnNear = nNear
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Append to pStr text that is the SQL literal representation of the
|
||||
// ** value contained in pValue.
|
||||
// */
|
||||
func _sqlite3QuoteValue(tls *libc.TLS, pStr uintptr, pValue uintptr, bEscape int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var i int32
|
||||
var nBlob Ti64
|
||||
var zArg, zBlob, zText, v2 uintptr
|
||||
_, _, _, _, _, _ = i, nBlob, zArg, zBlob, zText, v2
|
||||
/* As currently implemented, the string must be initially empty.
|
||||
** we might relax this requirement in the future, but that will
|
||||
** require enhancements to the implementation. */
|
||||
switch Xsqlite3_value_type(tls, pValue) {
|
||||
case int32(SQLITE_FLOAT):
|
||||
/* ,--- Show infinity as 9.0e+999
|
||||
** |
|
||||
** | ,--- 17 precision guarantees round-trip
|
||||
** v v */
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+16587, libc.VaList(bp+8, Xsqlite3_value_double(tls, pValue)))
|
||||
case int32(SQLITE_INTEGER):
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+1465, libc.VaList(bp+8, Xsqlite3_value_int64(tls, pValue)))
|
||||
case int32(SQLITE_BLOB):
|
||||
zBlob = Xsqlite3_value_blob(tls, pValue)
|
||||
nBlob = int64(Xsqlite3_value_bytes(tls, pValue))
|
||||
/* No encoding change */
|
||||
_sqlite3StrAccumEnlarge(tls, pStr, nBlob*int64(2)+int64(4))
|
||||
if libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(pStr)).FaccError) == 0 {
|
||||
zText = (*TStrAccum)(unsafe.Pointer(pStr)).FzText
|
||||
i = 0
|
||||
for {
|
||||
if !(int64(i) < nBlob) {
|
||||
break
|
||||
}
|
||||
**(**int8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(2)))) = _hexdigits[int32(**(**int8)(__ccgo_up(zBlob + uintptr(i))))>>int32(4)&int32(0x0F)]
|
||||
**(**int8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(3)))) = _hexdigits[int32(**(**int8)(__ccgo_up(zBlob + uintptr(i))))&int32(0x0F)]
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
**(**int8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(2)))) = int8('\'')
|
||||
**(**int8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(3)))) = int8('\000')
|
||||
**(**int8)(__ccgo_up(zText)) = int8('X')
|
||||
**(**int8)(__ccgo_up(zText + 1)) = int8('\'')
|
||||
(*TStrAccum)(unsafe.Pointer(pStr)).FnChar = libc.Uint32FromInt64(nBlob*int64(2) + int64(3))
|
||||
}
|
||||
case int32(SQLITE_TEXT):
|
||||
zArg = Xsqlite3_value_text(tls, pValue)
|
||||
if bEscape != 0 {
|
||||
v2 = __ccgo_ts + 16595
|
||||
} else {
|
||||
v2 = __ccgo_ts + 11953
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, pStr, v2, libc.VaList(bp+8, zArg))
|
||||
default:
|
||||
Xsqlite3_str_append(tls, pStr, __ccgo_ts+1705, int32(4))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Create a temporary file name in zBuf. zBuf must be allocated
|
||||
// ** by the calling process and must be big enough to hold at least
|
||||
// ** pVfs->mxPathname bytes.
|
||||
// */
|
||||
func _unixGetTempname(tls *libc.TLS, nBuf int32, zBuf uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var iLimit, rc, v1 int32
|
||||
var zDir uintptr
|
||||
var v2 bool
|
||||
var _ /* r at bp+0 */ Tu64
|
||||
_, _, _, _, _ = iLimit, rc, zDir, v1, v2
|
||||
iLimit = 0
|
||||
rc = SQLITE_OK
|
||||
/* It's odd to simulate an io-error here, but really this is just
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
** function failing.
|
||||
*/
|
||||
**(**int8)(__ccgo_up(zBuf)) = 0
|
||||
Xsqlite3_mutex_enter(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
zDir = _unixTempFileDir(tls)
|
||||
if zDir == uintptr(0) {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(25)<<libc.Int32FromInt32(8)
|
||||
} else {
|
||||
for cond := true; cond; cond = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zBuf, 0) == 0 {
|
||||
Xsqlite3_randomness(tls, int32(8), bp)
|
||||
**(**int8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2)))) = 0
|
||||
Xsqlite3_snprintf(tls, nBuf, zBuf, __ccgo_ts+4069, libc.VaList(bp+16, zDir, **(**Tu64)(__ccgo_up(bp)), 0))
|
||||
if v2 = int32(**(**int8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2))))) != 0; !v2 {
|
||||
v1 = iLimit
|
||||
iLimit = iLimit + 1
|
||||
}
|
||||
if v2 || v1 > int32(10) {
|
||||
rc = int32(SQLITE_ERROR)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** The following code executes when a syntax error first occurs.
|
||||
// */
|
||||
func _yy_syntax_error(tls *libc.TLS, yypParser uintptr, yymajor int32, _yyminor TToken) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
*(*TToken)(unsafe.Pointer(bp)) = _yyminor
|
||||
var pParse uintptr
|
||||
_ = pParse
|
||||
pParse = (*TyyParser)(unsafe.Pointer(yypParser)).FpParse
|
||||
/************ Begin %syntax_error code ****************************************/
|
||||
_ = yymajor /* Silence some compiler warnings */
|
||||
if **(**int8)(__ccgo_up((**(**TToken)(__ccgo_up(bp))).Fz)) != 0 {
|
||||
_parserSyntaxError(tls, pParse, bp)
|
||||
} else {
|
||||
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+25228, 0)
|
||||
}
|
||||
/************ End %syntax_error code ******************************************/
|
||||
/* Suppress warning about unused %extra_argument variable */
|
||||
(*TyyParser)(unsafe.Pointer(yypParser)).FpParse = pParse
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm) || (linux && loong64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __ACCUM_EPSILON__ = 0
|
||||
|
||||
const __ACCUM_FBIT__ = 15
|
||||
|
||||
const __ACCUM_IBIT__ = 16
|
||||
|
||||
const __ACCUM_MAX__ = 0
|
||||
|
||||
const __ACCUM_MIN__ = 0
|
||||
|
||||
const __DA_FBIT__ = 31
|
||||
|
||||
const __DA_IBIT__ = 32
|
||||
|
||||
const __DQ_FBIT__ = 63
|
||||
|
||||
const __DQ_IBIT__ = 0
|
||||
|
||||
const __FRACT_EPSILON__ = 0
|
||||
|
||||
const __FRACT_FBIT__ = 15
|
||||
|
||||
const __FRACT_IBIT__ = 0
|
||||
|
||||
const __FRACT_MAX__ = 0
|
||||
|
||||
const __FRACT_MIN__ = 0
|
||||
|
||||
const __HA_FBIT__ = 7
|
||||
|
||||
const __HA_IBIT__ = 8
|
||||
|
||||
const __HQ_FBIT__ = 15
|
||||
|
||||
const __HQ_IBIT__ = 0
|
||||
|
||||
const __LACCUM_EPSILON__ = 0
|
||||
|
||||
const __LACCUM_FBIT__ = 31
|
||||
|
||||
const __LACCUM_IBIT__ = 32
|
||||
|
||||
const __LACCUM_MAX__ = 0
|
||||
|
||||
const __LACCUM_MIN__ = 0
|
||||
|
||||
const __LFRACT_EPSILON__ = 0
|
||||
|
||||
const __LFRACT_FBIT__ = 31
|
||||
|
||||
const __LFRACT_IBIT__ = 0
|
||||
|
||||
const __LFRACT_MAX__ = 0
|
||||
|
||||
const __LFRACT_MIN__ = 0
|
||||
|
||||
const __LLACCUM_EPSILON__ = 0
|
||||
|
||||
const __LLACCUM_MAX__ = 0
|
||||
|
||||
const __LLACCUM_MIN__ = 0
|
||||
|
||||
const __LLFRACT_EPSILON__ = 0
|
||||
|
||||
const __LLFRACT_FBIT__ = 63
|
||||
|
||||
const __LLFRACT_IBIT__ = 0
|
||||
|
||||
const __LLFRACT_MAX__ = 0
|
||||
|
||||
const __LLFRACT_MIN__ = 0
|
||||
|
||||
const __QQ_FBIT__ = 7
|
||||
|
||||
const __QQ_IBIT__ = 0
|
||||
|
||||
const __SACCUM_EPSILON__ = 0
|
||||
|
||||
const __SACCUM_FBIT__ = 7
|
||||
|
||||
const __SACCUM_IBIT__ = 8
|
||||
|
||||
const __SACCUM_MAX__ = 0
|
||||
|
||||
const __SACCUM_MIN__ = 0
|
||||
|
||||
const __SA_FBIT__ = 15
|
||||
|
||||
const __SA_IBIT__ = 16
|
||||
|
||||
const __SFRACT_EPSILON__ = 0
|
||||
|
||||
const __SFRACT_FBIT__ = 7
|
||||
|
||||
const __SFRACT_IBIT__ = 0
|
||||
|
||||
const __SFRACT_MAX__ = 0
|
||||
|
||||
const __SFRACT_MIN__ = 0
|
||||
|
||||
const __SQ_FBIT__ = 31
|
||||
|
||||
const __SQ_IBIT__ = 0
|
||||
|
||||
const __TA_FBIT__ = 63
|
||||
|
||||
const __TA_IBIT__ = 64
|
||||
|
||||
const __TQ_FBIT__ = 127
|
||||
|
||||
const __TQ_IBIT__ = 0
|
||||
|
||||
const __UACCUM_EPSILON__ = 0
|
||||
|
||||
const __UACCUM_FBIT__ = 16
|
||||
|
||||
const __UACCUM_IBIT__ = 16
|
||||
|
||||
const __UACCUM_MAX__ = 0
|
||||
|
||||
const __UACCUM_MIN__ = 0
|
||||
|
||||
const __UDA_FBIT__ = 32
|
||||
|
||||
const __UDA_IBIT__ = 32
|
||||
|
||||
const __UDQ_FBIT__ = 64
|
||||
|
||||
const __UDQ_IBIT__ = 0
|
||||
|
||||
const __UFRACT_EPSILON__ = 0
|
||||
|
||||
const __UFRACT_FBIT__ = 16
|
||||
|
||||
const __UFRACT_IBIT__ = 0
|
||||
|
||||
const __UFRACT_MAX__ = 0
|
||||
|
||||
const __UFRACT_MIN__ = 0
|
||||
|
||||
const __UHA_FBIT__ = 8
|
||||
|
||||
const __UHA_IBIT__ = 8
|
||||
|
||||
const __UHQ_FBIT__ = 16
|
||||
|
||||
const __UHQ_IBIT__ = 0
|
||||
|
||||
const __ULACCUM_EPSILON__ = 0
|
||||
|
||||
const __ULACCUM_FBIT__ = 32
|
||||
|
||||
const __ULACCUM_IBIT__ = 32
|
||||
|
||||
const __ULACCUM_MAX__ = 0
|
||||
|
||||
const __ULACCUM_MIN__ = 0
|
||||
|
||||
const __ULFRACT_EPSILON__ = 0
|
||||
|
||||
const __ULFRACT_FBIT__ = 32
|
||||
|
||||
const __ULFRACT_IBIT__ = 0
|
||||
|
||||
const __ULFRACT_MAX__ = 0
|
||||
|
||||
const __ULFRACT_MIN__ = 0
|
||||
|
||||
const __ULLACCUM_EPSILON__ = 0
|
||||
|
||||
const __ULLACCUM_MAX__ = 0
|
||||
|
||||
const __ULLACCUM_MIN__ = 0
|
||||
|
||||
const __ULLFRACT_EPSILON__ = 0
|
||||
|
||||
const __ULLFRACT_FBIT__ = 64
|
||||
|
||||
const __ULLFRACT_IBIT__ = 0
|
||||
|
||||
const __ULLFRACT_MAX__ = 0
|
||||
|
||||
const __ULLFRACT_MIN__ = 0
|
||||
|
||||
const __UQQ_FBIT__ = 8
|
||||
|
||||
const __UQQ_IBIT__ = 0
|
||||
|
||||
const __USACCUM_EPSILON__ = 0
|
||||
|
||||
const __USACCUM_FBIT__ = 8
|
||||
|
||||
const __USACCUM_IBIT__ = 8
|
||||
|
||||
const __USACCUM_MAX__ = 0
|
||||
|
||||
const __USACCUM_MIN__ = 0
|
||||
|
||||
const __USA_FBIT__ = 16
|
||||
|
||||
const __USA_IBIT__ = 16
|
||||
|
||||
const __USFRACT_EPSILON__ = 0
|
||||
|
||||
const __USFRACT_FBIT__ = 8
|
||||
|
||||
const __USFRACT_IBIT__ = 0
|
||||
|
||||
const __USFRACT_MAX__ = 0
|
||||
|
||||
const __USFRACT_MIN__ = 0
|
||||
|
||||
const __USQ_FBIT__ = 32
|
||||
|
||||
const __USQ_IBIT__ = 0
|
||||
|
||||
const __UTA_FBIT__ = 64
|
||||
|
||||
const __UTA_IBIT__ = 64
|
||||
|
||||
const __UTQ_FBIT__ = 128
|
||||
|
||||
const __UTQ_IBIT__ = 0
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm) || (linux && arm64) || (linux && ppc64le)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const O_DIRECTORY = 16384
|
||||
|
||||
const O_NOFOLLOW = 32768
|
||||
|
||||
const O_TMPFILE = 4210688
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && loong64) || (linux && ppc64le)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __FLOAT128_TYPE__ = 1
|
||||
|
||||
const __builtin_copysignq = 0
|
||||
|
||||
const __builtin_fabsq = 0
|
||||
|
||||
const __builtin_huge_valq = 0
|
||||
|
||||
const __builtin_infq = 0
|
||||
|
||||
const __builtin_nanq = 0
|
||||
|
||||
const __builtin_nansq = 0
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm64) || (linux && riscv64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Append a single path element to the DbPath under construction
|
||||
// */
|
||||
func _appendOnePathElement(tls *libc.TLS, pPath uintptr, zName uintptr, nName int32) {
|
||||
bp := tls.Alloc(4240)
|
||||
defer tls.Free(4240)
|
||||
var got Tssize_t
|
||||
var zIn, v2 uintptr
|
||||
var v1 int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
var _ /* zLnk at bp+128 */ [4098]uint8
|
||||
_, _, _, _ = got, zIn, v1, v2
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zName))) == int32('.') {
|
||||
if nName == int32(1) {
|
||||
return
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zName + 1))) == int32('.') && nName == int32(2) {
|
||||
if (*TDbPath)(unsafe.Pointer(pPath)).FnUsed > int32(1) {
|
||||
for {
|
||||
v2 = pPath + 20
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) - 1
|
||||
v1 = *(*int32)(unsafe.Pointer(v2))
|
||||
if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr(v1)))) != int32('/')) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if (*TDbPath)(unsafe.Pointer(pPath)).FnUsed+nName+int32(2) >= (*TDbPath)(unsafe.Pointer(pPath)).FnOut {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = int32(SQLITE_ERROR)
|
||||
return
|
||||
}
|
||||
v2 = pPath + 20
|
||||
v1 = *(*int32)(unsafe.Pointer(v2))
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
||||
**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr(v1))) = uint8('/')
|
||||
libc.Xmemcpy(tls, (*TDbPath)(unsafe.Pointer(pPath)).FzOut+uintptr((*TDbPath)(unsafe.Pointer(pPath)).FnUsed), zName, libc.Uint64FromInt32(nName))
|
||||
**(**int32)(__ccgo_up(pPath + 20)) += nName
|
||||
if (*TDbPath)(unsafe.Pointer(pPath)).Frc == SQLITE_OK {
|
||||
**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr((*TDbPath)(unsafe.Pointer(pPath)).FnUsed))) = uint8(0)
|
||||
zIn = (*TDbPath)(unsafe.Pointer(pPath)).FzOut
|
||||
if (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(27)].FpCurrent})))(tls, zIn, bp) != 0 {
|
||||
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) != int32(ENOENT) {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47297)), __ccgo_ts+3740, zIn, int32(47297))
|
||||
}
|
||||
} else {
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(S_IFMT) == uint32(S_IFLNK) {
|
||||
v2 = pPath + 4
|
||||
v1 = *(*int32)(unsafe.Pointer(v2))
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
||||
if v1 > int32(SQLITE_MAX_SYMLINK) {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _sqlite3CantopenError(tls, int32(47303))
|
||||
return
|
||||
}
|
||||
got = (*(*func(*libc.TLS, uintptr, uintptr, Tsize_t) Tssize_t)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(26)].FpCurrent})))(tls, zIn, bp+128, libc.Uint64FromInt64(4098)-libc.Uint64FromInt32(2))
|
||||
if got <= 0 || got >= libc.Int64FromInt64(4098)-libc.Int64FromInt32(2) {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47308)), __ccgo_ts+3731, zIn, int32(47308))
|
||||
return
|
||||
}
|
||||
(**(**[4098]uint8)(__ccgo_up(bp + 128)))[got] = uint8(0)
|
||||
if libc.Int32FromUint8((**(**[4098]uint8)(__ccgo_up(bp + 128)))[0]) == int32('/') {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).FnUsed = 0
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(pPath + 20)) -= nName + int32(1)
|
||||
}
|
||||
_appendAllPathElements(tls, pPath, bp+128)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+748
@@ -0,0 +1,748 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm64) || (linux && loong64) || (linux && riscv64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type Tstat = struct {
|
||||
Fst_dev Tdev_t
|
||||
Fst_ino Tino_t
|
||||
Fst_mode Tmode_t
|
||||
Fst_nlink Tnlink_t
|
||||
Fst_uid Tuid_t
|
||||
Fst_gid Tgid_t
|
||||
Fst_rdev Tdev_t
|
||||
F__pad uint64
|
||||
Fst_size Toff_t
|
||||
Fst_blksize Tblksize_t
|
||||
F__pad2 int32
|
||||
Fst_blocks Tblkcnt_t
|
||||
Fst_atim Ttimespec
|
||||
Fst_mtim Ttimespec
|
||||
Fst_ctim Ttimespec
|
||||
F__unused [2]uint32
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
|
||||
// ** file-control operation. Enlarge the database to nBytes in size
|
||||
// ** (rounded up to the next chunk-size). If the database is already
|
||||
// ** nBytes or larger, this routine is a no-op.
|
||||
// */
|
||||
func _fcntlSizeHint(tls *libc.TLS, pFile uintptr, nByte Ti64) (r int32) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var iWrite, nSize Ti64
|
||||
var nBlk, nWrite, rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_, _, _, _, _ = iWrite, nBlk, nSize, nWrite, rc
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).FszChunk > 0 { /* Used to hold return values of fstat() */
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp) != 0 {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
nSize = (nByte + int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk) - int64(1)) / int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk) * int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk)
|
||||
if nSize > int64((**(**Tstat)(__ccgo_up(bp))).Fst_size) {
|
||||
/* If the OS does not have posix_fallocate(), fake it. Write a
|
||||
** single byte to the last byte in each block that falls entirely
|
||||
** within the extended region. Then, if required, a single byte
|
||||
** at offset (nSize-1), to set the size of the file correctly.
|
||||
** This is a similar technique to that used by glibc on systems
|
||||
** that do not have a real fallocate() call.
|
||||
*/
|
||||
nBlk = (**(**Tstat)(__ccgo_up(bp))).Fst_blksize /* File-system block size */
|
||||
nWrite = 0 /* Next offset to write to */
|
||||
iWrite = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size/int64(nBlk)*int64(nBlk) + int64(nBlk) - int64(1))
|
||||
for {
|
||||
if !(iWrite < nSize+int64(nBlk)-int64(1)) {
|
||||
break
|
||||
}
|
||||
if iWrite >= nSize {
|
||||
iWrite = nSize - int64(1)
|
||||
}
|
||||
nWrite = _seekAndWrite(tls, pFile, iWrite, __ccgo_ts+1704, int32(1))
|
||||
if nWrite != int32(1) {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
iWrite = iWrite + int64(nBlk)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).FmmapSizeMax > 0 && nByte > (*TunixFile)(unsafe.Pointer(pFile)).FmmapSize {
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).FszChunk <= 0 {
|
||||
if _robust_ftruncate(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, nByte) != 0 {
|
||||
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
||||
return _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(6)<<libc.Int32FromInt32(8), __ccgo_ts+3578, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, int32(44442))
|
||||
}
|
||||
}
|
||||
rc = _unixMapfile(tls, pFile, nByte)
|
||||
return rc
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if pFile has been renamed or unlinked since it was first opened.
|
||||
// */
|
||||
func _fileHasMoved(tls *libc.TLS, pFile uintptr) (r int32) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
return libc.BoolInt32((*TunixFile)(unsafe.Pointer(pFile)).FpInode != uintptr(0) && ((*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, bp) != 0 || uint64((**(**Tstat)(__ccgo_up(bp))).Fst_ino) != (*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FfileId.Fino))
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Given a file descriptor, locate the unixInodeInfo object that
|
||||
// ** describes that file descriptor. Create a new one if necessary. The
|
||||
// ** return value might be uninitialized if an error occurs.
|
||||
// **
|
||||
// ** The global mutex must held when calling this routine.
|
||||
// **
|
||||
// ** Return an appropriate error code.
|
||||
// */
|
||||
func _findInodeInfo(tls *libc.TLS, pFile uintptr, ppInode uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var fd, rc int32
|
||||
var pInode uintptr
|
||||
var _ /* fileId at bp+0 */ TunixFileId
|
||||
var _ /* statbuf at bp+16 */ Tstat
|
||||
_, _, _ = fd, pInode, rc /* Low-level file information */
|
||||
pInode = uintptr(0) /* Candidate unixInodeInfo object */
|
||||
/* Get low-level information about the file that we can used to
|
||||
** create a unique name for the file.
|
||||
*/
|
||||
fd = (*TunixFile)(unsafe.Pointer(pFile)).Fh
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, fd, bp+16)
|
||||
if rc != 0 {
|
||||
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
||||
return int32(SQLITE_IOERR)
|
||||
}
|
||||
libc.Xmemset(tls, bp, 0, uint64(16))
|
||||
(**(**TunixFileId)(__ccgo_up(bp))).Fdev = (**(**Tstat)(__ccgo_up(bp + 16))).Fst_dev
|
||||
(**(**TunixFileId)(__ccgo_up(bp))).Fino = uint64((**(**Tstat)(__ccgo_up(bp + 16))).Fst_ino)
|
||||
pInode = _inodeList
|
||||
for pInode != 0 && libc.Xmemcmp(tls, bp, pInode, uint64(16)) != 0 {
|
||||
pInode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext
|
||||
}
|
||||
if pInode == uintptr(0) {
|
||||
pInode = Xsqlite3_malloc64(tls, uint64(80))
|
||||
if pInode == uintptr(0) {
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
libc.Xmemset(tls, pInode, 0, uint64(80))
|
||||
libc.Xmemcpy(tls, pInode, bp, uint64(16))
|
||||
if _sqlite3Config.FbCoreMutex != 0 {
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex = Xsqlite3_mutex_alloc(tls, SQLITE_MUTEX_FAST)
|
||||
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex == uintptr(0) {
|
||||
Xsqlite3_free(tls, pInode)
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
}
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef = int32(1)
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext = _inodeList
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpPrev = uintptr(0)
|
||||
if _inodeList != 0 {
|
||||
(*TunixInodeInfo)(unsafe.Pointer(_inodeList)).FpPrev = pInode
|
||||
}
|
||||
_inodeList = pInode
|
||||
} else {
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef + 1
|
||||
}
|
||||
**(**uintptr)(__ccgo_up(ppInode)) = pInode
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Search for an unused file descriptor that was opened on the database
|
||||
// ** file (not a journal or super-journal file) identified by pathname
|
||||
// ** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
|
||||
// ** argument to this function.
|
||||
// **
|
||||
// ** Such a file descriptor may exist if a database connection was closed
|
||||
// ** but the associated file descriptor could not be closed because some
|
||||
// ** other file descriptor open on the same file is holding a file-lock.
|
||||
// ** Refer to comments in the unixClose() function and the lengthy comment
|
||||
// ** describing "Posix Advisory Locking" at the start of this file for
|
||||
// ** further details. Also, ticket #4018.
|
||||
// **
|
||||
// ** If a suitable file descriptor is found, then it is returned. If no
|
||||
// ** such file descriptor is located, -1 is returned.
|
||||
// */
|
||||
func _findReusableFd(tls *libc.TLS, zPath uintptr, flags int32) (r uintptr) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var pInode, pUnused, pp uintptr
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
_, _, _ = pInode, pUnused, pp
|
||||
pUnused = uintptr(0) /* Results of stat() call */
|
||||
_unixEnterMutex(tls)
|
||||
/* A stat() call may fail for various reasons. If this happens, it is
|
||||
** almost certain that an open() call on the same path will also fail.
|
||||
** For this reason, if an error occurs in the stat() call here, it is
|
||||
** ignored and -1 is returned. The caller will try to open a new file
|
||||
** descriptor on the same path, fail, and return an error to SQLite.
|
||||
**
|
||||
** Even if a subsequent open() call does succeed, the consequences of
|
||||
** not searching for a reusable file descriptor are not dire. */
|
||||
if _inodeList != uintptr(0) && 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zPath, bp) {
|
||||
pInode = _inodeList
|
||||
for pInode != 0 && ((*TunixInodeInfo)(unsafe.Pointer(pInode)).FfileId.Fdev != (**(**Tstat)(__ccgo_up(bp))).Fst_dev || (*TunixInodeInfo)(unsafe.Pointer(pInode)).FfileId.Fino != uint64((**(**Tstat)(__ccgo_up(bp))).Fst_ino)) {
|
||||
pInode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext
|
||||
}
|
||||
if pInode != 0 {
|
||||
Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
||||
flags = flags & (libc.Int32FromInt32(SQLITE_OPEN_READONLY) | libc.Int32FromInt32(SQLITE_OPEN_READWRITE))
|
||||
pp = pInode + 40
|
||||
for {
|
||||
if !(**(**uintptr)(__ccgo_up(pp)) != 0 && (*TUnixUnusedFd)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).Fflags != flags) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
pp = **(**uintptr)(__ccgo_up(pp)) + 8
|
||||
}
|
||||
pUnused = **(**uintptr)(__ccgo_up(pp))
|
||||
if pUnused != 0 {
|
||||
**(**uintptr)(__ccgo_up(pp)) = (*TUnixUnusedFd)(unsafe.Pointer(pUnused)).FpNext
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
||||
}
|
||||
}
|
||||
_unixLeaveMutex(tls)
|
||||
return pUnused
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Invoke open(). Do so multiple times, until it either succeeds or
|
||||
// ** fails for some reason other than EINTR.
|
||||
// **
|
||||
// ** If the file creation mode "m" is 0 then set it to the default for
|
||||
// ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
|
||||
// ** 0644) as modified by the system umask. If m is not 0, then
|
||||
// ** make the file creation mode be exactly m ignoring the umask.
|
||||
// **
|
||||
// ** The m parameter will be non-zero only when creating -wal, -journal,
|
||||
// ** and -shm files. We want those files to have *exactly* the same
|
||||
// ** permissions as their original database, unadulterated by the umask.
|
||||
// ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
|
||||
// ** transaction crashes and leaves behind hot journals, then any
|
||||
// ** process that is able to write to the database will also be able to
|
||||
// ** recover the hot journals.
|
||||
// */
|
||||
func _robust_open(tls *libc.TLS, z uintptr, f int32, m Tmode_t) (r int32) {
|
||||
bp := tls.Alloc(160)
|
||||
defer tls.Free(160)
|
||||
var fd int32
|
||||
var m2 Tmode_t
|
||||
var v1 uint32
|
||||
var _ /* statbuf at bp+0 */ Tstat
|
||||
_, _, _ = fd, m2, v1
|
||||
if m != 0 {
|
||||
v1 = m
|
||||
} else {
|
||||
v1 = uint32(SQLITE_DEFAULT_FILE_PERMISSIONS)
|
||||
}
|
||||
m2 = v1
|
||||
for int32(1) != 0 {
|
||||
fd = (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, z, f|int32(O_CLOEXEC), libc.Int32FromUint32(m2))
|
||||
if fd < 0 {
|
||||
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EINTR) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if fd >= int32(SQLITE_MINIMUM_FILE_DESCRIPTOR) {
|
||||
break
|
||||
}
|
||||
if f&(libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT)) == libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT) {
|
||||
(*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(16)].FpCurrent})))(tls, z)
|
||||
}
|
||||
(*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(1)].FpCurrent})))(tls, fd)
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3752, libc.VaList(bp+136, z, fd))
|
||||
fd = -int32(1)
|
||||
if (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, __ccgo_ts+3795, O_RDONLY, libc.Int32FromUint32(m)) < 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if fd >= 0 {
|
||||
if m != uint32(0) {
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, fd, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_size == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(0777) != m {
|
||||
(*(*func(*libc.TLS, int32, Tmode_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(14)].FpCurrent})))(tls, fd, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Test the existence of or access permissions of file zPath. The
|
||||
// ** test performed depends on the value of flags:
|
||||
// **
|
||||
// ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
|
||||
// ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
|
||||
// ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
|
||||
// **
|
||||
// ** Otherwise return 0.
|
||||
// */
|
||||
func _unixAccess(tls *libc.TLS, NotUsed uintptr, zPath uintptr, flags int32, pResOut uintptr) (r int32) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = NotUsed
|
||||
/* The spec says there are three possible values for flags. But only
|
||||
** two of them are actually used */
|
||||
if flags == SQLITE_ACCESS_EXISTS {
|
||||
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32(0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zPath, bp) && (!((**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(S_IFMT) == libc.Uint32FromInt32(S_IFREG)) || (**(**Tstat)(__ccgo_up(bp))).Fst_size > 0))
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32((*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zPath, libc.Int32FromInt32(W_OK)|libc.Int32FromInt32(R_OK)) == 0)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Determine the current size of a file in bytes
|
||||
// */
|
||||
func _unixFileSize(tls *libc.TLS, id uintptr, pSize uintptr) (r int32) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = rc
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(id)).Fh, bp)
|
||||
if rc != 0 {
|
||||
_storeLastErrno(tls, id, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
**(**Ti64)(__ccgo_up(pSize)) = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size)
|
||||
/* When opening a zero-size database, the findInodeInfo() procedure
|
||||
** writes a single byte into that file in order to work around a bug
|
||||
** in the OS-X msdos filesystem. In order to avoid problems with upper
|
||||
** layers, we need to report this file size as zero even though it is
|
||||
** really 1. Ticket #3260.
|
||||
*/
|
||||
if **(**Ti64)(__ccgo_up(pSize)) == int64(1) {
|
||||
**(**Ti64)(__ccgo_up(pSize)) = 0
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Memory map or remap the file opened by file-descriptor pFd (if the file
|
||||
// ** is already mapped, the existing mapping is replaced by the new). Or, if
|
||||
// ** there already exists a mapping for this file, and there are still
|
||||
// ** outstanding xFetch() references to it, this function is a no-op.
|
||||
// **
|
||||
// ** If parameter nByte is non-negative, then it is the requested size of
|
||||
// ** the mapping to create. Otherwise, if nByte is less than zero, then the
|
||||
// ** requested size is the size of the file on disk. The actual size of the
|
||||
// ** created mapping is either the requested size or the value configured
|
||||
// ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
|
||||
// **
|
||||
// ** SQLITE_OK is returned if no error occurs (even if the mapping is not
|
||||
// ** recreated as a result of outstanding references) or an SQLite error
|
||||
// ** code otherwise.
|
||||
// */
|
||||
func _unixMapfile(tls *libc.TLS, pFd uintptr, nMap Ti64) (r int32) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var _ /* statbuf at bp+0 */ Tstat
|
||||
if (*TunixFile)(unsafe.Pointer(pFd)).FnFetchOut > 0 {
|
||||
return SQLITE_OK
|
||||
}
|
||||
if nMap < 0 { /* Low-level file information */
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFd)).Fh, bp) != 0 {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
nMap = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size)
|
||||
}
|
||||
if nMap > (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax {
|
||||
nMap = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax
|
||||
}
|
||||
if nMap != (*TunixFile)(unsafe.Pointer(pFd)).FmmapSize {
|
||||
_unixRemapfile(tls, pFd, nMap)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Open a shared-memory area associated with open database file pDbFd.
|
||||
// ** This particular implementation uses mmapped files.
|
||||
// **
|
||||
// ** The file used to implement shared-memory is in the same directory
|
||||
// ** as the open database file and has the same name as the open database
|
||||
// ** file with the "-shm" suffix added. For example, if the database file
|
||||
// ** is "/home/user1/config.db" then the file that is created and mmapped
|
||||
// ** for shared memory will be called "/home/user1/config.db-shm".
|
||||
// **
|
||||
// ** Another approach to is to use files in /dev/shm or /dev/tmp or an
|
||||
// ** some other tmpfs mount. But if a file in a different directory
|
||||
// ** from the database file is used, then differing access permissions
|
||||
// ** or a chroot() might cause two different processes on the same
|
||||
// ** database to end up using different files for shared memory -
|
||||
// ** meaning that their memory would not really be shared - resulting
|
||||
// ** in database corruption. Nevertheless, this tmpfs file usage
|
||||
// ** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
|
||||
// ** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time
|
||||
// ** option results in an incompatible build of SQLite; builds of SQLite
|
||||
// ** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
|
||||
// ** same database file at the same time, database corruption will likely
|
||||
// ** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
|
||||
// ** "unsupported" and may go away in a future SQLite release.
|
||||
// **
|
||||
// ** When opening a new shared-memory file, if no other instances of that
|
||||
// ** file are currently open, in this process or in other processes, then
|
||||
// ** the file must be truncated to zero length or have its header cleared.
|
||||
// **
|
||||
// ** If the original database file (pDbFd) is using the "unix-excl" VFS
|
||||
// ** that means that an exclusive lock is held on the database file and
|
||||
// ** that no other processes are able to read or write the database. In
|
||||
// ** that case, we do not really need shared memory. No shared memory
|
||||
// ** file is created. The shared memory will be simulated with heap memory.
|
||||
// */
|
||||
func _unixOpenSharedMemory(tls *libc.TLS, pDbFd uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var nShmFilename, rc int32
|
||||
var p, pInode, pShmNode, zBasePath, zShm, v1 uintptr
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
_, _, _, _, _, _, _, _ = nShmFilename, p, pInode, pShmNode, rc, zBasePath, zShm, v1
|
||||
p = uintptr(0) /* The underlying mmapped file */
|
||||
rc = SQLITE_OK /* Size of the SHM filename in bytes */
|
||||
/* Allocate space for the new unixShm object. */
|
||||
p = Xsqlite3_malloc64(tls, uint64(24))
|
||||
if p == uintptr(0) {
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
libc.Xmemset(tls, p, 0, uint64(24))
|
||||
/* Check to see if a unixShmNode object already exists. Reuse an existing
|
||||
** one if present. Create a new one if necessary.
|
||||
*/
|
||||
_unixEnterMutex(tls)
|
||||
pInode = (*TunixFile)(unsafe.Pointer(pDbFd)).FpInode
|
||||
pShmNode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpShmNode
|
||||
if pShmNode == uintptr(0) { /* fstat() info for database file */
|
||||
zBasePath = (*TunixFile)(unsafe.Pointer(pDbFd)).FzPath
|
||||
/* Call fstat() to figure out the permissions on the database file. If
|
||||
** a new *-shm file is created, an attempt will be made to create it
|
||||
** with the same permissions.
|
||||
*/
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pDbFd)).Fh, bp) != 0 {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
goto shm_open_err
|
||||
}
|
||||
nShmFilename = int32(6) + libc.Int32FromUint64(libc.Xstrlen(tls, zBasePath))
|
||||
pShmNode = Xsqlite3_malloc64(tls, uint64(uint64(96)+libc.Uint64FromInt32(nShmFilename)))
|
||||
if pShmNode == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
goto shm_open_err
|
||||
}
|
||||
libc.Xmemset(tls, pShmNode, 0, uint64(96)+libc.Uint64FromInt32(nShmFilename))
|
||||
v1 = pShmNode + 1*96
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename = v1
|
||||
zShm = v1
|
||||
Xsqlite3_snprintf(tls, nShmFilename, zShm, __ccgo_ts+3982, libc.VaList(bp+136, zBasePath))
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = -int32(1)
|
||||
(*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pDbFd)).FpInode)).FpShmNode = pShmNode
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpInode = (*TunixFile)(unsafe.Pointer(pDbFd)).FpInode
|
||||
if _sqlite3Config.FbCoreMutex != 0 {
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex = Xsqlite3_mutex_alloc(tls, SQLITE_MUTEX_FAST)
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
goto shm_open_err
|
||||
}
|
||||
}
|
||||
if libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FbProcessLock) == 0 {
|
||||
if 0 == Xsqlite3_uri_boolean(tls, (*TunixFile)(unsafe.Pointer(pDbFd)).FzPath, __ccgo_ts+3989, 0) {
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = _robust_open(tls, zShm, libc.Int32FromInt32(O_RDWR)|libc.Int32FromInt32(O_CREAT)|libc.Int32FromInt32(O_NOFOLLOW), (**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(0777))
|
||||
}
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm < 0 {
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = _robust_open(tls, zShm, libc.Int32FromInt32(O_RDONLY)|libc.Int32FromInt32(O_NOFOLLOW), (**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(0777))
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm < 0 {
|
||||
rc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(45382)), __ccgo_ts+3542, zShm, int32(45382))
|
||||
goto shm_open_err
|
||||
}
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly = uint8(1)
|
||||
}
|
||||
/* If this process is running as root, make sure that the SHM file
|
||||
** is owned by the same user that owns the original database. Otherwise,
|
||||
** the original owner will not be able to connect.
|
||||
*/
|
||||
_robustFchown(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, (**(**Tstat)(__ccgo_up(bp))).Fst_uid, (**(**Tstat)(__ccgo_up(bp))).Fst_gid)
|
||||
rc = _unixLockSharedMemory(tls, pDbFd, pShmNode)
|
||||
if rc != SQLITE_OK && rc != libc.Int32FromInt32(SQLITE_READONLY)|libc.Int32FromInt32(5)<<libc.Int32FromInt32(8) {
|
||||
goto shm_open_err
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Make the new connection a child of the unixShmNode */
|
||||
(*TunixShm)(unsafe.Pointer(p)).FpShmNode = pShmNode
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRef = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRef + 1
|
||||
(*TunixFile)(unsafe.Pointer(pDbFd)).FpShm = p
|
||||
_unixLeaveMutex(tls)
|
||||
/* The reference count on pShmNode has already been incremented under
|
||||
** the cover of the unixEnterMutex() mutex and the pointer from the
|
||||
** new (struct unixShm) object to the pShmNode has been set. All that is
|
||||
** left to do is to link the new object into the linked list starting
|
||||
** at pShmNode->pFirst. This must be done while holding the
|
||||
** pShmNode->pShmMutex.
|
||||
*/
|
||||
Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
(*TunixShm)(unsafe.Pointer(p)).FpNext = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpFirst
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpFirst = p
|
||||
Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
return rc
|
||||
/* Jump here on any error */
|
||||
goto shm_open_err
|
||||
shm_open_err:
|
||||
;
|
||||
_unixShmPurge(tls, pDbFd) /* This call frees pShmNode if required */
|
||||
Xsqlite3_free(tls, p)
|
||||
_unixLeaveMutex(tls)
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called to obtain a pointer to region iRegion of the
|
||||
// ** shared-memory associated with the database file fd. Shared-memory regions
|
||||
// ** are numbered starting from zero. Each shared-memory region is szRegion
|
||||
// ** bytes in size.
|
||||
// **
|
||||
// ** If an error occurs, an error code is returned and *pp is set to NULL.
|
||||
// **
|
||||
// ** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
|
||||
// ** region has not been allocated (by any client, including one running in a
|
||||
// ** separate process), then *pp is set to NULL and SQLITE_OK returned. If
|
||||
// ** bExtend is non-zero and the requested shared-memory region has not yet
|
||||
// ** been allocated, it is allocated by this function.
|
||||
// **
|
||||
// ** If the shared-memory region has already been allocated or is allocated by
|
||||
// ** this call as described above, then it is mapped into this processes
|
||||
// ** address space (if it is not already), *pp is set to point to the mapped
|
||||
// ** memory and SQLITE_OK returned.
|
||||
// */
|
||||
func _unixShmMap(tls *libc.TLS, fd uintptr, iRegion int32, szRegion int32, bExtend int32, pp uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var apNew, p, pDbFd, pMem, pShmNode, zFile, v4 uintptr
|
||||
var i, iPg, nByte, nMap Ti64
|
||||
var nReqRegion, nShmPerMap, rc, v2 int32
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
var _ /* x at bp+128 */ int32
|
||||
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = apNew, i, iPg, nByte, nMap, nReqRegion, nShmPerMap, p, pDbFd, pMem, pShmNode, rc, zFile, v2, v4
|
||||
pDbFd = fd
|
||||
rc = SQLITE_OK
|
||||
nShmPerMap = _unixShmRegionPerMap(tls)
|
||||
/* If the shared-memory file has not yet been opened, open it now. */
|
||||
if (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm == uintptr(0) {
|
||||
rc = _unixOpenSharedMemory(tls, pDbFd)
|
||||
if rc != SQLITE_OK {
|
||||
return rc
|
||||
}
|
||||
}
|
||||
p = (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm
|
||||
pShmNode = (*TunixShm)(unsafe.Pointer(p)).FpShmNode
|
||||
Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisUnlocked != 0 {
|
||||
rc = _unixLockSharedMemory(tls, pDbFd, pShmNode)
|
||||
if rc != SQLITE_OK {
|
||||
goto shmpage_out
|
||||
}
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FisUnlocked = uint8(0)
|
||||
}
|
||||
/* Minimum number of regions required to be mapped. */
|
||||
nReqRegion = (iRegion + nShmPerMap) / nShmPerMap * nShmPerMap
|
||||
if libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) < nReqRegion { /* New apRegion[] array */
|
||||
nByte = int64(nReqRegion) * int64(szRegion) /* Used by fstat() */
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FszRegion = szRegion
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 0 {
|
||||
/* The requested region is not mapped into this processes address space.
|
||||
** Check to see if it has been allocated (i.e. if the wal-index file is
|
||||
** large enough to contain the requested region).
|
||||
*/
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, bp) != 0 {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(19)<<libc.Int32FromInt32(8)
|
||||
goto shmpage_out
|
||||
}
|
||||
if int64((**(**Tstat)(__ccgo_up(bp))).Fst_size) < nByte {
|
||||
/* The requested memory region does not exist. If bExtend is set to
|
||||
** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
|
||||
*/
|
||||
if !(bExtend != 0) {
|
||||
goto shmpage_out
|
||||
} else {
|
||||
/* Write to the last byte of each newly allocated or extended page */
|
||||
iPg = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size / int64(_pgsz))
|
||||
for {
|
||||
if !(iPg < nByte/int64(_pgsz)) {
|
||||
break
|
||||
}
|
||||
**(**int32)(__ccgo_up(bp + 128)) = 0
|
||||
if _seekAndWriteFd(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, iPg*int64(_pgsz)+int64(_pgsz)-int64(1), __ccgo_ts+1704, int32(1), bp+128) != int32(1) {
|
||||
zFile = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename
|
||||
rc = _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(19)<<libc.Int32FromInt32(8), __ccgo_ts+3613, zFile, int32(45526))
|
||||
goto shmpage_out
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
iPg = iPg + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Map the requested memory region into this processes address space. */
|
||||
apNew = Xsqlite3_realloc64(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion, uint64(libc.Uint64FromInt32(nReqRegion)*uint64(8)))
|
||||
if !(apNew != 0) {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(12)<<libc.Int32FromInt32(8)
|
||||
goto shmpage_out
|
||||
}
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion = apNew
|
||||
for libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) < nReqRegion {
|
||||
nMap = int64(szRegion) * int64(nShmPerMap)
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 0 {
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly != 0 {
|
||||
v2 = int32(PROT_READ)
|
||||
} else {
|
||||
v2 = libc.Int32FromInt32(PROT_READ) | libc.Int32FromInt32(PROT_WRITE)
|
||||
}
|
||||
pMem = (*(*func(*libc.TLS, uintptr, Tsize_t, int32, int32, int32, Toff_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(22)].FpCurrent})))(tls, uintptr(0), libc.Uint64FromInt64(nMap), v2, int32(MAP_SHARED), (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, int64(int64(szRegion)*libc.Int64FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion)))
|
||||
if pMem == uintptr(-libc.Int32FromInt32(1)) {
|
||||
rc = _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(21)<<libc.Int32FromInt32(8), __ccgo_ts+3700, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename, int32(45553))
|
||||
goto shmpage_out
|
||||
}
|
||||
} else {
|
||||
pMem = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nMap))
|
||||
if pMem == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
goto shmpage_out
|
||||
}
|
||||
libc.Xmemset(tls, pMem, 0, libc.Uint64FromInt64(nMap))
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(i < int64(nShmPerMap)) {
|
||||
break
|
||||
}
|
||||
**(**uintptr)(__ccgo_up((*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion + uintptr(libc.Int64FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion)+i)*8)) = pMem + uintptr(int64(szRegion)*i)
|
||||
goto _3
|
||||
_3:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
v4 = pShmNode + 32
|
||||
*(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) + nShmPerMap)
|
||||
}
|
||||
}
|
||||
goto shmpage_out
|
||||
shmpage_out:
|
||||
;
|
||||
if libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) > iRegion {
|
||||
**(**uintptr)(__ccgo_up(pp)) = **(**uintptr)(__ccgo_up((*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion + uintptr(iRegion)*8))
|
||||
} else {
|
||||
**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
|
||||
}
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly != 0 && rc == SQLITE_OK {
|
||||
rc = int32(SQLITE_READONLY)
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return the name of a directory in which to put temporary files.
|
||||
// ** If no suitable temporary file directory can be found, return NULL.
|
||||
// */
|
||||
func _unixTempFileDir(tls *libc.TLS) (r uintptr) {
|
||||
bp := tls.Alloc(128)
|
||||
defer tls.Free(128)
|
||||
var i, v1 uint32
|
||||
var zDir uintptr
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_, _, _ = i, zDir, v1
|
||||
i = uint32(0)
|
||||
zDir = Xsqlite3_temp_directory
|
||||
for int32(1) != 0 {
|
||||
if zDir != uintptr(0) && (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zDir, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(S_IFMT) == uint32(S_IFDIR) && (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zDir, int32(03)) == 0 {
|
||||
return zDir
|
||||
}
|
||||
if uint64(i) >= libc.Uint64FromInt64(48)/libc.Uint64FromInt64(8) {
|
||||
break
|
||||
}
|
||||
v1 = i
|
||||
i = i + 1
|
||||
zDir = _azTempDirs[v1]
|
||||
}
|
||||
return uintptr(0)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Check a unixFile that is a database. Verify the following:
|
||||
// **
|
||||
// ** (1) There is exactly one hard link on the file
|
||||
// ** (2) The file is not a symbolic link
|
||||
// ** (3) The file has not been renamed or unlinked
|
||||
// **
|
||||
// ** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
|
||||
// */
|
||||
func _verifyDbFile(tls *libc.TLS, pFile uintptr) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = rc
|
||||
/* These verifications occurs for the main database only */
|
||||
if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_NOLOCK) != 0 {
|
||||
return
|
||||
}
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp)
|
||||
if rc != 0 {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3860, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink == uint32(0) {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3884, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink > uint32(1) {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3913, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if _fileHasMoved(tls, pFile) != 0 {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3940, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && riscv64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const FIOQSIZE = 21600
|
||||
+13
File diff suppressed because one or more lines are too long
+18597
File diff suppressed because it is too large
Load Diff
+135
@@ -0,0 +1,135 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm) || (linux && arm64) || (linux && ppc64le) || (linux && riscv64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
|
||||
// ** The HH, MM, and SS must each be exactly 2 digits. The
|
||||
// ** fractional seconds FFFF can be one or more digits.
|
||||
// **
|
||||
// ** Return 1 if there is a parsing error and 0 on success.
|
||||
// */
|
||||
func _parseHhMmSs(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var ms, rScale float64
|
||||
var _ /* h at bp+0 */ int32
|
||||
var _ /* m at bp+4 */ int32
|
||||
var _ /* s at bp+8 */ int32
|
||||
_, _ = ms, rScale
|
||||
ms = float64(0)
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1204, libc.VaList(bp+24, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) == int32(':') {
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1212, libc.VaList(bp+24, bp+8)) != int32(1) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(2)
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) == int32('.') && libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate + 1)))])&int32(0x04) != 0 {
|
||||
rScale = float64(1)
|
||||
zDate = zDate + 1
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x04) != 0 {
|
||||
ms = float64(ms*float64(10)) + float64(**(**uint8)(__ccgo_up(zDate))) - libc.Float64FromUint8('0')
|
||||
rScale = rScale * float64(10)
|
||||
zDate = zDate + 1
|
||||
}
|
||||
ms = ms / rScale
|
||||
/* Truncate to avoid problems with sub-milliseconds
|
||||
** rounding. https://sqlite.org/forum/forumpost/766a2c9231 */
|
||||
if ms > float64(0.999) {
|
||||
ms = float64(0.999)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(bp + 8)) = 0
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = uint8(0)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 0, 0x1)
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = uint8(1)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fh = **(**int32)(__ccgo_up(bp))
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fm = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).Fs = float64(**(**int32)(__ccgo_up(bp + 8))) + ms
|
||||
if _parseTimezone(tls, zDate, p) != 0 {
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a timezone extension on the end of a date-time.
|
||||
// ** The extension is of the form:
|
||||
// **
|
||||
// ** (+/-)HH:MM
|
||||
// **
|
||||
// ** Or the "zulu" notation:
|
||||
// **
|
||||
// ** Z
|
||||
// **
|
||||
// ** If the parse is successful, write the number of minutes
|
||||
// ** of change in p->tz and return 0. If a parser error occurs,
|
||||
// ** return non-zero.
|
||||
// **
|
||||
// ** A missing specifier is not considered an error.
|
||||
// */
|
||||
func _parseTimezone(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c, sgn int32
|
||||
var _ /* nHr at bp+0 */ int32
|
||||
var _ /* nMn at bp+4 */ int32
|
||||
_, _ = c, sgn
|
||||
sgn = 0
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = 0
|
||||
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate)))
|
||||
if c == int32('-') {
|
||||
sgn = -int32(1)
|
||||
} else {
|
||||
if c == int32('+') {
|
||||
sgn = +libc.Int32FromInt32(1)
|
||||
} else {
|
||||
if c == int32('Z') || c == int32('z') {
|
||||
zDate = zDate + 1
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
goto zulu_time
|
||||
} else {
|
||||
return libc.BoolInt32(c != 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
zDate = zDate + 1
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1196, libc.VaList(bp+16, bp, bp+4)) != int32(2) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(5)
|
||||
(*TDateTime)(unsafe.Pointer(p)).Ftz = sgn * (**(**int32)(__ccgo_up(bp + 4)) + **(**int32)(__ccgo_up(bp))*int32(60))
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz == 0 { /* Forum post 2025-09-17T10:12:14z */
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(0), 4, 0x10)
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 3, 0x8)
|
||||
}
|
||||
goto zulu_time
|
||||
zulu_time:
|
||||
;
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x01) != 0 {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
return libc.BoolInt32(libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) != 0)
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && loong64) || (linux && ppc64le) || (linux && riscv64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __DBL_IS_IEC_60559__ = 1
|
||||
|
||||
const __FLT128_IS_IEC_60559__ = 1
|
||||
|
||||
const __FLT32X_IS_IEC_60559__ = 1
|
||||
|
||||
const __FLT32_IS_IEC_60559__ = 1
|
||||
|
||||
const __FLT64X_IS_IEC_60559__ = 1
|
||||
|
||||
const __FLT64_IS_IEC_60559__ = 1
|
||||
|
||||
const __FLT_IS_IEC_60559__ = 1
|
||||
|
||||
const __LDBL_IS_IEC_60559__ = 1
|
||||
+12828
File diff suppressed because it is too large
Load Diff
+104
@@ -0,0 +1,104 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64) || (linux && arm) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Open a new database handle.
|
||||
// */
|
||||
func Xsqlite3_open16(tls *libc.TLS, zFilename uintptr, ppDb uintptr) (r int32) {
|
||||
var pVal, zFilename8 uintptr
|
||||
var rc int32
|
||||
var v1 Tu8
|
||||
_, _, _, _ = pVal, rc, zFilename8, v1
|
||||
**(**uintptr)(__ccgo_up(ppDb)) = uintptr(0)
|
||||
rc = Xsqlite3_initialize(tls)
|
||||
if rc != 0 {
|
||||
return rc
|
||||
}
|
||||
if zFilename == uintptr(0) {
|
||||
zFilename = __ccgo_ts + 26292
|
||||
}
|
||||
pVal = _sqlite3ValueNew(tls, uintptr(0))
|
||||
_sqlite3ValueSetStr(tls, pVal, -int32(1), zFilename, uint8(SQLITE_UTF16LE), libc.UintptrFromInt32(0))
|
||||
zFilename8 = _sqlite3ValueText(tls, pVal, uint8(SQLITE_UTF8))
|
||||
if zFilename8 != 0 {
|
||||
rc = _openDatabase(tls, zFilename8, ppDb, libc.Uint32FromInt32(libc.Int32FromInt32(SQLITE_OPEN_READWRITE)|libc.Int32FromInt32(SQLITE_OPEN_CREATE)), uintptr(0))
|
||||
if rc == SQLITE_OK && !(libc.Int32FromUint16((*TSchema)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppDb)))).FaDb))).FpSchema)).FschemaFlags)&libc.Int32FromInt32(DB_SchemaLoaded) == libc.Int32FromInt32(DB_SchemaLoaded)) {
|
||||
v1 = libc.Uint8FromInt32(SQLITE_UTF16LE)
|
||||
(*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppDb)))).Fenc = v1
|
||||
(*TSchema)(unsafe.Pointer((**(**TDb)(__ccgo_up((*Tsqlite3)(unsafe.Pointer(**(**uintptr)(__ccgo_up(ppDb)))).FaDb))).FpSchema)).Fenc = v1
|
||||
}
|
||||
} else {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
}
|
||||
_sqlite3ValueFree(tls, pVal)
|
||||
return rc & int32(0xff)
|
||||
}
|
||||
|
||||
const __BYTE_ORDER = 1234
|
||||
|
||||
const __GNUC_WIDE_EXECUTION_CHARSET_NAME = "UTF-32LE"
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Attempt to parse the given string into a julian day number. Return
|
||||
// ** the number of errors.
|
||||
// **
|
||||
// ** The following are acceptable forms for the input string:
|
||||
// **
|
||||
// ** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
|
||||
// ** DDDD.DD
|
||||
// ** now
|
||||
// **
|
||||
// ** In the first form, the +/-HH:MM is always optional. The fractional
|
||||
// ** seconds extension (the ".FFF") is optional. The seconds portion
|
||||
// ** (":SS.FFF") is option. The year and date can be omitted as long
|
||||
// ** as there is a time string. The time string can be omitted as long
|
||||
// ** as there is a year and date.
|
||||
// */
|
||||
func _parseDateOrTime(tls *libc.TLS, context uintptr, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var _ /* r at bp+0 */ float64
|
||||
if _parseYyyyMmDd(tls, zDate, p) == 0 {
|
||||
return 0
|
||||
} else {
|
||||
if _parseHhMmSs(tls, zDate, p) == 0 {
|
||||
return 0
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, zDate, __ccgo_ts+1228) == 0 && _sqlite3NotPureFunc(tls, context) != 0 {
|
||||
return _setDateTimeToCurrent(tls, context, p)
|
||||
} else {
|
||||
if _sqlite3AtoF(tls, zDate, bp) > 0 {
|
||||
_setRawDateNumber(tls, p, **(**float64)(__ccgo_up(bp)))
|
||||
return 0
|
||||
} else {
|
||||
if (_sqlite3StrICmp(tls, zDate, __ccgo_ts+1232) == 0 || _sqlite3StrICmp(tls, zDate, __ccgo_ts+1239) == 0) && _sqlite3NotPureFunc(tls, context) != 0 {
|
||||
libc.SetBitFieldPtr8Uint32(p+44, libc.Uint32FromInt32(1), 2, 0x4)
|
||||
return _setDateTimeToCurrent(tls, context, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return int32(1)
|
||||
}
|
||||
|
||||
/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
|
||||
** Multiplying this by 86400000 gives 464269060799999 as the maximum value
|
||||
** for DateTime.iJD.
|
||||
**
|
||||
** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with
|
||||
** such a large integer literal, so we have to encode it.
|
||||
*/
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && arm64) || (freebsd && arm) || (linux && arm) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __BIGGEST_ALIGNMENT__ = 8
|
||||
+9
File diff suppressed because one or more lines are too long
+88
@@ -0,0 +1,88 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && ppc64le) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
const __FP_FAST_FMAL = 1
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Append a single path element to the DbPath under construction
|
||||
// */
|
||||
func _appendOnePathElement(tls *libc.TLS, pPath uintptr, zName uintptr, nName int32) {
|
||||
bp := tls.Alloc(4256)
|
||||
defer tls.Free(4256)
|
||||
var got Tssize_t
|
||||
var zIn, v2 uintptr
|
||||
var v1 int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
var _ /* zLnk at bp+144 */ [4098]uint8
|
||||
_, _, _, _ = got, zIn, v1, v2
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zName))) == int32('.') {
|
||||
if nName == int32(1) {
|
||||
return
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zName + 1))) == int32('.') && nName == int32(2) {
|
||||
if (*TDbPath)(unsafe.Pointer(pPath)).FnUsed > int32(1) {
|
||||
for {
|
||||
v2 = pPath + 20
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) - 1
|
||||
v1 = *(*int32)(unsafe.Pointer(v2))
|
||||
if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr(v1)))) != int32('/')) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if (*TDbPath)(unsafe.Pointer(pPath)).FnUsed+nName+int32(2) >= (*TDbPath)(unsafe.Pointer(pPath)).FnOut {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = int32(SQLITE_ERROR)
|
||||
return
|
||||
}
|
||||
v2 = pPath + 20
|
||||
v1 = *(*int32)(unsafe.Pointer(v2))
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
||||
**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr(v1))) = uint8('/')
|
||||
libc.Xmemcpy(tls, (*TDbPath)(unsafe.Pointer(pPath)).FzOut+uintptr((*TDbPath)(unsafe.Pointer(pPath)).FnUsed), zName, libc.Uint64FromInt32(nName))
|
||||
**(**int32)(__ccgo_up(pPath + 20)) += nName
|
||||
if (*TDbPath)(unsafe.Pointer(pPath)).Frc == SQLITE_OK {
|
||||
**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr((*TDbPath)(unsafe.Pointer(pPath)).FnUsed))) = uint8(0)
|
||||
zIn = (*TDbPath)(unsafe.Pointer(pPath)).FzOut
|
||||
if (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(27)].FpCurrent})))(tls, zIn, bp) != 0 {
|
||||
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) != int32(ENOENT) {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47297)), __ccgo_ts+3740, zIn, int32(47297))
|
||||
}
|
||||
} else {
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(S_IFMT) == uint32(S_IFLNK) {
|
||||
v2 = pPath + 4
|
||||
v1 = *(*int32)(unsafe.Pointer(v2))
|
||||
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
||||
if v1 > int32(SQLITE_MAX_SYMLINK) {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _sqlite3CantopenError(tls, int32(47303))
|
||||
return
|
||||
}
|
||||
got = (*(*func(*libc.TLS, uintptr, uintptr, Tsize_t) Tssize_t)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(26)].FpCurrent})))(tls, zIn, bp+144, libc.Uint64FromInt64(4098)-libc.Uint64FromInt32(2))
|
||||
if got <= 0 || got >= libc.Int64FromInt64(4098)-libc.Int64FromInt32(2) {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47308)), __ccgo_ts+3731, zIn, int32(47308))
|
||||
return
|
||||
}
|
||||
(**(**[4098]uint8)(__ccgo_up(bp + 144)))[got] = uint8(0)
|
||||
if libc.Int32FromUint8((**(**[4098]uint8)(__ccgo_up(bp + 144)))[0]) == int32('/') {
|
||||
(*TDbPath)(unsafe.Pointer(pPath)).FnUsed = 0
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(pPath + 20)) -= nName + int32(1)
|
||||
}
|
||||
_appendAllPathElements(tls, pPath, bp+144)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && arm64) || (linux && ppc64le) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const FP_FAST_FMAL = 1
|
||||
+640
@@ -0,0 +1,640 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && amd64) || (linux && ppc64le) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type Tblksize_t = int64
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
|
||||
// ** file-control operation. Enlarge the database to nBytes in size
|
||||
// ** (rounded up to the next chunk-size). If the database is already
|
||||
// ** nBytes or larger, this routine is a no-op.
|
||||
// */
|
||||
func _fcntlSizeHint(tls *libc.TLS, pFile uintptr, nByte Ti64) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var iWrite, nSize Ti64
|
||||
var nBlk, nWrite, rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_, _, _, _, _ = iWrite, nBlk, nSize, nWrite, rc
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).FszChunk > 0 { /* Used to hold return values of fstat() */
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp) != 0 {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
nSize = (nByte + int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk) - int64(1)) / int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk) * int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk)
|
||||
if nSize > int64((**(**Tstat)(__ccgo_up(bp))).Fst_size) {
|
||||
/* If the OS does not have posix_fallocate(), fake it. Write a
|
||||
** single byte to the last byte in each block that falls entirely
|
||||
** within the extended region. Then, if required, a single byte
|
||||
** at offset (nSize-1), to set the size of the file correctly.
|
||||
** This is a similar technique to that used by glibc on systems
|
||||
** that do not have a real fallocate() call.
|
||||
*/
|
||||
nBlk = int32((**(**Tstat)(__ccgo_up(bp))).Fst_blksize) /* File-system block size */
|
||||
nWrite = 0 /* Next offset to write to */
|
||||
iWrite = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size/int64(nBlk)*int64(nBlk) + int64(nBlk) - int64(1))
|
||||
for {
|
||||
if !(iWrite < nSize+int64(nBlk)-int64(1)) {
|
||||
break
|
||||
}
|
||||
if iWrite >= nSize {
|
||||
iWrite = nSize - int64(1)
|
||||
}
|
||||
nWrite = _seekAndWrite(tls, pFile, iWrite, __ccgo_ts+1704, int32(1))
|
||||
if nWrite != int32(1) {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
iWrite = iWrite + int64(nBlk)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).FmmapSizeMax > 0 && nByte > (*TunixFile)(unsafe.Pointer(pFile)).FmmapSize {
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).FszChunk <= 0 {
|
||||
if _robust_ftruncate(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, nByte) != 0 {
|
||||
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
||||
return _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(6)<<libc.Int32FromInt32(8), __ccgo_ts+3578, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, int32(44442))
|
||||
}
|
||||
}
|
||||
rc = _unixMapfile(tls, pFile, nByte)
|
||||
return rc
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if pFile has been renamed or unlinked since it was first opened.
|
||||
// */
|
||||
func _fileHasMoved(tls *libc.TLS, pFile uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
return libc.BoolInt32((*TunixFile)(unsafe.Pointer(pFile)).FpInode != uintptr(0) && ((*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, bp) != 0 || uint64((**(**Tstat)(__ccgo_up(bp))).Fst_ino) != (*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pFile)).FpInode)).FfileId.Fino))
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Given a file descriptor, locate the unixInodeInfo object that
|
||||
// ** describes that file descriptor. Create a new one if necessary. The
|
||||
// ** return value might be uninitialized if an error occurs.
|
||||
// **
|
||||
// ** The global mutex must held when calling this routine.
|
||||
// **
|
||||
// ** Return an appropriate error code.
|
||||
// */
|
||||
func _findInodeInfo(tls *libc.TLS, pFile uintptr, ppInode uintptr) (r int32) {
|
||||
bp := tls.Alloc(160)
|
||||
defer tls.Free(160)
|
||||
var fd, rc int32
|
||||
var pInode uintptr
|
||||
var _ /* fileId at bp+0 */ TunixFileId
|
||||
var _ /* statbuf at bp+16 */ Tstat
|
||||
_, _, _ = fd, pInode, rc /* Low-level file information */
|
||||
pInode = uintptr(0) /* Candidate unixInodeInfo object */
|
||||
/* Get low-level information about the file that we can used to
|
||||
** create a unique name for the file.
|
||||
*/
|
||||
fd = (*TunixFile)(unsafe.Pointer(pFile)).Fh
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, fd, bp+16)
|
||||
if rc != 0 {
|
||||
_storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
||||
return int32(SQLITE_IOERR)
|
||||
}
|
||||
libc.Xmemset(tls, bp, 0, uint64(16))
|
||||
(**(**TunixFileId)(__ccgo_up(bp))).Fdev = (**(**Tstat)(__ccgo_up(bp + 16))).Fst_dev
|
||||
(**(**TunixFileId)(__ccgo_up(bp))).Fino = uint64((**(**Tstat)(__ccgo_up(bp + 16))).Fst_ino)
|
||||
pInode = _inodeList
|
||||
for pInode != 0 && libc.Xmemcmp(tls, bp, pInode, uint64(16)) != 0 {
|
||||
pInode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext
|
||||
}
|
||||
if pInode == uintptr(0) {
|
||||
pInode = Xsqlite3_malloc64(tls, uint64(80))
|
||||
if pInode == uintptr(0) {
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
libc.Xmemset(tls, pInode, 0, uint64(80))
|
||||
libc.Xmemcpy(tls, pInode, bp, uint64(16))
|
||||
if _sqlite3Config.FbCoreMutex != 0 {
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex = Xsqlite3_mutex_alloc(tls, SQLITE_MUTEX_FAST)
|
||||
if (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex == uintptr(0) {
|
||||
Xsqlite3_free(tls, pInode)
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
}
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef = int32(1)
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext = _inodeList
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FpPrev = uintptr(0)
|
||||
if _inodeList != 0 {
|
||||
(*TunixInodeInfo)(unsafe.Pointer(_inodeList)).FpPrev = pInode
|
||||
}
|
||||
_inodeList = pInode
|
||||
} else {
|
||||
(*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FnRef + 1
|
||||
}
|
||||
**(**uintptr)(__ccgo_up(ppInode)) = pInode
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Search for an unused file descriptor that was opened on the database
|
||||
// ** file (not a journal or super-journal file) identified by pathname
|
||||
// ** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
|
||||
// ** argument to this function.
|
||||
// **
|
||||
// ** Such a file descriptor may exist if a database connection was closed
|
||||
// ** but the associated file descriptor could not be closed because some
|
||||
// ** other file descriptor open on the same file is holding a file-lock.
|
||||
// ** Refer to comments in the unixClose() function and the lengthy comment
|
||||
// ** describing "Posix Advisory Locking" at the start of this file for
|
||||
// ** further details. Also, ticket #4018.
|
||||
// **
|
||||
// ** If a suitable file descriptor is found, then it is returned. If no
|
||||
// ** such file descriptor is located, -1 is returned.
|
||||
// */
|
||||
func _findReusableFd(tls *libc.TLS, zPath uintptr, flags int32) (r uintptr) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var pInode, pUnused, pp uintptr
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
_, _, _ = pInode, pUnused, pp
|
||||
pUnused = uintptr(0) /* Results of stat() call */
|
||||
_unixEnterMutex(tls)
|
||||
/* A stat() call may fail for various reasons. If this happens, it is
|
||||
** almost certain that an open() call on the same path will also fail.
|
||||
** For this reason, if an error occurs in the stat() call here, it is
|
||||
** ignored and -1 is returned. The caller will try to open a new file
|
||||
** descriptor on the same path, fail, and return an error to SQLite.
|
||||
**
|
||||
** Even if a subsequent open() call does succeed, the consequences of
|
||||
** not searching for a reusable file descriptor are not dire. */
|
||||
if _inodeList != uintptr(0) && 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zPath, bp) {
|
||||
pInode = _inodeList
|
||||
for pInode != 0 && ((*TunixInodeInfo)(unsafe.Pointer(pInode)).FfileId.Fdev != (**(**Tstat)(__ccgo_up(bp))).Fst_dev || (*TunixInodeInfo)(unsafe.Pointer(pInode)).FfileId.Fino != uint64((**(**Tstat)(__ccgo_up(bp))).Fst_ino)) {
|
||||
pInode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpNext
|
||||
}
|
||||
if pInode != 0 {
|
||||
Xsqlite3_mutex_enter(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
||||
flags = flags & (libc.Int32FromInt32(SQLITE_OPEN_READONLY) | libc.Int32FromInt32(SQLITE_OPEN_READWRITE))
|
||||
pp = pInode + 40
|
||||
for {
|
||||
if !(**(**uintptr)(__ccgo_up(pp)) != 0 && (*TUnixUnusedFd)(unsafe.Pointer(**(**uintptr)(__ccgo_up(pp)))).Fflags != flags) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
pp = **(**uintptr)(__ccgo_up(pp)) + 8
|
||||
}
|
||||
pUnused = **(**uintptr)(__ccgo_up(pp))
|
||||
if pUnused != 0 {
|
||||
**(**uintptr)(__ccgo_up(pp)) = (*TUnixUnusedFd)(unsafe.Pointer(pUnused)).FpNext
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpLockMutex)
|
||||
}
|
||||
}
|
||||
_unixLeaveMutex(tls)
|
||||
return pUnused
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Determine the current size of a file in bytes
|
||||
// */
|
||||
func _unixFileSize(tls *libc.TLS, id uintptr, pSize uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = rc
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(id)).Fh, bp)
|
||||
if rc != 0 {
|
||||
_storeLastErrno(tls, id, **(**int32)(__ccgo_up(libc.X__errno_location(tls))))
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
**(**Ti64)(__ccgo_up(pSize)) = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size)
|
||||
/* When opening a zero-size database, the findInodeInfo() procedure
|
||||
** writes a single byte into that file in order to work around a bug
|
||||
** in the OS-X msdos filesystem. In order to avoid problems with upper
|
||||
** layers, we need to report this file size as zero even though it is
|
||||
** really 1. Ticket #3260.
|
||||
*/
|
||||
if **(**Ti64)(__ccgo_up(pSize)) == int64(1) {
|
||||
**(**Ti64)(__ccgo_up(pSize)) = 0
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Memory map or remap the file opened by file-descriptor pFd (if the file
|
||||
// ** is already mapped, the existing mapping is replaced by the new). Or, if
|
||||
// ** there already exists a mapping for this file, and there are still
|
||||
// ** outstanding xFetch() references to it, this function is a no-op.
|
||||
// **
|
||||
// ** If parameter nByte is non-negative, then it is the requested size of
|
||||
// ** the mapping to create. Otherwise, if nByte is less than zero, then the
|
||||
// ** requested size is the size of the file on disk. The actual size of the
|
||||
// ** created mapping is either the requested size or the value configured
|
||||
// ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
|
||||
// **
|
||||
// ** SQLITE_OK is returned if no error occurs (even if the mapping is not
|
||||
// ** recreated as a result of outstanding references) or an SQLite error
|
||||
// ** code otherwise.
|
||||
// */
|
||||
func _unixMapfile(tls *libc.TLS, pFd uintptr, nMap Ti64) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var _ /* statbuf at bp+0 */ Tstat
|
||||
if (*TunixFile)(unsafe.Pointer(pFd)).FnFetchOut > 0 {
|
||||
return SQLITE_OK
|
||||
}
|
||||
if nMap < 0 { /* Low-level file information */
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFd)).Fh, bp) != 0 {
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
nMap = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size)
|
||||
}
|
||||
if nMap > (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax {
|
||||
nMap = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax
|
||||
}
|
||||
if nMap != (*TunixFile)(unsafe.Pointer(pFd)).FmmapSize {
|
||||
_unixRemapfile(tls, pFd, nMap)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Open a shared-memory area associated with open database file pDbFd.
|
||||
// ** This particular implementation uses mmapped files.
|
||||
// **
|
||||
// ** The file used to implement shared-memory is in the same directory
|
||||
// ** as the open database file and has the same name as the open database
|
||||
// ** file with the "-shm" suffix added. For example, if the database file
|
||||
// ** is "/home/user1/config.db" then the file that is created and mmapped
|
||||
// ** for shared memory will be called "/home/user1/config.db-shm".
|
||||
// **
|
||||
// ** Another approach to is to use files in /dev/shm or /dev/tmp or an
|
||||
// ** some other tmpfs mount. But if a file in a different directory
|
||||
// ** from the database file is used, then differing access permissions
|
||||
// ** or a chroot() might cause two different processes on the same
|
||||
// ** database to end up using different files for shared memory -
|
||||
// ** meaning that their memory would not really be shared - resulting
|
||||
// ** in database corruption. Nevertheless, this tmpfs file usage
|
||||
// ** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
|
||||
// ** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time
|
||||
// ** option results in an incompatible build of SQLite; builds of SQLite
|
||||
// ** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
|
||||
// ** same database file at the same time, database corruption will likely
|
||||
// ** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
|
||||
// ** "unsupported" and may go away in a future SQLite release.
|
||||
// **
|
||||
// ** When opening a new shared-memory file, if no other instances of that
|
||||
// ** file are currently open, in this process or in other processes, then
|
||||
// ** the file must be truncated to zero length or have its header cleared.
|
||||
// **
|
||||
// ** If the original database file (pDbFd) is using the "unix-excl" VFS
|
||||
// ** that means that an exclusive lock is held on the database file and
|
||||
// ** that no other processes are able to read or write the database. In
|
||||
// ** that case, we do not really need shared memory. No shared memory
|
||||
// ** file is created. The shared memory will be simulated with heap memory.
|
||||
// */
|
||||
func _unixOpenSharedMemory(tls *libc.TLS, pDbFd uintptr) (r int32) {
|
||||
bp := tls.Alloc(160)
|
||||
defer tls.Free(160)
|
||||
var nShmFilename, rc int32
|
||||
var p, pInode, pShmNode, zBasePath, zShm, v1 uintptr
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
_, _, _, _, _, _, _, _ = nShmFilename, p, pInode, pShmNode, rc, zBasePath, zShm, v1
|
||||
p = uintptr(0) /* The underlying mmapped file */
|
||||
rc = SQLITE_OK /* Size of the SHM filename in bytes */
|
||||
/* Allocate space for the new unixShm object. */
|
||||
p = Xsqlite3_malloc64(tls, uint64(24))
|
||||
if p == uintptr(0) {
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
libc.Xmemset(tls, p, 0, uint64(24))
|
||||
/* Check to see if a unixShmNode object already exists. Reuse an existing
|
||||
** one if present. Create a new one if necessary.
|
||||
*/
|
||||
_unixEnterMutex(tls)
|
||||
pInode = (*TunixFile)(unsafe.Pointer(pDbFd)).FpInode
|
||||
pShmNode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpShmNode
|
||||
if pShmNode == uintptr(0) { /* fstat() info for database file */
|
||||
zBasePath = (*TunixFile)(unsafe.Pointer(pDbFd)).FzPath
|
||||
/* Call fstat() to figure out the permissions on the database file. If
|
||||
** a new *-shm file is created, an attempt will be made to create it
|
||||
** with the same permissions.
|
||||
*/
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pDbFd)).Fh, bp) != 0 {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
goto shm_open_err
|
||||
}
|
||||
nShmFilename = int32(6) + libc.Int32FromUint64(libc.Xstrlen(tls, zBasePath))
|
||||
pShmNode = Xsqlite3_malloc64(tls, uint64(uint64(96)+libc.Uint64FromInt32(nShmFilename)))
|
||||
if pShmNode == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
goto shm_open_err
|
||||
}
|
||||
libc.Xmemset(tls, pShmNode, 0, uint64(96)+libc.Uint64FromInt32(nShmFilename))
|
||||
v1 = pShmNode + 1*96
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename = v1
|
||||
zShm = v1
|
||||
Xsqlite3_snprintf(tls, nShmFilename, zShm, __ccgo_ts+3982, libc.VaList(bp+152, zBasePath))
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = -int32(1)
|
||||
(*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pDbFd)).FpInode)).FpShmNode = pShmNode
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpInode = (*TunixFile)(unsafe.Pointer(pDbFd)).FpInode
|
||||
if _sqlite3Config.FbCoreMutex != 0 {
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex = Xsqlite3_mutex_alloc(tls, SQLITE_MUTEX_FAST)
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
goto shm_open_err
|
||||
}
|
||||
}
|
||||
if libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FbProcessLock) == 0 {
|
||||
if 0 == Xsqlite3_uri_boolean(tls, (*TunixFile)(unsafe.Pointer(pDbFd)).FzPath, __ccgo_ts+3989, 0) {
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = _robust_open(tls, zShm, libc.Int32FromInt32(O_RDWR)|libc.Int32FromInt32(O_CREAT)|libc.Int32FromInt32(O_NOFOLLOW), (**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(0777))
|
||||
}
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm < 0 {
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = _robust_open(tls, zShm, libc.Int32FromInt32(O_RDONLY)|libc.Int32FromInt32(O_NOFOLLOW), (**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(0777))
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm < 0 {
|
||||
rc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(45382)), __ccgo_ts+3542, zShm, int32(45382))
|
||||
goto shm_open_err
|
||||
}
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly = uint8(1)
|
||||
}
|
||||
/* If this process is running as root, make sure that the SHM file
|
||||
** is owned by the same user that owns the original database. Otherwise,
|
||||
** the original owner will not be able to connect.
|
||||
*/
|
||||
_robustFchown(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, (**(**Tstat)(__ccgo_up(bp))).Fst_uid, (**(**Tstat)(__ccgo_up(bp))).Fst_gid)
|
||||
rc = _unixLockSharedMemory(tls, pDbFd, pShmNode)
|
||||
if rc != SQLITE_OK && rc != libc.Int32FromInt32(SQLITE_READONLY)|libc.Int32FromInt32(5)<<libc.Int32FromInt32(8) {
|
||||
goto shm_open_err
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Make the new connection a child of the unixShmNode */
|
||||
(*TunixShm)(unsafe.Pointer(p)).FpShmNode = pShmNode
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRef = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRef + 1
|
||||
(*TunixFile)(unsafe.Pointer(pDbFd)).FpShm = p
|
||||
_unixLeaveMutex(tls)
|
||||
/* The reference count on pShmNode has already been incremented under
|
||||
** the cover of the unixEnterMutex() mutex and the pointer from the
|
||||
** new (struct unixShm) object to the pShmNode has been set. All that is
|
||||
** left to do is to link the new object into the linked list starting
|
||||
** at pShmNode->pFirst. This must be done while holding the
|
||||
** pShmNode->pShmMutex.
|
||||
*/
|
||||
Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
(*TunixShm)(unsafe.Pointer(p)).FpNext = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpFirst
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpFirst = p
|
||||
Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
return rc
|
||||
/* Jump here on any error */
|
||||
goto shm_open_err
|
||||
shm_open_err:
|
||||
;
|
||||
_unixShmPurge(tls, pDbFd) /* This call frees pShmNode if required */
|
||||
Xsqlite3_free(tls, p)
|
||||
_unixLeaveMutex(tls)
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called to obtain a pointer to region iRegion of the
|
||||
// ** shared-memory associated with the database file fd. Shared-memory regions
|
||||
// ** are numbered starting from zero. Each shared-memory region is szRegion
|
||||
// ** bytes in size.
|
||||
// **
|
||||
// ** If an error occurs, an error code is returned and *pp is set to NULL.
|
||||
// **
|
||||
// ** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
|
||||
// ** region has not been allocated (by any client, including one running in a
|
||||
// ** separate process), then *pp is set to NULL and SQLITE_OK returned. If
|
||||
// ** bExtend is non-zero and the requested shared-memory region has not yet
|
||||
// ** been allocated, it is allocated by this function.
|
||||
// **
|
||||
// ** If the shared-memory region has already been allocated or is allocated by
|
||||
// ** this call as described above, then it is mapped into this processes
|
||||
// ** address space (if it is not already), *pp is set to point to the mapped
|
||||
// ** memory and SQLITE_OK returned.
|
||||
// */
|
||||
func _unixShmMap(tls *libc.TLS, fd uintptr, iRegion int32, szRegion int32, bExtend int32, pp uintptr) (r int32) {
|
||||
bp := tls.Alloc(160)
|
||||
defer tls.Free(160)
|
||||
var apNew, p, pDbFd, pMem, pShmNode, zFile, v4 uintptr
|
||||
var i, iPg, nByte, nMap Ti64
|
||||
var nReqRegion, nShmPerMap, rc, v2 int32
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
var _ /* x at bp+144 */ int32
|
||||
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = apNew, i, iPg, nByte, nMap, nReqRegion, nShmPerMap, p, pDbFd, pMem, pShmNode, rc, zFile, v2, v4
|
||||
pDbFd = fd
|
||||
rc = SQLITE_OK
|
||||
nShmPerMap = _unixShmRegionPerMap(tls)
|
||||
/* If the shared-memory file has not yet been opened, open it now. */
|
||||
if (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm == uintptr(0) {
|
||||
rc = _unixOpenSharedMemory(tls, pDbFd)
|
||||
if rc != SQLITE_OK {
|
||||
return rc
|
||||
}
|
||||
}
|
||||
p = (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm
|
||||
pShmNode = (*TunixShm)(unsafe.Pointer(p)).FpShmNode
|
||||
Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisUnlocked != 0 {
|
||||
rc = _unixLockSharedMemory(tls, pDbFd, pShmNode)
|
||||
if rc != SQLITE_OK {
|
||||
goto shmpage_out
|
||||
}
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FisUnlocked = uint8(0)
|
||||
}
|
||||
/* Minimum number of regions required to be mapped. */
|
||||
nReqRegion = (iRegion + nShmPerMap) / nShmPerMap * nShmPerMap
|
||||
if libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) < nReqRegion { /* New apRegion[] array */
|
||||
nByte = int64(nReqRegion) * int64(szRegion) /* Used by fstat() */
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FszRegion = szRegion
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 0 {
|
||||
/* The requested region is not mapped into this processes address space.
|
||||
** Check to see if it has been allocated (i.e. if the wal-index file is
|
||||
** large enough to contain the requested region).
|
||||
*/
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, bp) != 0 {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(19)<<libc.Int32FromInt32(8)
|
||||
goto shmpage_out
|
||||
}
|
||||
if int64((**(**Tstat)(__ccgo_up(bp))).Fst_size) < nByte {
|
||||
/* The requested memory region does not exist. If bExtend is set to
|
||||
** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
|
||||
*/
|
||||
if !(bExtend != 0) {
|
||||
goto shmpage_out
|
||||
} else {
|
||||
/* Write to the last byte of each newly allocated or extended page */
|
||||
iPg = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size / int64(_pgsz))
|
||||
for {
|
||||
if !(iPg < nByte/int64(_pgsz)) {
|
||||
break
|
||||
}
|
||||
**(**int32)(__ccgo_up(bp + 144)) = 0
|
||||
if _seekAndWriteFd(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, iPg*int64(_pgsz)+int64(_pgsz)-int64(1), __ccgo_ts+1704, int32(1), bp+144) != int32(1) {
|
||||
zFile = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename
|
||||
rc = _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(19)<<libc.Int32FromInt32(8), __ccgo_ts+3613, zFile, int32(45526))
|
||||
goto shmpage_out
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
iPg = iPg + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Map the requested memory region into this processes address space. */
|
||||
apNew = Xsqlite3_realloc64(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion, uint64(libc.Uint64FromInt32(nReqRegion)*uint64(8)))
|
||||
if !(apNew != 0) {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(12)<<libc.Int32FromInt32(8)
|
||||
goto shmpage_out
|
||||
}
|
||||
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion = apNew
|
||||
for libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) < nReqRegion {
|
||||
nMap = int64(szRegion) * int64(nShmPerMap)
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 0 {
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly != 0 {
|
||||
v2 = int32(PROT_READ)
|
||||
} else {
|
||||
v2 = libc.Int32FromInt32(PROT_READ) | libc.Int32FromInt32(PROT_WRITE)
|
||||
}
|
||||
pMem = (*(*func(*libc.TLS, uintptr, Tsize_t, int32, int32, int32, Toff_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(22)].FpCurrent})))(tls, uintptr(0), libc.Uint64FromInt64(nMap), v2, int32(MAP_SHARED), (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, int64(int64(szRegion)*libc.Int64FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion)))
|
||||
if pMem == uintptr(-libc.Int32FromInt32(1)) {
|
||||
rc = _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(21)<<libc.Int32FromInt32(8), __ccgo_ts+3700, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename, int32(45553))
|
||||
goto shmpage_out
|
||||
}
|
||||
} else {
|
||||
pMem = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nMap))
|
||||
if pMem == uintptr(0) {
|
||||
rc = int32(SQLITE_NOMEM)
|
||||
goto shmpage_out
|
||||
}
|
||||
libc.Xmemset(tls, pMem, 0, libc.Uint64FromInt64(nMap))
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(i < int64(nShmPerMap)) {
|
||||
break
|
||||
}
|
||||
**(**uintptr)(__ccgo_up((*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion + uintptr(libc.Int64FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion)+i)*8)) = pMem + uintptr(int64(szRegion)*i)
|
||||
goto _3
|
||||
_3:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
v4 = pShmNode + 32
|
||||
*(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) + nShmPerMap)
|
||||
}
|
||||
}
|
||||
goto shmpage_out
|
||||
shmpage_out:
|
||||
;
|
||||
if libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) > iRegion {
|
||||
**(**uintptr)(__ccgo_up(pp)) = **(**uintptr)(__ccgo_up((*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion + uintptr(iRegion)*8))
|
||||
} else {
|
||||
**(**uintptr)(__ccgo_up(pp)) = uintptr(0)
|
||||
}
|
||||
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly != 0 && rc == SQLITE_OK {
|
||||
rc = int32(SQLITE_READONLY)
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex)
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return the name of a directory in which to put temporary files.
|
||||
// ** If no suitable temporary file directory can be found, return NULL.
|
||||
// */
|
||||
func _unixTempFileDir(tls *libc.TLS) (r uintptr) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var i, v1 uint32
|
||||
var zDir uintptr
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_, _, _ = i, zDir, v1
|
||||
i = uint32(0)
|
||||
zDir = Xsqlite3_temp_directory
|
||||
for int32(1) != 0 {
|
||||
if zDir != uintptr(0) && (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zDir, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(S_IFMT) == uint32(S_IFDIR) && (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zDir, int32(03)) == 0 {
|
||||
return zDir
|
||||
}
|
||||
if uint64(i) >= libc.Uint64FromInt64(48)/libc.Uint64FromInt64(8) {
|
||||
break
|
||||
}
|
||||
v1 = i
|
||||
i = i + 1
|
||||
zDir = _azTempDirs[v1]
|
||||
}
|
||||
return uintptr(0)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Check a unixFile that is a database. Verify the following:
|
||||
// **
|
||||
// ** (1) There is exactly one hard link on the file
|
||||
// ** (2) The file is not a symbolic link
|
||||
// ** (3) The file has not been renamed or unlinked
|
||||
// **
|
||||
// ** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
|
||||
// */
|
||||
func _verifyDbFile(tls *libc.TLS, pFile uintptr) {
|
||||
bp := tls.Alloc(160)
|
||||
defer tls.Free(160)
|
||||
var rc int32
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = rc
|
||||
/* These verifications occurs for the main database only */
|
||||
if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_NOLOCK) != 0 {
|
||||
return
|
||||
}
|
||||
rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp)
|
||||
if rc != 0 {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3860, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink == uint64(0) {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3884, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink > uint64(1) {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3913, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
if _fileHasMoved(tls, pFile) != 0 {
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3940, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
||||
return
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && 386) || (freebsd && amd64) || (freebsd && arm) || (freebsd && arm64) || (linux && amd64) || (linux && ppc64le) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
type Tnlink_t = uint64
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64) || (linux && ppc64le) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Find the mode, uid and gid of file zFile.
|
||||
// */
|
||||
func _getFileMode(tls *libc.TLS, zFile uintptr, pMode uintptr, pUid uintptr, pGid uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var rc int32
|
||||
var _ /* sStat at bp+0 */ Tstat
|
||||
_ = rc /* Output of stat() on database file */
|
||||
rc = SQLITE_OK
|
||||
if 0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zFile, bp) {
|
||||
**(**Tmode_t)(__ccgo_up(pMode)) = (**(**Tstat)(__ccgo_up(bp))).Fst_mode & uint32(0777)
|
||||
**(**Tuid_t)(__ccgo_up(pUid)) = (**(**Tstat)(__ccgo_up(bp))).Fst_uid
|
||||
**(**Tgid_t)(__ccgo_up(pGid)) = (**(**Tstat)(__ccgo_up(bp))).Fst_gid
|
||||
} else {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Invoke open(). Do so multiple times, until it either succeeds or
|
||||
// ** fails for some reason other than EINTR.
|
||||
// **
|
||||
// ** If the file creation mode "m" is 0 then set it to the default for
|
||||
// ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
|
||||
// ** 0644) as modified by the system umask. If m is not 0, then
|
||||
// ** make the file creation mode be exactly m ignoring the umask.
|
||||
// **
|
||||
// ** The m parameter will be non-zero only when creating -wal, -journal,
|
||||
// ** and -shm files. We want those files to have *exactly* the same
|
||||
// ** permissions as their original database, unadulterated by the umask.
|
||||
// ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
|
||||
// ** transaction crashes and leaves behind hot journals, then any
|
||||
// ** process that is able to write to the database will also be able to
|
||||
// ** recover the hot journals.
|
||||
// */
|
||||
func _robust_open(tls *libc.TLS, z uintptr, f int32, m Tmode_t) (r int32) {
|
||||
bp := tls.Alloc(176)
|
||||
defer tls.Free(176)
|
||||
var fd int32
|
||||
var m2 Tmode_t
|
||||
var v1 uint32
|
||||
var _ /* statbuf at bp+0 */ Tstat
|
||||
_, _, _ = fd, m2, v1
|
||||
if m != 0 {
|
||||
v1 = m
|
||||
} else {
|
||||
v1 = uint32(SQLITE_DEFAULT_FILE_PERMISSIONS)
|
||||
}
|
||||
m2 = v1
|
||||
for int32(1) != 0 {
|
||||
fd = (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, z, f|int32(O_CLOEXEC), libc.Int32FromUint32(m2))
|
||||
if fd < 0 {
|
||||
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EINTR) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if fd >= int32(SQLITE_MINIMUM_FILE_DESCRIPTOR) {
|
||||
break
|
||||
}
|
||||
if f&(libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT)) == libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT) {
|
||||
(*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(16)].FpCurrent})))(tls, z)
|
||||
}
|
||||
(*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(1)].FpCurrent})))(tls, fd)
|
||||
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3752, libc.VaList(bp+152, z, fd))
|
||||
fd = -int32(1)
|
||||
if (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, __ccgo_ts+3795, O_RDONLY, libc.Int32FromUint32(m)) < 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if fd >= 0 {
|
||||
if m != uint32(0) {
|
||||
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, fd, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_size == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(0777) != m {
|
||||
(*(*func(*libc.TLS, int32, Tmode_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(14)].FpCurrent})))(tls, fd, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Test the existence of or access permissions of file zPath. The
|
||||
// ** test performed depends on the value of flags:
|
||||
// **
|
||||
// ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
|
||||
// ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
|
||||
// ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
|
||||
// **
|
||||
// ** Otherwise return 0.
|
||||
// */
|
||||
func _unixAccess(tls *libc.TLS, NotUsed uintptr, zPath uintptr, flags int32, pResOut uintptr) (r int32) {
|
||||
bp := tls.Alloc(144)
|
||||
defer tls.Free(144)
|
||||
var _ /* buf at bp+0 */ Tstat
|
||||
_ = NotUsed
|
||||
/* The spec says there are three possible values for flags. But only
|
||||
** two of them are actually used */
|
||||
if flags == SQLITE_ACCESS_EXISTS {
|
||||
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32(0 == (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zPath, bp) && (!((**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(S_IFMT) == libc.Uint32FromInt32(S_IFREG)) || (**(**Tstat)(__ccgo_up(bp))).Fst_size > 0))
|
||||
} else {
|
||||
**(**int32)(__ccgo_up(pResOut)) = libc.BoolInt32((*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zPath, libc.Int32FromInt32(W_OK)|libc.Int32FromInt32(R_OK)) == 0)
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64) || (linux && loong64) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const O_DIRECT = 16384
|
||||
|
||||
const O_DIRECTORY = 65536
|
||||
|
||||
const O_LARGEFILE = 32768
|
||||
|
||||
const O_NOFOLLOW = 131072
|
||||
|
||||
const O_TMPFILE = 4259840
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && 386) || (linux && amd64) || (linux && arm) || (linux && arm64) || (linux && loong64) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const EDEADLOCK = 35
|
||||
|
||||
const F2FS_IOC_ABORT_VOLATILE_WRITE = 62725
|
||||
|
||||
const F2FS_IOC_COMMIT_ATOMIC_WRITE = 62722
|
||||
|
||||
const F2FS_IOC_GET_FEATURES = 2147546380
|
||||
|
||||
const F2FS_IOC_START_ATOMIC_WRITE = 62721
|
||||
|
||||
const F2FS_IOC_START_VOLATILE_WRITE = 62723
|
||||
|
||||
const FIOASYNC = 21586
|
||||
|
||||
const FIOCLEX = 21585
|
||||
|
||||
const FIONBIO = 21537
|
||||
|
||||
const FIONCLEX = 21584
|
||||
|
||||
const FIONREAD = 21531
|
||||
|
||||
const MAP_LOCKED = 8192
|
||||
|
||||
const MAP_NORESERVE = 16384
|
||||
|
||||
const MCL_ONFAULT = 4
|
||||
|
||||
const TCFLSH = 21515
|
||||
|
||||
const TCGETA = 21509
|
||||
|
||||
const TCGETS = 21505
|
||||
|
||||
const TCGETX = 21554
|
||||
|
||||
const TCSBRK = 21513
|
||||
|
||||
const TCSETA = 21510
|
||||
|
||||
const TCSETAF = 21512
|
||||
|
||||
const TCSETAW = 21511
|
||||
|
||||
const TCSETS = 21506
|
||||
|
||||
const TCSETSF = 21508
|
||||
|
||||
const TCSETSW = 21507
|
||||
|
||||
const TCSETX = 21555
|
||||
|
||||
const TCSETXF = 21556
|
||||
|
||||
const TCSETXW = 21557
|
||||
|
||||
const TCXONC = 21514
|
||||
|
||||
const TIOCGDEV = 2147767346
|
||||
|
||||
const TIOCGEXCL = 2147767360
|
||||
|
||||
const TIOCGISO7816 = 2150126658
|
||||
|
||||
const TIOCGPGRP = 21519
|
||||
|
||||
const TIOCGPKT = 2147767352
|
||||
|
||||
const TIOCGPTLCK = 2147767353
|
||||
|
||||
const TIOCGPTN = 2147767344
|
||||
|
||||
const TIOCGPTPEER = 21569
|
||||
|
||||
const TIOCGWINSZ = 21523
|
||||
|
||||
const TIOCINQ = 21531
|
||||
|
||||
const TIOCOUTQ = 21521
|
||||
|
||||
const TIOCSIG = 1074025526
|
||||
|
||||
const TIOCSISO7816 = 3223868483
|
||||
|
||||
const TIOCSPGRP = 21520
|
||||
|
||||
const TIOCSPTLCK = 1074025521
|
||||
|
||||
const TIOCSWINSZ = 21524
|
||||
|
||||
const _IOC_NONE = 0
|
||||
|
||||
const _IOC_WRITE = 1
|
||||
+11574
File diff suppressed because it is too large
Load Diff
+204
@@ -0,0 +1,204 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && arm64) || (linux && arm64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function is called to obtain a shared lock on the database file.
|
||||
// ** It is illegal to call sqlite3PagerGet() until after this function
|
||||
// ** has been successfully called. If a shared-lock is already held when
|
||||
// ** this function is called, it is a no-op.
|
||||
// **
|
||||
// ** The following operations are also performed by this function.
|
||||
// **
|
||||
// ** 1) If the pager is currently in PAGER_OPEN state (no lock held
|
||||
// ** on the database file), then an attempt is made to obtain a
|
||||
// ** SHARED lock on the database file. Immediately after obtaining
|
||||
// ** the SHARED lock, the file-system is checked for a hot-journal,
|
||||
// ** which is played back if present. Following any hot-journal
|
||||
// ** rollback, the contents of the cache are validated by checking
|
||||
// ** the 'change-counter' field of the database file header and
|
||||
// ** discarded if they are found to be invalid.
|
||||
// **
|
||||
// ** 2) If the pager is running in exclusive-mode, and there are currently
|
||||
// ** no outstanding references to any pages, and is in the error state,
|
||||
// ** then an attempt is made to clear the error state by discarding
|
||||
// ** the contents of the page cache and rolling back any open journal
|
||||
// ** file.
|
||||
// **
|
||||
// ** If everything is successful, SQLITE_OK is returned. If an IO error
|
||||
// ** occurs while locking the database, checking for a hot-journal file or
|
||||
// ** rolling back a journal file, the IO error code is returned.
|
||||
// */
|
||||
func _sqlite3PagerSharedLock(tls *libc.TLS, pPager uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var f, rc int32
|
||||
var pVfs uintptr
|
||||
var _ /* bExists at bp+4 */ int32
|
||||
var _ /* bHotJournal at bp+0 */ int32
|
||||
var _ /* dbFileVers at bp+12 */ [16]uint8
|
||||
var _ /* fout at bp+8 */ int32
|
||||
_, _, _ = f, pVfs, rc
|
||||
rc = SQLITE_OK /* Return code */
|
||||
/* This routine is only called from b-tree and only when there are no
|
||||
** outstanding pages. This implies that the pager state should either
|
||||
** be OPEN or READER. READER is only possible if the pager is or was in
|
||||
** exclusive access mode. */
|
||||
if !((*TPager)(unsafe.Pointer(pPager)).FpWal != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN {
|
||||
**(**int32)(__ccgo_up(bp)) = int32(1) /* True if there exists a hot journal-file */
|
||||
rc = _pager_wait_on_lock(tls, pPager, int32(SHARED_LOCK))
|
||||
if rc != SQLITE_OK {
|
||||
goto failed
|
||||
}
|
||||
/* If a journal file exists, and there is no RESERVED lock on the
|
||||
** database file, then it either needs to be played back or deleted.
|
||||
*/
|
||||
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeLock) <= int32(SHARED_LOCK) {
|
||||
rc = _hasHotJournal(tls, pPager, bp)
|
||||
}
|
||||
if rc != SQLITE_OK {
|
||||
goto failed
|
||||
}
|
||||
if **(**int32)(__ccgo_up(bp)) != 0 {
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FreadOnly != 0 {
|
||||
rc = libc.Int32FromInt32(SQLITE_READONLY) | libc.Int32FromInt32(3)<<libc.Int32FromInt32(8)
|
||||
goto failed
|
||||
}
|
||||
/* Get an EXCLUSIVE lock on the database file. At this point it is
|
||||
** important that a RESERVED lock is not obtained on the way to the
|
||||
** EXCLUSIVE lock. If it were, another process might open the
|
||||
** database file, detect the RESERVED lock, and conclude that the
|
||||
** database is safe to read while this process is still rolling the
|
||||
** hot-journal back.
|
||||
**
|
||||
** Because the intermediate RESERVED lock is not requested, any
|
||||
** other process attempting to access the database file will get to
|
||||
** this point in the code and fail to obtain its own EXCLUSIVE lock
|
||||
** on the database file.
|
||||
**
|
||||
** Unless the pager is in locking_mode=exclusive mode, the lock is
|
||||
** downgraded to SHARED_LOCK before this function returns.
|
||||
*/
|
||||
rc = _pagerLockDb(tls, pPager, int32(EXCLUSIVE_LOCK))
|
||||
if rc != SQLITE_OK {
|
||||
goto failed
|
||||
}
|
||||
/* If it is not already open and the file exists on disk, open the
|
||||
** journal for read/write access. Write access is required because
|
||||
** in exclusive-access mode the file descriptor will be kept open
|
||||
** and possibly used for a transaction later on. Also, write-access
|
||||
** is usually required to finalize the journal in journal_mode=persist
|
||||
** mode (and also for journal_mode=truncate on some systems).
|
||||
**
|
||||
** If the journal does not exist, it usually means that some
|
||||
** other connection managed to get in and roll it back before
|
||||
** this connection obtained the exclusive lock above. Or, it
|
||||
** may mean that the pager was in the error-state when this
|
||||
** function was called and the journal file does not exist.
|
||||
*/
|
||||
if !((*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != libc.UintptrFromInt32(0)) && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FjournalMode) != int32(PAGER_JOURNALMODE_OFF) {
|
||||
pVfs = (*TPager)(unsafe.Pointer(pPager)).FpVfs /* True if journal file exists */
|
||||
rc = _sqlite3OsAccess(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, SQLITE_ACCESS_EXISTS, bp+4)
|
||||
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 4)) != 0 {
|
||||
**(**int32)(__ccgo_up(bp + 8)) = 0
|
||||
f = libc.Int32FromInt32(SQLITE_OPEN_READWRITE) | libc.Int32FromInt32(SQLITE_OPEN_MAIN_JOURNAL)
|
||||
rc = _sqlite3OsOpen(tls, pVfs, (*TPager)(unsafe.Pointer(pPager)).FzJournal, (*TPager)(unsafe.Pointer(pPager)).Fjfd, f, bp+8)
|
||||
if rc == SQLITE_OK && **(**int32)(__ccgo_up(bp + 8))&int32(SQLITE_OPEN_READONLY) != 0 {
|
||||
rc = _sqlite3CantopenError(tls, int32(65169))
|
||||
_sqlite3OsClose(tls, (*TPager)(unsafe.Pointer(pPager)).Fjfd)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Playback and delete the journal. Drop the database write
|
||||
** lock and reacquire the read lock. Purge the cache before
|
||||
** playing back the hot-journal so that we don't end up with
|
||||
** an inconsistent cache. Sync the hot journal before playing
|
||||
** it back since the process that crashed and left the hot journal
|
||||
** probably did not sync it and we are required to always sync
|
||||
** the journal before playing it back.
|
||||
*/
|
||||
if (*Tsqlite3_file)(unsafe.Pointer((*TPager)(unsafe.Pointer(pPager)).Fjfd)).FpMethods != uintptr(0) {
|
||||
rc = _pagerSyncHotJournal(tls, pPager)
|
||||
if rc == SQLITE_OK {
|
||||
rc = _pager_playback(tls, pPager, libc.BoolInt32(!((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0)))
|
||||
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_OPEN)
|
||||
}
|
||||
} else {
|
||||
if !((*TPager)(unsafe.Pointer(pPager)).FexclusiveMode != 0) {
|
||||
_pagerUnlockDb(tls, pPager, int32(SHARED_LOCK))
|
||||
}
|
||||
}
|
||||
if rc != SQLITE_OK {
|
||||
/* This branch is taken if an error occurs while trying to open
|
||||
** or roll back a hot-journal while holding an EXCLUSIVE lock. The
|
||||
** pager_unlock() routine will be called before returning to unlock
|
||||
** the file. If the unlock attempt fails, then Pager.eLock must be
|
||||
** set to UNKNOWN_LOCK (see the comment above the #define for
|
||||
** UNKNOWN_LOCK above for an explanation).
|
||||
**
|
||||
** In order to get pager_unlock() to do this, set Pager.eState to
|
||||
** PAGER_ERROR now. This is not actually counted as a transition
|
||||
** to ERROR state in the state diagram at the top of this file,
|
||||
** since we know that the same call to pager_unlock() will very
|
||||
** shortly transition the pager object to the OPEN state. Calling
|
||||
** assert_pager_state() would fail now, as it should not be possible
|
||||
** to be in ERROR state when there are zero outstanding page
|
||||
** references.
|
||||
*/
|
||||
_pager_error(tls, pPager, rc)
|
||||
goto failed
|
||||
}
|
||||
}
|
||||
if !((*TPager)(unsafe.Pointer(pPager)).FtempFile != 0) && (*TPager)(unsafe.Pointer(pPager)).FhasHeldSharedLock != 0 {
|
||||
rc = _sqlite3OsRead(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, bp+12, int32(16), int64(24))
|
||||
if rc != SQLITE_OK {
|
||||
if rc != libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(2)<<libc.Int32FromInt32(8) {
|
||||
goto failed
|
||||
}
|
||||
libc.Xmemset(tls, bp+12, 0, uint64(16))
|
||||
}
|
||||
if libc.Xmemcmp(tls, pPager+136, bp+12, uint64(16)) != 0 {
|
||||
_pager_reset(tls, pPager)
|
||||
/* Unmap the database file. It is possible that external processes
|
||||
** may have truncated the database file and then extended it back
|
||||
** to its original size while this process was not holding a lock.
|
||||
** In this case there may exist a Pager.pMap mapping that appears
|
||||
** to be the right size but is not actually valid. Avoid this
|
||||
** possibility by unmapping the db here. */
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FbUseFetch != 0 {
|
||||
_sqlite3OsUnfetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, 0, uintptr(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If there is a WAL file in the file-system, open this database in WAL
|
||||
** mode. Otherwise, the following function call is a no-op.
|
||||
*/
|
||||
rc = _pagerOpenWalIfPresent(tls, pPager)
|
||||
}
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
|
||||
rc = _pagerBeginReadTransaction(tls, pPager)
|
||||
}
|
||||
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FtempFile) == 0 && libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == PAGER_OPEN && rc == SQLITE_OK {
|
||||
rc = _pagerPagecount(tls, pPager, pPager+32)
|
||||
}
|
||||
goto failed
|
||||
failed:
|
||||
;
|
||||
if rc != SQLITE_OK {
|
||||
_pager_unlock(tls, pPager)
|
||||
} else {
|
||||
(*TPager)(unsafe.Pointer(pPager)).FeState = uint8(PAGER_READER)
|
||||
(*TPager)(unsafe.Pointer(pPager)).FhasHeldSharedLock = uint8(1)
|
||||
}
|
||||
return rc
|
||||
}
|
||||
+777
@@ -0,0 +1,777 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm) || (linux && arm64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Return TRUE if the given SQL string ends in a semicolon.
|
||||
// **
|
||||
// ** Special handling is require for CREATE TRIGGER statements.
|
||||
// ** Whenever the CREATE TRIGGER keywords are seen, the statement
|
||||
// ** must end with ";END;".
|
||||
// **
|
||||
// ** This implementation uses a state machine with 8 states:
|
||||
// **
|
||||
// ** (0) INVALID We have not yet seen a non-whitespace character.
|
||||
// **
|
||||
// ** (1) START At the beginning or end of an SQL statement. This routine
|
||||
// ** returns 1 if it ends in the START state and 0 if it ends
|
||||
// ** in any other state.
|
||||
// **
|
||||
// ** (2) NORMAL We are in the middle of statement which ends with a single
|
||||
// ** semicolon.
|
||||
// **
|
||||
// ** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
|
||||
// ** a statement.
|
||||
// **
|
||||
// ** (4) CREATE The keyword CREATE has been seen at the beginning of a
|
||||
// ** statement, possibly preceded by EXPLAIN and/or followed by
|
||||
// ** TEMP or TEMPORARY
|
||||
// **
|
||||
// ** (5) TRIGGER We are in the middle of a trigger definition that must be
|
||||
// ** ended by a semicolon, the keyword END, and another semicolon.
|
||||
// **
|
||||
// ** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
|
||||
// ** the end of a trigger definition.
|
||||
// **
|
||||
// ** (7) END We've seen the ";END" of the ";END;" that occurs at the end
|
||||
// ** of a trigger definition.
|
||||
// **
|
||||
// ** Transitions between states above are determined by tokens extracted
|
||||
// ** from the input. The following tokens are significant:
|
||||
// **
|
||||
// ** (0) tkSEMI A semicolon.
|
||||
// ** (1) tkWS Whitespace.
|
||||
// ** (2) tkOTHER Any other SQL token.
|
||||
// ** (3) tkEXPLAIN The "explain" keyword.
|
||||
// ** (4) tkCREATE The "create" keyword.
|
||||
// ** (5) tkTEMP The "temp" or "temporary" keyword.
|
||||
// ** (6) tkTRIGGER The "trigger" keyword.
|
||||
// ** (7) tkEND The "end" keyword.
|
||||
// **
|
||||
// ** Whitespace never causes a state transition and is always ignored.
|
||||
// ** This means that a SQL string of all whitespace is invalid.
|
||||
// **
|
||||
// ** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
|
||||
// ** to recognize the end of a trigger can be omitted. All we have to do
|
||||
// ** is look for a semicolon that is not part of an string or comment.
|
||||
// */
|
||||
func Xsqlite3_complete(tls *libc.TLS, zSql uintptr) (r int32) {
|
||||
var c, nId int32
|
||||
var state, token Tu8
|
||||
_, _, _, _ = c, nId, state, token
|
||||
state = uint8(0) /* Value of the next token */
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 {
|
||||
switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) {
|
||||
case int32(';'): /* A semicolon */
|
||||
token = uint8(tkSEMI)
|
||||
case int32(' '):
|
||||
fallthrough
|
||||
case int32('\r'):
|
||||
fallthrough
|
||||
case int32('\t'):
|
||||
fallthrough
|
||||
case int32('\n'):
|
||||
fallthrough
|
||||
case int32('\f'): /* White space is ignored */
|
||||
token = uint8(tkWS)
|
||||
case int32('/'): /* C-style comments */
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + 1))) != int32('*') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(2)
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && (libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != int32('*') || libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + 1))) != int32('/')) {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
zSql = zSql + 1
|
||||
token = uint8(tkWS)
|
||||
case int32('-'): /* SQL-style comments from "--" to end of line */
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql + 1))) != int32('-') {
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != int32('\n') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
token = uint8(tkWS)
|
||||
case int32('['): /* Microsoft-style identifiers in [...] */
|
||||
zSql = zSql + 1
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != int32(']') {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
case int32('`'): /* Grave-accent quoted symbols used by MySQL */
|
||||
fallthrough
|
||||
case int32('"'): /* single- and double-quoted strings */
|
||||
fallthrough
|
||||
case int32('\''):
|
||||
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql)))
|
||||
zSql = zSql + 1
|
||||
for **(**uint8)(__ccgo_up(zSql)) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) != c {
|
||||
zSql = zSql + 1
|
||||
}
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) == 0 {
|
||||
return 0
|
||||
}
|
||||
token = uint8(tkOTHER)
|
||||
default:
|
||||
if libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zSql)))])&int32(0x46) != 0 {
|
||||
nId = int32(1)
|
||||
for {
|
||||
if !(libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zSql + uintptr(nId))))])&int32(0x46) != 0) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
nId = nId + 1
|
||||
}
|
||||
switch libc.Int32FromUint8(**(**uint8)(__ccgo_up(zSql))) {
|
||||
case int32('c'):
|
||||
fallthrough
|
||||
case int32('C'):
|
||||
if nId == int32(6) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25281, int32(6)) == 0 {
|
||||
token = uint8(tkCREATE)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
case int32('t'):
|
||||
fallthrough
|
||||
case int32('T'):
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+21910, int32(7)) == 0 {
|
||||
token = uint8(tkTRIGGER)
|
||||
} else {
|
||||
if nId == int32(4) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25288, int32(4)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
if nId == int32(9) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25293, int32(9)) == 0 {
|
||||
token = uint8(tkTEMP)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
case int32('e'):
|
||||
fallthrough
|
||||
case int32('E'):
|
||||
if nId == int32(3) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25303, int32(3)) == 0 {
|
||||
token = uint8(tkEND)
|
||||
} else {
|
||||
if nId == int32(7) && Xsqlite3_strnicmp(tls, zSql, __ccgo_ts+25307, int32(7)) == 0 {
|
||||
token = uint8(tkEXPLAIN)
|
||||
} else {
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
}
|
||||
default:
|
||||
token = uint8(tkOTHER)
|
||||
break
|
||||
}
|
||||
zSql = zSql + uintptr(nId-int32(1))
|
||||
} else {
|
||||
/* Operators and special symbols */
|
||||
token = uint8(tkOTHER)
|
||||
}
|
||||
break
|
||||
}
|
||||
state = **(**Tu8)(__ccgo_up(uintptr(unsafe.Pointer(&_trans)) + uintptr(state)*8 + uintptr(token)))
|
||||
zSql = zSql + 1
|
||||
}
|
||||
return libc.BoolInt32(libc.Int32FromUint8(state) == int32(1))
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Extra floating-point literals to allow in JSON.
|
||||
// */
|
||||
var _aNanInfName = [5]TNanInfName{
|
||||
0: {
|
||||
Fc1: uint8('i'),
|
||||
Fc2: uint8('I'),
|
||||
Fn: uint8(3),
|
||||
FeType: uint8(JSONB_FLOAT),
|
||||
FnRepl: uint8(7),
|
||||
FzMatch: __ccgo_ts + 26501,
|
||||
FzRepl: __ccgo_ts + 26505,
|
||||
},
|
||||
1: {
|
||||
Fc1: uint8('i'),
|
||||
Fc2: uint8('I'),
|
||||
Fn: uint8(8),
|
||||
FeType: uint8(JSONB_FLOAT),
|
||||
FnRepl: uint8(7),
|
||||
FzMatch: __ccgo_ts + 26513,
|
||||
FzRepl: __ccgo_ts + 26505,
|
||||
},
|
||||
2: {
|
||||
Fc1: uint8('n'),
|
||||
Fc2: uint8('N'),
|
||||
Fn: uint8(3),
|
||||
FnRepl: uint8(4),
|
||||
FzMatch: __ccgo_ts + 1695,
|
||||
FzRepl: __ccgo_ts + 1690,
|
||||
},
|
||||
3: {
|
||||
Fc1: uint8('q'),
|
||||
Fc2: uint8('Q'),
|
||||
Fn: uint8(4),
|
||||
FnRepl: uint8(4),
|
||||
FzMatch: __ccgo_ts + 26522,
|
||||
FzRepl: __ccgo_ts + 1690,
|
||||
},
|
||||
4: {
|
||||
Fc1: uint8('s'),
|
||||
Fc2: uint8('S'),
|
||||
Fn: uint8(4),
|
||||
FnRepl: uint8(4),
|
||||
FzMatch: __ccgo_ts + 26527,
|
||||
FzRepl: __ccgo_ts + 1690,
|
||||
},
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Compare the 19-character string zNum against the text representation
|
||||
// ** value 2^63: 9223372036854775808. Return negative, zero, or positive
|
||||
// ** if zNum is less than, equal to, or greater than the string.
|
||||
// ** Note that zNum must contain exactly 19 characters.
|
||||
// **
|
||||
// ** Unlike memcmp() this routine is guaranteed to return the difference
|
||||
// ** in the values of the last digit if the only difference is in the
|
||||
// ** last digit. So, for example,
|
||||
// **
|
||||
// ** compare2pow63("9223372036854775800", 1)
|
||||
// **
|
||||
// ** will return -8.
|
||||
// */
|
||||
func _compare2pow63(tls *libc.TLS, zNum uintptr, incr int32) (r int32) {
|
||||
var c, i int32
|
||||
var pow63 uintptr
|
||||
_, _, _ = c, i, pow63
|
||||
c = 0
|
||||
/* 012345678901234567 */
|
||||
pow63 = __ccgo_ts + 1815
|
||||
i = 0
|
||||
for {
|
||||
if !(c == 0 && i < int32(18)) {
|
||||
break
|
||||
}
|
||||
c = (libc.Int32FromUint8(**(**uint8)(__ccgo_up(zNum + uintptr(i*incr)))) - libc.Int32FromUint8(**(**uint8)(__ccgo_up(pow63 + uintptr(i))))) * int32(10)
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if c == 0 {
|
||||
c = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zNum + uintptr(int32(18)*incr)))) - int32('8')
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Process a "special" query. A special query is identified as one with a
|
||||
// ** MATCH expression that begins with a '*' character. The remainder of
|
||||
// ** the text passed to the MATCH operator are used as the special query
|
||||
// ** parameters.
|
||||
// */
|
||||
func _fts5SpecialMatch(tls *libc.TLS, pTab uintptr, pCsr uintptr, zQuery uintptr) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var n, rc int32
|
||||
var z uintptr
|
||||
_, _, _ = n, rc, z
|
||||
rc = SQLITE_OK /* Return code */
|
||||
z = zQuery /* Number of bytes in text at z */
|
||||
for libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) == int32(' ') {
|
||||
z = z + 1
|
||||
}
|
||||
n = 0
|
||||
for {
|
||||
if !(**(**uint8)(__ccgo_up(z + uintptr(n))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z + uintptr(n)))) != int32(' ')) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
n = n + 1
|
||||
}
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FePlan = int32(FTS5_PLAN_SPECIAL)
|
||||
if n == int32(5) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+39843, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = int64(_sqlite3Fts5IndexReads(tls, (*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.FpIndex))
|
||||
} else {
|
||||
if n == int32(2) && 0 == Xsqlite3_strnicmp(tls, __ccgo_ts+5676, z, n) {
|
||||
(*TFts5Cursor)(unsafe.Pointer(pCsr)).FiSpecial = (*TFts5Cursor)(unsafe.Pointer(pCsr)).FiCsrId
|
||||
} else {
|
||||
/* An unrecognized directive. Return an error message. */
|
||||
(*TFts5FullTable)(unsafe.Pointer(pTab)).Fp.Fbase.FzErrMsg = Xsqlite3_mprintf(tls, __ccgo_ts+39849, libc.VaList(bp+8, n, z))
|
||||
rc = int32(SQLITE_ERROR)
|
||||
}
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Interpret the given string as a temp db location. Return 1 for file
|
||||
// ** backed temporary databases, 2 for the Red-Black tree in memory database
|
||||
// ** and 0 to use the compile-time default.
|
||||
// */
|
||||
func _getTempStore(tls *libc.TLS, z uintptr) (r int32) {
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) >= int32('0') && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) <= int32('2') {
|
||||
return libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) - int32('0')
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+18020) == 0 {
|
||||
return int32(1)
|
||||
} else {
|
||||
if _sqlite3StrICmp(tls, z, __ccgo_ts+19061) == 0 {
|
||||
return int32(2)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse a complete JSON string. Return 0 on success or non-zero if there
|
||||
// ** are any errors. If an error occurs, free all memory held by pParse,
|
||||
// ** but not pParse itself.
|
||||
// **
|
||||
// ** pParse must be initialized to an empty parse object prior to calling
|
||||
// ** this routine.
|
||||
// */
|
||||
func _jsonConvertTextToBlob(tls *libc.TLS, pParse uintptr, pCtx uintptr) (r int32) {
|
||||
var i int32
|
||||
var zJson uintptr
|
||||
_, _ = i, zJson
|
||||
zJson = (*TJsonParse)(unsafe.Pointer(pParse)).FzJson
|
||||
i = _jsonTranslateTextToBlob(tls, pParse, uint32(0))
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
i = -int32(1)
|
||||
}
|
||||
if i > 0 {
|
||||
for _jsonIsSpace[uint8(**(**uint8)(__ccgo_up(zJson + uintptr(i))))] != 0 {
|
||||
i = i + 1
|
||||
}
|
||||
if **(**uint8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
i = i + _json5Whitespace(tls, zJson+uintptr(i))
|
||||
if **(**uint8)(__ccgo_up(zJson + uintptr(i))) != 0 {
|
||||
if pCtx != 0 {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26486, -int32(1))
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
(*TJsonParse)(unsafe.Pointer(pParse)).FhasNonstd = uint8(1)
|
||||
}
|
||||
}
|
||||
if i <= 0 {
|
||||
if pCtx != uintptr(0) {
|
||||
if (*TJsonParse)(unsafe.Pointer(pParse)).Foom != 0 {
|
||||
Xsqlite3_result_error_nomem(tls, pCtx)
|
||||
} else {
|
||||
Xsqlite3_result_error(tls, pCtx, __ccgo_ts+26486, -int32(1))
|
||||
}
|
||||
}
|
||||
_jsonParseReset(tls, pParse)
|
||||
return int32(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Settle ofdEnabled from the environment, once. Called from sqlite3_os_init(),
|
||||
// ** before any file can be opened, so the mode is fixed before the first lock.
|
||||
// */
|
||||
func _ofdInitOnce(tls *libc.TLS) {
|
||||
var z uintptr
|
||||
_ = z
|
||||
if !(libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_ofdDecided))) != 0) {
|
||||
z = libc.Xgetenv(tls, __ccgo_ts+3805)
|
||||
libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_ofdEnabled)), libc.BoolInt32(z != uintptr(0) && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) != 0 && libc.Int32FromUint8(**(**uint8)(__ccgo_up(z))) != int32('0')))
|
||||
libc.AtomicStorePInt32(uintptr(unsafe.Pointer(&_ofdDecided)), int32(1))
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Parse dates of the form
|
||||
// **
|
||||
// ** YYYY-MM-DD HH:MM:SS.FFF
|
||||
// ** YYYY-MM-DD HH:MM:SS
|
||||
// ** YYYY-MM-DD HH:MM
|
||||
// ** YYYY-MM-DD
|
||||
// **
|
||||
// ** Write the result into the DateTime structure and return 0
|
||||
// ** on success and 1 if the input string is not a well-formed
|
||||
// ** date.
|
||||
// */
|
||||
func _parseYyyyMmDd(tls *libc.TLS, zDate uintptr, p uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var neg, v1 int32
|
||||
var _ /* D at bp+8 */ int32
|
||||
var _ /* M at bp+4 */ int32
|
||||
var _ /* Y at bp+0 */ int32
|
||||
_, _ = neg, v1
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) == int32('-') {
|
||||
zDate = zDate + 1
|
||||
neg = int32(1)
|
||||
} else {
|
||||
neg = 0
|
||||
}
|
||||
if _getDigits(tls, zDate, __ccgo_ts+1216, libc.VaList(bp+24, bp, bp+4, bp+8)) != int32(3) {
|
||||
return int32(1)
|
||||
}
|
||||
zDate = zDate + uintptr(10)
|
||||
for libc.Int32FromUint8(_sqlite3CtypeMap[uint8(**(**uint8)(__ccgo_up(zDate)))])&int32(0x01) != 0 || int32('T') == libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zDate))) {
|
||||
zDate = zDate + 1
|
||||
}
|
||||
if _parseHhMmSs(tls, zDate, p) == 0 {
|
||||
/* We got the time */
|
||||
} else {
|
||||
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zDate))) == 0 {
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidHMS = uint8(0)
|
||||
} else {
|
||||
return int32(1)
|
||||
}
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidJD = uint8(0)
|
||||
(*TDateTime)(unsafe.Pointer(p)).FvalidYMD = uint8(1)
|
||||
if neg != 0 {
|
||||
v1 = -**(**int32)(__ccgo_up(bp))
|
||||
} else {
|
||||
v1 = **(**int32)(__ccgo_up(bp))
|
||||
}
|
||||
(*TDateTime)(unsafe.Pointer(p)).FY = v1
|
||||
(*TDateTime)(unsafe.Pointer(p)).FM = **(**int32)(__ccgo_up(bp + 4))
|
||||
(*TDateTime)(unsafe.Pointer(p)).FD = **(**int32)(__ccgo_up(bp + 8))
|
||||
_computeFloor(tls, p)
|
||||
if (*TDateTime)(unsafe.Pointer(p)).Ftz != 0 {
|
||||
_computeJD(tls, p)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Allocate a private rbu VFS for the rbu handle passed as the only
|
||||
// ** argument. This VFS will be used unless the call to sqlite3rbu_open()
|
||||
// ** specified a URI with a vfs=? option in place of a target database
|
||||
// ** file name.
|
||||
// */
|
||||
func _rbuCreateVfs(tls *libc.TLS, p uintptr) {
|
||||
bp := tls.Alloc(96)
|
||||
defer tls.Free(96)
|
||||
var pVfs uintptr
|
||||
var _ /* rnd at bp+0 */ int32
|
||||
var _ /* zRnd at bp+4 */ [64]uint8
|
||||
_ = pVfs
|
||||
Xsqlite3_randomness(tls, int32(4), bp)
|
||||
Xsqlite3_snprintf(tls, int32(64), bp+4, __ccgo_ts+34354, libc.VaList(bp+80, **(**int32)(__ccgo_up(bp))))
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).Frc = Xsqlite3rbu_create_vfs(tls, bp+4, uintptr(0))
|
||||
if (*Tsqlite3rbu)(unsafe.Pointer(p)).Frc == SQLITE_OK {
|
||||
pVfs = Xsqlite3_vfs_find(tls, bp+4)
|
||||
(*Tsqlite3rbu)(unsafe.Pointer(p)).FzVfsName = (*Tsqlite3_vfs)(unsafe.Pointer(pVfs)).FzName
|
||||
(*Trbu_vfs)(unsafe.Pointer(pVfs)).FpRbu = p
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** An error occurred while parsing or otherwise processing a database
|
||||
// ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
|
||||
// ** ALTER TABLE RENAME COLUMN program. The error message emitted by the
|
||||
// ** sub-routine is currently stored in pParse->zErrMsg. This function
|
||||
// ** adds context to the error message and then stores it in pCtx.
|
||||
// */
|
||||
func _renameColumnParseError(tls *libc.TLS, pCtx uintptr, zWhen uintptr, pType uintptr, pObject uintptr, pParse uintptr) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var zErr, zN, zT, v1 uintptr
|
||||
_, _, _, _ = zErr, zN, zT, v1
|
||||
zT = Xsqlite3_value_text(tls, pType)
|
||||
zN = Xsqlite3_value_text(tls, pObject)
|
||||
if **(**uint8)(__ccgo_up(zWhen)) != 0 {
|
||||
v1 = __ccgo_ts + 11569
|
||||
} else {
|
||||
v1 = __ccgo_ts + 1704
|
||||
}
|
||||
zErr = _sqlite3MPrintf(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, __ccgo_ts+11571, libc.VaList(bp+8, zT, zN, v1, zWhen, (*TParse)(unsafe.Pointer(pParse)).FzErrMsg))
|
||||
Xsqlite3_result_error(tls, pCtx, zErr, -int32(1))
|
||||
_sqlite3DbFree(tls, (*TParse)(unsafe.Pointer(pParse)).Fdb, zErr)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /* IMP: R-25361-16150 This function is omitted from SQLite by default. It
|
||||
// ** is only available if the SQLITE_SOUNDEX compile-time option is used
|
||||
// ** when SQLite is built.
|
||||
// */
|
||||
// /*
|
||||
// ** Compute the soundex encoding of a word.
|
||||
// **
|
||||
// ** IMP: R-59782-00072 The soundex(X) function returns a string that is the
|
||||
// ** soundex encoding of the string X.
|
||||
// */
|
||||
func _soundexFunc(tls *libc.TLS, context uintptr, argc int32, argv uintptr) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var code, i, j, v3 int32
|
||||
var prevcode Tu8
|
||||
var zIn uintptr
|
||||
var _ /* zResult at bp+0 */ [8]uint8
|
||||
_, _, _, _, _, _ = code, i, j, prevcode, zIn, v3
|
||||
zIn = Xsqlite3_value_text(tls, **(**uintptr)(__ccgo_up(argv)))
|
||||
if zIn == uintptr(0) {
|
||||
zIn = __ccgo_ts + 1704
|
||||
}
|
||||
i = 0
|
||||
for {
|
||||
if !(**(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 && !(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))])&libc.Int32FromInt32(0x02) != 0)) {
|
||||
break
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
if **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0 {
|
||||
prevcode = _iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)]
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[0] = libc.Uint8FromInt32(libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i)))) & ^(libc.Int32FromUint8(_sqlite3CtypeMap[**(**Tu8)(__ccgo_up(zIn + uintptr(i)))]) & libc.Int32FromInt32(0x20)))
|
||||
j = int32(1)
|
||||
for {
|
||||
if !(j < int32(4) && **(**Tu8)(__ccgo_up(zIn + uintptr(i))) != 0) {
|
||||
break
|
||||
}
|
||||
code = libc.Int32FromUint8(_iCode[libc.Int32FromUint8(**(**Tu8)(__ccgo_up(zIn + uintptr(i))))&int32(0x7f)])
|
||||
if code > 0 {
|
||||
if code != libc.Int32FromUint8(prevcode) {
|
||||
prevcode = libc.Uint8FromInt32(code)
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[v3] = libc.Uint8FromInt32(code + int32('0'))
|
||||
}
|
||||
} else {
|
||||
prevcode = uint8(0)
|
||||
}
|
||||
goto _2
|
||||
_2:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
for j < int32(4) {
|
||||
v3 = j
|
||||
j = j + 1
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[v3] = uint8('0')
|
||||
}
|
||||
(**(**[8]uint8)(__ccgo_up(bp)))[j] = uint8(0)
|
||||
Xsqlite3_result_text(tls, context, bp, int32(4), uintptr(-libc.Int32FromInt32(1)))
|
||||
} else {
|
||||
/* IMP: R-64894-50321 The string "?000" is returned if the argument
|
||||
** is NULL or contains no ASCII alphabetic characters. */
|
||||
Xsqlite3_result_text(tls, context, __ccgo_ts+16622, int32(4), libc.UintptrFromInt32(0))
|
||||
}
|
||||
}
|
||||
|
||||
func _sqlite3Fts5ParseSetDistance(tls *libc.TLS, pParse uintptr, pNear uintptr, p uintptr) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var c uint8
|
||||
var i, nNear int32
|
||||
_, _, _ = c, i, nNear
|
||||
if pNear != 0 {
|
||||
nNear = 0
|
||||
if (*TFts5Token)(unsafe.Pointer(p)).Fn != 0 {
|
||||
i = 0
|
||||
for {
|
||||
if !(i < (*TFts5Token)(unsafe.Pointer(p)).Fn) {
|
||||
break
|
||||
}
|
||||
c = **(**uint8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))
|
||||
if libc.Int32FromUint8(c) < int32('0') || libc.Int32FromUint8(c) > int32('9') {
|
||||
_sqlite3Fts5ParseError(tls, pParse, __ccgo_ts+38634, libc.VaList(bp+8, (*TFts5Token)(unsafe.Pointer(p)).Fn, (*TFts5Token)(unsafe.Pointer(p)).Fp))
|
||||
return
|
||||
}
|
||||
if nNear < int32(214748363) {
|
||||
nNear = nNear*int32(10) + (libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TFts5Token)(unsafe.Pointer(p)).Fp + uintptr(i)))) - int32('0'))
|
||||
}
|
||||
/* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
} else {
|
||||
nNear = int32(FTS5_DEFAULT_NEARDIST)
|
||||
}
|
||||
(*TFts5ExprNearset)(unsafe.Pointer(pNear)).FnNear = nNear
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Append to pStr text that is the SQL literal representation of the
|
||||
// ** value contained in pValue.
|
||||
// */
|
||||
func _sqlite3QuoteValue(tls *libc.TLS, pStr uintptr, pValue uintptr, bEscape int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var i int32
|
||||
var nBlob Ti64
|
||||
var zArg, zBlob, zText, v2 uintptr
|
||||
_, _, _, _, _, _ = i, nBlob, zArg, zBlob, zText, v2
|
||||
/* As currently implemented, the string must be initially empty.
|
||||
** we might relax this requirement in the future, but that will
|
||||
** require enhancements to the implementation. */
|
||||
switch Xsqlite3_value_type(tls, pValue) {
|
||||
case int32(SQLITE_FLOAT):
|
||||
/* ,--- Show infinity as 9.0e+999
|
||||
** |
|
||||
** | ,--- 17 precision guarantees round-trip
|
||||
** v v */
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+16587, libc.VaList(bp+8, Xsqlite3_value_double(tls, pValue)))
|
||||
case int32(SQLITE_INTEGER):
|
||||
Xsqlite3_str_appendf(tls, pStr, __ccgo_ts+1465, libc.VaList(bp+8, Xsqlite3_value_int64(tls, pValue)))
|
||||
case int32(SQLITE_BLOB):
|
||||
zBlob = Xsqlite3_value_blob(tls, pValue)
|
||||
nBlob = int64(Xsqlite3_value_bytes(tls, pValue))
|
||||
/* No encoding change */
|
||||
_sqlite3StrAccumEnlarge(tls, pStr, nBlob*int64(2)+int64(4))
|
||||
if libc.Int32FromUint8((*TStrAccum)(unsafe.Pointer(pStr)).FaccError) == 0 {
|
||||
zText = (*TStrAccum)(unsafe.Pointer(pStr)).FzText
|
||||
i = 0
|
||||
for {
|
||||
if !(int64(i) < nBlob) {
|
||||
break
|
||||
}
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(2)))) = _hexdigits[libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBlob + uintptr(i))))>>int32(4)&int32(0x0F)]
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(i*int32(2)+int32(3)))) = _hexdigits[libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBlob + uintptr(i))))&int32(0x0F)]
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
i = i + 1
|
||||
}
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(2)))) = uint8('\'')
|
||||
**(**uint8)(__ccgo_up(zText + uintptr(nBlob*int64(2)+int64(3)))) = uint8('\000')
|
||||
**(**uint8)(__ccgo_up(zText)) = uint8('X')
|
||||
**(**uint8)(__ccgo_up(zText + 1)) = uint8('\'')
|
||||
(*TStrAccum)(unsafe.Pointer(pStr)).FnChar = libc.Uint32FromInt64(nBlob*int64(2) + int64(3))
|
||||
}
|
||||
case int32(SQLITE_TEXT):
|
||||
zArg = Xsqlite3_value_text(tls, pValue)
|
||||
if bEscape != 0 {
|
||||
v2 = __ccgo_ts + 16595
|
||||
} else {
|
||||
v2 = __ccgo_ts + 11953
|
||||
}
|
||||
Xsqlite3_str_appendf(tls, pStr, v2, libc.VaList(bp+8, zArg))
|
||||
default:
|
||||
Xsqlite3_str_append(tls, pStr, __ccgo_ts+1705, int32(4))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Create a temporary file name in zBuf. zBuf must be allocated
|
||||
// ** by the calling process and must be big enough to hold at least
|
||||
// ** pVfs->mxPathname bytes.
|
||||
// */
|
||||
func _unixGetTempname(tls *libc.TLS, nBuf int32, zBuf uintptr) (r int32) {
|
||||
bp := tls.Alloc(48)
|
||||
defer tls.Free(48)
|
||||
var iLimit, rc, v1 int32
|
||||
var zDir uintptr
|
||||
var v2 bool
|
||||
var _ /* r at bp+0 */ Tu64
|
||||
_, _, _, _, _ = iLimit, rc, zDir, v1, v2
|
||||
iLimit = 0
|
||||
rc = SQLITE_OK
|
||||
/* It's odd to simulate an io-error here, but really this is just
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
** function failing.
|
||||
*/
|
||||
**(**uint8)(__ccgo_up(zBuf)) = uint8(0)
|
||||
Xsqlite3_mutex_enter(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
zDir = _unixTempFileDir(tls)
|
||||
if zDir == uintptr(0) {
|
||||
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(25)<<libc.Int32FromInt32(8)
|
||||
} else {
|
||||
for cond := true; cond; cond = (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zBuf, 0) == 0 {
|
||||
Xsqlite3_randomness(tls, int32(8), bp)
|
||||
**(**uint8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2)))) = uint8(0)
|
||||
Xsqlite3_snprintf(tls, nBuf, zBuf, __ccgo_ts+4069, libc.VaList(bp+16, zDir, **(**Tu64)(__ccgo_up(bp)), 0))
|
||||
if v2 = libc.Int32FromUint8(**(**uint8)(__ccgo_up(zBuf + uintptr(nBuf-int32(2))))) != 0; !v2 {
|
||||
v1 = iLimit
|
||||
iLimit = iLimit + 1
|
||||
}
|
||||
if v2 || v1 > int32(10) {
|
||||
rc = int32(SQLITE_ERROR)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Xsqlite3_mutex_leave(tls, _sqlite3MutexAlloc(tls, int32(SQLITE_MUTEX_STATIC_VFS1)))
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** The following code executes when a syntax error first occurs.
|
||||
// */
|
||||
func _yy_syntax_error(tls *libc.TLS, yypParser uintptr, yymajor int32, _yyminor TToken) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
*(*TToken)(unsafe.Pointer(bp)) = _yyminor
|
||||
var pParse uintptr
|
||||
_ = pParse
|
||||
pParse = (*TyyParser)(unsafe.Pointer(yypParser)).FpParse
|
||||
/************ Begin %syntax_error code ****************************************/
|
||||
_ = yymajor /* Silence some compiler warnings */
|
||||
if **(**uint8)(__ccgo_up((**(**TToken)(__ccgo_up(bp))).Fz)) != 0 {
|
||||
_parserSyntaxError(tls, pParse, bp)
|
||||
} else {
|
||||
_sqlite3ErrorMsg(tls, pParse, __ccgo_ts+25228, 0)
|
||||
}
|
||||
/************ End %syntax_error code ******************************************/
|
||||
/* Suppress warning about unused %extra_argument variable */
|
||||
(*TyyParser)(unsafe.Pointer(yypParser)).FpParse = pParse
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const __FP_FAST_FMAF32 = 1
|
||||
|
||||
const __FP_FAST_FMAF32x = 1
|
||||
|
||||
const __FP_FAST_FMAF64 = 1
|
||||
+20813
File diff suppressed because it is too large
Load Diff
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
const _POSIX_V6_LP64_OFF64 = 1
|
||||
|
||||
const _POSIX_V7_LP64_OFF64 = 1
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (freebsd && amd64) || (freebsd && arm64) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
type Tfd_mask = uint64
|
||||
|
||||
const __LONG_MAX = 9223372036854775807
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This function performs the parts of the "close file" operation
|
||||
// ** common to all locking schemes. It closes the directory and file
|
||||
// ** handles, if they are valid, and sets all fields of the unixFile
|
||||
// ** structure to 0.
|
||||
// **
|
||||
// ** It is *not* necessary to hold the mutex when this routine is called,
|
||||
// ** even on VxWorks. A mutex will be acquired on VxWorks by the
|
||||
// ** vxworksReleaseFileId() routine.
|
||||
// */
|
||||
func _closeUnixFile(tls *libc.TLS, id uintptr) (r int32) {
|
||||
var pFile uintptr
|
||||
_ = pFile
|
||||
pFile = id
|
||||
_unixUnmapfile(tls, pFile)
|
||||
if (*TunixFile)(unsafe.Pointer(pFile)).Fh >= 0 {
|
||||
_robust_close(tls, pFile, (*TunixFile)(unsafe.Pointer(pFile)).Fh, int32(42654))
|
||||
(*TunixFile)(unsafe.Pointer(pFile)).Fh = -int32(1)
|
||||
}
|
||||
Xsqlite3_free(tls, (*TunixFile)(unsafe.Pointer(pFile)).FpPreallocatedUnused)
|
||||
libc.Xmemset(tls, pFile, 0, uint64(120))
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Obtain a reference to a memory mapped page object for page number pgno.
|
||||
// ** The new object will use the pointer pData, obtained from xFetch().
|
||||
// ** If successful, set *ppPage to point to the new page reference
|
||||
// ** and return SQLITE_OK. Otherwise, return an SQLite error code and set
|
||||
// ** *ppPage to zero.
|
||||
// **
|
||||
// ** Page references obtained by calling this function should be released
|
||||
// ** by calling pagerReleaseMapPage().
|
||||
// */
|
||||
func _pagerAcquireMapPage(tls *libc.TLS, pPager uintptr, pgno TPgno, pData uintptr, ppPage uintptr) (r int32) {
|
||||
var p, v1 uintptr
|
||||
_, _ = p, v1 /* Memory mapped page to return */
|
||||
if (*TPager)(unsafe.Pointer(pPager)).FpMmapFreelist != 0 {
|
||||
v1 = (*TPager)(unsafe.Pointer(pPager)).FpMmapFreelist
|
||||
p = v1
|
||||
**(**uintptr)(__ccgo_up(ppPage)) = v1
|
||||
(*TPager)(unsafe.Pointer(pPager)).FpMmapFreelist = (*TPgHdr)(unsafe.Pointer(p)).FpDirty
|
||||
(*TPgHdr)(unsafe.Pointer(p)).FpDirty = uintptr(0)
|
||||
libc.Xmemset(tls, (*TPgHdr)(unsafe.Pointer(p)).FpExtra, 0, uint64(8))
|
||||
} else {
|
||||
v1 = _sqlite3MallocZero(tls, uint64(80)+uint64((*TPager)(unsafe.Pointer(pPager)).FnExtra))
|
||||
p = v1
|
||||
**(**uintptr)(__ccgo_up(ppPage)) = v1
|
||||
if p == uintptr(0) {
|
||||
_sqlite3OsUnfetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, libc.Int64FromUint32(pgno-libc.Uint32FromInt32(1))*(*TPager)(unsafe.Pointer(pPager)).FpageSize, pData)
|
||||
return int32(SQLITE_NOMEM)
|
||||
}
|
||||
(*TPgHdr)(unsafe.Pointer(p)).FpExtra = p + 1*80
|
||||
(*TPgHdr)(unsafe.Pointer(p)).Fflags = uint16(PGHDR_MMAP)
|
||||
(*TPgHdr)(unsafe.Pointer(p)).FnRef = int64(1)
|
||||
(*TPgHdr)(unsafe.Pointer(p)).FpPager = pPager
|
||||
}
|
||||
(*TPgHdr)(unsafe.Pointer(p)).Fpgno = pgno
|
||||
(*TPgHdr)(unsafe.Pointer(p)).FpData = pData
|
||||
(*TPager)(unsafe.Pointer(pPager)).FnMmapOut = (*TPager)(unsafe.Pointer(pPager)).FnMmapOut + 1
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Find the current time (in Universal Coordinated Time). Write into *piNow
|
||||
// ** the current time and date as a Julian Day number times 86_400_000. In
|
||||
// ** other words, write into *piNow the number of milliseconds since the Julian
|
||||
// ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
|
||||
// ** proleptic Gregorian calendar.
|
||||
// **
|
||||
// ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
|
||||
// ** cannot be found.
|
||||
// */
|
||||
func _unixCurrentTimeInt64(tls *libc.TLS, NotUsed uintptr, piNow uintptr) (r int32) {
|
||||
bp := tls.Alloc(16)
|
||||
defer tls.Free(16)
|
||||
var rc int32
|
||||
var _ /* sNow at bp+0 */ Ttimeval
|
||||
_ = rc
|
||||
rc = SQLITE_OK
|
||||
libc.Xgettimeofday(tls, bp, uintptr(0)) /* Cannot fail given valid arguments */
|
||||
**(**Tsqlite3_int64)(__ccgo_up(piNow)) = _unixEpoch + int64(1000)*int64((**(**Ttimeval)(__ccgo_up(bp))).Ftv_sec) + int64((**(**Ttimeval)(__ccgo_up(bp))).Ftv_usec/int64(1000))
|
||||
_ = NotUsed
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Read data from a file into a buffer. Return SQLITE_OK if all
|
||||
// ** bytes were read successfully and SQLITE_IOERR if anything goes
|
||||
// ** wrong.
|
||||
// */
|
||||
func _unixRead(tls *libc.TLS, id uintptr, pBuf uintptr, amt int32, offset Tsqlite3_int64) (r int32) {
|
||||
var got, nCopy int32
|
||||
var pFile uintptr
|
||||
_, _, _ = got, nCopy, pFile
|
||||
pFile = id
|
||||
/* If this is a database file (not a journal, super-journal or temp
|
||||
** file), the bytes in the locking range should never be read or written. */
|
||||
/* Deal with as much of this read request as possible by transferring
|
||||
** data from the memory mapping using memcpy(). */
|
||||
if offset < (*TunixFile)(unsafe.Pointer(pFile)).FmmapSize {
|
||||
if offset+int64(amt) <= (*TunixFile)(unsafe.Pointer(pFile)).FmmapSize {
|
||||
libc.Xmemcpy(tls, pBuf, (*TunixFile)(unsafe.Pointer(pFile)).FpMapRegion+uintptr(offset), libc.Uint64FromInt32(amt))
|
||||
return SQLITE_OK
|
||||
} else {
|
||||
nCopy = int32((*TunixFile)(unsafe.Pointer(pFile)).FmmapSize - offset)
|
||||
libc.Xmemcpy(tls, pBuf, (*TunixFile)(unsafe.Pointer(pFile)).FpMapRegion+uintptr(offset), libc.Uint64FromInt32(nCopy))
|
||||
pBuf = pBuf + uintptr(nCopy)
|
||||
amt = amt - nCopy
|
||||
offset = offset + int64(nCopy)
|
||||
}
|
||||
}
|
||||
got = _seekAndRead(tls, pFile, offset, pBuf, amt)
|
||||
if got == amt {
|
||||
return SQLITE_OK
|
||||
} else {
|
||||
if got < 0 {
|
||||
/* pFile->lastErrno has been set by seekAndRead().
|
||||
** Usually we return SQLITE_IOERR_READ here, though for some
|
||||
** kinds of errors we return SQLITE_IOERR_CORRUPTFS. The
|
||||
** SQLITE_IOERR_CORRUPTFS will be converted into SQLITE_CORRUPT
|
||||
** prior to returning to the application by the sqlite3ApiExit()
|
||||
** routine.
|
||||
*/
|
||||
switch (*TunixFile)(unsafe.Pointer(pFile)).FlastErrno {
|
||||
case int32(ERANGE):
|
||||
fallthrough
|
||||
case int32(EIO):
|
||||
fallthrough
|
||||
case int32(ENXIO):
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(33)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(1)<<libc.Int32FromInt32(8)
|
||||
} else {
|
||||
_storeLastErrno(tls, pFile, 0) /* not a system error */
|
||||
/* Unread parts of the buffer must be zero-filled */
|
||||
libc.Xmemset(tls, pBuf+uintptr(got), 0, libc.Uint64FromInt32(amt-got))
|
||||
return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(2)<<libc.Int32FromInt32(8)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** Write the current contents of in-memory linked-list pList to a level-0
|
||||
// ** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if
|
||||
// ** successful, or an SQLite error code otherwise.
|
||||
// **
|
||||
// ** The format of a PMA is:
|
||||
// **
|
||||
// ** * A varint. This varint contains the total number of bytes of content
|
||||
// ** in the PMA (not including the varint itself).
|
||||
// **
|
||||
// ** * One or more records packed end-to-end in order of ascending keys.
|
||||
// ** Each record consists of a varint followed by a blob of data (the
|
||||
// ** key). The varint is the number of bytes in the blob of data.
|
||||
// */
|
||||
func _vdbeSorterListToPMA(tls *libc.TLS, pTask uintptr, pList uintptr) (r int32) {
|
||||
bp := tls.Alloc(64)
|
||||
defer tls.Free(64)
|
||||
var db, p, pNext uintptr
|
||||
var rc int32
|
||||
var _ /* writer at bp+0 */ TPmaWriter
|
||||
_, _, _, _ = db, p, pNext, rc
|
||||
db = (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fdb
|
||||
rc = SQLITE_OK /* Object used to write to the file */
|
||||
libc.Xmemset(tls, bp, 0, uint64(56))
|
||||
/* If the first temporary PMA file has not been opened, open it now. */
|
||||
if (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd == uintptr(0) {
|
||||
rc = _vdbeSorterOpenTempFile(tls, db, 0, pTask+64)
|
||||
}
|
||||
/* Try to get the file to memory map */
|
||||
if rc == SQLITE_OK {
|
||||
_vdbeSorterExtendFile(tls, db, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FiEof+(*TSorterList)(unsafe.Pointer(pList)).FszPMA+int64(9))
|
||||
}
|
||||
/* Sort the list */
|
||||
if rc == SQLITE_OK {
|
||||
rc = _vdbeSorterSort(tls, pTask, pList)
|
||||
}
|
||||
if rc == SQLITE_OK {
|
||||
pNext = uintptr(0)
|
||||
_vdbePmaWriterInit(tls, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FpFd, bp, (*TVdbeSorter)(unsafe.Pointer((*TSortSubtask)(unsafe.Pointer(pTask)).FpSorter)).Fpgsz, (*TSortSubtask)(unsafe.Pointer(pTask)).Ffile.FiEof)
|
||||
(*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA = (*TSortSubtask)(unsafe.Pointer(pTask)).FnPMA + 1
|
||||
_vdbePmaWriteVarint(tls, bp, libc.Uint64FromInt64((*TSorterList)(unsafe.Pointer(pList)).FszPMA))
|
||||
p = (*TSorterList)(unsafe.Pointer(pList)).FpList
|
||||
for {
|
||||
if !(p != 0) {
|
||||
break
|
||||
}
|
||||
pNext = *(*uintptr)(unsafe.Pointer(p + 8))
|
||||
_vdbePmaWriteVarint(tls, bp, libc.Uint64FromInt32((*TSorterRecord)(unsafe.Pointer(p)).FnVal))
|
||||
_vdbePmaWriteBlob(tls, bp, p+libc.UintptrFromInt32(1)*16, (*TSorterRecord)(unsafe.Pointer(p)).FnVal)
|
||||
if (*TSorterList)(unsafe.Pointer(pList)).FaMemory == uintptr(0) {
|
||||
Xsqlite3_free(tls, p)
|
||||
}
|
||||
goto _1
|
||||
_1:
|
||||
;
|
||||
p = pNext
|
||||
}
|
||||
(*TSorterList)(unsafe.Pointer(pList)).FpList = p
|
||||
rc = _vdbePmaWriterFinish(tls, bp, pTask+64+8, pTask+96)
|
||||
}
|
||||
return rc
|
||||
}
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
||||
|
||||
//go:build (darwin && amd64) || (darwin && arm64) || (freebsd && amd64) || (freebsd && arm64) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x)
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"modernc.org/libc"
|
||||
)
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** This API allows applications to modify the global configuration of
|
||||
// ** the SQLite library at run-time.
|
||||
// **
|
||||
// ** This routine should only be called when there are no outstanding
|
||||
// ** database connections or memory allocations. This routine is not
|
||||
// ** threadsafe. Failure to heed these warnings can lead to unpredictable
|
||||
// ** behavior.
|
||||
// */
|
||||
func Xsqlite3_config(tls *libc.TLS, op int32, va uintptr) (r int32) {
|
||||
var ap Tva_list
|
||||
var bOpenUri, rc int32
|
||||
var mxMmap, szMmap Tsqlite3_int64
|
||||
var pLogArg, pVal, xLog uintptr
|
||||
_, _, _, _, _, _, _, _ = ap, bOpenUri, mxMmap, pLogArg, pVal, rc, szMmap, xLog
|
||||
rc = SQLITE_OK
|
||||
/* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while
|
||||
** the SQLite library is in use. Except, a few selected opcodes
|
||||
** are allowed.
|
||||
*/
|
||||
if libc.AtomicLoadPInt32(uintptr(unsafe.Pointer(&_sqlite3Config))+340) != 0 {
|
||||
if op < 0 || op > int32(63) || libc.Uint64FromInt32(1)<<op&_mAnytimeConfigOption == uint64(0) {
|
||||
return _sqlite3MisuseError(tls, int32(187961))
|
||||
}
|
||||
}
|
||||
ap = va
|
||||
switch op {
|
||||
/* Mutex configuration options are only available in a threadsafe
|
||||
** compile.
|
||||
*/
|
||||
case int32(SQLITE_CONFIG_SINGLETHREAD):
|
||||
/* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to
|
||||
** Single-thread. */
|
||||
_sqlite3Config.FbCoreMutex = uint8(0) /* Disable mutex on core */
|
||||
_sqlite3Config.FbFullMutex = uint8(0) /* Disable mutex on connections */
|
||||
case int32(SQLITE_CONFIG_MULTITHREAD):
|
||||
/* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to
|
||||
** Multi-thread. */
|
||||
_sqlite3Config.FbCoreMutex = uint8(1) /* Enable mutex on core */
|
||||
_sqlite3Config.FbFullMutex = uint8(0) /* Disable mutex on connections */
|
||||
case int32(SQLITE_CONFIG_SERIALIZED):
|
||||
/* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to
|
||||
** Serialized. */
|
||||
_sqlite3Config.FbCoreMutex = uint8(1) /* Enable mutex on core */
|
||||
_sqlite3Config.FbFullMutex = uint8(1) /* Enable mutex on connections */
|
||||
case int32(SQLITE_CONFIG_MUTEX):
|
||||
/* Specify an alternative mutex implementation */
|
||||
_sqlite3Config.Fmutex = **(**Tsqlite3_mutex_methods)(__ccgo_up(libc.VaUintptr(&ap)))
|
||||
case int32(SQLITE_CONFIG_GETMUTEX):
|
||||
/* Retrieve the current mutex implementation */
|
||||
**(**Tsqlite3_mutex_methods)(__ccgo_up(libc.VaUintptr(&ap))) = _sqlite3Config.Fmutex
|
||||
case int32(SQLITE_CONFIG_MALLOC):
|
||||
/* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a
|
||||
** single argument which is a pointer to an instance of the
|
||||
** sqlite3_mem_methods structure. The argument specifies alternative
|
||||
** low-level memory allocation routines to be used in place of the memory
|
||||
** allocation routines built into SQLite. */
|
||||
_sqlite3Config.Fm = **(**Tsqlite3_mem_methods)(__ccgo_up(libc.VaUintptr(&ap)))
|
||||
case int32(SQLITE_CONFIG_GETMALLOC):
|
||||
/* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a
|
||||
** single argument which is a pointer to an instance of the
|
||||
** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is
|
||||
** filled with the currently defined memory allocation routines. */
|
||||
if _sqlite3Config.Fm.FxMalloc == uintptr(0) {
|
||||
_sqlite3MemSetDefault(tls)
|
||||
}
|
||||
**(**Tsqlite3_mem_methods)(__ccgo_up(libc.VaUintptr(&ap))) = _sqlite3Config.Fm
|
||||
case int32(SQLITE_CONFIG_MEMSTATUS):
|
||||
/* Cannot change at runtime */
|
||||
/* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes
|
||||
** single argument of type int, interpreted as a boolean, which enables
|
||||
** or disables the collection of memory allocation statistics. */
|
||||
_sqlite3Config.FbMemstat = libc.VaInt32(&ap)
|
||||
case int32(SQLITE_CONFIG_SMALL_MALLOC):
|
||||
_sqlite3Config.FbSmallMalloc = libc.Uint8FromInt32(libc.VaInt32(&ap))
|
||||
case int32(SQLITE_CONFIG_PAGECACHE):
|
||||
/* EVIDENCE-OF: R-18761-36601 There are three arguments to
|
||||
** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
|
||||
** the size of each page cache line (sz), and the number of cache lines
|
||||
** (N). */
|
||||
_sqlite3Config.FpPage = libc.VaUintptr(&ap)
|
||||
_sqlite3Config.FszPage = libc.VaInt32(&ap)
|
||||
_sqlite3Config.FnPage = libc.VaInt32(&ap)
|
||||
case int32(SQLITE_CONFIG_PCACHE_HDRSZ):
|
||||
/* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes
|
||||
** a single parameter which is a pointer to an integer and writes into
|
||||
** that integer the number of extra bytes per page required for each page
|
||||
** in SQLITE_CONFIG_PAGECACHE. */
|
||||
**(**int32)(__ccgo_up(libc.VaUintptr(&ap))) = _sqlite3HeaderSizeBtree(tls) + _sqlite3HeaderSizePcache(tls) + _sqlite3HeaderSizePcache1(tls)
|
||||
case int32(SQLITE_CONFIG_PCACHE):
|
||||
/* no-op */
|
||||
case int32(SQLITE_CONFIG_GETPCACHE):
|
||||
/* now an error */
|
||||
rc = int32(SQLITE_ERROR)
|
||||
case int32(SQLITE_CONFIG_PCACHE2):
|
||||
/* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a
|
||||
** single argument which is a pointer to an sqlite3_pcache_methods2
|
||||
** object. This object specifies the interface to a custom page cache
|
||||
** implementation. */
|
||||
_sqlite3Config.Fpcache2 = **(**Tsqlite3_pcache_methods2)(__ccgo_up(libc.VaUintptr(&ap)))
|
||||
case int32(SQLITE_CONFIG_GETPCACHE2):
|
||||
/* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a
|
||||
** single argument which is a pointer to an sqlite3_pcache_methods2
|
||||
** object. SQLite copies of the current page cache implementation into
|
||||
** that object. */
|
||||
if _sqlite3Config.Fpcache2.FxInit == uintptr(0) {
|
||||
_sqlite3PCacheSetDefault(tls)
|
||||
}
|
||||
**(**Tsqlite3_pcache_methods2)(__ccgo_up(libc.VaUintptr(&ap))) = _sqlite3Config.Fpcache2
|
||||
break
|
||||
/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only
|
||||
** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or
|
||||
** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */
|
||||
fallthrough
|
||||
case int32(SQLITE_CONFIG_LOOKASIDE):
|
||||
_sqlite3Config.FszLookaside = libc.VaInt32(&ap)
|
||||
_sqlite3Config.FnLookaside = libc.VaInt32(&ap)
|
||||
break
|
||||
/* Record a pointer to the logger function and its first argument.
|
||||
** The default is NULL. Logging is disabled if the function pointer is
|
||||
** NULL.
|
||||
*/
|
||||
fallthrough
|
||||
case int32(SQLITE_CONFIG_LOG):
|
||||
xLog = libc.VaUintptr(&ap)
|
||||
pLogArg = libc.VaUintptr(&ap)
|
||||
libc.AtomicStoreNUintptr(uintptr(unsafe.Pointer(&_sqlite3Config))+376, xLog, libc.Int32FromInt32(__ATOMIC_RELAXED))
|
||||
libc.AtomicStoreNUintptr(uintptr(unsafe.Pointer(&_sqlite3Config))+384, pLogArg, libc.Int32FromInt32(__ATOMIC_RELAXED))
|
||||
break
|
||||
/* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames
|
||||
** can be changed at start-time using the
|
||||
** sqlite3_config(SQLITE_CONFIG_URI,1) or
|
||||
** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
|
||||
*/
|
||||
fallthrough
|
||||
case int32(SQLITE_CONFIG_URI):
|
||||
/* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single
|
||||
** argument of type int. If non-zero, then URI handling is globally
|
||||
** enabled. If the parameter is zero, then URI handling is globally
|
||||
** disabled. */
|
||||
bOpenUri = libc.VaInt32(&ap)
|
||||
libc.AtomicStoreNUint8(uintptr(unsafe.Pointer(&_sqlite3Config))+6, libc.Uint8FromInt32(bOpenUri), libc.Int32FromInt32(__ATOMIC_RELAXED))
|
||||
case int32(SQLITE_CONFIG_COVERING_INDEX_SCAN):
|
||||
/* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN
|
||||
** option takes a single integer argument which is interpreted as a
|
||||
** boolean in order to enable or disable the use of covering indices for
|
||||
** full table scans in the query optimizer. */
|
||||
_sqlite3Config.FbUseCis = libc.Uint8FromInt32(libc.VaInt32(&ap))
|
||||
case int32(SQLITE_CONFIG_MMAP_SIZE):
|
||||
/* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit
|
||||
** integer (sqlite3_int64) values that are the default mmap size limit
|
||||
** (the default setting for PRAGMA mmap_size) and the maximum allowed
|
||||
** mmap size limit. */
|
||||
szMmap = libc.VaInt64(&ap)
|
||||
mxMmap = libc.VaInt64(&ap)
|
||||
/* EVIDENCE-OF: R-53367-43190 If either argument to this option is
|
||||
** negative, then that argument is changed to its compile-time default.
|
||||
**
|
||||
** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be
|
||||
** silently truncated if necessary so that it does not exceed the
|
||||
** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
|
||||
** compile-time option.
|
||||
*/
|
||||
if mxMmap < 0 || mxMmap > int64(SQLITE_MAX_MMAP_SIZE) {
|
||||
mxMmap = int64(SQLITE_MAX_MMAP_SIZE)
|
||||
}
|
||||
if szMmap < 0 {
|
||||
szMmap = SQLITE_DEFAULT_MMAP_SIZE
|
||||
}
|
||||
if szMmap > mxMmap {
|
||||
szMmap = mxMmap
|
||||
}
|
||||
_sqlite3Config.FmxMmap = mxMmap
|
||||
_sqlite3Config.FszMmap = szMmap
|
||||
case int32(SQLITE_CONFIG_PMASZ):
|
||||
_sqlite3Config.FszPma = libc.VaUint32(&ap)
|
||||
case int32(SQLITE_CONFIG_STMTJRNL_SPILL):
|
||||
_sqlite3Config.FnStmtSpill = libc.VaInt32(&ap)
|
||||
case int32(SQLITE_CONFIG_MEMDB_MAXSIZE):
|
||||
_sqlite3Config.FmxMemdbSize = libc.VaInt64(&ap)
|
||||
case int32(SQLITE_CONFIG_ROWID_IN_VIEW):
|
||||
pVal = libc.VaUintptr(&ap)
|
||||
**(**int32)(__ccgo_up(pVal)) = 0
|
||||
default:
|
||||
rc = int32(SQLITE_ERROR)
|
||||
break
|
||||
}
|
||||
_ = ap
|
||||
return rc
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /* The page getter for when memory-mapped I/O is enabled */
|
||||
func _getPageMMap(tls *libc.TLS, pPager uintptr, pgno TPgno, ppPage uintptr, flags int32) (r int32) {
|
||||
bp := tls.Alloc(32)
|
||||
defer tls.Free(32)
|
||||
var bMmapOk, rc int32
|
||||
var _ /* iFrame at bp+8 */ Tu32
|
||||
var _ /* pData at bp+16 */ uintptr
|
||||
var _ /* pPg at bp+0 */ uintptr
|
||||
_, _ = bMmapOk, rc
|
||||
rc = SQLITE_OK
|
||||
**(**uintptr)(__ccgo_up(bp)) = uintptr(0)
|
||||
**(**Tu32)(__ccgo_up(bp + 8)) = uint32(0) /* Frame to read from WAL file */
|
||||
/* It is acceptable to use a read-only (mmap) page for any page except
|
||||
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
|
||||
** flag was specified by the caller. And so long as the db is not a
|
||||
** temporary or in-memory database. */
|
||||
bMmapOk = libc.BoolInt32(pgno > uint32(1) && (libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) == int32(PAGER_READER) || flags&int32(PAGER_GET_READONLY) != 0))
|
||||
/* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
|
||||
** allows the compiler optimizer to reuse the results of the "pgno>1"
|
||||
** test in the previous statement, and avoid testing pgno==0 in the
|
||||
** common case where pgno is large. */
|
||||
if pgno <= uint32(1) && pgno == uint32(0) {
|
||||
return _sqlite3CorruptError(tls, int32(65497))
|
||||
}
|
||||
if bMmapOk != 0 && (*TPager)(unsafe.Pointer(pPager)).FpWal != uintptr(0) {
|
||||
rc = _sqlite3WalFindFrame(tls, (*TPager)(unsafe.Pointer(pPager)).FpWal, pgno, bp+8)
|
||||
if rc != SQLITE_OK {
|
||||
**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
|
||||
return rc
|
||||
}
|
||||
}
|
||||
if bMmapOk != 0 && **(**Tu32)(__ccgo_up(bp + 8)) == uint32(0) {
|
||||
**(**uintptr)(__ccgo_up(bp + 16)) = uintptr(0)
|
||||
rc = _sqlite3OsFetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, libc.Int64FromUint32(pgno-libc.Uint32FromInt32(1))*(*TPager)(unsafe.Pointer(pPager)).FpageSize, int32((*TPager)(unsafe.Pointer(pPager)).FpageSize), bp+16)
|
||||
if rc == SQLITE_OK && **(**uintptr)(__ccgo_up(bp + 16)) != 0 {
|
||||
if libc.Int32FromUint8((*TPager)(unsafe.Pointer(pPager)).FeState) > int32(PAGER_READER) || (*TPager)(unsafe.Pointer(pPager)).FtempFile != 0 {
|
||||
**(**uintptr)(__ccgo_up(bp)) = _sqlite3PagerLookup(tls, pPager, pgno)
|
||||
}
|
||||
if **(**uintptr)(__ccgo_up(bp)) == uintptr(0) {
|
||||
rc = _pagerAcquireMapPage(tls, pPager, pgno, **(**uintptr)(__ccgo_up(bp + 16)), bp)
|
||||
} else {
|
||||
_sqlite3OsUnfetch(tls, (*TPager)(unsafe.Pointer(pPager)).Ffd, libc.Int64FromUint32(pgno-libc.Uint32FromInt32(1))*(*TPager)(unsafe.Pointer(pPager)).FpageSize, **(**uintptr)(__ccgo_up(bp + 16)))
|
||||
}
|
||||
if **(**uintptr)(__ccgo_up(bp)) != 0 {
|
||||
**(**uintptr)(__ccgo_up(ppPage)) = **(**uintptr)(__ccgo_up(bp))
|
||||
return SQLITE_OK
|
||||
}
|
||||
}
|
||||
if rc != SQLITE_OK {
|
||||
**(**uintptr)(__ccgo_up(ppPage)) = uintptr(0)
|
||||
return rc
|
||||
}
|
||||
}
|
||||
return _getPageNormal(tls, pPager, pgno, ppPage, flags)
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** If pFd->sectorSize is non-zero when this function is called, it is a
|
||||
// ** no-op. Otherwise, the values of pFd->sectorSize and
|
||||
// ** pFd->deviceCharacteristics are set according to the file-system
|
||||
// ** characteristics.
|
||||
// **
|
||||
// ** There are two versions of this function. One for QNX and one for all
|
||||
// ** other systems.
|
||||
// */
|
||||
func _setDeviceCharacteristics(tls *libc.TLS, pFd uintptr) {
|
||||
if (*TunixFile)(unsafe.Pointer(pFd)).FsectorSize == 0 {
|
||||
/* Set the POWERSAFE_OVERWRITE flag if requested. */
|
||||
if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFd)).FctrlFlags)&int32(UNIXFILE_PSOW) != 0 {
|
||||
**(**int32)(__ccgo_up(pFd + 116)) |= int32(SQLITE_IOCAP_POWERSAFE_OVERWRITE)
|
||||
}
|
||||
**(**int32)(__ccgo_up(pFd + 116)) |= int32(SQLITE_IOCAP_SUBPAGE_READ)
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FsectorSize = int32(SQLITE_DEFAULT_SECTOR_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
// C documentation
|
||||
//
|
||||
// /*
|
||||
// ** If it is currently memory mapped, unmap file pFd.
|
||||
// */
|
||||
func _unixUnmapfile(tls *libc.TLS, pFd uintptr) {
|
||||
if (*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion != 0 {
|
||||
(*(*func(*libc.TLS, uintptr, Tsize_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(23)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion, libc.Uint64FromInt64((*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeActual))
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FpMapRegion = uintptr(0)
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSize = 0
|
||||
(*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeActual = 0
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user