Agent skill

Spark Catalyst

by aehrc in aehrc/pathling

Expert guidance for working with the Apache Spark Catalyst query optimisation framework.

Apache-2.0Auto-check passedDatabases

Install Spark Catalyst

skills CLI
$ npx skills add aehrc/pathling --skill spark-catalyst -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install aehrc/pathling spark-catalyst --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/aehrc/pathling.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/spark-catalyst .claude/skills/spark-catalyst && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
spark-catalyst
GitHub stars
137
Token cost
~5.4k tokens
SKILL.md length
759 words
Files
1
Skills in repo
25
Repo updated
First seen
Licence
Apache-2.0

At a glance

Expert guidance for working with the Apache Spark Catalyst query optimisation framework.

  • Works in 10 steps: TreeNode → Expression → QueryPlan → …
  • Working with Spark SQL internals
  • SKILL.md covers Overview of Catalyst, Core Architecture, Fundamental Concepts and Rule-Based Transformation…, plus 5 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Spark Catalyst is an agent skill from aehrc/pathling. Expert guidance for working with the Apache Spark Catalyst query optimisation framework. Use this skill when working with Spark SQL internals, creating custom expressions, implementing query optimisations, working with logical/physical plans, or extending Catalyst. Trigger keywords include "catalyst", "spark sql", "expression", "logical plan", "physical plan", "tree node", "query optimisation", "rule executor", "analyzer", "optimizer", "code generation".

Its SKILL.md is about 5.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Databases, covering Query optimization. It works with Apache Spark. The repository describes itself as: Tools that make it easier to use FHIR and clinical terminology within data analytics, built on Apache Spark. The licence is Apache-2.0.

When your agent uses it

  • Working with Spark SQL internals
  • Creating custom expressions
  • Implementing query optimisations
  • Working with logical/physical plans

Example prompts

  • “catalyst”
  • “spark sql”
  • “expression”
  • “/spark-catalyst”

Workflow steps

10 steps, taken from the step headings in SKILL.md.

  1. TreeNode
  2. Expression
  3. QueryPlan
  4. LogicalPlan
  5. InternalRow
  6. Rule and RuleExecutor
  7. Analyzer
  8. Optimizer
  9. CodeGen Framework
  10. Catalyst Type System

What it can do on your machine

Read from SKILL.md and the folder at commit 56a3b4a. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are scala).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Spark Catalyst loads about 5.4k tokens when it runs. Until then it costs about 118 tokens; SKILL.md has 759 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~118
When it runs · the whole SKILL.md, loaded when a task matches
~5.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from aehrc/pathling at commit 56a3b4a, republished under its Apache-2.0 licence (© aehrc). 759 words, ~5,398 tokens.

