Skip to content

Commit

Permalink
feat(backend): Remove WITHOUT ROWID from SQLite migrations (#1349)
Browse files Browse the repository at this point in the history
### Motivation
Issue that prompted this was unusually slow inserts when loading large
amounts of data into SQLite (using wa-sqlite and IndexedDB).

### Investigation
After some investigation, we found that the `WITHOUT ROWID` table
specification we add to all SQLite tables makes SQLite store data as a
B-Tree rather than a B*-Tree, which causes significant slowdowns for
large rows (significant w.r.t to the page size), and also causes the
incremental blob I/O mechanism to not work. See
https://www.sqlite.org/withoutrowid.html

With disabled FKs downstream, simply moving from `WITHOUT ROWID` to
ordinary tables with rowids the initial sync in Linearlite for 5k issues
(and 25k comments) was reduced from 30 sec to 6-7sec

This explanation also matches my observations that cutting down the
bodies of the comments/issues to a few characters seemed to
significantly speed everything up, as it would make the rows smaller and
easily fit within pages and thus the inefficiency of accessing long
blobs that comes with regular B-trees doesn't come up

I've further confirmed that it's unrelated to WASM boundaries etc by
creating a temporary table, inserting data there, and then copying it to
the actual table with `INSERT ... SELECT ...` so the data transfer is
all done within WASM and SQLite and it's still slow - which makes sense
with the above. I've also removed all triggers to ensure that it's not a
non-disabled trigger that's causing the slowdown.

Additionally, in the Linearlite experiments, moving to having rowids
results in a smaller storage footprint despite having to store an
additional column of rowids and an index (21mb vs 26mb), and looking at
how wa-sqlite stores stuff in IndexedDB, since each entry is a 4kb page,
when using `WITHOUT ROWID` a lot of pages are mostly empty (since blobs
are not stored sequentially as they are in B*-trees) so it ends up with
~6k pages whereas with rowids it ends up with ~4k pages and sampling the
pages I don't seem to find empty blocks of data.

### Requirements
If using ordinary tables in SQLite, there are 3 things to consider:
1. It is not necessary to specify a primary key
2. Primary keys are not also checked for being `NOT NULL` by default
3. The oplog needs to ignore the added `rowid` column from using
ordinary tables and replication should work seamlessly

For (1), the migration proxy will reject any schema that does not
specify a primary key as electrification requires it, so even if
technically an SQLite schema without a primary key is valid it will not
be accepted by the migrations proxy.

For (2), the SQLite migrations are generated by translating PG schemas,
and that translation will always enforce that primary keys are also `NOT
NULL`, so the resulting SQLite migration will always have both a
`PRIMARY KEY` constraint along with a `NOT NULL` constraint.

For (3), the oplog triggers only capture the actual columns of the
specified table and do not include the `rowid`, so the replication is
unaffected by this change, at least from what I could tell and test.


### Consequences
This update means that any new SQLite migrations generated will not have
different table definitions (without `WITHOUT ROWID` in them), but that
isn't too much of an issue. I've checked that replication works fine
between clients using `WITHOUT ROWID` in their tables and ones without,
and clients are ephemeral either way so I wouldn't mark this as a
breaking change.

That being said, for users to see the performance benefits of this
change they _will_ need to regenerate their migrations/clients.

### Notes
For the full performance benefit measured, the foreign key checks also
need to be disabled when applying transactions in the client, which
currently can be done with an optional config key but is not enabled by
default. I think we need to consider enabling it by default before
releasing a patch.
  • Loading branch information
msfstef authored Jun 13, 2024
1 parent 31b8297 commit 7b4b8d4
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 128 deletions.
5 changes: 5 additions & 0 deletions .changeset/khaki-needles-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@core/electric": patch
---

Remove `WITHOUT ROWID` specification on SQLite migrations for improved performance.
2 changes: 1 addition & 1 deletion clients/typescript/test/client/notifications.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async function runAndCheckNotifications(f: () => Promise<void>) {
async function cleanDB() {
await adapter.run({ sql: 'DROP TABLE IF EXISTS Items' })
await adapter.run({
sql: 'CREATE TABLE IF NOT EXISTS Items (value TEXT PRIMARY KEY NOT NULL, nbr INTEGER) WITHOUT ROWID;',
sql: 'CREATE TABLE IF NOT EXISTS Items (value TEXT PRIMARY KEY NOT NULL, nbr INTEGER);',
})
}

Expand Down
18 changes: 5 additions & 13 deletions clients/typescript/test/migrators/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ export const makeMigrationMetaData = (builder: QueryBuilder) => {
stmts: [
SatOpMigrate_Stmt.fromPartial({
type: SatOpMigrate_Type.CREATE_TABLE,
sql: `CREATE TABLE "${
builder.defaultNamespace
}"."stars" (\n "id" TEXT NOT NULL PRIMARY KEY,\n "avatar_url" TEXT NOT NULL,\n "name" TEXT,\n "starred_at" TEXT NOT NULL,\n "username" TEXT NOT NULL\n)${builder.sqliteOnly(
' WITHOUT ROWID'
)};\n`,
sql: `CREATE TABLE "${builder.defaultNamespace}"."stars" (\n "id" TEXT NOT NULL PRIMARY KEY,\n "avatar_url" TEXT NOT NULL,\n "name" TEXT,\n "starred_at" TEXT NOT NULL,\n "username" TEXT NOT NULL\n);\n`,
}),
],
table: SatOpMigrate_Table.fromPartial({
Expand Down Expand Up @@ -118,11 +114,7 @@ export const builderTests = (test: TestFn<ContextType>) => {
t.is(migration.version, migrationMetaData.version)
t.is(
migration.statements[0],
`CREATE TABLE "${
builder.defaultNamespace
}"."stars" (\n "id" TEXT NOT NULL PRIMARY KEY,\n "avatar_url" TEXT NOT NULL,\n "name" TEXT,\n "starred_at" TEXT NOT NULL,\n "username" TEXT NOT NULL\n)${builder.sqliteOnly(
' WITHOUT ROWID'
)};\n`
`CREATE TABLE "${builder.defaultNamespace}"."stars" (\n "id" TEXT NOT NULL PRIMARY KEY,\n "avatar_url" TEXT NOT NULL,\n "name" TEXT,\n "starred_at" TEXT NOT NULL,\n "username" TEXT NOT NULL\n);\n`
)

if (builder.dialect === 'SQLite') {
Expand Down Expand Up @@ -176,7 +168,7 @@ export const builderTests = (test: TestFn<ContextType>) => {
stmts: [
SatOpMigrate_Stmt.fromPartial({
type: 0,
sql: `CREATE TABLE "${builder.defaultNamespace}"."tenants" (\n "id" TEXT NOT NULL,\n "name" TEXT NOT NULL,\n CONSTRAINT "tenants_pkey" PRIMARY KEY ("id")\n) WITHOUT ROWID;\n`,
sql: `CREATE TABLE "${builder.defaultNamespace}"."tenants" (\n "id" TEXT NOT NULL,\n "name" TEXT NOT NULL,\n CONSTRAINT "tenants_pkey" PRIMARY KEY ("id")\n);\n`,
}),
],
table: SatOpMigrate_Table.fromPartial({
Expand Down Expand Up @@ -214,7 +206,7 @@ export const builderTests = (test: TestFn<ContextType>) => {
stmts: [
SatOpMigrate_Stmt.fromPartial({
type: 0,
sql: `CREATE TABLE "${builder.defaultNamespace}"."users" (\n "id" TEXT NOT NULL,\n "name" TEXT NOT NULL,\n "email" TEXT NOT NULL,\n "password_hash" TEXT NOT NULL,\n CONSTRAINT "users_pkey" PRIMARY KEY ("id")\n) WITHOUT ROWID;\n`,
sql: `CREATE TABLE "${builder.defaultNamespace}"."users" (\n "id" TEXT NOT NULL,\n "name" TEXT NOT NULL,\n "email" TEXT NOT NULL,\n "password_hash" TEXT NOT NULL,\n CONSTRAINT "users_pkey" PRIMARY KEY ("id")\n);\n`,
}),
],
table: SatOpMigrate_Table.fromPartial({
Expand Down Expand Up @@ -268,7 +260,7 @@ export const builderTests = (test: TestFn<ContextType>) => {
stmts: [
SatOpMigrate_Stmt.fromPartial({
type: 0,
sql: `CREATE TABLE "${builder.defaultNamespace}"."tenant_users" (\n "tenant_id" TEXT NOT NULL,\n "user_id" TEXT NOT NULL,\n CONSTRAINT "tenant_users_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants" ("id") ON DELETE CASCADE,\n CONSTRAINT "tenant_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE,\n CONSTRAINT "tenant_users_pkey" PRIMARY KEY ("tenant_id", "user_id")\n) WITHOUT ROWID;\n`,
sql: `CREATE TABLE "${builder.defaultNamespace}"."tenant_users" (\n "tenant_id" TEXT NOT NULL,\n "user_id" TEXT NOT NULL,\n CONSTRAINT "tenant_users_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants" ("id") ON DELETE CASCADE,\n CONSTRAINT "tenant_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE,\n CONSTRAINT "tenant_users_pkey" PRIMARY KEY ("tenant_id", "user_id")\n);\n`,
}),
],
table: SatOpMigrate_Table.fromPartial({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ CREATE TABLE "stars" (
"starred_at" TEXT NOT NULL,
"username" TEXT NOT NULL,
CONSTRAINT "stars_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ CREATE TABLE "beers" (
"star_id" TEXT,
CONSTRAINT "beers_star_id_fkey" FOREIGN KEY ("star_id") REFERENCES "stars" ("id"),
CONSTRAINT "beers_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
4 changes: 2 additions & 2 deletions clients/typescript/test/satellite/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ test.serial('migration transaction contains all information', async (t) => {
stmts: [
Proto.SatOpMigrate_Stmt.create({
type: Proto.SatOpMigrate_Type.CREATE_TABLE,
sql: 'CREATE TABLE "foo" (\n "value" TEXT NOT NULL,\n CONSTRAINT "foo_pkey" PRIMARY KEY ("value")\n) WITHOUT ROWID;\n',
sql: 'CREATE TABLE "foo" (\n "value" TEXT NOT NULL,\n CONSTRAINT "foo_pkey" PRIMARY KEY ("value")\n);\n',
}),
],
table: Proto.SatOpMigrate_Table.create({
Expand Down Expand Up @@ -485,7 +485,7 @@ test.serial('migration transaction contains all information', async (t) => {
{
migrationType: Proto.SatOpMigrate_Type.CREATE_TABLE,
table: migrate.table,
sql: 'CREATE TABLE "foo" (\n "value" TEXT NOT NULL,\n CONSTRAINT "foo_pkey" PRIMARY KEY ("value")\n) WITHOUT ROWID;\n',
sql: 'CREATE TABLE "foo" (\n "value" TEXT NOT NULL,\n CONSTRAINT "foo_pkey" PRIMARY KEY ("value")\n);\n',
},
],
origin: begin.origin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ Write your SQLite migration below.
*/
CREATE TABLE IF NOT EXISTS items (
value TEXT PRIMARY KEY NOT NULL
) WITHOUT ROWID;
);

CREATE TABLE IF NOT EXISTS parent (
id INTEGER PRIMARY KEY NOT NULL,
value TEXT,
other INTEGER DEFAULT 0
) WITHOUT ROWID;
);

CREATE TABLE IF NOT EXISTS child (
id INTEGER PRIMARY KEY NOT NULL,
parent INTEGER NOT NULL,
FOREIGN KEY(parent) REFERENCES parent(id)
) WITHOUT ROWID;
);
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
CREATE TABLE IF NOT EXISTS items (
value TEXT PRIMARY KEY NOT NULL
) WITHOUT ROWID;
);

CREATE TABLE IF NOT EXISTS parent (
id INTEGER PRIMARY KEY NOT NULL,
value TEXT,
other INTEGER DEFAULT 0
) WITHOUT ROWID;
);

CREATE TABLE IF NOT EXISTS child (
id INTEGER PRIMARY KEY NOT NULL,
parent INTEGER NOT NULL,
FOREIGN KEY(parent) REFERENCES parent(id)
) WITHOUT ROWID;
);

/*---------------------------------------------
Below are templated triggers added by Satellite
Expand Down
6 changes: 3 additions & 3 deletions clients/typescript/test/support/migrations/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"name": "20230123_170646_833_test_schema",
"postgres_body": "\nCREATE TABLE public.parent (\n id bigint PRIMARY KEY,\n value text,\n other bigint DEFAULT 0);\nALTER TABLE public.parent REPLICA IDENTITY FULL;\n\nCREATE TABLE public.items (\n value text PRIMARY KEY);\nALTER TABLE public.items REPLICA IDENTITY FULL;\n\nCREATE TABLE public.child (\n id bigint PRIMARY KEY,\n parent bigint NOT NULL,\n FOREIGN KEY(parent) REFERENCES parent(id) MATCH SIMPLE);\nALTER TABLE public.child REPLICA IDENTITY FULL;\n",
"satellite_body": [
"CREATE TABLE IF NOT EXISTS items (\n value TEXT PRIMARY KEY NOT NULL\n) WITHOUT ROWID;",
"CREATE TABLE IF NOT EXISTS parent (\n id INTEGER PRIMARY KEY NOT NULL,\n value TEXT,\n other INTEGER DEFAULT 0\n) WITHOUT ROWID;",
"CREATE TABLE IF NOT EXISTS child (\n id INTEGER PRIMARY KEY NOT NULL,\n parent INTEGER NOT NULL,\n FOREIGN KEY(parent) REFERENCES parent(id)\n) WITHOUT ROWID;",
"CREATE TABLE IF NOT EXISTS items (\n value TEXT PRIMARY KEY NOT NULL\n);",
"CREATE TABLE IF NOT EXISTS parent (\n id INTEGER PRIMARY KEY NOT NULL,\n value TEXT,\n other INTEGER DEFAULT 0\n);",
"CREATE TABLE IF NOT EXISTS child (\n id INTEGER PRIMARY KEY NOT NULL,\n parent INTEGER NOT NULL,\n FOREIGN KEY(parent) REFERENCES parent(id)\n);",
"DROP TABLE IF EXISTS _electric_trigger_settings;",
"CREATE TABLE _electric_trigger_settings(tablename TEXT PRIMARY KEY, flag INTEGER);",
"INSERT INTO _electric_trigger_settings(tablename,flag) VALUES ('main.child', 1);",
Expand Down
10 changes: 5 additions & 5 deletions clients/typescript/test/support/migrations/migrations.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ defmodule Electric.Postgres.Dialect.SQLite do
"("
]),
stmt(defn, join, pretty),
") WITHOUT ROWID;",
");",
""
],
if(pretty, do: "\n", else: "")
Expand Down
14 changes: 7 additions & 7 deletions components/electric/test/electric/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@ defmodule Electric.PlugTest do

assert [
{~c"0001/migration.sql",
"CREATE TABLE \"a\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"a_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n\nCREATE INDEX \"a_idx\" ON \"a\" (\"value\" ASC);\n\nCREATE TABLE \"b\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"b_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;"},
"CREATE TABLE \"a\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"a_pkey\" PRIMARY KEY (\"id\")\n);\n\nCREATE INDEX \"a_idx\" ON \"a\" (\"value\" ASC);\n\nCREATE TABLE \"b\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"b_pkey\" PRIMARY KEY (\"id\")\n);"},
{~c"0001/metadata.json", metadata_json_0001},
{~c"0002/migration.sql",
"CREATE TABLE \"c\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"c_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;"},
"CREATE TABLE \"c\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"c_pkey\" PRIMARY KEY (\"id\")\n);"},
{~c"0002/metadata.json", metadata_json_0002},
{~c"0003/migration.sql",
"CREATE TABLE \"d\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"d_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n\nALTER TABLE \"d\" ADD COLUMN \"is_valid\" INTEGER;"},
"CREATE TABLE \"d\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"d_pkey\" PRIMARY KEY (\"id\")\n);\n\nALTER TABLE \"d\" ADD COLUMN \"is_valid\" INTEGER;"},
{~c"0003/metadata.json", metadata_json_0003},
{~c"0004/migration.sql",
"CREATE TABLE \"e\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"e_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;"},
"CREATE TABLE \"e\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"e_pkey\" PRIMARY KEY (\"id\")\n);"},
{~c"0004/metadata.json", metadata_json_0004}
] = file_list

Expand All @@ -98,7 +98,7 @@ defmodule Electric.PlugTest do
%SatOpMigrate.Stmt{
type: :CREATE_TABLE,
sql:
"CREATE TABLE \"a\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"a_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n"
"CREATE TABLE \"a\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"a_pkey\" PRIMARY KEY (\"id\")\n);\n"
},
%SatOpMigrate.Stmt{
type: :CREATE_INDEX,
Expand Down Expand Up @@ -226,10 +226,10 @@ defmodule Electric.PlugTest do

assert [
{~c"0003/migration.sql",
"CREATE TABLE \"d\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"d_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n\nALTER TABLE \"d\" ADD COLUMN \"is_valid\" INTEGER;"},
"CREATE TABLE \"d\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"d_pkey\" PRIMARY KEY (\"id\")\n);\n\nALTER TABLE \"d\" ADD COLUMN \"is_valid\" INTEGER;"},
{~c"0003/metadata.json", metadata_json_0003},
{~c"0004/migration.sql",
"CREATE TABLE \"e\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"e_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;"},
"CREATE TABLE \"e\" (\n \"id\" TEXT NOT NULL,\n \"value\" TEXT NOT NULL,\n CONSTRAINT \"e_pkey\" PRIMARY KEY (\"id\")\n);"},
{~c"0004/metadata.json", metadata_json_0004}
] = file_list

Expand Down
24 changes: 12 additions & 12 deletions components/electric/test/electric/postgres/dialect/sqlite_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"i6" INTEGER,
"i7" REAL,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand Down Expand Up @@ -154,7 +154,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
~s["i6" INTEGER,],
~s["i7" REAL,],
~s[CONSTRAINT "i_pkey" PRIMARY KEY ("id")],
~s[) WITHOUT ROWID;]
~s[);]
])
end

Expand All @@ -169,7 +169,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
CREATE TABLE IF NOT EXISTS "i" (
"id" INTEGER NOT NULL,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand All @@ -186,7 +186,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
CREATE TABLE "i" (
"id" INTEGER NOT NULL,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand All @@ -205,7 +205,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"id" INTEGER NOT NULL,
"name" TEXT(256) NOT NULL,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand All @@ -230,7 +230,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
CONSTRAINT "i_j_id_fkey" FOREIGN KEY ("j_id") REFERENCES "j" ("id") ON DELETE CASCADE ON UPDATE SET DEFAULT,
CONSTRAINT "i_j_id2_fkey" FOREIGN KEY ("j_id2") REFERENCES "j" ("id"),
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand Down Expand Up @@ -258,7 +258,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
CONSTRAINT "starts" CHECK ((substring("c3", 1, 3) == 'his')),
CONSTRAINT "percent" CHECK ((("c2" >= 0) AND ("c2" <= 100))),
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand All @@ -278,7 +278,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"c1" INTEGER,
CONSTRAINT "i_pkey" PRIMARY KEY ("id"),
CONSTRAINT "i_c1_key" UNIQUE ("c1")
) WITHOUT ROWID;
);
"""
end

Expand All @@ -301,7 +301,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"c2" INTEGER,
CONSTRAINT "i_pkey" PRIMARY KEY ("id"),
CONSTRAINT "i_c1_c2_key" UNIQUE ("c1", "c2")
) WITHOUT ROWID;
);
"""
end

Expand Down Expand Up @@ -336,7 +336,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"c8" INTEGER DEFAULT (CAST('13' AS INTEGER)),
"c9" TEXT DEFAULT current_timestamp,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end

Expand Down Expand Up @@ -364,7 +364,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"vv1" TEXT GENERATED ALWAYS AS ("v1" || "v2") STORED,
"vv2" TEXT GENERATED ALWAYS AS (coalesce(upper("v1"), '') || coalesce(ltrim("v2", 'x'), '') || coalesce("v3", '')) STORED,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end
end
Expand Down Expand Up @@ -465,7 +465,7 @@ defmodule Electric.Postgres.Dialect.SqliteTest do
"id" INTEGER NOT NULL,
"k" INTEGER DEFAULT '0' NOT NULL,
CONSTRAINT "i_pkey" PRIMARY KEY ("id")
) WITHOUT ROWID;
);
"""
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ defmodule Electric.Postgres.ReplicationTest do
%SatOpMigrate.Stmt{
type: :CREATE_TABLE,
sql:
"CREATE TABLE \"fish\" (\n \"id\" INTEGER NOT NULL,\n CONSTRAINT \"fish_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n"
"CREATE TABLE \"fish\" (\n \"id\" INTEGER NOT NULL,\n CONSTRAINT \"fish_pkey\" PRIMARY KEY (\"id\")\n);\n"
}
]

Expand Down Expand Up @@ -175,7 +175,7 @@ defmodule Electric.Postgres.ReplicationTest do
%SatOpMigrate.Stmt{
type: :CREATE_TABLE,
sql:
"CREATE TABLE \"front\" (\n \"id\" INTEGER NOT NULL,\n \"frog_id\" INTEGER NOT NULL,\n CONSTRAINT \"front_frog_id_fkey\" FOREIGN KEY (\"frog_id\") REFERENCES \"fish\" (\"id\"),\n CONSTRAINT \"front_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n"
"CREATE TABLE \"front\" (\n \"id\" INTEGER NOT NULL,\n \"frog_id\" INTEGER NOT NULL,\n CONSTRAINT \"front_frog_id_fkey\" FOREIGN KEY (\"frog_id\") REFERENCES \"fish\" (\"id\"),\n CONSTRAINT \"front_pkey\" PRIMARY KEY (\"id\")\n);\n"
}
]

Expand Down Expand Up @@ -345,7 +345,7 @@ defmodule Electric.Postgres.ReplicationTest do
%SatOpMigrate.Stmt{
type: :CREATE_TABLE,
sql:
"CREATE TABLE \"wall\" (\n \"id\" INTEGER NOT NULL,\n \"finish\" TEXT,\n CONSTRAINT \"wall_pkey\" PRIMARY KEY (\"id\")\n) WITHOUT ROWID;\n"
"CREATE TABLE \"wall\" (\n \"id\" INTEGER NOT NULL,\n \"finish\" TEXT,\n CONSTRAINT \"wall_pkey\" PRIMARY KEY (\"id\")\n);\n"
}
]

Expand Down
Loading

0 comments on commit 7b4b8d4

Please sign in to comment.