ericsink / SQLitePCL.raw

A Portable Class Library (PCL) for low-level (raw) access to SQLite
Apache License 2.0
512 stars 106 forks source link

SQLitePCLRaw.bundle_e_sqlcipher version > 2.1.0 ```non-deterministic``` error when inserting into a database table #520

Closed iplusMario closed 1 year ago

iplusMario commented 1 year ago

I get the following non-deterministic error when inserting into a database table when using HasComputedColumnSql("DATETIME()", true).

Example:

modelBuilder.Entity<Model>()
                    .Property(k => k.ChangeDate)
                    .HasComputedColumnSql("DATETIME()", true);

Version: EFCore: 6 EntityFramewrokCore: 6.0.8 and 6.0.9 EntityFramewrokCore.SqLite.Core: 6.0.8 and 6.0.9 SQLitePCLRaw.bundle_e_sqlcipher version: 2.1.1 and 2.1.2

ericsink commented 1 year ago

What is the actual error message?

Did this happen with versions before 2.1.1, or does it look like a regression?

Is this specific to Entity Framework?

Does it happen with e_sqlite3, or only with e_sqlcipher?

iplusMario commented 1 year ago

What is the actual error message?

Did this happen with versions before 2.1.1, or does it look like a regression?

Is this specific to Entity Framework?

Does it happen with e_sqlite3, or only with e_sqlcipher?

I only tried with e_sqlchiper. With version 2.1.0 insert doesn't throw errors.

ericsink commented 1 year ago

Can you attach a minimal repro sample project?

iplusMario commented 1 year ago

Can you attach a minimal repro sample project?

SQLitePCLRaw.zip

There are three projects within the solution:

ericsink commented 1 year ago

@iplusMario Thanks -- that's very helpful.

I think the problem is that SQLite simply doesn't allow what you are trying to do.

The documentation for SQLite indicates that non-deterministic functions cannot be used in the expression for a generated column. See section 2.3.3 of the following page:

https://www.sqlite.org/gencol.html

There is also a special section in the following page about a bug fix in 3.35.2:

https://www.sqlite.org/deterministic.html

Basically, prior to 3.35.2, SQLite considered DATETIME() to be deterministic, which was a bug.

This would explain why the problem does not show up in 2.1.0 but does in 2.1.2. In SQLitePCLRaw 2.1.0, the e_sqlcipher builds were based on a SQLite version prior to 3.35.2.

To confirm, if you change your test to say DATETIME('now'), the error occurs with SQLitePCLRaw 2.1.0 as well.

iplusMario commented 1 year ago

@ericsink Thanks for the detailed reply.

To confirm, if you change your test to say DATETIME('now'), the error occurs with SQLitePCLRaw 2.1.0 as well.

Yes I first tried using DateTime('now') and got a non-deterministic error. Then I read somwhere that DateTime() is a deterministic function and replaced DateTime('now') with DateTime().