Download SKILL.mdSave it as .claude/skills/spark-catalyst/SKILL.md (or your agent's skills folder).
name
spark-catalyst
description
Expert guidance for working with the Apache Spark Catalyst query optimisation framework. Use this skill when working with Spark SQL internals, creating custom expressions, implementing query optimisations, working with logical/physical plans, or extending Catalyst. Trigger keywords include "catalyst", "spark sql", "expression", "logical plan", "physical plan", "tree node", "query optimisation", "rule executor", "analyzer", "optimizer", "code generation".

You are an expert in the Apache Spark Catalyst query optimisation framework. This skill provides comprehensive guidance on using the Catalyst API for query processing, optimisation, and code generation.

Overview of Catalyst

Apache Spark Catalyst is a query optimisation framework that powers Spark SQL and DataFrames. It provides:

  • Extensible query optimiser based on functional programming constructs
  • Tree-based representation of query plans and expressions
  • Rule-based transformations for query optimisation
  • Code generation for high-performance query execution
  • Cost-based optimisation for join reordering and other decisions

Core Architecture

Module Structure

The Catalyst module is located at sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ and contains:

catalyst/
├── analysis/           # Query analysis and resolution
├── catalog/           # Catalog management and metadata
├── expressions/       # Expression definitions and evaluation
├── optimizer/         # Query optimisation rules
├── parser/            # SQL parsing
├── planning/          # Query planning strategies
├── plans/             # Query plan representations
│   ├── logical/       # Logical plan operators
│   └── physical/      # Physical plan operators
├── rules/             # Rule execution framework
├── trees/             # Tree node infrastructure
├── types/             # Data type utilities
└── util/              # Utility classes

Fundamental Concepts

1. TreeNode

TreeNode is the base class for all tree structures in Catalyst, including expressions and query plans.

Key Concepts
scala
abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product {
  // Children of this node.
  def children: Seq[BaseType]

  // Transform this tree by applying a function to all nodes.
  def transform(rule: PartialFunction[BaseType, BaseType]): BaseType

  // Transform all nodes bottom-up.
  def transformDown(rule: PartialFunction[BaseType, BaseType]): BaseType

  // Transform all nodes top-down.
  def transformUp(rule: PartialFunction[BaseType, BaseType]): BaseType

  // Fast equality check.
  def fastEquals(other: TreeNode[_]): Boolean

  // Tree pattern matching for efficient traversal.
  def treePatternBits: BitSet
}
Tree Transformation Patterns

Bottom-up transformation:

scala
plan.transformUp {
  case Filter(condition, child) if isAlwaysTrue(condition) =>
    child
}

Top-down transformation:

scala
plan.transformDown {
  case Project(projectList, child) =>
    // Transform project first, then children
    optimiseProject(projectList, child)
}

Collect nodes matching a pattern:

scala
val filters = plan.collect {
  case f @ Filter(_, _) => f
}
2. Expression

Expression is the base class for all expression trees in Catalyst.

Expression Hierarchy
  • LeafExpression: No children (e.g., Literal, AttributeReference)
  • UnaryExpression: One child (e.g., Cast, Not, IsNull)
  • BinaryExpression: Two children (e.g., Add, EqualTo, And)
  • TernaryExpression: Three children (e.g., If, Substring)
  • QuaternaryExpression: Four children
Key Properties
scala
abstract class Expression extends TreeNode[Expression] {
  // Can this expression be evaluated at query planning time?
  def foldable: Boolean

  // Does this expression always return the same result for fixed inputs?
  def deterministic: Boolean

  // Can this expression evaluate to null?
  def nullable: Boolean

  // Data type of the expression result.
  def dataType: DataType

  // Evaluate this expression given an input row.
  def eval(input: InternalRow): Any

  // Generate code for this expression.
  def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode

  // Attributes referenced by this expression.
  def references: AttributeSet
}
Common Expression Types

Literal values:

scala
Literal(42)                    // Integer literal
Literal("hello")               // String literal
Literal(null, StringType)      // Null literal

Attribute references:

scala
AttributeReference("name", StringType, nullable = true)()
AttributeReference("age", IntegerType, nullable = false)()

Predicates:

scala
EqualTo(left, right)           // left = right
GreaterThan(left, right)       // left > right
LessThanOrEqual(left, right)   // left <= right
And(left, right)               // left AND right
Or(left, right)                // left OR right
Not(child)                     // NOT child

Arithmetic:

scala
Add(left, right)               // left + right
Subtract(left, right)          // left - right
Multiply(left, right)          // left * right
Divide(left, right)            // left / right

String operations:

scala
Substring(str, pos, len)       // substring(str, pos, len)
Upper(child)                   // upper(child)
Lower(child)                   // lower(child)
Concat(children)               // concat(child1, child2, ...)

Type conversion:

scala
Cast(child, targetType)        // cast(child as targetType)
3. QueryPlan

QueryPlan is the base class for both logical and physical query plans.

Key Properties
scala
abstract class QueryPlan[PlanType <: QueryPlan[PlanType]]
  extends TreeNode[PlanType] {

  // Output schema of this plan node.
  def output: Seq[Attribute]

  // Set of output attributes.
  def outputSet: AttributeSet

  // Set of attributes from all children.
  def inputSet: AttributeSet

  // Attributes produced by this node.
  def producedAttributes: AttributeSet

  // Attributes referenced by expressions.
  def references: AttributeSet

  // Attributes referenced but not provided by children.
  def missingInput: AttributeSet

  // All expressions in this plan node.
  def expressions: Seq[Expression]

  // Transform expressions in this plan.
  def transformExpressions(rule: PartialFunction[Expression, Expression]): PlanType
}
4. LogicalPlan

Logical plans represent query semantics without execution strategy.

Common Logical Operators

Data sources:

scala
// Read from a relation.
LogicalRelation(relation, output, catalogTable)

// Local in-memory data.
LocalRelation(output, data)

// Empty relation.
EmptyRelation(output)

Projections and filters:

scala
// Project specific columns.
Project(projectList: Seq[NamedExpression], child: LogicalPlan)

// Filter rows.
Filter(condition: Expression, child: LogicalPlan)

// Select distinct rows.
Distinct(child: LogicalPlan)

Aggregations:

scala
// Group by and aggregate.
Aggregate(
  groupingExpressions: Seq[Expression],
  aggregateExpressions: Seq[NamedExpression],
  child: LogicalPlan
)

Joins:

scala
// Join two relations.
Join(
  left: LogicalPlan,
  right: LogicalPlan,
  joinType: JoinType,
  condition: Option[Expression],
  hint: JoinHint
)

Sorting:

scala
// Sort rows.
Sort(
  order: Seq[SortOrder],
  global: Boolean,
  child: LogicalPlan
)

Limits:

scala
// Limit number of rows.
Limit(limitExpr: Expression, child: LogicalPlan)

Set operations:

scala
// Union of two relations.
Union(children: Seq[LogicalPlan])

// Intersection.
Intersect(left: LogicalPlan, right: LogicalPlan, isAll: Boolean)

// Difference.
Except(left: LogicalPlan, right: LogicalPlan, isAll: Boolean)
5. InternalRow

InternalRow is the internal representation of a row in Catalyst.

Key Methods
scala
abstract class InternalRow extends SpecializedGetters {
  // Number of fields in this row.
  def numFields: Int

  // Check if field at ordinal is null.
  def isNullAt(ordinal: Int): Boolean

  // Get value at ordinal.
  def get(ordinal: Int, dataType: DataType): Any

  // Specialised getters for primitive types.
  def getBoolean(ordinal: Int): Boolean
  def getByte(ordinal: Int): Byte
  def getShort(ordinal: Int): Short
  def getInt(ordinal: Int): Int
  def getLong(ordinal: Int): Long
  def getFloat(ordinal: Int): Float
  def getDouble(ordinal: Int): Double
  def getDecimal(ordinal: Int, precision: Int, scale: Int): Decimal
  def getUTF8String(ordinal: Int): UTF8String

  // Update value at ordinal.
  def update(ordinal: Int, value: Any): Unit

  // Set field to null.
  def setNullAt(ordinal: Int): Unit

  // Create a copy of this row.
  def copy(): InternalRow

  // Convert to Scala sequence.
  def toSeq(schema: StructType): Seq[Any]
}

Rule-Based Transformation Framework

6. Rule and RuleExecutor

Rules define tree transformations, and RuleExecutor applies them in batches.

Defining Rules
scala
// Basic rule.
object MyOptimisationRule extends Rule[LogicalPlan] {
  def apply(plan: LogicalPlan): LogicalPlan = plan.transformUp {
    case Filter(condition, child) if isAlwaysTrue(condition) =>
      child
  }
}

// Configurable rule.
case class MyParameterisedRule(conf: SQLConf) extends Rule[LogicalPlan] {
  def apply(plan: LogicalPlan): LogicalPlan = {
    if (conf.myFeatureEnabled) {
      optimisePlan(plan)
    } else {
      plan
    }
  }
}
Rule Execution Strategies
scala
abstract class RuleExecutor[TreeType <: TreeNode[_]] {
  // Define batches of rules to execute.
  protected def batches: Seq[Batch]

  // Execute all batches on the plan.
  def execute(plan: TreeType): TreeType
}

// Batch execution strategies.
abstract class Strategy
case class Once extends Strategy
case class FixedPoint(maxIterations: Int) extends Strategy
Example RuleExecutor
scala
object MyOptimiser extends RuleExecutor[LogicalPlan] {
  val batches = Seq(
    Batch("Normalisation", Once,
      EliminateSubqueryAliases,
      RemoveRedundantAliases
    ),
    Batch("Operator Optimisation", FixedPoint(100),
      PushDownPredicate,
      ConstantFolding,
      ColumnPruning
    ),
    Batch("Join Reordering", Once,
      CostBasedJoinReorder
    )
  )
}
7. Analyzer

The Analyzer resolves unresolved logical plans by binding attributes, functions, and tables.

Key Analysis Rules
  • ResolveReferences: Bind attribute references to their sources
  • ResolveRelations: Bind table references to catalog entries
  • ResolveFunctions: Bind function calls to function implementations
  • TypeCoercion: Insert implicit type casts
  • ResolveSubquery: Analyse subquery expressions
  • CheckAnalysis: Verify the plan is valid
Example Usage
scala
val analyzer = new Analyzer(catalogManager)
val analysedPlan = analyzer.execute(unresolvedPlan)
8. Optimizer

The Optimizer transforms logical plans to improve query performance.

Key Optimisation Rules

Predicate pushdown:

scala
// Push filters below projections.
PushDownPredicate

// Push filters into join conditions.
PushPredicateThroughJoin

// Push filters to data sources.
PushDownPredicates

Projection pushdown:

scala
// Eliminate unnecessary columns.
ColumnPruning

// Combine adjacent projections.
CollapseProject

Constant folding:

scala
// Evaluate constant expressions.
ConstantFolding

// Simplify expressions.
SimplifyConditionals
SimplifyCasts

Join optimisation:

scala
// Reorder joins for better performance.
CostBasedJoinReorder

// Eliminate redundant joins.
EliminateOuterJoin

Subquery optimisation:

scala
// Decorrelate correlated subqueries.
DecorrelateInnerQuery

// Merge scalar subqueries.
MergeScalarSubqueries

Code Generation

9. CodeGen Framework

Catalyst generates optimised Java bytecode for query execution.

Key Components

CodegenContext:

Manages code generation state including variable declarations, functions, and class structure.

ExprCode:

Represents generated code for an expression evaluation.

scala
case class ExprCode(
  code: Block,              // Generated code block
  isNull: ExprValue,        // Variable for null check
  value: ExprValue          // Variable for result value
)
Expression Code Generation
scala
trait CodegenFallback extends Expression {
  // Fallback to interpreted evaluation.
  protected def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
    ctx.references += this
    val objectTerm = ctx.addReferenceObj("expression", this)
    ExprCode(
      code = code"""
        boolean ${ev.isNull} = true;
        ${CodeGenerator.javaType(dataType)} ${ev.value} =
          ${CodeGenerator.defaultValue(dataType)};
        Object result = $objectTerm.eval(${ctx.INPUT_ROW});
        if (result != null) {
          ${ev.isNull} = false;
          ${ev.value} = (${CodeGenerator.boxedType(dataType)}) result;
        }
      """,
      isNull = ev.isNull,
      value = ev.value
    )
  }
}
Projection Generation
scala
// Generate unsafe projection from expressions.
val projection = GenerateUnsafeProjection.generate(expressions)
val result = projection(inputRow)

