Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or functionalequivalent?

2013-05-07 Thread James K. Lowden
On Tue, 7 May 2013 18:54:48 +0200
Hick Gunter  wrote:

> The problem with checking the ID of the last inserted row is that the
> abstraction for checking it cannot reasonably know that a query is an
> insert;
> 
> Essentially doing a string match for "INSERT " in the query executed
> would be a leaky abstraction.

Ah.  When you said "leak", I thought you meant memory leak.  

I have to tell you I don't have much sympathy for the "problem" you
propose to solve.  I don't understand the purpose of an application
that 

1.  issues a query not knowing whether it's an INSERT, and
2.  needs to know the row id of the inserted row

I can tell you for sure that 

> "INSERT INTO b (a) VALUES (c)" => the ID of the inserted row

won't work, because more than one row might have been inserted.  

More important, though: the problem you're trying to solve is created
by the way you're going about it.   Let's look at the SQL.  

> CREATE TABLE t1 ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, d
> TEXT );

That table has no natural key.  It has an id column declared as a key,
but the user-provided data -- column d -- is indistinguishably
duplicated. If the user provides "a" three times, and the DBMS generates
meaningless numbers to distinguish them.  At most, the user knows he has
three a's, and that the computer -- for reasons of its own -- has
assigned them numbers.  

The table also presents the application programmer with problems beyond
those you're seeking to address, e.g.

1.  How to delete one of the 'a' rows?  Just pick the first one?  
2.  How to change one of the 'a' rows to 'b'?  Pick one?  
3.  How to limit the number of 'a' rows?  A trigger?  

Now consider a better design:

CREATE TABLE t1 ( 
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
q INTEGER, 
d TEXT, 
unique(d)
);

where column q is the count of d, and id remains an auto-generated
number (for your sake, perhaps for efficiency). 

To retrieve the id (please observe the use of single quotes):

insert into t1 (q,d) values (1,'a'), (1,'b');
select id, d from t1 where d in ('a', 'b');

You will note that the three questions I posed are also easily
answered.  

That is how the problem you propose to solve is conventionally
solved.  Of course, it presupposes a natural key and that the
application retains the values it inserted for which it wants the
DBMS-generated ids.  In other words, it uses the system according to
its strengths, as it was designed to be used.  

In short, the whole problem of discovering the generated row id
disappears with judicious (one might say "correct") use of the DBMS.  It
definitely does not warrant an API change.  

Orthogonal to the row-id issue is the "what kind of query is it?"
question.  It's easy to imagine uses for information from the parser.
A general solution would be an API function to return the tokenized
query; the caller could search the tree for the operators/keywords of
interest.  

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


Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or functionalequivalent?

2013-05-07 Thread Nico Williams
On Tue, May 7, 2013 at 7:14 AM, Mikael  wrote:
> A generalized way of getting if an ID was inserted on the last performed
> query and if so which, is of value for instance when inserting a row into a
> table with an AUTOINCREMENT key e.g.

This can get tricky if you have BEFORE INSERT triggers that insert
rows in other tables and then RAISE(IGNORE).  Of if the table is a
VIEW with an INSTEAD OF INSERT trigger that does something similar.  A
last rowid function might... return nothing (inserts/updates done in
trigger bodies not exposed) or it might show you the last rowid
touched by the trigger -- either way it's not what you'd want.

If the one INSERT turns into any number of inserts (or updates! or
deletes!) other than 1, then what?

For me the best thing to do here is to just do your INSERTs and
UPDATEs and then SELECT to find the results.  If you must then do a
SELECT after each INSERT/UPDATE to find out what you got.  This works
whether there's triggers or not.

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


Re: [sqlite] Suspected bug in SELECT EXCEPT ORDER COLLATE

2013-05-07 Thread Nico Williams
On Mon, May 6, 2013 at 9:39 PM, Keith Medcalf  wrote:
>> I read this:
>>
>> SELECT a FROM t1 EXCEPT SELECT a FROM t2 ORDER BY a;
>>
>> as saying "select all a from t1 that are not in t2, *then* order that
>> by that a".
>
> No, that is not what it says, actually.  The translation of your statement 
> into SQL Declarative would be:

Certainly if you look at SQL books and the SQLite docs you get the
impression that the ordering term applies to the final result set.
There's no point ordering, say, correlated sub-queries.  Some RDBMSes
seem to allow it, though I'm not sure what that means if anything
outside the context of group_concat()-like aggregate functions --
perhaps it works only as a hint to the query planner that ordering an
intermediate result set will net better performance?

In any case, SQLite3 only allows ORDER BY at the very end of a select,
not in sub-selects.  And it applies the ORDER BY to the result set.
It seems outrageous to think that a COLLATE clause on ORDER BY should
be applied transitively to anything other than ordering the final set
unless the result is guaranteed to be the same.  At the very least
it's weird and surprising.

There *is* a point to ordering sets for aggregate function
computation, because some aggregate functions are produce different
results for the same input set in different orders.  E.g.,
group_concat().  But this is a different story.  Outside of such
aggregate functions there's no point to ordering anything but the
final result set.

> select a from t1 where not exists (select * from t2 where a = t1.a) order by 
> a;

You can rewrite EXCEPT that way.  That doesn't mean that the first
statement is not equivalent to this one; on the contrary, you can
rewrite that way because the result is equivalent to the first.  And
this might well be logical proof that there's bug here!  But I'm
probably stretching something...

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


Re: [sqlite] Slowness with FTS Queries and non-FTS tables

2013-05-07 Thread Dan Kennedy

On 05/08/2013 01:54 AM, Scott Robison wrote:

On Tue, 30 Apr 2013 23:56:35 -0700 (PDT)
Paul Vercellotti  wrote:


We've got some trouble with FTS4 queries taking too long in which
we're looking for a subset of matching records in the FTS table, as
narrowed by a non-FTS table.
{details snipped}

