1pub mod ai_udf;
5mod bridge;
6mod channel_source;
7pub mod complex_type_lambda;
9pub mod complex_type_udf;
11mod exec;
12pub mod execute;
14pub mod format_bridge_udf;
16pub mod json_extensions;
18pub mod json_path;
20pub mod json_tvf;
22pub mod json_types;
24pub mod json_udaf;
26pub mod json_udf;
28pub mod live_source;
30pub mod lookup_join;
32pub mod lookup_join_exec;
34pub mod proctime_udf;
36mod source;
37mod table_provider;
38pub mod watermark_udf;
41pub mod window_udf;
43
44pub use ai_udf::{ai_function_markers, AiFunctionMarker};
45pub use bridge::{BridgeSendError, BridgeSender, BridgeStream, BridgeTrySendError, StreamBridge};
46pub use channel_source::ChannelStreamSource;
47pub use complex_type_lambda::{
48 register_lambda_functions, ArrayFilter, ArrayReduce, ArrayTransform, MapFilter,
49 MapTransformValues,
50};
51pub use complex_type_udf::{
52 register_complex_type_functions, MapContainsKey, MapFromArrays, MapKeys, MapValues, StructDrop,
53 StructExtract, StructMerge, StructRename, StructSet,
54};
55pub use exec::StreamingScanExec;
56pub use execute::{execute_streaming_sql, DdlResult, QueryResult, StreamingSqlResult};
57pub use format_bridge_udf::{FromJsonUdf, ParseEpochUdf, ParseTimestampUdf, ToJsonUdf};
58pub use json_extensions::{
59 register_json_extensions, JsonInferSchema, JsonToColumns, JsonbDeepMerge, JsonbExcept,
60 JsonbFlatten, JsonbMerge, JsonbPick, JsonbRenameKeys, JsonbStripNulls, JsonbUnflatten,
61};
62pub use json_path::{CompiledJsonPath, JsonPathStep, JsonbPathExistsUdf, JsonbPathMatchUdf};
63pub use json_tvf::{
64 register_json_table_functions, JsonbArrayElementsTextTvf, JsonbArrayElementsTvf,
65 JsonbEachTextTvf, JsonbEachTvf, JsonbObjectKeysTvf,
66};
67pub use json_udaf::{JsonAgg, JsonObjectAgg};
68pub use json_udf::{
69 JsonBuildArray, JsonBuildObject, JsonTypeof, JsonbContainedBy, JsonbContains, JsonbExists,
70 JsonbExistsAll, JsonbExistsAny, JsonbGet, JsonbGetIdx, JsonbGetPath, JsonbGetPathText,
71 JsonbGetText, JsonbGetTextIdx, ToJsonb,
72};
73pub use live_source::{LiveSourceHandle, LiveSourceProvider};
74pub use lookup_join_exec::{
75 LookupJoinExec, LookupJoinExtensionPlanner, LookupSnapshot, LookupTableRegistry,
76 PartialLookupJoinExec, PartialLookupState, RegisteredLookup,
77};
78pub use proctime_udf::ProcTimeUdf;
79pub use source::{SortColumn, StreamSource, StreamSourceRef};
80pub use table_provider::StreamingTableProvider;
81pub use watermark_udf::WatermarkUdf;
82pub use window_udf::{
83 CumulateWindowEnd, CumulateWindowStart, HopWindowEnd, HopWindowStart, SessionWindowStart,
84 TumbleWindowEnd, TumbleWindowStart,
85};
86
87use std::sync::atomic::AtomicI64;
88use std::sync::Arc;
89
90use datafusion::execution::SessionStateBuilder;
91use datafusion::prelude::*;
92use datafusion_expr::ScalarUDF;
93
94use crate::planner::streaming_optimizer::{StreamingPhysicalValidator, StreamingValidatorMode};
95
96#[must_use]
103pub fn base_session_config() -> SessionConfig {
104 let mut config = SessionConfig::new();
105 config.options_mut().sql_parser.enable_ident_normalization = false;
106 config = config.with_target_partitions(1);
110 config
111}
112
113#[must_use]
119pub fn create_session_context() -> SessionContext {
120 SessionContext::new_with_config(base_session_config())
121}
122
123#[must_use]
144pub fn create_streaming_context() -> SessionContext {
145 create_streaming_context_with_validator(StreamingValidatorMode::Reject)
146}
147
148#[must_use]
156pub fn create_streaming_context_with_validator(mode: StreamingValidatorMode) -> SessionContext {
157 let config = base_session_config().with_batch_size(8192);
158
159 let ctx = if matches!(mode, StreamingValidatorMode::Off) {
160 SessionContext::new_with_config(config)
161 } else {
162 let default_state = SessionStateBuilder::new()
166 .with_config(config.clone())
167 .with_default_features()
168 .build();
169 let mut rules: Vec<
170 Arc<dyn datafusion::physical_optimizer::PhysicalOptimizerRule + Send + Sync>,
171 > = vec![Arc::new(StreamingPhysicalValidator::new(mode))];
172 rules.extend(default_state.physical_optimizers().iter().cloned());
173
174 let state = SessionStateBuilder::new()
175 .with_config(config)
176 .with_default_features()
177 .with_physical_optimizer_rules(rules)
178 .build();
179 SessionContext::new_with_state(state)
180 };
181
182 register_streaming_functions(&ctx);
183 ctx
184}
185
186fn register_non_watermark_udfs(ctx: &SessionContext) {
191 ctx.register_udf(ScalarUDF::new_from_impl(TumbleWindowStart::new()));
192 ctx.register_udf(ScalarUDF::new_from_impl(TumbleWindowEnd::new()));
193 ctx.register_udf(ScalarUDF::new_from_impl(HopWindowStart::new()));
194 ctx.register_udf(ScalarUDF::new_from_impl(HopWindowEnd::new()));
195 ctx.register_udf(ScalarUDF::new_from_impl(SessionWindowStart::new()));
196 ctx.register_udf(ScalarUDF::new_from_impl(CumulateWindowStart::new()));
197 ctx.register_udf(ScalarUDF::new_from_impl(CumulateWindowEnd::new()));
198 ctx.register_udf(ScalarUDF::new_from_impl(ProcTimeUdf::new()));
199 for marker in ai_function_markers() {
200 ctx.register_udf(marker);
201 }
202 register_json_functions(ctx);
203 register_json_extensions(ctx);
204 register_complex_type_functions(ctx);
205 register_lambda_functions(ctx);
206}
207
208pub fn register_streaming_functions(ctx: &SessionContext) {
213 register_non_watermark_udfs(ctx);
214 ctx.register_udf(ScalarUDF::new_from_impl(WatermarkUdf::unset()));
215}
216
217pub fn register_streaming_functions_with_watermark(
222 ctx: &SessionContext,
223 watermark_ms: Arc<AtomicI64>,
224) {
225 register_non_watermark_udfs(ctx);
226 ctx.register_udf(ScalarUDF::new_from_impl(WatermarkUdf::new(watermark_ms)));
227}
228
229pub fn register_json_functions(ctx: &SessionContext) {
232 ctx.register_udf(ScalarUDF::new_from_impl(JsonbGet::new()));
234 ctx.register_udf(ScalarUDF::new_from_impl(JsonbGetIdx::new()));
235 ctx.register_udf(ScalarUDF::new_from_impl(JsonbGetText::new()));
236 ctx.register_udf(ScalarUDF::new_from_impl(JsonbGetTextIdx::new()));
237 ctx.register_udf(ScalarUDF::new_from_impl(JsonbGetPath::new()));
238 ctx.register_udf(ScalarUDF::new_from_impl(JsonbGetPathText::new()));
239
240 ctx.register_udf(ScalarUDF::new_from_impl(JsonbExists::new()));
242 ctx.register_udf(ScalarUDF::new_from_impl(JsonbExistsAny::new()));
243 ctx.register_udf(ScalarUDF::new_from_impl(JsonbExistsAll::new()));
244
245 ctx.register_udf(ScalarUDF::new_from_impl(JsonbContains::new()));
247 ctx.register_udf(ScalarUDF::new_from_impl(JsonbContainedBy::new()));
248
249 ctx.register_udf(ScalarUDF::new_from_impl(JsonTypeof::new()));
251 ctx.register_udf(ScalarUDF::new_from_impl(JsonBuildObject::new()));
252 ctx.register_udf(ScalarUDF::new_from_impl(JsonBuildArray::new()));
253 ctx.register_udf(ScalarUDF::new_from_impl(ToJsonb::new()));
254
255 ctx.register_udaf(datafusion_expr::AggregateUDF::new_from_impl(JsonAgg::new()));
257 ctx.register_udaf(datafusion_expr::AggregateUDF::new_from_impl(
258 JsonObjectAgg::new(),
259 ));
260
261 ctx.register_udf(ScalarUDF::new_from_impl(ParseEpochUdf::new()));
263 ctx.register_udf(ScalarUDF::new_from_impl(ParseTimestampUdf::new()));
264 ctx.register_udf(ScalarUDF::new_from_impl(ToJsonUdf::new()));
265 ctx.register_udf(ScalarUDF::new_from_impl(FromJsonUdf::new()));
266
267 ctx.register_udf(ScalarUDF::new_from_impl(JsonbPathExistsUdf::new()));
269 ctx.register_udf(ScalarUDF::new_from_impl(JsonbPathMatchUdf::new()));
270
271 register_json_table_functions(ctx);
273}
274
275#[cfg(test)]
276mod tests;