@powersync/service-module-postgres 0.19.2 → 0.19.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/PostgresRouteAPIAdapter.d.ts +1 -1
- package/dist/api/PostgresRouteAPIAdapter.js +63 -72
- package/dist/api/PostgresRouteAPIAdapter.js.map +1 -1
- package/dist/module/PostgresModule.js.map +1 -1
- package/dist/replication/MissingReplicationSlotError.d.ts +41 -0
- package/dist/replication/MissingReplicationSlotError.js +33 -0
- package/dist/replication/MissingReplicationSlotError.js.map +1 -0
- package/dist/replication/PostgresErrorRateLimiter.js +1 -1
- package/dist/replication/PostgresErrorRateLimiter.js.map +1 -1
- package/dist/replication/SnapshotQuery.js +2 -2
- package/dist/replication/SnapshotQuery.js.map +1 -1
- package/dist/replication/WalStream.d.ts +37 -14
- package/dist/replication/WalStream.js +145 -41
- package/dist/replication/WalStream.js.map +1 -1
- package/dist/replication/WalStreamReplicationJob.d.ts +1 -1
- package/dist/replication/WalStreamReplicationJob.js +7 -4
- package/dist/replication/WalStreamReplicationJob.js.map +1 -1
- package/dist/replication/WalStreamReplicator.d.ts +0 -1
- package/dist/replication/WalStreamReplicator.js +0 -22
- package/dist/replication/WalStreamReplicator.js.map +1 -1
- package/dist/replication/replication-index.d.ts +3 -1
- package/dist/replication/replication-index.js +3 -1
- package/dist/replication/replication-index.js.map +1 -1
- package/dist/replication/replication-utils.d.ts +3 -11
- package/dist/replication/replication-utils.js +101 -164
- package/dist/replication/replication-utils.js.map +1 -1
- package/dist/replication/wal-budget-utils.d.ts +23 -0
- package/dist/replication/wal-budget-utils.js +57 -0
- package/dist/replication/wal-budget-utils.js.map +1 -0
- package/dist/types/registry.js +1 -1
- package/dist/types/registry.js.map +1 -1
- package/package.json +15 -11
- package/sql/check-source-configuration.plpgsql +13 -0
- package/sql/debug-tables-info-batched.plpgsql +230 -0
- package/CHANGELOG.md +0 -843
- package/src/api/PostgresRouteAPIAdapter.ts +0 -356
- package/src/index.ts +0 -1
- package/src/module/PostgresModule.ts +0 -122
- package/src/replication/ConnectionManagerFactory.ts +0 -33
- package/src/replication/PgManager.ts +0 -122
- package/src/replication/PgRelation.ts +0 -41
- package/src/replication/PostgresErrorRateLimiter.ts +0 -48
- package/src/replication/SnapshotQuery.ts +0 -213
- package/src/replication/WalStream.ts +0 -1157
- package/src/replication/WalStreamReplicationJob.ts +0 -138
- package/src/replication/WalStreamReplicator.ts +0 -79
- package/src/replication/replication-index.ts +0 -5
- package/src/replication/replication-utils.ts +0 -398
- package/src/types/registry.ts +0 -275
- package/src/types/resolver.ts +0 -227
- package/src/types/types.ts +0 -44
- package/src/utils/application-name.ts +0 -8
- package/src/utils/migration_lib.ts +0 -80
- package/src/utils/populate_test_data.ts +0 -37
- package/src/utils/populate_test_data_worker.ts +0 -53
- package/src/utils/postgres_version.ts +0 -8
- package/test/src/checkpoints.test.ts +0 -86
- package/test/src/chunked_snapshots.test.ts +0 -161
- package/test/src/env.ts +0 -11
- package/test/src/large_batch.test.ts +0 -241
- package/test/src/pg_test.test.ts +0 -729
- package/test/src/resuming_snapshots.test.ts +0 -160
- package/test/src/route_api_adapter.test.ts +0 -62
- package/test/src/schema_changes.test.ts +0 -655
- package/test/src/setup.ts +0 -12
- package/test/src/slow_tests.test.ts +0 -519
- package/test/src/storage_combination.test.ts +0 -35
- package/test/src/types/registry.test.ts +0 -149
- package/test/src/util.ts +0 -151
- package/test/src/validation.test.ts +0 -63
- package/test/src/wal_stream.test.ts +0 -607
- package/test/src/wal_stream_utils.ts +0 -284
- package/test/tsconfig.json +0 -27
- package/tsconfig.json +0 -34
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -3
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
DO $$
|
|
2
|
+
DECLARE
|
|
3
|
+
input_patterns jsonb := current_setting('powersync.debug.table_patterns', true)::jsonb;
|
|
4
|
+
current_publication text := current_setting('powersync.debug.publication_name', true);
|
|
5
|
+
select_probe_results jsonb := '[]'::jsonb;
|
|
6
|
+
debug_cursor refcursor := 'powersync_debug_tables_cursor';
|
|
7
|
+
select_target record;
|
|
8
|
+
BEGIN
|
|
9
|
+
-- Capture per-table read failures without aborting the whole batch.
|
|
10
|
+
FOR select_target IN
|
|
11
|
+
WITH patterns AS (
|
|
12
|
+
SELECT *
|
|
13
|
+
FROM jsonb_to_recordset(input_patterns) AS p(
|
|
14
|
+
pattern_ord int,
|
|
15
|
+
schema_name text,
|
|
16
|
+
table_pattern text,
|
|
17
|
+
is_wildcard boolean,
|
|
18
|
+
table_prefix text,
|
|
19
|
+
input_name text
|
|
20
|
+
)
|
|
21
|
+
)
|
|
22
|
+
SELECT
|
|
23
|
+
p.pattern_ord,
|
|
24
|
+
p.schema_name,
|
|
25
|
+
c.relname AS table_name,
|
|
26
|
+
c.oid::int8 AS relid
|
|
27
|
+
FROM patterns p
|
|
28
|
+
JOIN pg_namespace n ON n.nspname = p.schema_name
|
|
29
|
+
JOIN pg_class c ON c.relnamespace = n.oid
|
|
30
|
+
WHERE c.relkind = 'r'
|
|
31
|
+
AND (
|
|
32
|
+
(p.is_wildcard AND c.relname LIKE p.table_pattern AND left(c.relname, length(p.table_prefix)) = p.table_prefix)
|
|
33
|
+
OR
|
|
34
|
+
(NOT p.is_wildcard AND c.relname = p.table_pattern)
|
|
35
|
+
)
|
|
36
|
+
ORDER BY p.pattern_ord, c.relname
|
|
37
|
+
LOOP
|
|
38
|
+
BEGIN
|
|
39
|
+
-- Query a single row from each table, to confirm that we can query the table
|
|
40
|
+
-- (no permission errors)
|
|
41
|
+
-- %I covers identifier escaping
|
|
42
|
+
EXECUTE format('SELECT 1 FROM %I.%I LIMIT 1', select_target.schema_name, select_target.table_name);
|
|
43
|
+
select_probe_results := select_probe_results || jsonb_build_array(
|
|
44
|
+
jsonb_build_object(
|
|
45
|
+
'pattern_ord', select_target.pattern_ord,
|
|
46
|
+
'relid', select_target.relid,
|
|
47
|
+
'message', NULL
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
EXCEPTION WHEN OTHERS THEN
|
|
51
|
+
select_probe_results := select_probe_results || jsonb_build_array(
|
|
52
|
+
jsonb_build_object(
|
|
53
|
+
'pattern_ord', select_target.pattern_ord,
|
|
54
|
+
'relid', select_target.relid,
|
|
55
|
+
'message', SQLERRM
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
END;
|
|
59
|
+
END LOOP;
|
|
60
|
+
|
|
61
|
+
-- OPEN debug_cursor to allow returning results
|
|
62
|
+
OPEN debug_cursor FOR
|
|
63
|
+
WITH patterns AS (
|
|
64
|
+
-- Rehydrate the requested patterns once for the bulk metadata pass.
|
|
65
|
+
SELECT *
|
|
66
|
+
FROM jsonb_to_recordset(input_patterns) AS p(
|
|
67
|
+
pattern_ord int,
|
|
68
|
+
schema_name text,
|
|
69
|
+
table_pattern text,
|
|
70
|
+
is_wildcard boolean,
|
|
71
|
+
table_prefix text,
|
|
72
|
+
input_name text
|
|
73
|
+
)
|
|
74
|
+
),
|
|
75
|
+
matched AS (
|
|
76
|
+
-- Expand each requested pattern to the concrete tables that exist.
|
|
77
|
+
SELECT
|
|
78
|
+
p.pattern_ord,
|
|
79
|
+
p.schema_name,
|
|
80
|
+
p.table_pattern,
|
|
81
|
+
p.is_wildcard,
|
|
82
|
+
p.input_name,
|
|
83
|
+
c.relid,
|
|
84
|
+
c.table_name,
|
|
85
|
+
c.relreplident,
|
|
86
|
+
c.relrowsecurity
|
|
87
|
+
FROM patterns p
|
|
88
|
+
LEFT JOIN LATERAL (
|
|
89
|
+
SELECT
|
|
90
|
+
c.oid::int8 AS relid,
|
|
91
|
+
c.relname AS table_name,
|
|
92
|
+
c.relreplident,
|
|
93
|
+
c.relrowsecurity
|
|
94
|
+
FROM pg_namespace n
|
|
95
|
+
JOIN pg_class c ON c.relnamespace = n.oid
|
|
96
|
+
WHERE n.nspname = p.schema_name
|
|
97
|
+
AND c.relkind = 'r'
|
|
98
|
+
AND (
|
|
99
|
+
(p.is_wildcard AND c.relname LIKE p.table_pattern AND left(c.relname, length(p.table_prefix)) = p.table_prefix)
|
|
100
|
+
OR
|
|
101
|
+
(NOT p.is_wildcard AND c.relname = p.table_pattern)
|
|
102
|
+
)
|
|
103
|
+
ORDER BY c.relname
|
|
104
|
+
) c ON true
|
|
105
|
+
WHERE NOT p.is_wildcard OR c.relid IS NOT NULL
|
|
106
|
+
),
|
|
107
|
+
existing AS (
|
|
108
|
+
-- Deduplicate matched tables while carrying the pg_class metadata we already have.
|
|
109
|
+
SELECT DISTINCT
|
|
110
|
+
relid::oid AS relid,
|
|
111
|
+
CASE relreplident
|
|
112
|
+
WHEN 'd' THEN 'default'
|
|
113
|
+
WHEN 'n' THEN 'nothing'
|
|
114
|
+
WHEN 'f' THEN 'full'
|
|
115
|
+
WHEN 'i' THEN 'index'
|
|
116
|
+
END AS replication_identity,
|
|
117
|
+
relrowsecurity AS rls_enabled
|
|
118
|
+
FROM matched
|
|
119
|
+
WHERE relid IS NOT NULL
|
|
120
|
+
),
|
|
121
|
+
replication_columns AS (
|
|
122
|
+
-- Resolve the actual replication-id columns for default/index/full modes.
|
|
123
|
+
SELECT
|
|
124
|
+
e.relid,
|
|
125
|
+
a.attname AS name,
|
|
126
|
+
a.attnum AS attnum
|
|
127
|
+
FROM existing e
|
|
128
|
+
JOIN pg_index i ON i.indrelid = e.relid AND i.indisprimary
|
|
129
|
+
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
130
|
+
WHERE e.replication_identity = 'default' AND a.attnum > 0
|
|
131
|
+
|
|
132
|
+
UNION ALL
|
|
133
|
+
|
|
134
|
+
SELECT
|
|
135
|
+
e.relid,
|
|
136
|
+
a.attname AS name,
|
|
137
|
+
a.attnum AS attnum
|
|
138
|
+
FROM existing e
|
|
139
|
+
JOIN pg_index i ON i.indrelid = e.relid AND i.indisreplident
|
|
140
|
+
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
141
|
+
WHERE e.replication_identity = 'index' AND a.attnum > 0
|
|
142
|
+
|
|
143
|
+
UNION ALL
|
|
144
|
+
|
|
145
|
+
SELECT
|
|
146
|
+
e.relid,
|
|
147
|
+
a.attname AS name,
|
|
148
|
+
a.attnum AS attnum
|
|
149
|
+
FROM existing e
|
|
150
|
+
JOIN pg_attribute a ON a.attrelid = e.relid
|
|
151
|
+
WHERE e.replication_identity = 'full' AND a.attnum > 0
|
|
152
|
+
),
|
|
153
|
+
publication_membership AS (
|
|
154
|
+
-- Check publication membership in bulk instead of once per table.
|
|
155
|
+
SELECT
|
|
156
|
+
m.pattern_ord,
|
|
157
|
+
m.relid
|
|
158
|
+
FROM matched m
|
|
159
|
+
JOIN pg_publication_tables p
|
|
160
|
+
ON p.pubname = current_publication
|
|
161
|
+
AND p.schemaname = m.schema_name
|
|
162
|
+
AND p.tablename = m.table_name
|
|
163
|
+
WHERE m.relid IS NOT NULL
|
|
164
|
+
),
|
|
165
|
+
user_info AS (
|
|
166
|
+
-- Current-role capabilities are constant across all tables in this batch.
|
|
167
|
+
SELECT
|
|
168
|
+
current_user AS username,
|
|
169
|
+
r.rolsuper AS is_superuser,
|
|
170
|
+
r.rolbypassrls AS bypasses_rls
|
|
171
|
+
FROM pg_roles r
|
|
172
|
+
WHERE r.rolname = current_user
|
|
173
|
+
),
|
|
174
|
+
rls_check AS (
|
|
175
|
+
-- Pair role capabilities with the row-security metadata already carried from pg_class.
|
|
176
|
+
SELECT
|
|
177
|
+
e.relid::int8 AS relid,
|
|
178
|
+
e.rls_enabled,
|
|
179
|
+
u.username,
|
|
180
|
+
u.is_superuser,
|
|
181
|
+
u.bypasses_rls
|
|
182
|
+
FROM existing e
|
|
183
|
+
CROSS JOIN user_info u
|
|
184
|
+
),
|
|
185
|
+
select_probes AS (
|
|
186
|
+
-- Rehydrate the recorded SELECT probe failures for the final result set.
|
|
187
|
+
SELECT *
|
|
188
|
+
FROM jsonb_to_recordset(select_probe_results) AS s(
|
|
189
|
+
pattern_ord int,
|
|
190
|
+
relid int8,
|
|
191
|
+
message text
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
SELECT
|
|
195
|
+
m.pattern_ord,
|
|
196
|
+
m.schema_name,
|
|
197
|
+
COALESCE(m.table_name, m.input_name) AS name,
|
|
198
|
+
m.relid AS relation_id,
|
|
199
|
+
e.replication_identity,
|
|
200
|
+
COALESCE(
|
|
201
|
+
jsonb_agg(rc.name ORDER BY rc.attnum) FILTER (WHERE rc.name IS NOT NULL),
|
|
202
|
+
'[]'::jsonb
|
|
203
|
+
)::text AS replication_id_json,
|
|
204
|
+
sp.message AS select_error,
|
|
205
|
+
(pm.relid IS NOT NULL) AS in_publication,
|
|
206
|
+
rls.rls_enabled,
|
|
207
|
+
rls.username,
|
|
208
|
+
rls.is_superuser,
|
|
209
|
+
rls.bypasses_rls
|
|
210
|
+
FROM matched m
|
|
211
|
+
LEFT JOIN existing e ON e.relid = m.relid
|
|
212
|
+
LEFT JOIN replication_columns rc ON rc.relid = m.relid
|
|
213
|
+
LEFT JOIN publication_membership pm ON pm.pattern_ord = m.pattern_ord AND pm.relid = m.relid
|
|
214
|
+
LEFT JOIN rls_check rls ON rls.relid = m.relid
|
|
215
|
+
LEFT JOIN select_probes sp ON sp.pattern_ord = m.pattern_ord AND sp.relid = m.relid
|
|
216
|
+
GROUP BY
|
|
217
|
+
m.pattern_ord,
|
|
218
|
+
m.schema_name,
|
|
219
|
+
COALESCE(m.table_name, m.input_name),
|
|
220
|
+
m.relid,
|
|
221
|
+
e.replication_identity,
|
|
222
|
+
sp.message,
|
|
223
|
+
pm.relid,
|
|
224
|
+
rls.rls_enabled,
|
|
225
|
+
rls.username,
|
|
226
|
+
rls.is_superuser,
|
|
227
|
+
rls.bypasses_rls
|
|
228
|
+
ORDER BY m.pattern_ord, COALESCE(m.table_name, m.input_name);
|
|
229
|
+
END
|
|
230
|
+
$$
|