// Generate mutable projection.
val mutableProjection = GenerateMutableProjection.generate(expressions)
val outputRow = mutableProjection(inputRow)

// Generate safe projection.
val safeProjection = GenerateSafeProjection.generate(expressions)
Predicate Generation
scala
// Generate predicate for filter condition.
val predicate = GeneratePredicate.generate(condition)
val passes = predicate.eval(row)
Ordering Generation
scala
// Generate row comparator.
val ordering = GenerateOrdering.generate(sortOrders)
val compareResult = ordering.compare(row1, row2)

Working with Data Types

10. Catalyst Type System
Primitive Types
scala
BooleanType
ByteType
ShortType
IntegerType
LongType
FloatType
DoubleType
StringType
BinaryType
DateType
TimestampType
TimestampNTZType
Complex Types
scala
// Array type.
ArrayType(elementType: DataType, containsNull: Boolean)

// Map type.
MapType(keyType: DataType, valueType: DataType, valueContainsNull: Boolean)

// Struct type.
StructType(fields: Seq[StructField])

// Struct field.
StructField(name: String, dataType: DataType, nullable: Boolean, metadata: Metadata)
Decimal Types
scala
DecimalType(precision: Int, scale: Int)
DecimalType.SYSTEM_DEFAULT  // Decimal(38, 18)

