Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
0c83436
refactor: host declaration scope shapes natively with native ordering…
kvlonge Oct 15, 2026
3f408b4
refactor: host configuration, measurement, SQL value, cursor value an…
kvlonge Oct 15, 2026
d645485
refactor: host planner, migration and plan entry shapes natively with…
kvlonge Oct 15, 2026
4376097
refactor: host compile exceptions, rule engine, references, discovery…
kvlonge Oct 15, 2026
d65a427
refactor: host compile output, macro and lineage-fact shapes natively
kvlonge Oct 15, 2026
2e9fdb1
refactor: host custom-rule records natively and move Rust-only rule c…
kvlonge Oct 15, 2026
7485cf6
refactor: publish eligible direct-build source freshness natively
kvlonge Oct 15, 2026
b766766
chore: record staying constant and rule API shapes and drop empty pac…
kvlonge Oct 15, 2026
91a8c93
chore: keep lint and presentation package markers and drop stale pack…
kvlonge Oct 15, 2026
5251ffd
fix: keep the MacroContext import path project macros use
kvlonge Oct 15, 2026
5426174
chore: record the MacroContext import path exception
kvlonge Oct 15, 2026
39d6320
fix: reconcile round-two native shapes with main's janitor, discovery…
kvlonge Oct 15, 2026
2e904c9
test: point remaining test scripts at natively hosted shapes
kvlonge Oct 15, 2026
f62e564
fix: accept path-like Dagster CLI arguments and match Python isalnum …
kvlonge Oct 15, 2026
48cef6b
refactor: reuse the shared integration loader name rule in project va…
kvlonge Oct 15, 2026
3f81565
refactor: use the native query-diff artifact name grammar in the exec…
kvlonge Oct 15, 2026
22b61f9
refactor: classify executed statements for relation cache invalidatio…
kvlonge Oct 15, 2026
c3f9b48
refactor: build ingestr destination URIs and command lines natively
kvlonge Oct 15, 2026
b0eea5b
chore: drop ingestr command module kept alive by integration
kvlonge Oct 15, 2026
4f18a58
test: import native SourceEntry in ingestr test types
kvlonge Oct 15, 2026
ff4fbc4
style: sort query artifact imports
kvlonge Oct 15, 2026
e716a1e
refactor: project Dagster and Rivers DAG assets and checks natively
kvlonge Oct 15, 2026
9a0706b
refactor: host planner value records on the shared native record mech…
kvlonge Oct 15, 2026
40f0204
refactor: export Rust-owned constants from sqlbuild._native
kvlonge Oct 15, 2026
0470462
chore: move cost package fensu exception to its models module
kvlonge Oct 15, 2026
6da7765
refactor: render append-only state table DDL and source freshness ins…
kvlonge Oct 15, 2026
af40f39
refactor: format diagnostics console lines natively behind the loggin…
kvlonge Oct 15, 2026
d9eeab6
refactor: stamp compile reuse and macro call store interpreter identi…
kvlonge Oct 15, 2026
c5e46dd
refactor: project microbatch coverage and render microbatch state SQL…
kvlonge Oct 15, 2026
9d24bb9
refactor: validate lifecycle events against a native event catalogue
kvlonge Oct 15, 2026
4432cc5
refactor: name the lifecycle payload rule type
kvlonge Oct 15, 2026
53723fc
fix: use the single source freshness table name constant after integr…
kvlonge Oct 15, 2026
01fad76
chore: require one evidenced rule for every Python boundary stays entry
kvlonge Oct 15, 2026
315d0cc
refactor: drop constant re-export shims and host freshness columns na…
kvlonge Oct 15, 2026
fb461da
chore: reconcile stays entries after removing re-export shims
kvlonge Oct 15, 2026
4a36397
refactor: route, redact and retain diagnostic log records and validat…
kvlonge Oct 15, 2026
9aa5114
refactor: map adapter connections to dlt destinations natively
kvlonge Oct 15, 2026
4fd70f7
refactor: coerce dbt profile as_bool and as_number values natively
kvlonge Oct 15, 2026
2b1924f
refactor: single-source diagnostic log record field and logger consta…
kvlonge Oct 15, 2026
c6df205
fix: format any integer debug console duration like Python without ra…
kvlonge Oct 15, 2026
bfa7e19
refactor: move flagged rule, Python-node, Dagster translator and star…
kvlonge Oct 16, 2026
65c41cc
chore: drop fensu exceptions for removed Python packages
kvlonge Oct 16, 2026
e9c0146
fix: keep tolerating None in hook reads as before
kvlonge Oct 16, 2026
11385cc
refactor: run project-tree queries and tracked-file selection natively
kvlonge Oct 16, 2026
3d1ccd6
test: split hook read cases into success and rejection tests
kvlonge Oct 16, 2026
1654c77
fix: stamp startup inputs with platform path rules on Windows
kvlonge Oct 16, 2026
8845304
fix: resolve project-tree paths with platform path rules on Windows
kvlonge Oct 16, 2026
78f5470
fix: set the allocator purge delay before the launched entry loads na…
kvlonge Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 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 @@ -32,6 +32,9 @@ use crate::assembly::analysis_session::constants::{
use crate::assembly::analysis_session::models::NullabilityCallback;
use crate::assembly::analysis_session::models::{ColumnFact, LineageRow};
use crate::assembly::analysis_session::types::{Pairs, Shapes};
use crate::nullability_rules::main::conditional_result_nullability::conditional_result_nullability;
use crate::nullability_rules::main::first_arg_nullability::first_arg_nullability;
use crate::nullability_rules::main::safe_cast_nullability::safe_cast_nullability;
use crate::type_system::main::normalize_type::normalize_type;
use crate::type_system::models::{NormalizedType, TypeFamily};

Expand Down Expand Up @@ -1020,36 +1023,13 @@ fn combined(node_kind: &str, rule: Option<&str>, arguments: &[&'static str]) ->
return UNKNOWN_NULLABILITY;
}
match rule {
Some(FIRST_ARG_RULE) => arguments.first().copied().unwrap_or(UNKNOWN_NULLABILITY),
Some(CONDITIONAL_RESULT_RULE) => conditional_result(arguments),
Some(SAFE_CAST_RULE) => safe_cast(arguments),
Some(FIRST_ARG_RULE) => first_arg_nullability(arguments),
Some(CONDITIONAL_RESULT_RULE) => conditional_result_nullability(arguments),
Some(SAFE_CAST_RULE) => safe_cast_nullability(arguments),
_ => UNKNOWN_NULLABILITY,
}
}

/// Python's `safe_cast_nullability`.
fn safe_cast(arguments: &[&'static str]) -> &'static str {
if arguments.first() == Some(&NULLABLE_NULLABILITY) {
NULLABLE_NULLABILITY
} else {
UNKNOWN_NULLABILITY
}
}

/// Python's `conditional_result_nullability`.
fn conditional_result(arguments: &[&'static str]) -> &'static str {
let [_, when_true, when_false, ..] = arguments else {
return UNKNOWN_NULLABILITY;
};
if *when_true == NON_NULL_NULLABILITY && *when_false == NON_NULL_NULLABILITY {
return NON_NULL_NULLABILITY;
}
if *when_true == NULLABLE_NULLABILITY || *when_false == NULLABLE_NULLABILITY {
return NULLABLE_NULLABILITY;
}
UNKNOWN_NULLABILITY
}

/// Python's `_infer_polyglot_column_nullability`.
fn column_nullability(
column: &Expression,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use crate::assembly::analysis_session::_helpers::dict_walk::{
parse_one_or_error, payload, relation_name, render_type, to_dict, truthy, upper,
};
use crate::assembly::analysis_session::constants::{
ALIAS_AST_KIND, CAST_AST_KIND, CTE_AST_KIND, DUCKDB_DIALECT, DYNAMIC_VALUE_SOURCE_KINDS,
MOTHERDUCK_DIALECT, PIVOT_AST_KIND, QUERY_AST_KINDS, SELECT_AST_KIND,
SIMPLIFIED_PIVOT_DIALECTS, SUPPORTED_PIVOT_DIALECTS, TYPE_PRESERVING_AGGREGATES,
UNKNOWN_NULLABILITY, UNKNOWN_TYPE,
ALIAS_AST_KIND, CAST_AST_KIND, DUCKDB_DIALECT, DYNAMIC_VALUE_SOURCE_KINDS, MOTHERDUCK_DIALECT,
PIVOT_AST_KIND, QUERY_AST_KINDS, SELECT_AST_KIND, SIMPLIFIED_PIVOT_DIALECTS,
SUPPORTED_PIVOT_DIALECTS, TYPE_PRESERVING_AGGREGATES, UNKNOWN_NULLABILITY, UNKNOWN_TYPE,
};
use crate::assembly::analysis_session::models::{
ColumnFact, ContractProof, DynamicFamily, PivotModel, PivotOutcome, PivotTables,
};
use crate::assembly::analysis_session::types::Shapes;
use sqlbuild_core::constants::CTE_AST_KIND;

/// What an internal native failure of a pivot proof names.
const PIVOT_CONTEXT: &str = "native dynamic pivot proof";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ pub(crate) const COLUMN_AST_KIND: &str = "column";
pub(crate) const TABLE_AST_KIND: &str = "table";
pub(crate) const FUNCTION_AST_KIND: &str = "function";
pub(crate) const ALIAS_AST_KIND: &str = "alias";
pub(crate) const CTE_AST_KIND: &str = "cte";
pub(crate) const STAR_AST_KIND: &str = "star";
pub(crate) const DYNAMIC_VALUE_SOURCE_KINDS: [&str; 3] = ["pivot_any", "select", "query"];
pub(crate) const DEPENDENCY_FUNCTION_NAMES: [&str; 3] = ["__ref", "__source", "__seed"];
Expand Down
6 changes: 4 additions & 2 deletions crates/sqlbuild-analysis/src/contracts/_helpers/promotion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use crate::contracts::_helpers::setting_help::{
};
use crate::contracts::constants::{
CONTRACT_ENFORCED, IMMEDIATE_PROMOTION_MODE, MICROBATCH_INCREMENTAL_MODE,
PROMOTION_CONFLICT_CODE, PROMOTION_REMOVE_CONTRACT_HELP, SETTINGS_SECTION,
STAGED_LIFECYCLE_MATERIALIZATIONS, STAGED_PROMOTION_MODE, TABLE_PROMOTION_MODE_SETTING_KEY,
PROMOTION_CONFLICT_CODE, PROMOTION_REMOVE_CONTRACT_HELP, STAGED_LIFECYCLE_MATERIALIZATIONS,
};
use crate::contracts::models::{PromotionConflict, PromotionModel, PromotionRequest};
use sqlbuild_core::constants::SETTINGS_SECTION;
use sqlbuild_core::constants::STAGED_PROMOTION_MODE;
use sqlbuild_core::constants::TABLE_PROMOTION_MODE_SETTING_KEY;

/// One conflict per enforced-contract table model when the effective promotion is immediate.
pub(crate) fn promotion_conflicts(request: &PromotionRequest) -> Vec<PromotionConflict> {
Expand Down
5 changes: 1 addition & 4 deletions crates/sqlbuild-analysis/src/contracts/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ pub(crate) const MISSING_DECLARATIONS_CODE: &str = "K006";
pub(crate) const DYNAMIC_OUTPUT_NOT_PROVEN_CODE: &str = "K011";
pub(crate) const PROMOTION_CONFLICT_CODE: &str = "K011";

pub(crate) const CONTRACT_ENFORCED: &str = "enforced";
pub const CONTRACT_ENFORCED: &str = "enforced";
pub(crate) const CONTRACT_NONE: &str = "none";
pub(crate) const STAGED_LIFECYCLE_MATERIALIZATIONS: [&str; 2] = ["table", "incremental"];
pub(crate) const MICROBATCH_INCREMENTAL_MODE: &str = "microbatch";
pub(crate) const IMMEDIATE_PROMOTION_MODE: &str = "immediate";
pub(crate) const STAGED_PROMOTION_MODE: &str = "staged";
pub(crate) const SETTINGS_SECTION: &str = "settings";
pub(crate) const TABLE_PROMOTION_MODE_SETTING_KEY: &str = "table_promotion_mode";

pub(crate) const NO_COMPILER_EVIDENCE: &str = "no compiler evidence";
pub(crate) const DYNAMIC_OUTPUT_NOT_PROVEN_HELP: &str = "project one supported runtime-dynamic pivot through a wildcard output boundary and declare every generated family";
Expand Down
2 changes: 1 addition & 1 deletion crates/sqlbuild-analysis/src/contracts/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Model column contracts and promotion conflicts.

pub(crate) mod _helpers;
pub(crate) mod constants;
pub mod constants;
pub mod main;
pub mod models;

Expand Down
1 change: 1 addition & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/_helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub(crate) mod checks;
pub(crate) mod edges;
pub(crate) mod nodes;
pub(crate) mod projection;
pub(crate) mod selection;
pub(crate) mod values;
27 changes: 27 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/_helpers/projection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Node lookups the orchestrator projections share.

use std::collections::HashMap;

use crate::dag_artifact::models::DagProjectionGraph;

/// Node index by id; a later node with a repeated id replaces the earlier one.
pub(crate) fn nodes_by_id(graph: &DagProjectionGraph) -> HashMap<&str, usize> {
graph
.nodes
.iter()
.enumerate()
.map(|(index, node)| (node.id.as_str(), index))
.collect()
}

/// Upstream node ids by downstream node id, in edge order.
pub(crate) fn upstream_by_id(graph: &DagProjectionGraph) -> HashMap<&str, Vec<&str>> {
let mut upstream: HashMap<&str, Vec<&str>> = HashMap::new();
for (from_id, to_id) in &graph.edges {
upstream
.entry(to_id.as_str())
.or_default()
.push(from_id.as_str());
}
upstream
}
2 changes: 2 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ pub(crate) const SELECTOR_KIND_CHECK: &str = "check";
pub(crate) const SELECTOR_KIND_TEST: &str = "test";
pub(crate) const SELECTOR_KIND_SEPARATOR: &str = ":";
pub(crate) const SELECTOR_MODELS_PREFIX: &str = "models/";
/// The orchestrator kind every SQLBuild asset carries.
pub(crate) const SQLBUILD_ASSET_KIND: &str = "sqlbuild";
37 changes: 37 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/main/dag_asset_plans.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! The asset nodes an orchestrator definition owns and their dependencies.

use std::collections::HashMap;

use crate::dag_artifact::_helpers::projection::{nodes_by_id, upstream_by_id};
use crate::dag_artifact::models::{AssetNodePlan, AssetProjectionPolicy, DagProjectionGraph};

/// Each node of an asset kind, in artifact order, with its upstream nodes in edge order.
#[must_use]
pub fn dag_asset_plans(
graph: &DagProjectionGraph,
policy: &AssetProjectionPolicy,
) -> Vec<AssetNodePlan> {
let nodes: HashMap<&str, usize> = nodes_by_id(graph);
let upstream: HashMap<&str, Vec<&str>> = upstream_by_id(graph);
let is_asset = |index: usize| policy.asset_kinds.contains(&graph.nodes[index].kind);
let mut plans: Vec<AssetNodePlan> = Vec::new();
for (index, node) in graph.nodes.iter().enumerate() {
if !is_asset(index) {
continue;
}
let mut dependencies: Vec<usize> = Vec::new();
for upstream_id in upstream.get(node.id.as_str()).into_iter().flatten() {
match nodes.get(upstream_id) {
Some(dependency) if !policy.upstream_asset_kinds_only || is_asset(*dependency) => {
dependencies.push(*dependency);
}
_ => {}
}
}
plans.push(AssetNodePlan {
node: index,
upstream: dependencies,
});
}
plans
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! The orchestrator kinds of one asset.

use crate::dag_artifact::constants::SQLBUILD_ASSET_KIND;
use crate::dag_artifact::models::AssetSpecKindPolicy;

/// `sqlbuild` plus `view`/`table` for models, the node kind for direct kinds, else nothing more.
#[must_use]
pub fn dag_asset_spec_kinds(
(kind, materialization_type): (&str, &str),
policy: &AssetSpecKindPolicy,
) -> Vec<String> {
let detail: Option<&str> = if kind == policy.model_kind {
Some(if materialization_type == policy.view_materialization {
"view"
} else {
"table"
})
} else if policy.direct_kinds.contains(kind) {
Some(kind)
} else {
None
};
std::iter::once(SQLBUILD_ASSET_KIND)
.chain(detail)
.map(str::to_owned)
.collect()
}
42 changes: 42 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/main/dag_check_plans.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! The checks an orchestrator check definition exposes and the nodes they check.

use std::collections::HashMap;

use crate::dag_artifact::_helpers::projection::nodes_by_id;
use crate::dag_artifact::models::{
CheckKindFilter, CheckPlan, DagProjectionCheck, DagProjectionGraph,
};

/// Whether `filter` exposes checks of `kind`.
fn exposed(filter: &CheckKindFilter, kind: &str) -> bool {
!filter.excluded.contains(kind)
&& filter
.required
.as_ref()
.is_none_or(|required| required.contains(kind))
}

/// The indexes of the known nodes `check` names, in its order.
fn checked_nodes(nodes: &HashMap<&str, usize>, check: &DagProjectionCheck) -> Vec<usize> {
check
.checked_asset_ids
.iter()
.filter_map(|id| nodes.get(id.as_str()).copied())
.collect()
}

/// Every check in artifact order, whether `filter` exposes its kind, and its known checked nodes.
#[must_use]
pub fn dag_check_plans(graph: &DagProjectionGraph, filter: &CheckKindFilter) -> Vec<CheckPlan> {
let nodes: HashMap<&str, usize> = nodes_by_id(graph);
graph
.checks
.iter()
.enumerate()
.map(|(index, check)| CheckPlan {
check: index,
included: exposed(filter, &check.kind),
nodes: checked_nodes(&nodes, check),
})
.collect()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! The selected nodes an orchestrator owns as assets.

use std::collections::BTreeSet;

use crate::dag_artifact::models::DagProjectionGraph;

/// Indexes of nodes whose id is selected and whose kind is an asset kind, in artifact order.
#[must_use]
pub fn dag_selected_asset_nodes(
graph: &DagProjectionGraph,
selected_ids: &BTreeSet<String>,
asset_kinds: &BTreeSet<String>,
) -> Vec<usize> {
graph
.nodes
.iter()
.enumerate()
.filter(|(_, node)| selected_ids.contains(&node.id) && asset_kinds.contains(&node.kind))
.map(|(index, _)| index)
.collect()
}
4 changes: 4 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/main/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
pub mod build_dag_json;
pub mod dag_asset_plans;
pub mod dag_asset_spec_kinds;
pub mod dag_check_plans;
pub mod dag_selected_asset_nodes;
pub mod resolve_dag_selection;
65 changes: 65 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/models.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! The compiled project, Python node graph and authored values the DAG artifact is built from.

use std::collections::BTreeSet;

use crate::assembly::project::types::ObjectKey;
use crate::dag_artifact::types::{DagColumnLineage, DagValue};

Expand Down Expand Up @@ -243,6 +245,69 @@ pub struct DagSelectionGraph {
pub checks: Vec<DagSelectionCheck>,
}

/// One DAG artifact node as orchestrator asset projection reads it.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DagProjectionNode {
pub id: String,
pub kind: String,
}

/// One DAG artifact check as orchestrator check projection reads it.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DagProjectionCheck {
pub kind: String,
pub checked_asset_ids: Vec<String>,
}

/// The DAG artifact's nodes, `(from, to)` edges and checks, in artifact order.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DagProjectionGraph {
pub nodes: Vec<DagProjectionNode>,
pub edges: Vec<(String, String)>,
pub checks: Vec<DagProjectionCheck>,
}

/// Which nodes become orchestrator assets and which upstream nodes they depend on.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AssetProjectionPolicy {
/// Node kinds the orchestrator owns as assets.
pub asset_kinds: BTreeSet<String>,
/// Upstream nodes of other kinds are left out of an asset's dependencies.
pub upstream_asset_kinds_only: bool,
}

/// One asset node and the nodes it depends on, as indexes into the graph's nodes.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AssetNodePlan {
pub node: usize,
pub upstream: Vec<usize>,
}

/// Which check kinds a check definition exposes.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct CheckKindFilter {
pub excluded: BTreeSet<String>,
/// When set, only these kinds are exposed.
pub required: Option<BTreeSet<String>>,
}

/// One check, whether its kind is exposed, and the nodes it checks as graph indexes.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct CheckPlan {
pub check: usize,
pub included: bool,
pub nodes: Vec<usize>,
}

/// How an asset's orchestrator kinds follow from its node kind and materialization.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AssetSpecKindPolicy {
pub model_kind: String,
pub view_materialization: String,
/// Node kinds reported as their own orchestrator kind.
pub direct_kinds: BTreeSet<String>,
}

/// The node lookup and edge indexes every selector token resolves against.
#[derive(Debug)]
pub(crate) struct DagSelectionIndex<'a> {
Expand Down
2 changes: 2 additions & 0 deletions crates/sqlbuild-analysis/src/dag_artifact/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
mod build_dag_json;
#[path = "tests/helpers.rs"]
mod helpers;
#[path = "tests/test_projection.rs"]
mod projection;
#[path = "tests/test_types.rs"]
mod test_types;
Loading
Loading