I've recently had to work through a similar issue. My worst case searching
performance wasn't as bad as you're describing but was not "optimal" for
our needs, but I had other problems. One was the size of my full text
index, which could include millions of rows of email message bodies and
various textual header lines. "Pure" inserts into the index weren't too
bad, but anytime the FTS b-tree structures got "too big" and needed to be
merged, sqlite could enter a really slow state allocating tons of memory
during the merge when a single inserted row triggered the behavior. By
"really slow state" I mean in excess of twenty minutes processing after
allocating a single chunk of memory hundreds of megabytes large. When the
full text index grew large enough, it would eventually fail to merge when
it could not allocate a sufficiently large block of data (in excess of 200
megabytes, likely due to a highly fragmented heap; the nature of the
application and the team that has developed it means that the heap is
fragmented, and I can't do much to reduce that fragmentation, even though
otherwise plenty of memory is available, without re-writing significant
other pieces of code; I want to do that eventually, but it is not an option
at the moment).


Another way to go is to use the 'merge=X,Y' and 'automerge=0' commands:

  http://www.sqlite.org/fts3.html#mergecmd

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


Re: [sqlite] Update statement

2013-05-07 Thread skywind mailing lists
Hi Peter,

thanks.

But it does not seem to work in my environment. Probably somewhere a bug on my 
side.

Hartwig

Am 07.05.2013 um 19:55 schrieb Peter Aronson:

> At least for SQLite it appears to be.  From the Update doc page 
> (http://www.sqlite.org/lang_update.html):
> 
> "The modifications made to each row affected by an UPDATE statement are 
> determined by the list of assignments following the SET keyword. Each 
> assignment 
> specifies a column name to the left of the equals sign and a scalar 
> expression 
> to the right. For each affected row, the named columns are set to the values 
> found by evaluating the corresponding scalar expressions. If a single 
> column-name appears more than once in the list of assignment expressions, all 
> but the rightmost occurrence is ignored. Columns that do not appear in the 
> list 
> of assignments are left unmodified. The scalar expressions may refer to 
> columns 
> of the row being updated. In this case all scalar expressions are evaluated 
> before any assignments are made."
> 
> And in fact I rely on it behaving this way for in one place in my SQLite code 
> and it seems to be working correctly.
> 
> Peter
> 
> - Original Message 
>> From: skywind mailing lists 
>> To: General Discussion of SQLite Database 
>> Sent: Tue, May 7, 2013 10:46:42 AM
>> Subject: Re: [sqlite] Update statement
>> 
>> Hi,
>> 
>> my question is: is it guaranteed that it works?
>> 
>> Regards,
>> Hartwig
>> 
>> Am 07.05.2013 um 03:24 schrieb James K. Lowden:
>> 
>>> On Mon, 6 May 2013 23:53:40 +0100
>>> Simon Slavin  wrote:
>>> 
> How do I create this kind of update statement?
> 
> UPDATE T SET a=0.5*(a+b), b=0.5*(b-a);
> 
> The RHS should always be used with the values of a and b before the
> assignment.
> 
> I think that the result of this kind of statement is undefined, or?
 
 No need to worry, it will work the way you want it to work:
 
 The row is read.
 The new values are calculated.
 The new values are written to the database.
>>> ...
 That was a terrible description. 
>>> 
>>> Actually that's not a bad approximation of what happens.  Here's a
>>> simpler example:
>>> 
>>> sqlite> create table t(a int, b int);
>>> sqlite> insert into t values (1,2);
>>> sqlite> select * from t;
>>> a  b
>>> --  --
>>> 1  2
>>> sqlite> update t set a=b, b=a;  -- Et Voila! 
>>> sqlite> select * from t;
>>> a  b
>>> --  --
>>> 2  1
>>> 
>>> There is no "RHS".  The syntax and semantics of SQL are its own; they
>>> cannot be extrapolated from other languages.  
>> 
>> I know but everybody knows what I meant, or? And its a quite brief 
> description.
>> 
>>> 
>>> --jkl
>>> ___
>>> sqlite-users mailing list
>>> sqlite-users@sqlite.org
>>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>> 
>> ___
>> sqlite-users mailing list
>> sqlite-users@sqlite.org
>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>> 
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

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


Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or functionalequivalent?

2013-05-07 Thread Mikael
Hi Günter,

Great, yes that makes sense!

So that solves it.


I was thinking about this and thought there must be some way to do this
already; thank you so much for pointing this out.

This would also open up for picking up several inserted id:s from one query
which is nice.

Thanks,
Mikael

2013/5/7 Hick Gunter 

>  How about calling sqlite3_update_hook()?
>
> ** **
>
> You will be notified about all UPDATE, INSERT and DELETE operations as
> they occur, with the database, table and rowid affected and in the thread
> executing the statement.
>
> ** **
>
> If you register a well-behaved function (i.e. that calls the previously
> registered function) these hooks may even be layered…
>
> ** **
>
> *Von:* Mikael [mailto:mikael.tr...@gmail.com]
> *Gesendet:* Dienstag, 07. Mai 2013 14:15
> *An:* Richard Hipp; Simon Slavin; Hick Gunter; James K. Lowden; General
> Discussion of SQLite Database
> *Betreff:* Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or
> functionalequivalent?
>
> ** **
>
> Hi,
>
> ** **
>
> Thanks for your feedback, James.
>
> ** **
>
> A generalized way of getting if an ID was inserted on the last performed
> query and if so which, is of value for instance when inserting a row into a
> table with an AUTOINCREMENT key e.g.
>
> ** **
>
> CREATE TABLE t (
>
>  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
>
>  d  TEXT
>
> );
>
> ** **
>
> and then inserting into it, e.g.
>
> ** **
>
> "INSERT INTO t (d) VALUES (\"a\");" => inserted id: 1
>
> "INSERT INTO t (d) VALUES (\"a\");" => inserted id: 2
>
> "INSERT INTO t (d) VALUES (\"b\");" => inserted id: 3
>
> "INSERT INTO t (d) VALUES (\"b\");" => inserted id: 4
>
> "INSERT INTO t (d) VALUES (\"c\");" => inserted id: 5
>
> ** **
>
> This functionality makes a lot of sense in at least certain SQLite
> bindings. In the places where it's not strictly required, it will still
> provide clarity which is valuable in debug, and convenience from being
> dynamic, please see the example use ~15 rows below for this -
>
> ** **
>
> ** **
>
> So what I'm looking for is a general mechanism for deriving the ID
> inserted for a query. E.g.:
>
> ** **
>
> "SELECT a FROM b" => none
>
> ** **
>
> "UPDATE b SET a = c" => none
>
> ** **
>
> "INSERT IGNORE INTO b (a) VALUES (c)" and the ID was already in there =>
> none
>
> ** **
>
> "INSERT IGNORE INTO b (a) VALUES (c)" and the ID was not already in there
> => the ID of the inserted row
>
> ** **
>
> "INSERT INTO b (a) VALUES (c)" => the ID of the inserted row
>
> ** **
>
> ** **
>
> Thanks to this, a SQLite binding can be achieved which
> dynamically/*automatically* detects not only if it was a readonly or
> non-readonly query, but also within the non-readonly query if it was an
> update or insert, and thus a generalized query mechanism can be devised
> that behaves like:
>
> ** **
>
> SELECT query  => The query results
>
> UPDATE query => The number of rows updated
>
> INSERT query => The ID of the row inserted, or none (by null/false/0/etc.)
> 
>
> ** **
>
> ** **
>
> This is to create a general abstraction for this purpose. Indeed SQLite
> performs queries, well, at the level of query and, the meaningful work you
> do with SQLite is at the granularity of a query, so it appears reasonable
> to me that there would be a mechanism using which you could retrieve the ID
> of the row inserted by a particular query.
>
> ** **
>
> A generalized "rows changed by this query" abstraction can be implemented
> as of today, using sqlite3_changes which returns the number of changed rows
> in the *last performed query*, the error reporting (as to check
> sqlite3_changes was set on the last query) and possibly secondarily
> by stmt_readonly .
>
> ** **
>
> ** **
>
> The problem with checking the ID of the last inserted row is that the
> abstraction for checking it cannot reasonably know that a query is an
> insert;
>
> ** **
>
> Essentially doing a string match for "INSERT " in the query executed would
> be a leaky abstraction.
>
> ** **
>
> Getting a copy of SQLite's SQL parser's data could be something, but then
> - this is a bit beyond my current SQLite skills - aren't there mechanisms
> to make INSERT:s indirectly in SQLite, like through a database-stored
> procedure or alike?
>
> ** **
>
> That would make any abstraction like this leak, because it wouldn't know
> if an INSERT was made during a query, and that knowledge is required as to
> know if sqlite3_last_insert_rowid regards the last inserted ID or not.
>
> ** **
>
> ** **
>
> ** **
>
> And to illustrate how sqlite3_changes and sqlite3_last_insert_rowid does
> not deliver for automatic query ID retrieval:
>
> ** **
>
> Using these two, let's define an attempt at a general mechanism for this,
> in pseudocode:
>
> ** **
>
> var last_rowId_on_last_query = 0;
>
> function query(query) {
>
>  lock_mutex();

[sqlite] Who can explain the xCodec API?

2013-05-07 Thread Neo Anderson
I'm trying to implement a encryption VFS, but it turned out it's too tedious 
and error prone. The main cause is that my simple VFS does not handle locking 
well (or not at all). This leads to database file corruption when inserting 
thousands of records (I believe).

Then I turned to the commercial SEE (http://www.hwaci.com/sw/sqlite/see.html). 
But it does not mention how it is implemented.

I searched the Internet and it seems that sqlite.c source file has this macro:

SQLITE_HAS_CODEC

But there is no documentation on this API.

I need enlightenment. 
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Update statement

2013-05-07 Thread Simon Slavin

On 7 May 2013, at 8:04pm, Luuk  wrote:

> http://www.andrew.cmu.edu/user/shadow/sql/sql1992.txt
> chapter:  13.9 
> 6) The s are effectively evaluated before updat-
>ing the object row. If a  contains a reference
>to a column of T, then the reference is to the value of that
>column in the object row before any value of the object row is
>updated.

Thank you Luuk.

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


Re: [sqlite] Update statement

2013-05-07 Thread Luuk

On 07-05-2013 19:46, skywind mailing lists wrote:

Hi,

my question is: is it guaranteed that it works?

Regards,
Hartwig



http://www.andrew.cmu.edu/user/shadow/sql/sql1992.txt
chapter:  13.9 
 6) The s are effectively evaluated before updat-
ing the object row. If a  contains a 
reference

to a column of T, then the reference is to the value of that
column in the object row before any value of the object row is
updated.
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Slowness with FTS Queries and non-FTS tables

2013-05-07 Thread Scott Robison
On Tue, 30 Apr 2013 23:56:35 -0700 (PDT)
Paul Vercellotti  wrote:

> We've got some trouble with FTS4 queries taking too long in which
> we're looking for a subset of matching records in the FTS table, as
> narrowed by a non-FTS table.
> {details snipped}

I've recently had to work through a similar issue. My worst case searching
performance wasn't as bad as you're describing but was not "optimal" for
our needs, but I had other problems. One was the size of my full text
index, which could include millions of rows of email message bodies and
various textual header lines. "Pure" inserts into the index weren't too
bad, but anytime the FTS b-tree structures got "too big" and needed to be
merged, sqlite could enter a really slow state allocating tons of memory
during the merge when a single inserted row triggered the behavior. By
"really slow state" I mean in excess of twenty minutes processing after
allocating a single chunk of memory hundreds of megabytes large. When the
full text index grew large enough, it would eventually fail to merge when
it could not allocate a sufficiently large block of data (in excess of 200
megabytes, likely due to a highly fragmented heap; the nature of the
application and the team that has developed it means that the heap is
fragmented, and I can't do much to reduce that fragmentation, even though
otherwise plenty of memory is available, without re-writing significant
other pieces of code; I want to do that eventually, but it is not an option
at the moment).

It occurred to me that because I needed to only do a full text search on a
subset of the full text index (which is not natively possible because of
the nature of the FTS subsystem) that an "ideal" workaround would be to
create a separate full text index for each "sectionID" of my other table.
So instead of just having a single ftstable, I would have "ftstable_1",
"ftstable_2", ... "ftstable_x" where x was my maximum sectionID. I tried
that solution and it unfortunately does not scale. While there is not a
limit on the number of tables you can have (beyond the maximum size of the
database, I assume), adding new tables to a database really gets slow as
the count of tables increases. After several thousand tables have been
added (realizing that a single virtual FTS table results in 3 to 5 physical
shadow tables being created as well), it is visibly slower to continue
adding more tables. I have to assume (though that is dangerous) that
preparing statements to interact with those tables is also going to be
slower, but just the lack of speed creating tables was enough for me to
avoid that solution, so I never tested how fast it was to interact with
that large a set of tables. In my test, I was working with a "schema" that
needed so support approximately 3 sectionIDs, and that number varies
with the exact nature of the users data.

After some more thinking on the subject, I realized that I didn't
necessarily need to have one full text index per sectionID. It would be
sufficient for my needs to split my full text index into individual
buckets. I took my sectionID modulus some number, and used that remainder
as part of the name of an ftstable that only includes a subset of all full
text index data. The right number for you to use is going to depend on the
nature of your data, but for my purposes I used 53. It is a prime number
that tends to avoid any weird clumping of data that would cause grossly
imbalanced full text index buckets, and instead of tens of thousands of
tables in the database, I only wind up with several hundred. This approach
kept the size of the individual full text indexes down to a more manageable
level and gave me the following advantages:

1. Each single full text index is only roughly 2% of the size of the
original monolithic full text index, so inserts that trigger merging
behavior never exhibit the original worst case performance. This means that
I could support far more messages (theoretically) before suffering failure
due to heap fragmentation (probably), but with the current sizes of
datasets that I need to work with there is no problem.

2. Matching search terms in the full text index is now faster. It is still
not optimal because while I only need the matches for a single sectionID, I
will get matches for multiple sections due to the bucket approach. Since
the average query will return about 2% of the result set size as before,
performance is greatly enhanced.

One final note: for our purposes, we wound up moving our full text indexes
out into a separate database. That is not strictly necessary, but it helped
improve other performance issues related to database contention by allowing
one thread to write to the original database that included the sectionID
table portions, and another thread to build the full text index buckets. By
minimizing write contention between the two threads, we were able to insert
more data per second and decrease the time to build the SQLite databases.
That may or may not be us

Re: [sqlite] Update statement

2013-05-07 Thread Peter Aronson
At least for SQLite it appears to be.  From the Update doc page 
(http://www.sqlite.org/lang_update.html):

"The modifications made to each row affected by an UPDATE statement are 
determined by the list of assignments following the SET keyword. Each 
assignment 
specifies a column name to the left of the equals sign and a scalar expression 
to the right. For each affected row, the named columns are set to the values 
found by evaluating the corresponding scalar expressions. If a single 
column-name appears more than once in the list of assignment expressions, all 
but the rightmost occurrence is ignored. Columns that do not appear in the list 
of assignments are left unmodified. The scalar expressions may refer to columns 
of the row being updated. In this case all scalar expressions are evaluated 
before any assignments are made."

And in fact I rely on it behaving this way for in one place in my SQLite code 
and it seems to be working correctly.

Peter

- Original Message 
> From: skywind mailing lists 
> To: General Discussion of SQLite Database 
> Sent: Tue, May 7, 2013 10:46:42 AM
> Subject: Re: [sqlite] Update statement
> 
> Hi,
> 
> my question is: is it guaranteed that it works?
> 
> Regards,
> Hartwig
> 
> Am 07.05.2013 um 03:24 schrieb James K. Lowden:
> 
> > On Mon, 6 May 2013 23:53:40 +0100
> > Simon Slavin  wrote:
> > 
> >>> How do I create this kind of update statement?
> >>> 
> >>> UPDATE T SET a=0.5*(a+b), b=0.5*(b-a);
> >>> 
> >>> The RHS should always be used with the values of a and b before the
> >>> assignment.
> >>> 
> >>> I think that the result of this kind of statement is undefined, or?
> >> 
> >> No need to worry, it will work the way you want it to work:
> >> 
> >> The row is read.
> >> The new values are calculated.
> >> The new values are written to the database.
> > ...
> >> That was a terrible description. 
> > 
> > Actually that's not a bad approximation of what happens.  Here's a
> > simpler example:
> > 
> > sqlite> create table t(a int, b int);
> > sqlite> insert into t values (1,2);
> > sqlite> select * from t;
> > a          b        
> > --  --
> > 1          2        
> > sqlite> update t set a=b, b=a;  -- Et Voila! 
> > sqlite> select * from t;
> > a          b        
> > --  --
> > 2          1        
> > 
> > There is no "RHS".  The syntax and semantics of SQL are its own; they
> > cannot be extrapolated from other languages.  
> 
> I know but everybody knows what I meant, or? And its a quite brief 
description.
> 
> > 
> > --jkl
> > ___
> > sqlite-users mailing list
> > sqlite-users@sqlite.org
> > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> 
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> 
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Update statement

2013-05-07 Thread skywind mailing lists
Hi,

my question is: is it guaranteed that it works?

Regards,
Hartwig

Am 07.05.2013 um 03:24 schrieb James K. Lowden:

> On Mon, 6 May 2013 23:53:40 +0100
> Simon Slavin  wrote:
> 
>>> How do I create this kind of update statement?
>>> 
>>> UPDATE T SET a=0.5*(a+b), b=0.5*(b-a);
>>> 
>>> The RHS should always be used with the values of a and b before the
>>> assignment.
>>> 
>>> I think that the result of this kind of statement is undefined, or?
>> 
>> No need to worry, it will work the way you want it to work:
>> 
>> The row is read.
>> The new values are calculated.
>> The new values are written to the database.
> ...
>> That was a terrible description. 
> 
> Actually that's not a bad approximation of what happens.  Here's a
> simpler example:
> 
> sqlite> create table t(a int, b int);
> sqlite> insert into t values (1,2);
> sqlite> select * from t;
> a   b 
> --  --
> 1   2 
> sqlite> update t set a=b, b=a;  -- Et Voila! 
> sqlite> select * from t;
> a   b 
> --  --
> 2   1 
> 
> There is no "RHS".  The syntax and semantics of SQL are its own; they
> cannot be extrapolated from other languages.  

I know but everybody knows what I meant, or? And its a quite brief description.

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

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


Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or functionalequivalent?

2013-05-07 Thread Hick Gunter
How about calling sqlite3_update_hook()?

You will be notified about all UPDATE, INSERT and DELETE operations as they 
occur, with the database, table and rowid affected and in the thread executing 
the statement.

If you register a well-behaved function (i.e. that calls the previously 
registered function) these hooks may even be layered...

Von: Mikael [mailto:mikael.tr...@gmail.com]
Gesendet: Dienstag, 07. Mai 2013 14:15
An: Richard Hipp; Simon Slavin; Hick Gunter; James K. Lowden; General 
Discussion of SQLite Database
Betreff: Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or 
functionalequivalent?

Hi,

Thanks for your feedback, James.

A generalized way of getting if an ID was inserted on the last performed query 
and if so which, is of value for instance when inserting a row into a table 
with an AUTOINCREMENT key e.g.

CREATE TABLE t (
 id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
 d  TEXT
);

and then inserting into it, e.g.

"INSERT INTO t (d) VALUES (\"a\");" => inserted id: 1
"INSERT INTO t (d) VALUES (\"a\");" => inserted id: 2
"INSERT INTO t (d) VALUES (\"b\");" => inserted id: 3
"INSERT INTO t (d) VALUES (\"b\");" => inserted id: 4
"INSERT INTO t (d) VALUES (\"c\");" => inserted id: 5

This functionality makes a lot of sense in at least certain SQLite bindings. In 
the places where it's not strictly required, it will still provide clarity 
which is valuable in debug, and convenience from being dynamic, please see the 
example use ~15 rows below for this -


So what I'm looking for is a general mechanism for deriving the ID inserted for 
a query. E.g.:

"SELECT a FROM b" => none

"UPDATE b SET a = c" => none

"INSERT IGNORE INTO b (a) VALUES (c)" and the ID was already in there => none

"INSERT IGNORE INTO b (a) VALUES (c)" and the ID was not already in there => 
the ID of the inserted row

"INSERT INTO b (a) VALUES (c)" => the ID of the inserted row


Thanks to this, a SQLite binding can be achieved which 
dynamically/*automatically* detects not only if it was a readonly or 
non-readonly query, but also within the non-readonly query if it was an update 
or insert, and thus a generalized query mechanism can be devised that behaves 
like:

SELECT query  => The query results
UPDATE query => The number of rows updated
INSERT query => The ID of the row inserted, or none (by null/false/0/etc.)


This is to create a general abstraction for this purpose. Indeed SQLite 
performs queries, well, at the level of query and, the meaningful work you do 
with SQLite is at the granularity of a query, so it appears reasonable to me 
that there would be a mechanism using which you could retrieve the ID of the 
row inserted by a particular query.

A generalized "rows changed by this query" abstraction can be implemented as of 
today, using sqlite3_changes which returns the number of changed rows in the 
*last performed query*, the error reporting (as to check sqlite3_changes was 
set on the last query) and possibly secondarily by stmt_readonly .


The problem with checking the ID of the last inserted row is that the 
abstraction for checking it cannot reasonably know that a query is an insert;

Essentially doing a string match for "INSERT " in the query executed would be a 
leaky abstraction.

Getting a copy of SQLite's SQL parser's data could be something, but then - 
this is a bit beyond my current SQLite skills - aren't there mechanisms to make 
INSERT:s indirectly in SQLite, like through a database-stored procedure or 
alike?

That would make any abstraction like this leak, because it wouldn't know if an 
INSERT was made during a query, and that knowledge is required as to know if 
sqlite3_last_insert_rowid regards the last inserted ID or not.



And to illustrate how sqlite3_changes and sqlite3_last_insert_rowid does not 
deliver for automatic query ID retrieval:

Using these two, let's define an attempt at a general mechanism for this, in 
pseudocode:

var last_rowId_on_last_query = 0;
function query(query) {
 lock_mutex();
 sqlite_perform_query(query);
 var last_rowId = sqlite_last_rowid();
 var id_of_this_row = (last_rowId != last_rowId_on_last_query) ? last_rowId 
: null;
 last_rowId_on_last_query = last_rowId;
 unlock_mutex();
 return id_of_this_row;
}

Now, let's set up these two tables

CREATE TABLE t1 ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, d TEXT );
CREATE TABLE t2 ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, d TEXT );

and now make some inserts with it! The use of query() above is implied here.

"INSERT INTO t1 (d) VALUES (\"a\");" => 1- Correct!
"INSERT INTO t1 (d) VALUES (\"a\");" => 2- Correct!
"INSERT INTO t2 (d) VALUES (\"a\");" => 1- Correct!
"INSERT INTO t2 (d) VALUES (\"a\");" => 2- Correct!
"INSERT INTO t2 (d) VALUES (\"a\");" => 3- Correct!
"INSERT INTO t1 (d) VALUES (\"a\");" => null - Error, abstraction leak, ouch!


All of this leakiness would be undone if before a query, the SQLite user could 
reset the s

Re: [sqlite] Is there a way to select a precision?

2013-05-07 Thread Michael Black
OK...this way then...it's stored correctly and the view should display
correctly in a 3rd party app.
Correctly gives the 99 cent discount.
Should work for any 2 decimal place number.


create table mine(a number(10,2));
create view v1 as select a/100.0 as a from mine;
create trigger t1 after insert on mine
for each row begin
update mine set a = cast(round(new.a*100) as integer) where
rowid=new.rowid;
end;
create trigger t2 after update on mine
for each row
begin
update mine set a=cast(round(a*100) as integer) where
typeof(a)!='integer' and rowid=new.rowid;
end;
insert into mine values(1.0/3.0);
select * from mine;
select a*3 from v1;
.99
update mine set a=1/3.0;
select a*3 from v1;
.99



-Original Message-
From: sqlite-users-boun...@sqlite.org
[mailto:sqlite-users-boun...@sqlite.org] On Behalf Of James K. Lowden
Sent: Monday, May 06, 2013 8:03 PM
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] Is there a way to select a precision?

On Mon, 6 May 2013 07:42:43 -0500
"Michael Black"  wrote:

> Yes...other databases do respect NUMBER(10,2) on SELECT's.
...
> Can you simply use round to do what you want?
> CREATE TABLE stuff(f number(10,2));
> INSERT INTO "stuff" VALUES(1.0/3.0);
> sqlite> select f from stuff;
> 0.333
> sqlite> select round(f,2) from stuff;
> 0.33

To be clear, Paul van Helden isn't talking about SELECT.  He's talking
about INSERT, about not storing more precision that the input actually
represents.  

Apply a 33% discount to a $3.00 purchase.  Is the bill $2.00, or
$2.01?  If you say $2.00, then apply a 33% discount to three $1
purchases in three separate months.  I imagine you'd agree the total
discount is just 99 cents.  

Whether or not SQLite ought to support exact decimal types is a
separate question; I don't think anyone is saying it should.  But it
isn't just a matter of presentation.  

--jkl




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

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


Re: [sqlite] Security concern with new fts3tokenize virtual table

2013-05-07 Thread Dan Kennedy

On 05/07/2013 05:17 PM, Ralf Junker wrote:

The new fts3tokenize virtual table calls the fts3_tokenizer()

...


However, this call is rejected if, for security reasons,

So the problem is that with the authorizer block in place, the fts3tokneize 
virtual table does not work. One would have to compromise functionality for 
security.

Is there no other way to retrieve the tokenizer besides calling 
fts3_tokenizer()?



Good point. Changed it to avoid fts3_tokenizer(). Thanks.

Dan.

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


Re: [sqlite] How do sqlite3_reset_last_insert_rowid() or functionalequivalent?

2013-05-07 Thread Mikael
Hi,

Thanks for your feedback, James.

A generalized way of getting if an ID was inserted on the last performed
query and if so which, is of value for instance when inserting a row into a
table with an AUTOINCREMENT key e.g.

CREATE TABLE t (
 id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
 d  TEXT
);


and then inserting into it, e.g.

"INSERT INTO t (d) VALUES (\"a\");" => inserted id: 1
"INSERT INTO t (d) VALUES (\"a\");" => inserted id: 2
"INSERT INTO t (d) VALUES (\"b\");" => inserted id: 3
"INSERT INTO t (d) VALUES (\"b\");" => inserted id: 4
"INSERT INTO t (d) VALUES (\"c\");" => inserted id: 5


This functionality makes a lot of sense in at least certain SQLite
bindings. In the places where it's not strictly required, it will still
provide clarity which is valuable in debug, and convenience from being
dynamic, please see the example use ~15 rows below for this -


So what I'm looking for is a general mechanism for deriving the ID inserted
for a query. E.g.:

"SELECT a FROM b" => none

"UPDATE b SET a = c" => none

"INSERT IGNORE INTO b (a) VALUES (c)" and the ID was already in there =>
none

"INSERT IGNORE INTO b (a) VALUES (c)" and the ID was not already in there
=> the ID of the inserted row

"INSERT INTO b (a) VALUES (c)" => the ID of the inserted row



Thanks to this, a SQLite binding can be achieved which
dynamically/*automatically* detects not only if it was a readonly or
non-readonly query, but also within the non-readonly query if it was an
update or insert, and thus a generalized query mechanism can be devised
that behaves like:

SELECT query  => The query results
UPDATE query => The number of rows updated
INSERT query => The ID of the row inserted, or none (by null/false/0/etc.)



This is to create a general abstraction for this purpose. Indeed SQLite
performs queries, well, at the level of query and, the meaningful work you
do with SQLite is at the granularity of a query, so it appears reasonable
to me that there would be a mechanism using which you could retrieve the ID
of the row inserted by a particular query.

A generalized "rows changed by this query" abstraction can be implemented
as of today, using sqlite3_changes which returns the number of changed rows
in the *last performed query*, the error reporting (as to check
sqlite3_changes was set on the last query) and possibly secondarily
by stmt_readonly .


The problem with checking the ID of the last inserted row is that the
abstraction for checking it cannot reasonably know that a query is an
insert;

Essentially doing a string match for "INSERT " in the query executed would
be a leaky abstraction.

Getting a copy of SQLite's SQL parser's data could be something, but then -
this is a bit beyond my current SQLite skills - aren't there mechanisms to
make INSERT:s indirectly in SQLite, like through a database-stored
procedure or alike?

That would make any abstraction like this leak, because it wouldn't know if
an INSERT was made during a query, and that knowledge is required as to
know if sqlite3_last_insert_rowid regards the last inserted ID or not.



And to illustrate how sqlite3_changes and sqlite3_last_insert_rowid does
not deliver for automatic query ID retrieval:

Using these two, let's define an attempt at a general mechanism for this,
in pseudocode:

var last_rowId_on_last_query = 0;
function query(query) {
 lock_mutex();
 sqlite_perform_query(query);
 var last_rowId = sqlite_last_rowid();
 var id_of_this_row = (last_rowId != last_rowId_on_last_query) ?
last_rowId : null;
 last_rowId_on_last_query = last_rowId;
 unlock_mutex();
 return id_of_this_row;
}


Now, let's set up these two tables

CREATE TABLE t1 ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, d TEXT );
CREATE TABLE t2 ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, d TEXT );


and now make some inserts with it! The use of query() above is implied here.

"INSERT INTO t1 (d) VALUES (\"a\");" => 1- Correct!
"INSERT INTO t1 (d) VALUES (\"a\");" => 2- Correct!
"INSERT INTO t2 (d) VALUES (\"a\");" => 1- Correct!
"INSERT INTO t2 (d) VALUES (\"a\");" => 2- Correct!
"INSERT INTO t2 (d) VALUES (\"a\");" => 3- Correct!
"INSERT INTO t1 (d) VALUES (\"a\");" => null - Error, abstraction leak,
ouch!



All of this leakiness would be undone if before a query, the SQLite user
could reset the sqlite3_last_insert_rowid . By that, the user can just
check the sqlite3_last_insert_rowid right after the query, and by that know
that that was .

It may be a bit too simplistic if a query inserted several ID:s as you
pointed out, though at least it's general unlike the present solution, and
can be made to fit any usecase at least I have in reach, as in SQLite any
INSERT operation can be performed one row per query with OK-to-great
performance.


Introduction of a sqlite3_reset_last_insert_rowid would be complimenting
the current sqlite_int64 sqlite3_last_insert_rowid at sqlite3.c row
114023-114028:

/*
** Return the ROWID of the mos

Re: [sqlite] Very important performance regression due to totally different query plan

2013-05-07 Thread Richard Hipp
On Mon, May 6, 2013 at 3:15 PM, Stephane MANKOWSKI wrote:

> Hi,
>
> I am the main developer of Skrooge (application using sqlite) and since my
> upgrade to ubuntu 13.04, I have very bad performances due to sqlite.
>

Have you considered including source code (the sqlite3.c and sqlite3.h
files) for the version of SQLite that works for you in our source tree and
statically linking it, so that OS upgrades do not cause problems like this?
-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Very important performance regression due to totally different query plan

2013-05-07 Thread Stephane MANKOWSKI

Hi,

I am the main developer of Skrooge (application using sqlite) and since 
my upgrade to ubuntu 13.04, I have very bad performances due to sqlite.

Here is my analysis:

All tests are done with the file 
http://skrooge.org/files/skrooge_bug_performance.sqlite


*=*
*ON UBUNTU QUANTAL:sqlite version 3.7.13 2012-06-11 02:05:22 
f5b5a13f7394dc143aa136f1d4faba6839eaa6dc*


sqlite> SELECT 
ABS(TOTAL(f_REALCURRENTAMOUNT))>=400,ABS(TOTAL(f_REALCURRENTAMOUNT)) 
FROM v_operation_consolidated WHERE d_date!='-00-00' AND 
((STRFTIME('%Y-%m',d_date)=STRFTIME('%Y-%m',date('now','start of 
month','-1 month';

1|2704.0
CPU Time: user *0.18* sys 0.012000 (*GOOD PERFORMANCES*)

sqlite> SELECT * FROM v_category_display;
...
CPU Time: user 0.812000 sys 0.016000

sqlite> explain query plan SELECT * FROM v_category_display;
sele  order  from  deta
  -    
1 0  4 SCAN TABLE suboperation USING INDEX 
idx_suboperation_category_id (~7341 rows)
1 1  0 SEARCH TABLE operation USING INTEGER PRIMARY 
KEY (rowid=?) (~1 rows)
1 2  1 SEARCH TABLE account USING INTEGER PRIMARY 
KEY (rowid=?) (~1 rows)
1 3  2 SEARCH TABLE bank USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)
1 4  3 SEARCH TABLE unit USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)

1 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 2
2 0  0 SEARCH TABLE unit USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)

2 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 3
3 0  0 SEARCH TABLE unitvalue AS s USING INDEX 
uidx_unitvalue2 (rd_unit_id=? AND d_date=?) (~1 rows)

3 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 4
4 0  0 SEARCH TABLE unitvalue AS s USING COVERING 
INDEX uidx_unitvalue2 (rd_unit_id=?) (~1 rows)

2 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 5
5 0  0 SEARCH TABLE unit USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)

5 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 6
6 0  0 SEARCH TABLE unitvalue AS s USING INDEX 
uidx_unitvalue2 (rd_unit_id=? AND d_date=?) (~1 rows)

6 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 7
7 0  0 SEARCH TABLE unitvalue AS s USING COVERING 
INDEX uidx_unitvalue2 (rd_unit_id=?) (~1 rows)

0 0  0 SCAN TABLE category (~78 rows)
0 1  1 SEARCH SUBQUERY 1 AS t USING AUTOMATIC 
COVERING INDEX (i_IDCATEGORY=?) (~3 rows)

0 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 8
8 0  1 SEARCH TABLE suboperation AS so USING INDEX 
idx_suboperation_category_id (r_category_id=?) (~102 rows)
8 1  0 SEARCH TABLE operation AS o USING INTEGER 
PRIMARY KEY (rowid=?) (~1 rows)

0 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 9
100  4 SCAN TABLE suboperation USING INDEX 
idx_suboperation_category_id (~7341 rows)
101  0 SEARCH TABLE operation USING INTEGER PRIMARY 
KEY (rowid=?) (~1 rows)
102  1 SEARCH TABLE account USING INTEGER PRIMARY 
KEY (rowid=?) (~1 rows)
103  2 SEARCH TABLE bank USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)
104  3 SEARCH TABLE unit USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)

100  0 EXECUTE CORRELATED SCALAR SUBQUERY 11
110  0 SEARCH TABLE unit USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)

110  0 EXECUTE CORRELATED SCALAR SUBQUERY 12
120  0 SEARCH TABLE unitvalue AS s USING INDEX 
uidx_unitvalue2 (rd_unit_id=? AND d_date=?) (~1 rows)

120  0 EXECUTE CORRELATED SCALAR SUBQUERY 13
130  0 SEARCH TABLE unitvalue AS s USING COVERING 
INDEX uidx_unitvalue2 (rd_unit_id=?) (~1 rows)

110  0 EXECUTE CORRELATED SCALAR SUBQUERY 14
140  0 SEARCH TABLE unit USING INTEGER PRIMARY KEY 
(rowid=?) (~1 rows)

140  0 EXECUTE CORRELATED SCALAR SUBQUERY 15
150  0 SEARCH TABLE unitvalue AS s USING INDEX 
uidx_unitvalue2 (rd_unit_id=? AND d_date=?) (~1 rows)

150  0 EXECUTE CORRELATED SCALAR SUBQUERY 16
160  0 SEARCH TABLE unitvalue AS s USING COVERING 
INDEX uidx_unitvalue2 (rd_unit_id=?) (~1 rows)

9 0  0 SCAN TABLE category (~39 rows)
9 1  1 SEARCH SUBQUERY 10 AS t USING AUTOMATIC 
COVERING INDEX (i_IDCATEGORY=?) (~3 rows)

0 0  0 EXECUTE CORRELATED SCALAR SUBQUERY 17
170  1 SEARCH TABLE suboperation AS so USING INDEX 
idx_suboperation_category_id (r_category_id=?) (~102 rows)
171  0 SEARCH TABLE operation AS o USING I

Re: [sqlite] Suspected bug in SELECT EXCEPT ORDER COLLATE

2013-05-07 Thread Staffan Tylen
I just wish to confirm that the workaround shown by Nico works fine for me
which makes the issue low priority from my point of view.
Thanks all.

Staffan



On Tue, May 7, 2013 at 5:00 AM, Keith Medcalf  wrote:

>
> So you are saying that:
>
> Select a from t1 except select a from t2 order by a collate nocase;
>
> Should internally be computed as
>
> Select a from (select a from t1 except select a from t2) order by a
> collate nocase;
>
> ?
>
>
>
>
> ---
> ()  ascii ribbon campaign against html e-mail
> /\  www.asciiribbon.org
>
>
> > -Original Message-
> > From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users-
> > boun...@sqlite.org] On Behalf Of Richard Hipp
> > Sent: Monday, 06 May, 2013 20:46
> > To: General Discussion of SQLite Database
> > Subject: Re: [sqlite] Suspected bug in SELECT EXCEPT ORDER COLLATE
> >
> > On Mon, May 6, 2013 at 10:29 PM, Simon Slavin 
> > wrote:
> >
> > >
> > > The problem, I think, is that a COLLATE shouldn't change any value
> > anyhow,
> > > no matter which SELECT the ORDER clause is attached to.  The COLLATE
> > > modifier is part of the ORDER BY clause.  It is there to change the
> > ORDER
> > > that the values are returned in, not the values themselves.
> >
> >
> > And, indeed, that is exactly what COLLATE is doing.
> >
> > The problem is this:  When SQLite sees the ORDER BY clause on the EXCEPT
> > it
> > tries to do the EXCEPT using a merge.  In other words, it computes two
> > subqueries:  (SELECT .. FROM x ORDER BY ...) and (SELECT ... FROM y ORDER
> > BY ...).  Then it looks at the output of these subqueries, row by row.
> >
> > (1)  x > (2)  x>y:  pop y
> > (3)  x=y:  pop and discard both x and y
> >
> > You can implement INTERSECT, UNION, and UNION ALL in much the same way,
> by
> > supplying different actions for each of the above cases.
> >
> > The above works great (and is very efficient) if the collating sequence
> of
> > the ORDER BY is the same as the natural collating sequence of the output
> > columns.  If it isn't, then the above code gives the wrong answer.  The
> > basic problem is that SQLite is not recognizing that the collating
> > sequences are different and is trying to use the algorithm above when it
> > it
> > shouldn't.
> >
> > This was an oversight when I first implemented the merging algorithm 5
> > years ago.  It didn't occur to me then (and apparently hasn't occurred to
> > anybody else in the last 5 years) that the collating sequence in the
> ORDER
> > BY might be different from the natural collating sequence of the result
> > columns.
> >
> > Unfortunately, the merge algorithm outlined above is the only means
> SQLite
> > currently has for doing a compound select that contains an ORDER BY.  In
> > order to fix this, I'm going to have to come up with a whole new
> > algorithm,
> > just for this case.  ON the other hand, since nobody has noticed it in 5
> > years, presumably it doesn't come up that often, so there isn't a huge
> > rush
> > to get the fix in.  So I'm going to take my time and try to come up with
> > the minimally disruptive fix.
> >
> >
> >
> > >  And something like
> > >
> > > SELECT x EXCEPT y
> > >
> > > is subtracting one set from another, and in sets the order doesn't
> > matter.
> > >  The problem is something like doing
> > >
> > > SELECT words FROM dictionary ORDER BY words COLLATE NOCASE
> > >
> > > and getting all the words back as capital letters.  This shouldn't
> > happen.
> > >
> > > Simon.
> > > ___
> > > sqlite-users mailing list
> > > sqlite-users@sqlite.org
> > > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> > >
> >
> >
> >
> > --
> > D. Richard Hipp
> > d...@sqlite.org
> > ___
> > sqlite-users mailing list
> > sqlite-users@sqlite.org
> > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
>
>
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] Security concern with new fts3tokenize virtual table

2013-05-07 Thread Ralf Junker
The new fts3tokenize virtual table calls the fts3_tokenizer() SQL function 
internally to retrieve the pointer to the tokenizer implementation for a FTS 
table:

http://www.sqlite.org/src/artifact/a29f126b9e6c6a6f1021a8f7440bf125e68af1f9?ln=74-100

However, this call is rejected if, for security reasons, the fts3_tokenizer() 
function is blocked by an authorizer callback:

"SECURITY WARNING: If the fts3/4 extension is used in an environment where 
potentially malicious users may execute arbitrary SQL, they should be prevented 
from invoking the fts3_tokenizer() function, possibly using the authorization 
callback." (http://www.sqlite.org/fts3.html#section_8_1).

So the problem is that with the authorizer block in place, the fts3tokneize 
virtual table does not work. One would have to compromise functionality for 
security.

Is there no other way to retrieve the tokenizer besides calling 
fts3_tokenizer()?

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