Common Patterns and Best Practices

Pattern 1: Creating Custom Expressions
scala
case class MyCustomFunction(child: Expression) extends UnaryExpression {
  // Define output type.
  override def dataType: DataType = StringType

  // Can the result be null?
  override def nullable: Boolean = child.nullable

  // Evaluate the expression.
  override def eval(input: InternalRow): Any = {
    val value = child.eval(input)
    if (value == null) {
      null
    } else {
      // Custom logic here.
      UTF8String.fromString(value.toString.toUpperCase)
    }
  }

  // Generate code for this expression.
  override protected def doGenCode(
      ctx: CodegenContext,
      ev: ExprCode): ExprCode = {
    val childGen = child.genCode(ctx)
    ev.copy(code = code"""
      ${childGen.code}
      boolean ${ev.isNull} = ${childGen.isNull};
      ${CodeGenerator.javaType(dataType)} ${ev.value} =
        ${CodeGenerator.defaultValue(dataType)};
      if (!${ev.isNull}) {
        ${ev.value} = UTF8String.fromString(
          ${childGen.value}.toString().toUpperCase());
      }
    """)
  }

  // Override for pretty printing.
  override def prettyName: String = "my_custom_function"
}
Pattern 2: Creating Custom Optimisation Rules
scala
object EliminateRedundantCasts extends Rule[LogicalPlan] {
  def apply(plan: LogicalPlan): LogicalPlan = plan.transformAllExpressions {
    case Cast(child, dataType, _, _) if child.dataType == dataType =>
      // Remove cast if types match.
      child
  }
}
Pattern 3: Pattern Matching on Plans
scala
plan match {
  case Project(projectList, child) =>
    // Handle projection.

  case Filter(condition, Project(projectList, child)) =>
    // Handle filter over projection.

  case Join(left, right, joinType, Some(condition), _) =>
    // Handle join with condition.

  case Aggregate(grouping, aggregates, child) =>
    // Handle aggregation.

  case _ =>
    // Default case.
}
Pattern 4: Traversing Expression Trees
scala
// Find all attribute references.
val attributes = expr.collect {
  case a: AttributeReference => a
}

