Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0e654eb
refactor: answer native string enum value and name reads from their d…
kvlonge Oct 17, 2026
d71aac4
perf: hash SQL rule cache keys in parallel without the GIL, answer Py…
kvlonge Oct 17, 2026
23d8879
perf: make written artifact paths absolute natively and tidy the para…
kvlonge Oct 17, 2026
2a96d74
perf: build header contract records positionally and skip per-model e…
kvlonge Oct 17, 2026
8e5a396
perf: skip built-in rule evaluation when no rules are selected
kvlonge Oct 17, 2026
9f83773
perf: hand the rules request its scope projection without a Python ro…
kvlonge Oct 17, 2026
57f01f7
perf: index SQL rule models by path instead of rescanning every earli…
kvlonge Oct 17, 2026
c23049c
perf: keep discovered model file paths native so lint inputs skip pat…
kvlonge Oct 17, 2026
2981340
refactor: read model file paths strictly at construction
kvlonge Oct 17, 2026
0a68f0e
perf: retain native header columns until public projection
kvlonge Oct 17, 2026
9c037cc
perf: reuse rule parser tokens for dependency classification
kvlonge Oct 17, 2026
b14af9f
perf: reduce SQL test planning copies and marker scans
kvlonge Oct 17, 2026
7f767e3
perf: recognize bounded SQL test templates without full ASTs
kvlonge Oct 17, 2026
a50d24a
fix: recognize Snowflake test templates with parser-safe markers
kvlonge Oct 17, 2026
3b69554
perf: dispatch SQL non-code scans by opening byte
kvlonge Oct 17, 2026
39fbafe
perf: key internal rules caches with BLAKE3
kvlonge Oct 17, 2026
5bce4ec
perf: write compiled artifact batches on a small thread pool
kvlonge Oct 17, 2026
66b6549
perf: hash batch-wide analysis settings once per batch
kvlonge Oct 17, 2026
cbbb363
perf: keep discovered model file data native
kvlonge Oct 17, 2026
de8c4ce
perf: read model headers natively in a parallel pre-pass
kvlonge Oct 17, 2026
b6476ae
perf: read compiled model text natively in post-analysis consumers
kvlonge Oct 17, 2026
046c10e
test: cover native header columns through the real CLI
kvlonge Oct 17, 2026
2877bfd
refactor: satisfy native boundary policy for native model data
kvlonge Oct 17, 2026
c041112
fix: run the model header pre-pass in turn when its pool cannot start
kvlonge Oct 17, 2026
07f3a7c
feat: evaluate built-in rules speculatively with deferred cache writes
kvlonge Oct 17, 2026
541d999
feat: report early built-in rules timings in compile JSON
kvlonge Oct 17, 2026
5162915
perf: start built-in rules once compile recovers model types
kvlonge Oct 17, 2026
1ef47ad
fix: treat failed early built-in rules as a miss
kvlonge Oct 17, 2026
518cdb9
Merge branch 'main' into perf/chi-607-orchestration
kvlonge Oct 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

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 @@ -165,6 +165,7 @@ impl SessionCatalog {
let mut shared: Vec<Option<SharedQuery>> = self.shared_queries(batch, &cleaned)?;
self.shared_members += shared.iter().flatten().count();
let mut query_digests: HashMap<&str, MemoKey> = HashMap::new();
let batch_digest: MemoKey = batch_key_digest(batch);
let keys: Vec<Option<MemoKey>> = batch
.members
.iter()
Expand All @@ -174,7 +175,12 @@ impl SessionCatalog {
let query: MemoKey = *query_digests
.entry(share.key.as_str())
.or_insert_with(|| Sha256::digest(share.key.as_bytes()).into());
Some(shared_result_key(batch, member, share, &query))
Some(shared_result_key(
batch,
member,
share,
(&query, &batch_digest),
))
})
.collect();
for (member, sql) in batch.members.iter().zip(&cleaned) {
Expand Down Expand Up @@ -609,21 +615,23 @@ impl SessionCatalog {
}
};
query_indexes.push(query_index);
let template: Value = json!({
"queryIndex": query_index,
"references": lineage_resources(member, share.as_ref()),
"functionReturnTypes": function_return_types,
"declaredColumnOrder": declared_column_order(member, batch.nullability),
"recoverCteFacts": member.recover_cte_facts,
"richTypeInference": batch.rich_type_inference,
});
let template_index: usize =
*template_keys
.entry(template.to_string())
.or_insert_with(|| {
templates.push(template);
templates.len() - 1
});
let references: Map<String, Value> = lineage_resources(member, share.as_ref());
let declared: Value = json!(declared_column_order(member, batch.nullability));
let member_template_identity: String =
json!([query_index, references, declared, member.recover_cte_facts]).to_string();
let template_index: usize = *template_keys
.entry(member_template_identity)
.or_insert_with(|| {
templates.push(json!({
"queryIndex": query_index,
"references": references,
"functionReturnTypes": function_return_types,
"declaredColumnOrder": declared,
"recoverCteFacts": member.recover_cte_facts,
"richTypeInference": batch.rich_type_inference,
}));
templates.len() - 1
});
let resource_names: Map<String, Value> = member
.lineage_references
.iter()
Expand Down Expand Up @@ -897,12 +905,19 @@ fn named_sources(
.collect()
}

