Path: blob/main/crates/polars-sql/src/table_functions.rs
6940 views
use std::str::FromStr;12#[cfg(any(3feature = "csv",4feature = "parquet",5feature = "ipc",6feature = "json"7))]8use polars_core::prelude::polars_ensure;9use polars_core::prelude::{PolarsError, PolarsResult, polars_bail};10#[cfg(feature = "csv")]11use polars_lazy::prelude::LazyCsvReader;12use polars_lazy::prelude::LazyFrame;13use polars_utils::plpath::PlPath;14use sqlparser::ast::{FunctionArg, FunctionArgExpr};1516/// Table functions that are supported by Polars17#[allow(clippy::enum_variant_names)]18pub(crate) enum PolarsTableFunctions {19/// SQL 'read_csv' function.20/// ```sql21/// SELECT * FROM read_csv('path/to/file.csv')22/// ```23#[cfg(feature = "csv")]24ReadCsv,25/// SQL 'read_parquet' function.26/// ```sql27/// SELECT * FROM read_parquet('path/to/file.parquet')28/// ```29#[cfg(feature = "parquet")]30ReadParquet,31/// SQL 'read_ipc' function.32/// ```sql33/// SELECT * FROM read_ipc('path/to/file.ipc')34/// ```35#[cfg(feature = "ipc")]36ReadIpc,37/// SQL 'read_json' function (*only ndjson is currently supported*).38/// ```sql39/// SELECT * FROM read_json('path/to/file.json')40/// ```41#[cfg(feature = "json")]42ReadJson,43}4445impl FromStr for PolarsTableFunctions {46type Err = PolarsError;4748#[allow(unreachable_code)]49fn from_str(s: &str) -> Result<Self, Self::Err> {50Ok(match s {51#[cfg(feature = "csv")]52"read_csv" => PolarsTableFunctions::ReadCsv,53#[cfg(feature = "parquet")]54"read_parquet" => PolarsTableFunctions::ReadParquet,55#[cfg(feature = "ipc")]56"read_ipc" => PolarsTableFunctions::ReadIpc,57#[cfg(feature = "json")]58"read_json" => PolarsTableFunctions::ReadJson,59_ => polars_bail!(SQLInterface: "'{}' is not a supported table function", s),60})61}62}6364impl PolarsTableFunctions {65#[allow(unused_variables, unreachable_patterns)]66pub(crate) fn execute(&self, args: &[FunctionArg]) -> PolarsResult<(PlPath, LazyFrame)> {67match self {68#[cfg(feature = "csv")]69PolarsTableFunctions::ReadCsv => self.read_csv(args),70#[cfg(feature = "parquet")]71PolarsTableFunctions::ReadParquet => self.read_parquet(args),72#[cfg(feature = "ipc")]73PolarsTableFunctions::ReadIpc => self.read_ipc(args),74#[cfg(feature = "json")]75PolarsTableFunctions::ReadJson => self.read_ndjson(args),76_ => unreachable!(),77}78}7980#[cfg(feature = "csv")]81fn read_csv(&self, args: &[FunctionArg]) -> PolarsResult<(PlPath, LazyFrame)> {82polars_ensure!(args.len() == 1, SQLSyntax: "`read_csv` expects a single file path; found {:?} arguments", args.len());8384use polars_lazy::frame::LazyFileListReader;85let path = self.get_file_path_from_arg(&args[0])?;86let lf = LazyCsvReader::new(path.clone())87.with_try_parse_dates(true)88.with_missing_is_null(true)89.finish()?;90Ok((path, lf))91}9293#[cfg(feature = "parquet")]94fn read_parquet(&self, args: &[FunctionArg]) -> PolarsResult<(PlPath, LazyFrame)> {95polars_ensure!(args.len() == 1, SQLSyntax: "`read_parquet` expects a single file path; found {:?} arguments", args.len());9697let path = self.get_file_path_from_arg(&args[0])?;98let lf = LazyFrame::scan_parquet(path.clone(), Default::default())?;99Ok((path, lf))100}101102#[cfg(feature = "ipc")]103fn read_ipc(&self, args: &[FunctionArg]) -> PolarsResult<(PlPath, LazyFrame)> {104polars_ensure!(args.len() == 1, SQLSyntax: "`read_ipc` expects a single file path; found {:?} arguments", args.len());105106let path = self.get_file_path_from_arg(&args[0])?;107let lf = LazyFrame::scan_ipc(path.clone(), Default::default())?;108Ok((path, lf))109}110#[cfg(feature = "json")]111fn read_ndjson(&self, args: &[FunctionArg]) -> PolarsResult<(PlPath, LazyFrame)> {112polars_ensure!(args.len() == 1, SQLSyntax: "`read_ndjson` expects a single file path; found {:?} arguments", args.len());113114use polars_lazy::frame::LazyFileListReader;115use polars_lazy::prelude::LazyJsonLineReader;116117let path = self.get_file_path_from_arg(&args[0])?;118let lf = LazyJsonLineReader::new(path.clone()).finish()?;119Ok((path, lf))120}121122#[allow(dead_code)]123fn get_file_path_from_arg(&self, arg: &FunctionArg) -> PolarsResult<PlPath> {124use sqlparser::ast::{Expr as SQLExpr, Value as SQLValue};125match arg {126FunctionArg::Unnamed(FunctionArgExpr::Expr(SQLExpr::Value(127SQLValue::SingleQuotedString(s),128))) => Ok(PlPath::from_str(s)),129_ => polars_bail!(130SQLSyntax:131"expected a valid file path as a single-quoted string; found: {}", arg,132),133}134}135}136137impl PolarsTableFunctions {138// list sql names of all table functions139pub(crate) fn keywords() -> &'static [&'static str] {140&[141#[cfg(feature = "csv")]142"read_csv",143#[cfg(feature = "parquet")]144"read_parquet",145#[cfg(feature = "ipc")]146"read_ipc",147#[cfg(feature = "json")]148"read_json",149]150}151}152153154