// Find all subqueries.
val subqueries = expr.collect {
  case s: SubqueryExpression => s
}

// Transform specific expression types.
val transformed = expr.transformUp {
  case Add(Literal(0, _), right) => right
  case Add(left, Literal(0, _)) => left
}
Pattern 5: Attribute Resolution
scala
// Resolve attribute by name.
def resolve(attrName: String, input: LogicalPlan): Option[Attribute] = {
  input.output.find(_.name == attrName)
}

// Resolve with qualifier.
def resolveQualified(
    qualifier: Seq[String],
    attrName: String,
    input: LogicalPlan): Option[Attribute] = {
  input.output.find { attr =>
    attr.qualifier.startsWith(qualifier) && attr.name == attrName
  }
}
Pattern 6: Working with Schema
scala
// Create schema from attributes.
val schema = StructType(attributes.map { attr =>
  StructField(attr.name, attr.dataType, attr.nullable, attr.metadata)
})

// Convert schema to attributes.
val attributes = schema.toAttributes

// Add column to schema.
val newSchema = schema.add("newColumn", StringType, nullable = true)

// Drop column from schema.
val reducedSchema = StructType(schema.filterNot(_.name == "dropColumn"))

Testing Catalyst Components

Unit Testing Expressions
scala
test("my custom function") {
  val input = Literal("hello")
  val expr = MyCustomFunction(input)

  // Test evaluation.
  assert(expr.eval(null) == UTF8String.fromString("HELLO"))

  // Test properties.
  assert(expr.dataType == StringType)
  assert(expr.foldable)
  assert(expr.deterministic)
}
Testing Optimisation Rules
scala
test("eliminate redundant casts") {
  val plan = Project(
    Seq(Alias(Cast(AttributeReference("x", IntegerType)(), IntegerType), "y")()),
    testRelation
  )

  val optimised = EliminateRedundantCasts(plan)

  val expected = Project(
    Seq(Alias(AttributeReference("x", IntegerType)(), "y")()),
    testRelation
  )

  comparePlans(optimised, expected)
}

Performance Considerations

