extralite 1.12 → 1.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +64 -28
- data/Rakefile +1 -1
- data/bin/update_sqlite_source +26 -0
- data/ext/extralite/common.c +347 -0
- data/ext/extralite/database.c +385 -0
- data/ext/extralite/extralite.h +59 -0
- data/ext/extralite/extralite_ext.c +4 -2
- data/ext/extralite/prepared_statement.c +238 -0
- data/ext/extralite/sqlite3.c +5568 -3801
- data/ext/extralite/sqlite3.h +341 -31
- data/lib/extralite/version.rb +1 -1
- data/test/perf_hash.rb +1 -1
- data/test/perf_prepared.rb +64 -0
- data/test/test_prepared_statement.rb +165 -0
- metadata +9 -3
- data/ext/extralite/extralite.c +0 -702
data/ext/extralite/sqlite3.h
CHANGED
@@ -146,9 +146,9 @@ extern "C" {
|
|
146
146
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
147
147
|
** [sqlite_version()] and [sqlite_source_id()].
|
148
148
|
*/
|
149
|
-
#define SQLITE_VERSION "3.
|
150
|
-
#define SQLITE_VERSION_NUMBER
|
151
|
-
#define SQLITE_SOURCE_ID "2022-
|
149
|
+
#define SQLITE_VERSION "3.38.0"
|
150
|
+
#define SQLITE_VERSION_NUMBER 3038000
|
151
|
+
#define SQLITE_SOURCE_ID "2022-02-22 18:58:40 40fa792d359f84c3b9e9d6623743e1a59826274e221df1bde8f47086968a1bab"
|
152
152
|
|
153
153
|
/*
|
154
154
|
** CAPI3REF: Run-Time Library Version Numbers
|
@@ -566,7 +566,7 @@ SQLITE_API int sqlite3_exec(
|
|
566
566
|
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
|
567
567
|
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
|
568
568
|
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
|
569
|
-
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
|
569
|
+
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
|
570
570
|
|
571
571
|
/*
|
572
572
|
** CAPI3REF: Flags For File Open Operations
|
@@ -3824,13 +3824,14 @@ SQLITE_API void sqlite3_free_filename(char*);
|
|
3824
3824
|
** sqlite3_extended_errcode() might change with each API call.
|
3825
3825
|
** Except, there are some interfaces that are guaranteed to never
|
3826
3826
|
** change the value of the error code. The error-code preserving
|
3827
|
-
** interfaces
|
3827
|
+
** interfaces include the following:
|
3828
3828
|
**
|
3829
3829
|
** <ul>
|
3830
3830
|
** <li> sqlite3_errcode()
|
3831
3831
|
** <li> sqlite3_extended_errcode()
|
3832
3832
|
** <li> sqlite3_errmsg()
|
3833
3833
|
** <li> sqlite3_errmsg16()
|
3834
|
+
** <li> sqlite3_error_offset()
|
3834
3835
|
** </ul>
|
3835
3836
|
**
|
3836
3837
|
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
|
@@ -3845,6 +3846,13 @@ SQLITE_API void sqlite3_free_filename(char*);
|
|
3845
3846
|
** ^(Memory to hold the error message string is managed internally
|
3846
3847
|
** and must not be freed by the application)^.
|
3847
3848
|
**
|
3849
|
+
** ^If the most recent error references a specific token in the input
|
3850
|
+
** SQL, the sqlite3_error_offset() interface returns the byte offset
|
3851
|
+
** of the start of that token. ^The byte offset returned by
|
3852
|
+
** sqlite3_error_offset() assumes that the input SQL is UTF8.
|
3853
|
+
** ^If the most recent error does not reference a specific token in the input
|
3854
|
+
** SQL, then the sqlite3_error_offset() function returns -1.
|
3855
|
+
**
|
3848
3856
|
** When the serialized [threading mode] is in use, it might be the
|
3849
3857
|
** case that a second error occurs on a separate thread in between
|
3850
3858
|
** the time of the first error and the call to these interfaces.
|
@@ -3864,6 +3872,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
|
|
3864
3872
|
SQLITE_API const char *sqlite3_errmsg(sqlite3*);
|
3865
3873
|
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
|
3866
3874
|
SQLITE_API const char *sqlite3_errstr(int);
|
3875
|
+
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
|
3867
3876
|
|
3868
3877
|
/*
|
3869
3878
|
** CAPI3REF: Prepared Statement Object
|
@@ -4275,6 +4284,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
|
|
4275
4284
|
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
|
4276
4285
|
** read-only no-op if the table already exists, but
|
4277
4286
|
** sqlite3_stmt_readonly() still returns false for such a statement.
|
4287
|
+
**
|
4288
|
+
** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
|
4289
|
+
** statement, then sqlite3_stmt_readonly(X) returns the same value as
|
4290
|
+
** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
|
4278
4291
|
*/
|
4279
4292
|
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
4280
4293
|
|
@@ -4343,6 +4356,8 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
|
|
4343
4356
|
**
|
4344
4357
|
** ^The sqlite3_value objects that are passed as parameters into the
|
4345
4358
|
** implementation of [application-defined SQL functions] are protected.
|
4359
|
+
** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
|
4360
|
+
** are protected.
|
4346
4361
|
** ^The sqlite3_value object returned by
|
4347
4362
|
** [sqlite3_column_value()] is unprotected.
|
4348
4363
|
** Unprotected sqlite3_value objects may only be used as arguments
|
@@ -7122,24 +7137,56 @@ struct sqlite3_index_info {
|
|
7122
7137
|
**
|
7123
7138
|
** These macros define the allowed values for the
|
7124
7139
|
** [sqlite3_index_info].aConstraint[].op field. Each value represents
|
7125
|
-
** an operator that is part of a constraint term in the
|
7140
|
+
** an operator that is part of a constraint term in the WHERE clause of
|
7126
7141
|
** a query that uses a [virtual table].
|
7127
|
-
|
7128
|
-
|
7129
|
-
|
7130
|
-
|
7131
|
-
|
7132
|
-
|
7133
|
-
|
7134
|
-
|
7135
|
-
|
7136
|
-
|
7137
|
-
|
7138
|
-
|
7139
|
-
|
7140
|
-
|
7141
|
-
|
7142
|
-
|
7142
|
+
**
|
7143
|
+
** ^The left-hand operand of the operator is given by the corresponding
|
7144
|
+
** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
|
7145
|
+
** operand is the rowid.
|
7146
|
+
** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
|
7147
|
+
** operators have no left-hand operand, and so for those operators the
|
7148
|
+
** corresponding aConstraint[].iColumn is meaningless and should not be
|
7149
|
+
** used.
|
7150
|
+
**
|
7151
|
+
** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
|
7152
|
+
** value 255 are reserved to represent functions that are overloaded
|
7153
|
+
** by the [xFindFunction|xFindFunction method] of the virtual table
|
7154
|
+
** implementation.
|
7155
|
+
**
|
7156
|
+
** The right-hand operands for each constraint might be accessible using
|
7157
|
+
** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
|
7158
|
+
** operand is only available if it appears as a single constant literal
|
7159
|
+
** in the input SQL. If the right-hand operand is another column or an
|
7160
|
+
** expression (even a constant expression) or a parameter, then the
|
7161
|
+
** sqlite3_vtab_rhs_value() probably will not be able to extract it.
|
7162
|
+
** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
|
7163
|
+
** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
|
7164
|
+
** and hence calls to sqlite3_vtab_rhs_value() for those operators will
|
7165
|
+
** always return SQLITE_NOTFOUND.
|
7166
|
+
**
|
7167
|
+
** The collating sequence to be used for comparison can be found using
|
7168
|
+
** the [sqlite3_vtab_collation()] interface. For most real-world virtual
|
7169
|
+
** tables, the collating sequence of constraints does not matter (for example
|
7170
|
+
** because the constraints are numeric) and so the sqlite3_vtab_collation()
|
7171
|
+
** interface is no commonly needed.
|
7172
|
+
*/
|
7173
|
+
#define SQLITE_INDEX_CONSTRAINT_EQ 2
|
7174
|
+
#define SQLITE_INDEX_CONSTRAINT_GT 4
|
7175
|
+
#define SQLITE_INDEX_CONSTRAINT_LE 8
|
7176
|
+
#define SQLITE_INDEX_CONSTRAINT_LT 16
|
7177
|
+
#define SQLITE_INDEX_CONSTRAINT_GE 32
|
7178
|
+
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
|
7179
|
+
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
|
7180
|
+
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
|
7181
|
+
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
|
7182
|
+
#define SQLITE_INDEX_CONSTRAINT_NE 68
|
7183
|
+
#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
|
7184
|
+
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
7185
|
+
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
7186
|
+
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
7187
|
+
#define SQLITE_INDEX_CONSTRAINT_LIMIT 73
|
7188
|
+
#define SQLITE_INDEX_CONSTRAINT_OFFSET 74
|
7189
|
+
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
|
7143
7190
|
|
7144
7191
|
/*
|
7145
7192
|
** CAPI3REF: Register A Virtual Table Implementation
|
@@ -7168,7 +7215,7 @@ struct sqlite3_index_info {
|
|
7168
7215
|
** destructor.
|
7169
7216
|
**
|
7170
7217
|
** ^If the third parameter (the pointer to the sqlite3_module object) is
|
7171
|
-
** NULL then no new module is
|
7218
|
+
** NULL then no new module is created and any existing modules with the
|
7172
7219
|
** same name are dropped.
|
7173
7220
|
**
|
7174
7221
|
** See also: [sqlite3_drop_modules()]
|
@@ -7944,7 +7991,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
|
7944
7991
|
#define SQLITE_TESTCTRL_SEEK_COUNT 30
|
7945
7992
|
#define SQLITE_TESTCTRL_TRACEFLAGS 31
|
7946
7993
|
#define SQLITE_TESTCTRL_TUNE 32
|
7947
|
-
#define
|
7994
|
+
#define SQLITE_TESTCTRL_LOGEST 33
|
7995
|
+
#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */
|
7948
7996
|
|
7949
7997
|
/*
|
7950
7998
|
** CAPI3REF: SQL Keyword Checking
|
@@ -8467,6 +8515,16 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
|
8467
8515
|
** The counter is incremented on the first [sqlite3_step()] call of each
|
8468
8516
|
** cycle.
|
8469
8517
|
**
|
8518
|
+
** [[SQLITE_STMTSTATUS_FILTER_MISS]]
|
8519
|
+
** [[SQLITE_STMTSTATUS_FILTER HIT]]
|
8520
|
+
** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br>
|
8521
|
+
** SQLITE_STMTSTATUS_FILTER_MISS</dt>
|
8522
|
+
** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join
|
8523
|
+
** step was bypassed because a Bloom filter returned not-found. The
|
8524
|
+
** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of
|
8525
|
+
** times that the Bloom filter returned a find, and thus the join step
|
8526
|
+
** had to be processed as normal.
|
8527
|
+
**
|
8470
8528
|
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
|
8471
8529
|
** <dd>^This is the approximate number of bytes of heap memory
|
8472
8530
|
** used to store the prepared statement. ^This value is not actually
|
@@ -8481,6 +8539,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
|
8481
8539
|
#define SQLITE_STMTSTATUS_VM_STEP 4
|
8482
8540
|
#define SQLITE_STMTSTATUS_REPREPARE 5
|
8483
8541
|
#define SQLITE_STMTSTATUS_RUN 6
|
8542
|
+
#define SQLITE_STMTSTATUS_FILTER_MISS 7
|
8543
|
+
#define SQLITE_STMTSTATUS_FILTER_HIT 8
|
8484
8544
|
#define SQLITE_STMTSTATUS_MEMUSED 99
|
8485
8545
|
|
8486
8546
|
/*
|
@@ -9449,19 +9509,269 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
|
|
9449
9509
|
|
9450
9510
|
/*
|
9451
9511
|
** CAPI3REF: Determine The Collation For a Virtual Table Constraint
|
9512
|
+
** METHOD: sqlite3_index_info
|
9452
9513
|
**
|
9453
9514
|
** This function may only be called from within a call to the [xBestIndex]
|
9454
|
-
** method of a [virtual table].
|
9515
|
+
** method of a [virtual table]. This function returns a pointer to a string
|
9516
|
+
** that is the name of the appropriate collation sequence to use for text
|
9517
|
+
** comparisons on the constraint identified by its arguments.
|
9455
9518
|
**
|
9456
|
-
** The first argument must be the
|
9457
|
-
** first parameter to the xBestIndex() method. The second argument
|
9458
|
-
** an index into the aConstraint[] array belonging to the
|
9459
|
-
** structure passed to xBestIndex.
|
9460
|
-
**
|
9461
|
-
**
|
9519
|
+
** The first argument must be the pointer to the [sqlite3_index_info] object
|
9520
|
+
** that is the first parameter to the xBestIndex() method. The second argument
|
9521
|
+
** must be an index into the aConstraint[] array belonging to the
|
9522
|
+
** sqlite3_index_info structure passed to xBestIndex.
|
9523
|
+
**
|
9524
|
+
** Important:
|
9525
|
+
** The first parameter must be the same pointer that is passed into the
|
9526
|
+
** xBestMethod() method. The first parameter may not be a pointer to a
|
9527
|
+
** different [sqlite3_index_info] object, even an exact copy.
|
9528
|
+
**
|
9529
|
+
** The return value is computed as follows:
|
9530
|
+
**
|
9531
|
+
** <ol>
|
9532
|
+
** <li><p> If the constraint comes from a WHERE clause expression that contains
|
9533
|
+
** a [COLLATE operator], then the name of the collation specified by
|
9534
|
+
** that COLLATE operator is returned.
|
9535
|
+
** <li><p> If there is no COLLATE operator, but the column that is the subject
|
9536
|
+
** of the constraint specifies an alternative collating sequence via
|
9537
|
+
** a [COLLATE clause] on the column definition within the CREATE TABLE
|
9538
|
+
** statement that was passed into [sqlite3_declare_vtab()], then the
|
9539
|
+
** name of that alternative collating sequence is returned.
|
9540
|
+
** <li><p> Otherwise, "BINARY" is returned.
|
9541
|
+
** </ol>
|
9462
9542
|
*/
|
9463
9543
|
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
|
9464
9544
|
|
9545
|
+
/*
|
9546
|
+
** CAPI3REF: Determine if a virtual table query is DISTINCT
|
9547
|
+
** METHOD: sqlite3_index_info
|
9548
|
+
**
|
9549
|
+
** This API may only be used from within an [xBestIndex|xBestIndex method]
|
9550
|
+
** of a [virtual table] implementation. The result of calling this
|
9551
|
+
** interface from outside of xBestIndex() is undefined and probably harmful.
|
9552
|
+
**
|
9553
|
+
** ^The sqlite3_vtab_distinct() interface returns an integer that is
|
9554
|
+
** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct()
|
9555
|
+
** gives the virtual table additional information about how the query
|
9556
|
+
** planner wants the output to be ordered. As long as the virtual table
|
9557
|
+
** can meet the ordering requirements of the query planner, it may set
|
9558
|
+
** the "orderByConsumed" flag.
|
9559
|
+
**
|
9560
|
+
** <ol><li value="0"><p>
|
9561
|
+
** ^If the sqlite3_vtab_distinct() interface returns 0, that means
|
9562
|
+
** that the query planner needs the virtual table to return all rows in the
|
9563
|
+
** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
|
9564
|
+
** [sqlite3_index_info] object. This is the default expectation. If the
|
9565
|
+
** virtual table outputs all rows in sorted order, then it is always safe for
|
9566
|
+
** the xBestIndex method to set the "orderByConsumed" flag, regardless of
|
9567
|
+
** the return value from sqlite3_vtab_distinct().
|
9568
|
+
** <li value="1"><p>
|
9569
|
+
** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
|
9570
|
+
** that the query planner does not need the rows to be returned in sorted order
|
9571
|
+
** as long as all rows with the same values in all columns identified by the
|
9572
|
+
** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
|
9573
|
+
** is doing a GROUP BY.
|
9574
|
+
** <li value="2"><p>
|
9575
|
+
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
|
9576
|
+
** that the query planner does not need the rows returned in any particular
|
9577
|
+
** order, as long as rows with the same values in all "aOrderBy" columns
|
9578
|
+
** are adjacent.)^ ^(Furthermore, only a single row for each particular
|
9579
|
+
** combination of values in the columns identified by the "aOrderBy" field
|
9580
|
+
** needs to be returned.)^ ^It is always ok for two or more rows with the same
|
9581
|
+
** values in all "aOrderBy" columns to be returned, as long as all such rows
|
9582
|
+
** are adjacent. ^The virtual table may, if it chooses, omit extra rows
|
9583
|
+
** that have the same value for all columns identified by "aOrderBy".
|
9584
|
+
** ^However omitting the extra rows is optional.
|
9585
|
+
** This mode is used for a DISTINCT query.
|
9586
|
+
** </ol>
|
9587
|
+
**
|
9588
|
+
** ^For the purposes of comparing virtual table output values to see if the
|
9589
|
+
** values are same value for sorting purposes, two NULL values are considered
|
9590
|
+
** to be the same. In other words, the comparison operator is "IS"
|
9591
|
+
** (or "IS NOT DISTINCT FROM") and not "==".
|
9592
|
+
**
|
9593
|
+
** If a virtual table implementation is unable to meet the requirements
|
9594
|
+
** specified above, then it must not set the "orderByConsumed" flag in the
|
9595
|
+
** [sqlite3_index_info] object or an incorrect answer may result.
|
9596
|
+
**
|
9597
|
+
** ^A virtual table implementation is always free to return rows in any order
|
9598
|
+
** it wants, as long as the "orderByConsumed" flag is not set. ^When the
|
9599
|
+
** the "orderByConsumed" flag is unset, the query planner will add extra
|
9600
|
+
** [bytecode] to ensure that the final results returned by the SQL query are
|
9601
|
+
** ordered correctly. The use of the "orderByConsumed" flag and the
|
9602
|
+
** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful
|
9603
|
+
** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed"
|
9604
|
+
** flag might help queries against a virtual table to run faster. Being
|
9605
|
+
** overly aggressive and setting the "orderByConsumed" flag when it is not
|
9606
|
+
** valid to do so, on the other hand, might cause SQLite to return incorrect
|
9607
|
+
** results.
|
9608
|
+
*/
|
9609
|
+
SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
|
9610
|
+
|
9611
|
+
/*
|
9612
|
+
** CAPI3REF: Identify and handle IN constraints in xBestIndex
|
9613
|
+
**
|
9614
|
+
** This interface may only be used from within an
|
9615
|
+
** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
|
9616
|
+
** The result of invoking this interface from any other context is
|
9617
|
+
** undefined and probably harmful.
|
9618
|
+
**
|
9619
|
+
** ^(A constraint on a virtual table of the form
|
9620
|
+
** "[IN operator|column IN (...)]" is
|
9621
|
+
** communicated to the xBestIndex method as a
|
9622
|
+
** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
|
9623
|
+
** this constraint, it must set the corresponding
|
9624
|
+
** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
|
9625
|
+
** the usual mode of handling IN operators, SQLite generates [bytecode]
|
9626
|
+
** that invokes the [xFilter|xFilter() method] once for each value
|
9627
|
+
** on the right-hand side of the IN operator.)^ Thus the virtual table
|
9628
|
+
** only sees a single value from the right-hand side of the IN operator
|
9629
|
+
** at a time.
|
9630
|
+
**
|
9631
|
+
** In some cases, however, it would be advantageous for the virtual
|
9632
|
+
** table to see all values on the right-hand of the IN operator all at
|
9633
|
+
** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
|
9634
|
+
**
|
9635
|
+
** <ol>
|
9636
|
+
** <li><p>
|
9637
|
+
** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
|
9638
|
+
** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
|
9639
|
+
** is an [IN operator] that can be processed all at once. ^In other words,
|
9640
|
+
** sqlite3_vtab_in() with -1 in the third argument is a mechanism
|
9641
|
+
** by which the virtual table can ask SQLite if all-at-once processing
|
9642
|
+
** of the IN operator is even possible.
|
9643
|
+
**
|
9644
|
+
** <li><p>
|
9645
|
+
** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
|
9646
|
+
** to SQLite that the virtual table does or does not want to process
|
9647
|
+
** the IN operator all-at-once, respectively. ^Thus when the third
|
9648
|
+
** parameter (F) is non-negative, this interface is the mechanism by
|
9649
|
+
** which the virtual table tells SQLite how it wants to process the
|
9650
|
+
** IN operator.
|
9651
|
+
** </ol>
|
9652
|
+
**
|
9653
|
+
** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
|
9654
|
+
** within the same xBestIndex method call. ^For any given P,N pair,
|
9655
|
+
** the return value from sqlite3_vtab_in(P,N,F) will always be the same
|
9656
|
+
** within the same xBestIndex call. ^If the interface returns true
|
9657
|
+
** (non-zero), that means that the constraint is an IN operator
|
9658
|
+
** that can be processed all-at-once. ^If the constraint is not an IN
|
9659
|
+
** operator or cannot be processed all-at-once, then the interface returns
|
9660
|
+
** false.
|
9661
|
+
**
|
9662
|
+
** ^(All-at-once processing of the IN operator is selected if both of the
|
9663
|
+
** following conditions are met:
|
9664
|
+
**
|
9665
|
+
** <ol>
|
9666
|
+
** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
|
9667
|
+
** integer. This is how the virtual table tells SQLite that it wants to
|
9668
|
+
** use the N-th constraint.
|
9669
|
+
**
|
9670
|
+
** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
|
9671
|
+
** non-negative had F>=1.
|
9672
|
+
** </ol>)^
|
9673
|
+
**
|
9674
|
+
** ^If either or both of the conditions above are false, then SQLite uses
|
9675
|
+
** the traditional one-at-a-time processing strategy for the IN constraint.
|
9676
|
+
** ^If both conditions are true, then the argvIndex-th parameter to the
|
9677
|
+
** xFilter method will be an [sqlite3_value] that appears to be NULL,
|
9678
|
+
** but which can be passed to [sqlite3_vtab_in_first()] and
|
9679
|
+
** [sqlite3_vtab_in_next()] to find all values on the right-hand side
|
9680
|
+
** of the IN constraint.
|
9681
|
+
*/
|
9682
|
+
SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
|
9683
|
+
|
9684
|
+
/*
|
9685
|
+
** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
|
9686
|
+
**
|
9687
|
+
** These interfaces are only useful from within the
|
9688
|
+
** [xFilter|xFilter() method] of a [virtual table] implementation.
|
9689
|
+
** The result of invoking these interfaces from any other context
|
9690
|
+
** is undefined and probably harmful.
|
9691
|
+
**
|
9692
|
+
** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
|
9693
|
+
** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
|
9694
|
+
** xFilter method which invokes these routines, and specifically
|
9695
|
+
** a parameter that was previously selected for all-at-once IN constraint
|
9696
|
+
** processing use the [sqlite3_vtab_in()] interface in the
|
9697
|
+
** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
|
9698
|
+
** an xFilter argument that was selected for all-at-once IN constraint
|
9699
|
+
** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
|
9700
|
+
** exhibit some other undefined or harmful behavior.
|
9701
|
+
**
|
9702
|
+
** ^(Use these routines to access all values on the right-hand side
|
9703
|
+
** of the IN constraint using code like the following:
|
9704
|
+
**
|
9705
|
+
** <blockquote><pre>
|
9706
|
+
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
|
9707
|
+
** rc==SQLITE_OK && pVal
|
9708
|
+
** rc=sqlite3_vtab_in_next(pList, &pVal)
|
9709
|
+
** ){
|
9710
|
+
** // do something with pVal
|
9711
|
+
** }
|
9712
|
+
** if( rc!=SQLITE_OK ){
|
9713
|
+
** // an error has occurred
|
9714
|
+
** }
|
9715
|
+
** </pre></blockquote>)^
|
9716
|
+
**
|
9717
|
+
** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
|
9718
|
+
** routines return SQLITE_OK and set *P to point to the first or next value
|
9719
|
+
** on the RHS of the IN constraint. ^If there are no more values on the
|
9720
|
+
** right hand side of the IN constraint, then *P is set to NULL and these
|
9721
|
+
** routines return [SQLITE_DONE]. ^The return value might be
|
9722
|
+
** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
|
9723
|
+
**
|
9724
|
+
** The *ppOut values returned by these routines are only valid until the
|
9725
|
+
** next call to either of these routines or until the end of the xFilter
|
9726
|
+
** method from which these routines were called. If the virtual table
|
9727
|
+
** implementation needs to retain the *ppOut values for longer, it must make
|
9728
|
+
** copies. The *ppOut values are [protected sqlite3_value|protected].
|
9729
|
+
*/
|
9730
|
+
SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
|
9731
|
+
SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
|
9732
|
+
|
9733
|
+
/*
|
9734
|
+
** CAPI3REF: Constraint values in xBestIndex()
|
9735
|
+
** METHOD: sqlite3_index_info
|
9736
|
+
**
|
9737
|
+
** This API may only be used from within the [xBestIndex|xBestIndex method]
|
9738
|
+
** of a [virtual table] implementation. The result of calling this interface
|
9739
|
+
** from outside of an xBestIndex method are undefined and probably harmful.
|
9740
|
+
**
|
9741
|
+
** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
|
9742
|
+
** the [xBestIndex] method of a [virtual table] implementation, with P being
|
9743
|
+
** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
|
9744
|
+
** J being a 0-based index into P->aConstraint[], then this routine
|
9745
|
+
** attempts to set *V to the value of the right-hand operand of
|
9746
|
+
** that constraint if the right-hand operand is known. ^If the
|
9747
|
+
** right-hand operand is not known, then *V is set to a NULL pointer.
|
9748
|
+
** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
|
9749
|
+
** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
|
9750
|
+
** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
|
9751
|
+
** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
|
9752
|
+
** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
|
9753
|
+
** something goes wrong.
|
9754
|
+
**
|
9755
|
+
** The sqlite3_vtab_rhs_value() interface is usually only successful if
|
9756
|
+
** the right-hand operand of a constraint is a literal value in the original
|
9757
|
+
** SQL statement. If the right-hand operand is an expression or a reference
|
9758
|
+
** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
|
9759
|
+
** will probably return [SQLITE_NOTFOUND].
|
9760
|
+
**
|
9761
|
+
** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
|
9762
|
+
** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
|
9763
|
+
** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
|
9764
|
+
**
|
9765
|
+
** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
|
9766
|
+
** and remains valid for the duration of the xBestIndex method call.
|
9767
|
+
** ^When xBestIndex returns, the sqlite3_value object returned by
|
9768
|
+
** sqlite3_vtab_rhs_value() is automatically deallocated.
|
9769
|
+
**
|
9770
|
+
** The "_rhs_" in the name of this routine is an appreviation for
|
9771
|
+
** "Right-Hand Side".
|
9772
|
+
*/
|
9773
|
+
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
|
9774
|
+
|
9465
9775
|
/*
|
9466
9776
|
** CAPI3REF: Conflict resolution modes
|
9467
9777
|
** KEYWORDS: {conflict resolution mode}
|
data/lib/extralite/version.rb
CHANGED
data/test/perf_hash.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
|
5
|
+
gemfile do
|
6
|
+
source 'https://rubygems.org'
|
7
|
+
gem 'extralite', path: '..'
|
8
|
+
gem 'sqlite3'
|
9
|
+
gem 'benchmark-ips'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'benchmark/ips'
|
13
|
+
require 'fileutils'
|
14
|
+
|
15
|
+
DB_PATH = '/tmp/extralite_sqlite3_perf.db'
|
16
|
+
|
17
|
+
def prepare_database(count)
|
18
|
+
FileUtils.rm(DB_PATH) rescue nil
|
19
|
+
db = Extralite::Database.new(DB_PATH)
|
20
|
+
db.query('create table foo ( a integer primary key, b text )')
|
21
|
+
db.query('begin')
|
22
|
+
count.times { db.query('insert into foo (b) values (?)', "hello#{rand(1000)}" )}
|
23
|
+
db.query('commit')
|
24
|
+
end
|
25
|
+
|
26
|
+
def sqlite3_prepare
|
27
|
+
db = SQLite3::Database.new(DB_PATH, :results_as_hash => true)
|
28
|
+
db.prepare('select * from foo')
|
29
|
+
end
|
30
|
+
|
31
|
+
def sqlite3_run(stmt, count)
|
32
|
+
# db = SQLite3::Database.new(DB_PATH, :results_as_hash => true)
|
33
|
+
results = stmt.execute.to_a
|
34
|
+
raise unless results.size == count
|
35
|
+
end
|
36
|
+
|
37
|
+
def extralite_prepare
|
38
|
+
db = Extralite::Database.new(DB_PATH)
|
39
|
+
db.prepare('select * from foo')
|
40
|
+
end
|
41
|
+
|
42
|
+
def extralite_run(stmt, count)
|
43
|
+
# db = Extralite::Database.new(DB_PATH)
|
44
|
+
results = stmt.query
|
45
|
+
raise unless results.size == count
|
46
|
+
end
|
47
|
+
|
48
|
+
[10, 1000, 100000].each do |c|
|
49
|
+
puts; puts; puts "Record count: #{c}"
|
50
|
+
|
51
|
+
prepare_database(c)
|
52
|
+
|
53
|
+
sqlite3_stmt = sqlite3_prepare
|
54
|
+
extralite_stmt = extralite_prepare
|
55
|
+
|
56
|
+
Benchmark.ips do |x|
|
57
|
+
x.config(:time => 3, :warmup => 1)
|
58
|
+
|
59
|
+
x.report("sqlite3") { sqlite3_run(sqlite3_stmt, c) }
|
60
|
+
x.report("extralite") { extralite_run(extralite_stmt, c) }
|
61
|
+
|
62
|
+
x.compare!
|
63
|
+
end
|
64
|
+
end
|