[sqlite] Optimizer limitation with partial indexes

2020-02-11 Thread Jens Alfke
I'm running into a problem with partial indexes; apparently the query optimizer 
isn't smart enough.

I currently have indexes of the form
CREATE INDEX Index1 ON Table (expr1)
CREATE INDEX Index2 ON Table (expr2)
where expr1 and expr2 are expressions involving table columns.

The problematic queries are of the form
SELECT * FROM Table WHERE (expr1 > val1 OR expr2 > val2) AND expr3
Such a query correctly uses the above indexes — the EXPLAIN command shows it's 
using a multi-index OR combining two 'search table using index' loops.

If, however, I try to make the indexes smaller by changing them to
CREATE INDEX Index1 ON Table (expr1) WHERE expr3
CREATE INDEX Index2 ON Table (expr2) WHERE expr3
the query stops using the indexes effectively. It's reduced to doing 'scan 
table using index', i.e. O(n).

It looks like what happens is that the optimizer doesn't associate the "AND 
expr3" clause with the "expr1" and "expr2" comparisons. In other words, it 
doesn't realize that (A OR B) AND C is equivalent to (A AND C) OR (B AND C).

If this were a hand-written SELECT statement it would be easy to work around 
this, but it's not. It's the output of a query translator that generates SQL, 
and it can generate arbitrary queries with arbitrary combinations of operators.

I know the SQLite optimizer isn't a Mathematica-grade symbolic logic analyzer! 
But I'm wondering if in this case there's a way around this limitation?

—Jens
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Please increase the default for SQLITE_MAX_VARIABLE_NUMBER

2020-02-11 Thread J. King
On February 11, 2020 1:43:30 p.m. EST, Jens Alfke  wrote:
>I ran into this a few months ago. I ended up just biting the bullet and
>constructing a SQL statement by hand, concatenating comma-separated
>values inside an "IN (…)" expression.
>
>Yes, SQL injection is a danger. But if you're being bad in just one
>place, and you review that code, you can do this safely. SQLite's C API
>even has a function that escapes strings for you, and if you're not
>coding in C/C++, it's easy to write your own; basically
>   str ⟶ "'" + str.replace("'", "''") + "'"


Same here, for what it's worth. Since SQLite also has a 1M byte statement 
length limit I had my application embed terms once an IN() expression exceeded 
a certain number of terms, but used parameters always for string terms longer 
than a couple hundred bytes. 
-- 
J. King
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Please increase the default for SQLITE_MAX_VARIABLE_NUMBER

2020-02-11 Thread Richard Hipp
On 2/11/20, J. King  wrote:
> SQLite also has a 1M byte statement
> length limit ...

The statement length limit is yet another defense against mischief
caused by SQL injections.

-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Please increase the default for SQLITE_MAX_VARIABLE_NUMBER

2020-02-11 Thread Jens Alfke


> On Feb 11, 2020, at 2:10 AM, Digital Dog  wrote:
> 
> Thanks for enlighening again. It was just a thought. It seems it would be a
> lot of design and code to maintain the performance while preventing the
> original problem from happening. Not worth the trouble. But maybe
> increasing the parameter count to 10.000 would not hurt?

I ran into this a few months ago. I ended up just biting the bullet and 
constructing a SQL statement by hand, concatenating comma-separated values 
inside an "IN (…)" expression.

Yes, SQL injection is a danger. But if you're being bad in just one place, and 
you review that code, you can do this safely. SQLite's C API even has a 
function that escapes strings for you, and if you're not coding in C/C++, it's 
easy to write your own; basically
str ⟶ "'" + str.replace("'", "''") + "'"

—Jens
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Make sqlite3 database searchable on Mac OS X

2020-02-11 Thread Jens Alfke


> On Feb 10, 2020, at 8:10 PM, Peng Yu  wrote:
> 
> It seems that sqlite3 databases are not searchable by Spotlight on Mac
> OS X. Is there a way to make them searchable? Thanks.

How would Spotlight know what tables or columns to index? It doesn't understand 
what database schema mean, and it can't tell a column with user-visible text 
apart from one with internal info.

You can write a Spotlight indexer plugin for your application that recognizes 
your file type and scans your SQLite database to generate indexing data.

The downside is that Spotlight is fundamentally file-based: it considers a file 
to be a single entity. So when the user searches for something that's in your 
database, it will just show the database file as a hit. It won't show separate 
results for every row that matches.

(Some apps work around this by creating stub files in a hidden directory, one 
file per entity. All these files need to contain is a record identifier so your 
indexer can index the file by looking at the corresponding row in the database. 
Spotlight will return the stub file as a match; when your app is told to open 
it, it looks at its record ID and displays the corresponding database row in 
its UI. Apple Mail is an example; there's a directory somewhere in 
~/Library/Mail that contains an empty file for every email message.)

—Jens

PS: Disclaimer: My knowledge of Spotlight is years out of date; it may be that 
it's advanced since then.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to group this?

2020-02-11 Thread Bart Smissaert
Solved this now, nil to do with SQL, but just running a different search
(other value code and then you can ask for a secondary value and no need
anymore to find the matching pair).

RBS

On Mon, Feb 10, 2020 at 8:22 AM Bart Smissaert 
wrote:

> I fully agree with you, but I sofar I have no control over this data, I
> have it like I showed.
> As far as I can see there always will be a secondary value, but as you say
> I can't be sure.
> All this has to do with changing our clinical coding system from Read
> codes to Snomed.
> In the old setup there was the concept of a secondary value (systolic >>
> diastolic), but it
> seems in this particular case that is missing.
> I get the data by running searches (not SQL) on a clinical database and I
> have no control
> over this database.
> I will see if I can get better data with a different search, to do with
> blood pressure values.
>
> RBS
>
> On Mon, Feb 10, 2020 at 3:12 AM Richard Damon 
> wrote:
>
>> On 2/9/20 7:24 PM, Bart Smissaert wrote:
>> > ID ENTRY_DATE TERM NUMERIC_VALUE ROWID
>> > 
>> > 1308 15/Mar/2013 Systolic 127 701559
>> > 1308 15/Mar/2013 Diastolic 81 701568
>> > 1308 27/Jun/2013 Systolic 132 701562
>> > 1308 27/Jun/2013 Systolic 141 701563
>> > 1308 27/Jun/2013 Systolic 143 701564
>> > 1308 27/Jun/2013 Diastolic 82 701571
>> > 1308 27/Jun/2013 Diastolic 85 701572
>> > 1308 27/Jun/2013 Diastolic 94 701573
>> > 278975701 08/Mar/2018 Systolic 136 1583551
>> > 278975701 08/Mar/2018 Diastolic 99 1583591
>> > 278975701 04/Apr/2018 Systolic 119 1583552
>> > 278975701 04/Apr/2018 Systolic 124 1583553
>> > 278975701 04/Apr/2018 Systolic 130 1583554
>> > 278975701 04/Apr/2018 Diastolic 74 1583592
>> > 278975701 04/Apr/2018 Diastolic 75 1583593
>> > 278975701 04/Apr/2018 Diastolic 85 1583594
>> >
>> > These are systolic and diastolic blood pressures for 2 people with the
>> ID's
>> > 1308 and 278975701, ordered by ID asc, ENTRY_DATE asc, ROWID asc.
>> > Systolic and diastolic values are a pair and should be grouped in one
>> row.
>> > This is no problem if there is only one pair for one date, but sometimes
>> > there multiple pairs per date.
>> > The pairing should be based on the rowed if there are multiple pairs by
>> > date, so for ID 1308
>> > I should get:
>> >
>> > 127/81
>> > 132/82
>> > 141/85
>> > 143/94
>> >
>> > What should be the SQL to group like this?
>> >
>> > RBS
>>
>> To be honest, I think the problem is fundamentally badly designed. You
>> say pair the two readings by ROWID, but they of course don't have the
>> same ROWID, but you seem to be saying to pair them sorted by ROWID (1st
>> to 1st, 2nd to 2nd, etc). The fundamental problem is what if there isn't
>> the same number of each? You may say that you know that there will
>> always be the same number, but there is no constraint that forces this,
>> so any general program is going to have to deal with the possibility
>> (and at least throw out an error when it sees that).
>>
>>
>> --
>> Richard Damon
>>
>> ___
>> sqlite-users mailing list
>> sqlite-users@mailinglists.sqlite.org
>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>>
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] "INSERT INTO table AS alias" is invalid inside triggers

2020-02-11 Thread nomad
On Mon Feb 10, 2020 at 01:34:12AM +0100, no...@null.net wrote:
> I suspect I have found a parsing error in SQLite 3.30.1. Given the
> ...
> However if I wrap it inside a trigger:
> 
> CREATE TABLE t2(b INTEGER);
> 
> CREATE TRIGGER t2_ai
> AFTER INSERT ON t2
> FOR EACH ROW BEGIN
> 
> INSERT INTO t1 AS original (a) VALUES(NEW.b)
>   ON CONFLICT DO NOTHING;
> 
> END;
> 
> Then SQLite fails to prepare: near "AS": syntax error [for Statement
> "CREATE TRIGGER"]

I see the same behaviour with 3.31.1. Could I ask the devs if this is
likely to be fixed at some point or will remain as is?

On a related note and perhaps more generally interesting, I find the
UPSERT mechanism quite useful for updating specific multiple rows in a
specific order:

INSERT INTO
table
SELECT
columns
FROM
table
LEFT JOIN
other_table
ON
join_condition
WHERE
where_condition
ORDER BY
order_condition
ON CONFLICT DO UPDATE SET
x,y,z = (values or some other query)

Previously I have used temporary tables and complicated recursive
triggers to achieve what the above appears to do. I would be very
interested in hearing from those that know better if the above is
reliable and functions the way I think it does.  It is certainly much
easier to understand and I assume more efficient. 

Some systems apparently support an UPDATE ... JOIN syntax but I find
the SQLite UPSERT implementation more powerful because of the ORDER BY
possibility.

-- 
Mark Lawrence
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Please increase the default for SQLITE_MAX_VARIABLE_NUMBER

2020-02-11 Thread Digital Dog
On Mon, Feb 10, 2020 at 9:03 PM Richard Hipp  wrote:

> On 2/10/20, Digital Dog  wrote:
> > Maybe they should be treated as a
> > dictionary/hashtable/linked list or similar?
> >
>
>

> Parameter look-ups are on the critical path.  How much performance are
> you willing to give up in order to have parameters with larger
> numbers?
>
>
Thanks for enlighening again. It was just a thought. It seems it would be a
lot of design and code to maintain the performance while preventing the
original problem from happening. Not worth the trouble. But maybe
increasing the parameter count to 10.000 would not hurt?


> --
> D. Richard Hipp
> d...@sqlite.org
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to group this?

2020-02-11 Thread Jean-Luc Hainaut

On 11/02/2020 01:35, Simon Slavin wrote:

I don't think that creating an index on a view actually works, does it?
You're right.  What was I thinking ?  Maybe I've used another implementation of 
SQL that it does work on.  Thanks for picking me up on it.


You are right, SQL Server allows you to create an index on a view.

J-L Hainaut


___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users