Show full SKILL.md (309 more words)Show less
Efficient Tree Traversal
  • Use tree patterns: Tree patterns enable efficient pattern matching without full traversal.
  • Cache results: Use lazy vals for expensive computations like outputSet and references.
  • Minimise transformations: Only transform nodes that need changes.
  • Use fastEquals: For quick equality checks without deep comparison.
Code Generation Best Practices
  • Minimise virtual calls: Generated code should avoid virtual method calls in tight loops.
  • Use primitive types: Avoid boxing/unboxing in generated code.
  • Inline small functions: Inline simple operations for better performance.
  • Batch operations: Process multiple rows or columns together when possible.
Rule Application Strategies
  • Order rules carefully: Place more common optimisations first.
  • Use Once for expensive rules: Cost-based optimisation should run once.
  • Set appropriate iteration limits: Balance optimisation quality with compile time.
  • Track ineffective rules: Use rule tracking to skip rules that won't apply.

Common Pitfalls

  1. Forgetting nullability: Always handle null values in expressions.
  2. Incorrect type coercion: Ensure type casts are valid and safe.
  3. Infinite rule loops: Rules must converge to a fixed point.
  4. Breaking plan invariants: Maintain output schema and semantics.
  5. Leaking state: Expressions should be stateless unless explicitly marked.
  6. Inefficient traversal: Use tree patterns and targeted transformations.
  7. Missing code generation: Implement doGenCode for custom expressions.
  8. Incorrect attribute resolution: Use proper resolution with qualifiers.

Additional Resources

  • Source code: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/
  • Tests: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/
  • Spark SQL documentation: Official Spark SQL programming guide
  • Research paper: "Spark SQL: Relational Data Processing in Spark" (SIGMOD 2015)

Summary

The Catalyst framework provides:

  • Tree-based representation for queries and expressions
  • Rule-based transformation framework for optimisation
  • Extensibility for custom expressions and optimisations
  • Code generation for high-performance execution
  • Type-safe API for query manipulation

Key extension points:

  • Custom expressions (extend Expression)
  • Custom optimisation rules (extend Rule[LogicalPlan])
  • Custom analysis rules (extend Rule[LogicalPlan])
  • Custom data sources (implement TableProvider)
  • Custom aggregate functions (extend AggregateFunction)

When working with Catalyst, focus on immutability, type safety, and efficient tree traversal patterns.

© aehrc, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/spark-catalyst of aehrc/pathling.

Open the folder on GitHubat commit 56a3b4a

Compare with similar skills

Spark Catalyst next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Spark Catalyst compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Spark Catalyst this skillaehrc/pathling137—~5.4kAutomated safety check: PassApache-2.0
Clickhouse IohellangleZ/burn-in-cceverywhere-ralph11214 repos~2.5kAutomated safety check: PassNone
Altimate Data Warehouse DelegateAltimateAI/data-engineering-skills128—~1.4kAutomated safety check: PassMIT
Expensive Snowflake Query FinderAltimateAI/data-engineering-skills128—~662Automated safety check: PassMIT
Tinybird Datafile RulesTryGhost/Ghost55k—~417Automated safety check: PassMIT
Optimizing Databricks SQLAltimateAI/data-engineering-skills128—~6.7kAutomated safety check: PassMIT

Similar skills

  • Clickhouse Io

    hellangleZ/burn-in-cceverywhere-ralph

    ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.

    112 GitHub starsUsed in 14 repos~2.5k tokens
    DatabasesAuto-check passed
  • Altimate Data Warehouse Delegate

    AltimateAI/data-engineering-skills

    Delegates dbt and warehouse tasks such as lineage, migrations and cost attribution to the altimate-code CLI agent and relays its answer back.

    128 GitHub stars~1.4k tokensUpdated 7 days ago
    DatabasesAuto-check passed
  • Expensive Snowflake Query Finder

    AltimateAI/data-engineering-skills

    Ranks the costliest, slowest or heaviest-scanning Snowflake queries from query history and suggests how to optimize them.

    128 GitHub stars~662 tokensUpdated 7 days ago
    DatabasesAuto-check passed
  • Rules for writing Tinybird datasources, pipes, endpoints and materialized views, with SQL constraints, optimization habits and deduplication patterns.

    55k GitHub stars~417 tokensUpdated yesterday
    DatabasesAuto-check passed
  • Optimizing Databricks SQL

    AltimateAI/data-engineering-skills

    Analyze DBSQL queries, including SQL embedded in notebooks (spark.sql(...), %sql cells), for anti-patterns, lint issues, and performance problems, using Databricks-specific dialect and platform…

    128 GitHub stars~6.7k tokensUpdated 7 days ago
    DatabasesAuto-check passed
  • SQL Optimization Patterns

    ynulihao/AgentSkillOS

    Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries.

    617 GitHub starsUsed in 11 repos~3.3k tokens
    DatabasesAuto-check passed

