-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(iceberg): Adds support for read_iceberg with metadata_location t…
…o Daft-SQL (#3701)
- Loading branch information
Showing
11 changed files
with
211 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,3 +43,6 @@ log/ | |
|
||
# helix editor | ||
.helix | ||
|
||
# uv | ||
uv.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use daft_logical_plan::LogicalPlanBuilder; | ||
use sqlparser::ast::TableFunctionArgs; | ||
|
||
use super::{expr_to_iocfg, SQLTableFunction}; | ||
use crate::{error::SQLPlannerResult, unsupported_sql_err, SQLPlanner}; | ||
|
||
pub(super) struct ReadDeltalakeFunction; | ||
|
||
#[cfg(feature = "python")] | ||
impl SQLTableFunction for ReadDeltalakeFunction { | ||
fn plan( | ||
&self, | ||
planner: &SQLPlanner, | ||
args: &TableFunctionArgs, | ||
) -> SQLPlannerResult<LogicalPlanBuilder> { | ||
let (uri, io_config) = match args.args.as_slice() { | ||
[uri] => (uri, None), | ||
[uri, io_config] => { | ||
let args = planner.parse_function_args(&[io_config.clone()], &["io_config"], 0)?; | ||
let io_config = args.get_named("io_config").map(expr_to_iocfg).transpose()?; | ||
(uri, io_config) | ||
} | ||
_ => unsupported_sql_err!("Expected one or two arguments"), | ||
}; | ||
let uri = planner.plan_function_arg(uri)?; | ||
|
||
let Some(uri) = uri.as_literal().and_then(|lit| lit.as_str()) else { | ||
unsupported_sql_err!("Expected a string literal for the first argument"); | ||
}; | ||
|
||
daft_scan::builder::delta_scan(uri, io_config, true).map_err(From::from) | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "python"))] | ||
impl SQLTableFunction for ReadDeltalakeFunction { | ||
fn plan( | ||
&self, | ||
planner: &SQLPlanner, | ||
args: &TableFunctionArgs, | ||
) -> SQLPlannerResult<LogicalPlanBuilder> { | ||
unsupported_sql_err!("`read_deltalake` function is not supported. Enable the `python` feature to use this function.") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use common_io_config::IOConfig; | ||
use daft_logical_plan::LogicalPlanBuilder; | ||
use sqlparser::ast::TableFunctionArgs; | ||
|
||
use super::SQLTableFunction; | ||
use crate::{ | ||
error::{PlannerError, SQLPlannerResult}, | ||
functions::{self, SQLFunctionArguments}, | ||
SQLPlanner, | ||
}; | ||
|
||
/// The Daft-SQL `read_iceberg` table-value function. | ||
pub(super) struct SqlReadIceberg; | ||
|
||
/// The Daft-SQL `read_iceberg` table-value function arguments. | ||
struct SqlReadIcebergArgs { | ||
metadata_location: String, | ||
snapshot_id: Option<usize>, | ||
io_config: Option<IOConfig>, | ||
} | ||
|
||
impl SqlReadIcebergArgs { | ||
/// Like a TryFrom<SQLFunctionArguments> but from TalbeFunctionArgs directly and passing the planner. | ||
fn try_from(planner: &SQLPlanner, args: &TableFunctionArgs) -> SQLPlannerResult<Self> { | ||
planner.plan_function_args(&args.args, &["snapshot_id", "io_config"], 1) | ||
} | ||
} | ||
|
||
impl TryFrom<SQLFunctionArguments> for SqlReadIcebergArgs { | ||
type Error = PlannerError; | ||
|
||
/// This is required to use `planner.plan_function_args` | ||
fn try_from(args: SQLFunctionArguments) -> Result<Self, Self::Error> { | ||
let metadata_location: String = args | ||
.try_get_positional(0)? | ||
.expect("read_iceberg requires a path"); | ||
let snapshot_id: Option<usize> = args.try_get_named("snapshot_id")?; | ||
let io_config: Option<IOConfig> = functions::args::parse_io_config(&args)?.into(); | ||
Ok(Self { | ||
metadata_location, | ||
snapshot_id, | ||
io_config, | ||
}) | ||
} | ||
} | ||
|
||
/// Translates the `read_iceberg` table-value function to a logical scan operator. | ||
#[cfg(feature = "python")] | ||
impl SQLTableFunction for SqlReadIceberg { | ||
fn plan( | ||
&self, | ||
planner: &SQLPlanner, | ||
args: &TableFunctionArgs, | ||
) -> SQLPlannerResult<LogicalPlanBuilder> { | ||
let args = SqlReadIcebergArgs::try_from(planner, args)?; | ||
Ok(daft_scan::builder::iceberg_scan( | ||
args.metadata_location, | ||
args.snapshot_id, | ||
args.io_config, | ||
)?) | ||
} | ||
} | ||
|
||
/// Translates the `read_iceberg` table-value function to a logical scan operator (errors without python feature). | ||
#[cfg(not(feature = "python"))] | ||
impl SQLTableFunction for SqlReadIceberg { | ||
fn plan( | ||
&self, | ||
planner: &SQLPlanner, | ||
args: &TableFunctionArgs, | ||
) -> SQLPlannerResult<LogicalPlanBuilder> { | ||
crate::unsupported_sql_err!("`read_iceberg` function is not supported. Enable the `python` feature to use this function.") | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import pytest | ||
|
||
import daft | ||
|
||
|
||
@pytest.mark.skip( | ||
"invoke manually via `uv run tests/sql/test_table_functions/test_read_iceberg.py <metadata_location>`" | ||
) | ||
def test_read_iceberg(metadata_location): | ||
df = daft.sql(f"SELECT * FROM read_iceberg('{metadata_location}')") | ||
print(df.collect()) | ||
|
||
|
||
if __name__ == "__main__": | ||
import sys | ||
|
||
if len(sys.argv) < 2: | ||
print("usage: test_read_iceberg.py <metadata_location>") | ||
sys.exit(1) | ||
test_read_iceberg(metadata_location=sys.argv[1]) |
File renamed without changes.