Thanks, Mike and Clemens. I got your solutions.

Seems there is no graceful way to do this.
It would be better if virtual table can provide more flexibilities,
although it might introduce some issues.

2015-06-23 9:19 GMT-07:00 Mike Nicolino <mike.nicolino at centrify.com>:

> I'll summarize what I've done; note that I don't consider myself an
> 'expert' in this area.  What I have works, but others may have suggestions
> on improvements.  (I'd actually be happy to hear any suggestions).
>
> For my virtual tables I generate an additional 'special' column called
> '_MatchFilter' (the leading underscore is my convention identifying it as
> 'special').  It's a string column that returns either empty string or the
> specified 'filter' from the where clause if specified.  This column is a
> placeholder and not useful, except when used in a where clause with 'match'
> or '='.  In these cases, my BestIndex prefers queries including
> _MatchFilter with 'match' or '=' over all others and Filter takes the
> match/= compare value and passes it as a custom query to my 'table' so it
> can do things more efficiently.  Example:
>
>         select * from MyTable where _MatchFilter match "my custom query
> here"
>         select * from MyTable where _MatchFilter = "my custom query here"
>
> You still have to handle cases where _MatchFilter gets 'and'ed with
> additional clauses of course in your BestIndex and Filter, though at worst
> you should be able to run your custom query and then in memory filter the
> results on the other clause (or vice versa).  But you can get really crazy
> with what you allow for the filter in this manner, passing it directly to
> your virtual table implementation.
>
> What you want to do with Average is somewhat different; you really don't
> need a custom query, but a way to avoid having SQLite do the average for
> your table.  One trick I can think of is adding your own special column to
> the table '_Average', that returns the calculated average.  Its somewhat
> strange in that ever 'row' would contain the average of course.  If it's
> still expensive to calculate, you might require something similar to my
> _MatchFilter' arrangement to cause '_Average' to generate and return '0'
> for it if not present in the where clause.
>
> This is all somewhat hacky of course and non-standard if you're exposing
> SQL to users.
>
> MikeN
>
>
> -----Original Message-----
> From: sqlite-users-bounces at mailinglists.sqlite.org [mailto:
> sqlite-users-bounces at mailinglists.sqlite.org] On Behalf Of Jerry
> Sent: Monday, June 22, 2015 2:47 PM
> To: General Discussion of SQLite Database
> Subject: Re: [sqlite] What's the best way to pass function information to
> virtual table?
>
> Hi, MikeN.
>
> Assuming I want to compute the average value of all keys, how to write the
> query for this using match?
>
> For example, if I write SQL in this way
>
> > SELECT avg(key) From table WHERE key MATCH('avg');
>
> with MATCH info, the virtual table is able to know the query is looking
> for average value for the keys.
> Now, assume the virtual table is able to compute the average faster than
> SQLite, after I get the average value, how can I return the result
> immediately without SQLite going through the aggregator avg()?
>
> What are your queries like when you "pass arbitrary specialized queries
> directly to my virtual table"?
>
> Thanks,
> -C.Lin
>
> 2015-06-17 8:48 GMT-07:00 Mike Nicolino <mike.nicolino at centrify.com>:
>
> > The override of match() trick works pretty well for cases like this.
> > I've overridden match in my virtual table implementation to allow me
> > to pass arbitrary specialized queries directly to my virtual table
> > modules for cases that I know the virtual table can do a better job
> > that SQLite on that query.  Downside is if you're exposing the SQL to
> > users of course as using match in such a manner is non-standard.
> >
> > MikeN
> >
> >
> > -----Original Message-----
> > From: sqlite-users-bounces at mailinglists.sqlite.org [mailto:
> > sqlite-users-bounces at mailinglists.sqlite.org] On Behalf Of Clemens
> > Ladisch
> > Sent: Wednesday, June 17, 2015 1:23 AM
> > To: sqlite-users at mailinglists.sqlite.org
> > Subject: Re: [sqlite] What's the best way to pass function information
> > to virtual table?
> >
> > Jerry wrote:
> > > With xBestIndex and xFilter, we can pass the constraint information
> > > (e.g., those from WHERE clause) to virtual table (through struct
> > > sqlite3_index_info), so that we can locate the cursor to narrow the
> > > search space.
> > > However, it does not provide information about functions used in SQL
> > > queries.
> > >
> > > For example,
> > >
> > >> SELECT MAX(key) from Table tab;
> > >
> > > The virtual table has no way to know the function MAX is called
> >
> > SQLite has a special optimization for this particular query, and
> > rewrites it as "SELECT key FROM tab ORDER BY key DESC LIMIT 1".
> >
> > > The virtual table provides xFindFunction to override functions
> > > (maybe this can be used to pass some information).
> >
> > For example, the full-text search module overrides the match()
> > function; you could do something similar:
> >   SELECT key FROM tab WHERE tab MATCH 'max(key)'
> >
> > > But it seems only general functions can be override -- it has not
> > > effect on aggregate functions.
> >
> > The virtual table interface does not allow access to all the internals
> > of the query optimizer.
> >
> > When there is an aggregate function, you can filter the rows that will
> > be given to it, but the actual aggregation is still done by SQLite.
> >
> > If you can compute aggregates more efficiently than SQLite, you could
> > create a separate virtual table:
> >   SELECT max_key FROM tab_agg
> > but this would not work for more complex queries.
> >
> >
> > Regards,
> > Clemens
> > _______________________________________________
> > sqlite-users mailing list
> > sqlite-users at mailinglists.sqlite.org
> > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> > _______________________________________________
> > sqlite-users mailing list
> > sqlite-users at mailinglists.sqlite.org
> > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> >
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>

Reply via email to