More from aehrc/pathling

All 25 skills in this repo
  • Fhir API

    aehrc/pathling

    Expert guidance for implementing FHIR RESTful API servers and clients following the HL7 FHIR specification.

    137 GitHub starsUsed in 1 repo~1.5k tokens
    Auto-check passed
  • Fhir Bulk Data

    aehrc/pathling

    Expert guidance for implementing FHIR Bulk Data Access (Flat FHIR) following the HL7 specification.

    137 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Databricks CLI

    aehrc/pathling

    Expert guidance for using the Databricks CLI to manage Databricks workspaces, clusters, jobs, pipelines, Unity Catalog, SQL warehouses, serving endpoints, secrets, bundles, and all other Databricks…

    137 GitHub stars~2.1k tokensUpdated yesterday
    Auto-check passed
  • Fhir Search Spec

    aehrc/pathling

    FHIR RESTful search specification expert with access to the official HL7 search specification text and the formal SearchParameter registry.

    137 GitHub stars~649 tokensUpdated yesterday
    Auto-check passed
  • Design and generate comprehensive FHIRPath test suites using input domain partitioning and Pathling's DSL test framework.

    137 GitHub stars~3.6k tokensUpdated yesterday
    Auto-check passed
  • Hapi Fhir Server

    aehrc/pathling

    Expert guidance for implementing FHIR servers using HAPI FHIR Plain Server framework.

    137 GitHub stars~2.6k tokensUpdated yesterday
    Auto-check passed

Works with

Questions about Spark Catalyst

What does Spark Catalyst do?

Expert guidance for working with the Apache Spark Catalyst query optimisation framework. Spark Catalyst is an agent skill from aehrc/pathling. Expert guidance for working with the Apache Spark Catalyst query optimisation framework.

When should I use Spark Catalyst?

Spark Catalyst fits situations like: working with Spark SQL internals; creating custom expressions; implementing query optimisations; working with logical/physical plans.

How do I install Spark Catalyst in Claude Code?

Run `npx skills add aehrc/pathling --skill spark-catalyst -a claude-code`. Or copy the skill folder (.claude/skills/spark-catalyst in aehrc/pathling) into .claude/skills/spark-catalyst in your project. Claude Code loads it when a task matches its description.

How do I install Spark Catalyst in Codex?

Run `npx skills add aehrc/pathling --skill spark-catalyst -a codex`. Or copy the skill folder (.claude/skills/spark-catalyst in aehrc/pathling) into .agents/skills/spark-catalyst in your project. Codex loads it when a task matches its description.

Can I use Spark Catalyst in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add aehrc/pathling --skill spark-catalyst -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/spark-catalyst, .gemini/skills/spark-catalyst, .github/skills/spark-catalyst and .opencode/skills/spark-catalyst in your project.

What does Spark Catalyst need to run?

SKILL.md names no scripts, command-line tools or credentials: Spark Catalyst is instructions for the agent only.

Does Spark Catalyst access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Spark Catalyst safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Spark Catalyst use?

Spark Catalyst is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Spark Catalyst use?

About 5.4k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Spark Catalyst?

Skills that share tags, products or a category with Spark Catalyst: Clickhouse Io (hellangleZ/burn-in-cceverywhere-ralph, 112 stars), Altimate Data Warehouse Delegate (AltimateAI/data-engineering-skills, 128 stars), Expensive Snowflake Query Finder (AltimateAI/data-engineering-skills, 128 stars) and Tinybird Datafile Rules (TryGhost/Ghost, 55k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Spark Catalyst?

aehrc (a GitHub organization) maintains it in aehrc/pathling, which has 137 GitHub stars. The repository holds 25 skills in this directory. The repository was last updated on October 8, 2026.

Source: aehrc/pathling on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.