@@ -246,7 +246,8 @@ pub struct Codegen<M: cranelift_module::Module = ObjectModule> {
246246 // Source tables read fully into memory (not pushed down to SQL): the
247247 // `run *source` fast path and the in-memory `knot_source_read` fallback.
248248 // Surfaced as a build-time INFO diagnostic naming each such table.
249− in_memory_source_reads: HashMap<String, ast::Span>,
249+ // Maps the source name → (read span, the function that read it: run/run1/…).
250+ in_memory_source_reads: HashMap<String, (ast::Span, String)>,
250251
251252 /// Source name → its `*name` declaration span (for the full-read warning's
252253 /// trace back to where the relation is declared).
@@ -1100,7 +1101,7 @@ fn compile_inner<M: cranelift_module::Module>(
11001101 // memory instead of pushing the query down to SQL. One diagnostic listing
11011102 // every such table; advice only — it never fails the build.
11021103 if !cg.in_memory_source_reads.is_empty() {
1103− let mut entries: Vec<(&String, &ast::Span)> = cg.in_memory_source_reads.iter().collect();
1104+ let mut entries: Vec<(&String, &(ast::Span, String))> = cg.in_memory_source_reads.iter().collect();
11041105 entries.sort_by_key(|(n, _)| (*n).clone());
11051106 let names = entries
11061107 .iter()
@@ -1112,8 +1113,8 @@ fn compile_inner<M: cranelift_module::Module>(
11121113 names,
11131114 if entries.len() == 1 { "" } else { "s" },
11141115 ));
1115− for (name, span) in &entries {
1116− diag = diag.label(**span, format!("`*{name}` is read in full here"));
1116+ for (name, (span, how)) in &entries {
1117+ diag = diag.label(*span, format!("`*{name}` is read in full here ({how})"));
11171118 // Trace back to the source's declaration.
11181119 if let Some(decl_span) = cg.source_decl_spans.get(*name) {
11191120 diag = diag.label(*decl_span, format!("`*{name}` is declared here"));
@@ -5005,7 +5006,8 @@ impl<M: cranelift_module::Module> Codegen<M> {
50055006 // SQL-pushdown matcher — it loads the whole relation into
50065007 // memory via `knot_source_read`. Track it for the build-time
50075008 // INFO diagnostic naming full in-memory reads.
5008− self.in_memory_source_reads.insert(name.clone(), expr.span);
5009+ self.in_memory_source_reads
5010+ .insert(name.clone(), (expr.span, "a direct read".to_string()));
50095011 let schema = self.source_schemas.get(name).cloned().unwrap_or_default();
50105012 let (name_ptr, name_len) = self.string_ptr(builder, name);
50115013 let (schema_ptr, schema_len) = self.string_ptr(builder, &schema);
@@ -7194,7 +7196,7 @@ impl<M: cranelift_module::Module> Codegen<M> {
71947196 && let Some(schema) = self.source_schemas.get(&source_name).cloned()
71957197 {
71967198 self.in_memory_source_reads
7197− .insert(source_name.clone(), args[0].span);
7199+ .insert(source_name.clone(), (args[0].span, "base.run".to_string()));
71987200 self.emit_stm_track_read(builder, &source_name);
71997201 let (name_ptr, name_len) = self.string_ptr(builder, &source_name);
72007202 let (schema_ptr, schema_len) = self.string_ptr(builder, &schema);