+4
-4
consumer/src/db/operations/feed/like.rs
+4
-4
consumer/src/db/operations/feed/like.rs
···
242
242
// - Without post actor_id: scans all segments, ~50-500ms
243
243
// - With post actor_id: selective decompression, ~0.5ms
244
244
//
245
-
// The like's rkey tells us the earliest possible chunk (posts can only have likes created
246
-
// after the post itself), so we filter rkey >= like_rkey to avoid scanning old chunks.
245
+
// The like's rkey tells us the latest possible chunk (posts can only have likes created
246
+
// after the post itself), so we filter rkey <= like_rkey to avoid scanning newer chunks.
247
247
248
-
// Step 1: Find which post has this like (rkey >= $1 for chunk exclusion)
248
+
// Step 1: Find which post has this like (rkey <= $1 for chunk exclusion)
249
249
let post_key = conn
250
250
.query_opt(
251
251
"SELECT actor_id, rkey
252
252
FROM posts
253
253
WHERE $2 = ANY(like_actor_ids)
254
254
AND $1 = ANY(like_rkeys)
255
-
AND rkey >= $1
255
+
AND rkey <= $1
256
256
LIMIT 1",
257
257
&[&rkey, &actor_id],
258
258
)
+8
-8
parakeet-db/src/tid_util.rs
+8
-8
parakeet-db/src/tid_util.rs
···
74
74
table
75
75
};
76
76
77
-
/// Minimum valid TID timestamp (2022-01-01 00:00:00 UTC in microseconds) (2023 is probably more accurate but we'll be slightly permissive)
78
-
const MIN_VALID_TIMESTAMP_MICROS: i64 = 1_640_995_200_000_000; // 2022-01-01
77
+
/// Minimum valid TID timestamp (2023-01-01 00:00:00 UTC in microseconds)
78
+
const MIN_VALID_TIMESTAMP_MICROS: i64 = 1_672_531_200_000_000; // 2023-01-01
79
79
80
-
/// Maximum valid TID timestamp (2028-01-01 00:00:00 UTC in microseconds)
81
-
const MAX_VALID_TIMESTAMP_MICROS: i64 = 1_830_297_600_000_000; // 2028-01-01 (exclusive)
80
+
/// Maximum valid TID timestamp (2027-01-01 00:00:00 UTC in microseconds, exclusive)
81
+
const MAX_VALID_TIMESTAMP_MICROS: i64 = 1_798_761_600_000_000; // 2027-01-01 (exclusive)
82
82
83
83
/// Error type for TID operations
84
84
#[derive(Debug, Clone, PartialEq, Eq)]
···
117
117
TidError::TimestampOutOfRange { timestamp_micros } => {
118
118
write!(
119
119
f,
120
-
"TID timestamp {} is outside valid range (2022-01-01 to 2027-12-31)",
120
+
"TID timestamp {} is outside valid range (2023-01-01 to 2026-12-31)",
121
121
timestamp_micros
122
122
)
123
123
}
···
165
165
return false;
166
166
}
167
167
168
-
// Decode TID to check timestamp range (2022-2028 inclusive)
168
+
// Decode TID to check timestamp range (2023-2026 inclusive)
169
169
// This is a fast decode-in-place without error handling since we already validated format
170
170
let mut result: i64 = 0;
171
171
for &byte in bytes {
···
176
176
// Extract timestamp (upper 53 bits, shift right by 10 to remove clock ID)
177
177
let timestamp_micros = result >> 10;
178
178
179
-
// Check if timestamp is within valid range (2022-01-01 to 2027-12-31)
179
+
// Check if timestamp is within valid range (2023-01-01 to 2026-12-31)
180
180
(MIN_VALID_TIMESTAMP_MICROS..MAX_VALID_TIMESTAMP_MICROS).contains(×tamp_micros)
181
181
}
182
182
···
246
246
// Extract timestamp (upper 53 bits, shift right by 10 to remove clock ID)
247
247
let timestamp_micros = result >> 10;
248
248
249
-
// Check if timestamp is within valid range (2022-01-01 to 2027-12-31)
249
+
// Check if timestamp is within valid range (2023-01-01 to 2026-12-31)
250
250
if !(MIN_VALID_TIMESTAMP_MICROS..MAX_VALID_TIMESTAMP_MICROS).contains(×tamp_micros) {
251
251
return Err(TidError::TimestampOutOfRange { timestamp_micros });
252
252
}
+26
-10
parakeet/tests/sql/batch_loading_test.rs
+26
-10
parakeet/tests/sql/batch_loading_test.rs
···
148
148
149
149
// Use the ACTUAL query builder from the source code
150
150
let query = parakeet::loaders::build_lists_batch_query();
151
-
let uris = vec!["at://did:plc:test/app.bsky.graph.list/123"];
151
+
152
+
// The query expects owner_actor_ids and rkeys as separate arrays
153
+
// For testing, we just need to ensure the query is valid
154
+
let actor_ids = vec![1i32]; // Sample actor IDs
155
+
let rkeys = vec!["123".to_string()]; // Sample rkeys
152
156
153
157
diesel_async::RunQueryDsl::execute(
154
158
diesel::sql_query(query)
155
-
.bind::<Array<diesel::sql_types::Text>, _>(&uris),
159
+
.bind::<Array<diesel::sql_types::Integer>, _>(&actor_ids)
160
+
.bind::<Array<diesel::sql_types::Text>, _>(&rkeys),
156
161
&mut conn,
157
162
)
158
163
.await
···
170
175
171
176
// Use the ACTUAL query builder from the source code
172
177
let query = parakeet::loaders::build_feedgens_batch_query();
173
-
let uris = vec!["at://did:plc:test/app.bsky.feed.generator/123"];
178
+
179
+
// The query expects owner_actor_ids and rkeys as separate arrays
180
+
// For testing, we just need to ensure the query is valid
181
+
let actor_ids = vec![1i32]; // Sample actor IDs
182
+
let rkeys = vec!["123".to_string()]; // Sample rkeys
174
183
175
184
diesel_async::RunQueryDsl::execute(
176
185
diesel::sql_query(query)
177
-
.bind::<Array<diesel::sql_types::Text>, _>(&uris),
186
+
.bind::<Array<diesel::sql_types::Integer>, _>(&actor_ids)
187
+
.bind::<Array<diesel::sql_types::Text>, _>(&rkeys),
178
188
&mut conn,
179
189
)
180
190
.await
···
192
202
193
203
// Use the ACTUAL query builder from the source code
194
204
let query = parakeet::loaders::build_starterpacks_batch_query();
195
-
let uris = vec!["at://did:plc:test/app.bsky.graph.starterpack/123"];
205
+
206
+
// The query expects owner_actor_ids and rkeys as separate arrays
207
+
// For testing, we just need to ensure the query is valid
208
+
let actor_ids = vec![1i32]; // Sample actor IDs
209
+
let rkeys = vec![123i64]; // Sample rkeys (bigint for starterpacks)
196
210
197
211
diesel_async::RunQueryDsl::execute(
198
212
diesel::sql_query(query)
199
-
.bind::<Array<diesel::sql_types::Text>, _>(&uris),
213
+
.bind::<Array<diesel::sql_types::Integer>, _>(&actor_ids)
214
+
.bind::<Array<diesel::sql_types::BigInt>, _>(&rkeys),
200
215
&mut conn,
201
216
)
202
217
.await
···
213
228
let mut conn = pool.get().await.wrap_err("Failed to get connection")?;
214
229
215
230
// Use the ACTUAL query builder from the source code
216
-
// This tests that feedgens query properly constructs URIs
217
-
// Query expects URIs (not natural keys), so construct AT-URI format
231
+
// The query expects owner_actor_ids and rkeys as separate arrays
218
232
let query = parakeet::loaders::build_feedgens_batch_query();
219
-
let uris = vec!["at://did:plc:test/app.bsky.feed.generator/test".to_string()];
233
+
let actor_ids = vec![1i32]; // Sample actor IDs
234
+
let rkeys = vec!["test".to_string()]; // Sample rkeys
220
235
221
236
diesel_async::RunQueryDsl::execute(
222
237
diesel::sql_query(query)
223
-
.bind::<Array<diesel::sql_types::Text>, _>(&uris),
238
+
.bind::<Array<diesel::sql_types::Integer>, _>(&actor_ids)
239
+
.bind::<Array<diesel::sql_types::Text>, _>(&rkeys),
224
240
&mut conn,
225
241
)
226
242
.await