On Fri, Aug 4, 2017 at 6:24 PM, Nico Williams <n...@cryptonector.com> wrote:

> On Fri, Aug 04, 2017 at 06:06:55PM +0200, Sylvain Pointeau wrote:
> > Please find below the last source code, I removed the check on the table
> > (NOT NULL on both sql_val and seq_inc)
>
> Yeah, I saw.  I think this is another argument for SQLite3 needing a
> strict-type mode!
>
> > Now I would like to implement the seq_currval:
> >
> > Oracle raises an exception because seq_nextval must be called at least
> one
> > time for the session
>
> I'm not sure how to implement this.  Maybe with the sessions extension.
>
> But I don't think this is an important semantic in the context of
> SQLite3 -- after all, it's "lite".
>

we could implement it like (in pseudo code):

var currvalues = map[string,number]

function seq_nextval(seq_name) {
  update sequence set val = val + inc where name = seq_name
  nextval = select val from sequence where name = seq_name
  currvalues[seq_name] = nextval
  return nextval
}

function seq_currval(seq_name) {
  if currvalues[seq_name] is not set => raise error
  return currvalues[seq_name]
}


>
> > H2 returns init minus seq (making nextval returning the init value) =>
> this
> > is also the trick I used so the update is simpler so more efficient
>
> I don't follow.  What's H2?
>
>
H2 is a java embedded database, similar to sqlite. I recently moved most of
my projects (in java/kotlin) to sqlite, one is still using H2, mainly due
to the sequence.


> > do you agree that we must use a variable mapping sequenceName => last
> > nextval
> >
> > should I use a very simple structure (fixed sized array and O(n) access)?
> > or use a map? but then I would rather prefer to switch to C++, unless you
> > have a better idea?
>
> I don't understand this.
>

see the pseudo code above, how to implement the map[string,number] in C? a
fixed sized array?


>
> > #include "sqlite3ext.h"
> > SQLITE_EXTENSION_INIT1
> >
> > void sp_seq_init(sqlite3_context *context, int argc, sqlite3_value
> **argv) {
> >   int rc = 0;
> >   sqlite3_stmt *stmt;
> >   sqlite3 *db = sqlite3_context_db_handle(context);
> >
> >   const unsigned char* seq_name = sqlite3_value_text(argv[0]);
> >   long seq_init_val = sqlite3_value_int64(argv[1]);
> >   long seq_inc_val = argc < 3 ? 1 : sqlite3_value_int64(argv[2]);
> >
> >   rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS SP_SEQUENCE ( " \
> >   " SEQ_NAME TEXT PRIMARY KEY, " \
> >   " SEQ_VAL INTEGER, " \
> >   " SEQ_INC INTEGER " \
> >   " )", 0, 0, 0);
> >
> >   if( rc != SQLITE_OK ) {
> >     sqlite3_result_error(context, sqlite3_errmsg(db), -1);
> >     return;
> >   }
>
> You could still check the types here...  It won't kill performance --
> after all, this is only at sequence init time.
>
> Also, you could keep the CHECK constraints on the name and increment
> columns, and not on the current columns.  Not sure it's worth it.
>
>
ok I did it

  rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS SP_SEQUENCE ( " \
  " SEQ_NAME TEXT NOT NULL PRIMARY KEY, " \
  " SEQ_VAL INTEGER, " \
  " SEQ_INIT INTEGER NOT NULL, " \
  " SEQ_INC INTEGER NOT NULL CHECK (SEQ_INC<>0) " \
  " )", 0, 0, 0);

however I noticed that because I am retrieving the params as int64:
'10a' becomes 10,
'abc' becomes 0
null becomes 0

and I think that is ok, so the SEQ_INIT INTEGER NOT NULL can never be null
and the SEQ_INC can never be 0 due to the check

The rest looks good.
>
> Also, I saw D. R. Hipp's discussion of increased write concurrency.
> Ooops!  (Also, great news!)  Maybe you should change the code for the
> next value to a loop like I described earlier (get the current value,
> update to add 1 where the value hasn't changed, repeat until the update
> statement updates one row, not zero).
>

I did not really understand your logic here.

Best regards,
Sylvain
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to