/// Digest of Python's `shared_result_keys` entry, given its shared query's digest.
/// Digest of the settings every member of `batch` shares, hashed once per batch.
fn batch_key_digest(batch: &Batch<'_>) -> MemoKey {
let shared: String =
json!([batch.rich_type_inference, batch.function_return_types]).to_string();
Sha256::digest(shared.as_bytes()).into()
}

/// Digest of Python's `shared_result_keys` entry, given its shared query's and batch's digests.
fn shared_result_key(
batch: &Batch<'_>,
member: &BatchMember<'_>,
share: &SharedQuery,
query: &MemoKey,
(query, batch_digest): (&MemoKey, &MemoKey),
) -> MemoKey {
let reference_types: Vec<(&str, &str)> = member
.lineage_references
Expand All @@ -911,14 +926,13 @@ fn shared_result_key(
.collect();
let rest: String = json!([
member.recover_cte_facts,
batch.rich_type_inference,
batch.function_return_types,
declared_column_order(member, batch.nullability),
reference_types,
])
.to_string();
let mut hasher: Sha256 = Sha256::new();
hasher.update(query);
hasher.update(batch_digest);
hasher.update(rest.as_bytes());
hasher.finalize().into()
}
Expand Down
13 changes: 7 additions & 6 deletions crates/sqlbuild-analysis/src/compiled_project/models.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Facts a compile's producers retain about each resource, in production order.

use std::collections::{BTreeMap, HashMap};
use std::sync::Arc;

use serde_json::Value;

Expand All @@ -17,11 +18,11 @@ pub struct CompiledModelFacts {
pub name: String,
pub relative_path: String,
/// SQL after variable, declaration and macro expansion.
pub query_sql: String,
pub query_sql: Arc<str>,
/// The authored query below the `MODEL (...)` header.
pub authored_query_sql: String,
pub authored_query_sql: Arc<str>,
/// The whole authored file.
pub authored_sql: String,
pub authored_sql: Arc<str>,
pub config: ModelConfigFacts,
pub references: Vec<ModelReferenceFact>,
pub schema: Option<ModelSchemaFact>,
Expand Down Expand Up @@ -210,9 +211,9 @@ pub struct SplicedSql {
pub struct PlainModel {
pub name: String,
pub relative_path: String,
pub query_sql: String,
pub authored_query_sql: String,
pub authored_sql: String,
pub query_sql: Arc<str>,
pub authored_query_sql: Arc<str>,
pub authored_sql: Arc<str>,
pub config: ModelConfigFacts,
/// The attached schema entry; present when the header declares description, columns or audits.
pub schema: Option<ModelSchemaFact>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::compiled_project::models::{CompiledModelFacts, ModelAnalysisFact};
pub(super) fn model(name: &str, query_sql: &str) -> CompiledModelFacts {
CompiledModelFacts {
name: name.to_owned(),
query_sql: query_sql.to_owned(),
query_sql: query_sql.into(),
..CompiledModelFacts::default()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn given_recorded_models_when_reading_then_order_and_latest_facts_are_kept() {
.map(|facts| facts.name.as_str())
.collect();
let query_sql: Option<&str> =
model_facts(&project, "orders").map(|facts| facts.query_sql.as_str());
model_facts(&project, "orders").map(|facts| &*facts.query_sql);

assert_eq!(order, test_case.expected_order, "{}", test_case.description);
assert_eq!(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub(crate) const SIMPLE_TEMPLATE_DIALECTS: [&str; 2] = ["duckdb", "snowflake"];
pub(crate) const MAX_TEMPLATE_DEPTH: usize = 32;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod assembly;
pub mod authored_macro_calls;
pub mod case_identity;
pub(crate) mod check_independence;
pub(crate) mod constants;
pub mod cte_rename;
pub mod cte_slices;
pub mod cte_sql;
Expand All @@ -19,3 +20,4 @@ pub mod reference_calls;
pub mod relation_markers;
pub mod rendering;
pub mod scenario_extraction;
pub(crate) mod simple_template;
Loading
Loading