Skip to content

Types and Schemas

Spark SQL uses a rich type system. Learn how to work with schemas in the spark_connect crate and cast columns between types.

Spark SQL Types

Map Spark SQL types to their Rust spark_connect::types::DataType equivalents:

Spark Type Rust DataType
StringType DataType::String { collation: "UTF8_BINARY".to_string() }
IntegerType DataType::Integer
LongType DataType::Long
FloatType DataType::Float
DoubleType DataType::Double
BooleanType DataType::Boolean
BinaryType DataType::Binary
DateType DataType::Date
TimestampType DataType::Timestamp
DecimalType DataType::Decimal { precision: 10, scale: 2 }
ArrayType DataType::Array { element_type: Box::new(DataType::String { ... }), contains_null: true }
MapType DataType::Map { key_type: Box::new(...), value_type: Box::new(...), value_contains_null: true }
StructType DataType::Struct { fields: Vec<StructField> }

Inspecting Schemas

Access schema information from a DataFrame:

// Get full schema
let schema = df.schema()?;

// Print schema
df.print_schema()?;

// Get list of (name, type) tuples
let dtypes = df.dtypes()?;
for (name, dtype) in dtypes {
    println!("{}: {}", name, dtype);
}

Building a Schema

Define a schema explicitly when reading or creating DataFrames:

use spark_connect::types::DataType;

// Define schema as DDL string
let schema_ddl = "name string, age int, salary long";

let df = spark.read()
    .schema(schema_ddl.to_string())
    .csv("/path/to/data.csv");

Casting Columns

Convert a column to a different type with .cast():

use spark_connect::types::DataType;

// Cast to LongType
let df = df.with_column("id", col("id").cast(DataType::Long));

// Cast to DoubleType
let df = df.with_column("price", col("price").cast(DataType::Double));

// Cast with a type name string
let df = df.with_column("created", col("created").cast_str("timestamp"));

Nested Types

Work with complex nested structures:

use spark_connect::types::{DataType, StructField};
use std::collections::BTreeMap;

// Array of strings
let array_of_strings = DataType::Array {
    element_type: Box::new(DataType::String {
        collation: "UTF8_BINARY".to_string(),
    }),
    contains_null: true,
};

// Map with string keys and integer values
let map_type = DataType::Map {
    key_type: Box::new(DataType::String {
        collation: "UTF8_BINARY".to_string(),
    }),
    value_type: Box::new(DataType::Integer),
    value_contains_null: true,
};

// Nested struct
let nested = DataType::Struct {
    fields: vec![
        StructField {
            name: "name".to_string(),
            data_type: DataType::String {
                collation: "UTF8_BINARY".to_string(),
            },
            nullable: true,
            metadata: BTreeMap::new(),
        },
        StructField {
            name: "tags".to_string(),
            data_type: DataType::Array {
                element_type: Box::new(DataType::String {
                    collation: "UTF8_BINARY".to_string(),
                }),
                contains_null: true,
            },
            nullable: true,
            metadata: BTreeMap::new(),
        },
    ],
};

Note

Nullable fields allow NULL values. Set to False when a field must always have a value.