Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-plan/src/plans/functions/schema.rs
8433 views
1
#[cfg(feature = "pivot")]
2
use polars_core::utils::try_get_supertype;
3
4
use super::*;
5
use crate::constants::get_len_name;
6
7
impl FunctionIR {
8
pub(crate) fn clear_cached_schema(&self) {
9
use FunctionIR::*;
10
// We will likely add more branches later
11
#[allow(clippy::single_match)]
12
match self {
13
#[cfg(feature = "pivot")]
14
Unpivot { schema, .. } => {
15
let mut guard = schema.lock().unwrap();
16
*guard = None;
17
},
18
RowIndex { schema, .. } | Explode { schema, .. } => {
19
let mut guard = schema.lock().unwrap();
20
*guard = None;
21
},
22
_ => {},
23
}
24
}
25
26
pub fn schema<'a>(&self, input_schema: &'a SchemaRef) -> PolarsResult<Cow<'a, SchemaRef>> {
27
use FunctionIR::*;
28
match self {
29
Opaque { schema, .. } => match schema {
30
None => Ok(Cow::Borrowed(input_schema)),
31
Some(schema_fn) => {
32
let output_schema = schema_fn.get_schema(input_schema)?;
33
Ok(Cow::Owned(output_schema))
34
},
35
},
36
#[cfg(feature = "python")]
37
OpaquePython(OpaquePythonUdf { schema, .. }) => Ok(schema
38
.as_ref()
39
.map(|schema| Cow::Owned(schema.clone()))
40
.unwrap_or_else(|| Cow::Borrowed(input_schema))),
41
FastCount { alias, .. } => {
42
let mut schema: Schema = Schema::with_capacity(1);
43
let name = alias.clone().unwrap_or_else(get_len_name);
44
schema.insert_at_index(0, name, IDX_DTYPE)?;
45
Ok(Cow::Owned(Arc::new(schema)))
46
},
47
Rechunk => Ok(Cow::Borrowed(input_schema)),
48
Unnest { columns, separator } => {
49
#[cfg(feature = "dtype-struct")]
50
{
51
let mut new_schema = Schema::with_capacity(input_schema.len() * 2);
52
for (name, dtype) in input_schema.iter() {
53
if columns.iter().any(|item| item == name) {
54
match dtype {
55
DataType::Struct(flds) => {
56
for fld in flds {
57
let fld_name = match separator {
58
None => fld.name().clone(),
59
Some(sep) => {
60
polars_utils::format_pl_smallstr!(
61
"{name}{sep}{}",
62
fld.name()
63
)
64
},
65
};
66
new_schema.with_column(fld_name, fld.dtype().clone());
67
}
68
},
69
DataType::Unknown(_) => {
70
// pass through unknown
71
},
72
_ => {
73
polars_bail!(
74
SchemaMismatch: "expected struct dtype, got: `{}`", dtype
75
);
76
},
77
}
78
} else {
79
new_schema.with_column(name.clone(), dtype.clone());
80
}
81
}
82
83
Ok(Cow::Owned(Arc::new(new_schema)))
84
}
85
#[cfg(not(feature = "dtype-struct"))]
86
{
87
panic!("activate feature 'dtype-struct'")
88
}
89
},
90
RowIndex { schema, name, .. } => Ok(Cow::Owned(row_index_schema(
91
schema,
92
input_schema,
93
name.clone(),
94
))),
95
Explode {
96
schema,
97
options: _,
98
columns,
99
} => explode_schema(schema, input_schema, columns),
100
#[cfg(feature = "pivot")]
101
Unpivot { schema, args } => unpivot_schema(args, schema, input_schema),
102
Hint(_) => Ok(Cow::Borrowed(input_schema)),
103
}
104
}
105
}
106
107
fn row_index_schema(
108
cached_schema: &CachedSchema,
109
input_schema: &SchemaRef,
110
name: PlSmallStr,
111
) -> SchemaRef {
112
let mut guard = cached_schema.lock().unwrap();
113
if let Some(schema) = &*guard {
114
return schema.clone();
115
}
116
let mut schema = (**input_schema).clone();
117
schema.insert_at_index(0, name, IDX_DTYPE).unwrap();
118
let schema_ref = Arc::new(schema);
119
*guard = Some(schema_ref.clone());
120
schema_ref
121
}
122
123
fn explode_schema<'a>(
124
cached_schema: &CachedSchema,
125
schema: &'a Schema,
126
columns: &[PlSmallStr],
127
) -> PolarsResult<Cow<'a, SchemaRef>> {
128
let mut guard = cached_schema.lock().unwrap();
129
if let Some(schema) = &*guard {
130
return Ok(Cow::Owned(schema.clone()));
131
}
132
let mut schema = schema.clone();
133
134
// columns to string
135
columns.iter().try_for_each(|name| {
136
match schema.try_get(name)? {
137
DataType::List(inner) => {
138
schema.with_column(name.clone(), inner.as_ref().clone());
139
},
140
#[cfg(feature = "dtype-array")]
141
DataType::Array(inner, _) => {
142
schema.with_column(name.clone(), inner.as_ref().clone());
143
},
144
_ => {},
145
}
146
147
PolarsResult::Ok(())
148
})?;
149
let schema = Arc::new(schema);
150
*guard = Some(schema.clone());
151
Ok(Cow::Owned(schema))
152
}
153
154
#[cfg(feature = "pivot")]
155
fn unpivot_schema<'a>(
156
args: &UnpivotArgsIR,
157
cached_schema: &CachedSchema,
158
input_schema: &'a Schema,
159
) -> PolarsResult<Cow<'a, SchemaRef>> {
160
let mut guard = cached_schema.lock().unwrap();
161
if let Some(schema) = &*guard {
162
return Ok(Cow::Owned(schema.clone()));
163
}
164
165
let mut new_schema = args
166
.index
167
.iter()
168
.map(|id| Ok(Field::new(id.clone(), input_schema.try_get(id)?.clone())))
169
.collect::<PolarsResult<Schema>>()?;
170
171
new_schema.with_column(args.variable_name.clone(), DataType::String);
172
173
// We need to determine the supertype of all value columns.
174
let mut supertype = DataType::Null;
175
176
for name in &args.on {
177
let dtype = input_schema.try_get(name)?;
178
supertype = try_get_supertype(&supertype, dtype)?;
179
}
180
181
new_schema.with_column(args.value_name.clone(), supertype);
182
let schema = Arc::new(new_schema);
183
*guard = Some(schema.clone());
184
Ok(Cow::Owned(schema))
185
}
186
187