Skip to content

Commit bd226a4

Browse files
adriangbclaude
andcommitted
test: cover the erroring defaults of the ctx capability channels
A serialization layer that implements only the required encode/decode hooks must reject encode_function / decode_function / config_options requests with errors naming the requested type, exercised directly through the public ctx surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PzhFvJM2cEXzy9tixZeRYg
1 parent ad37eea commit bd226a4

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

datafusion/physical-expr-common/src/physical_expr.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,3 +1453,91 @@ mod proto_helper_tests {
14531453
));
14541454
}
14551455
}
1456+
1457+
/// Tests for the erroring defaults of the dispatch traits' capability
1458+
/// channels: a serialization layer that implements only the required
1459+
/// `encode`/`decode` must reject function-codec and session-config requests
1460+
/// with errors naming the requested type, not panic or silently succeed.
1461+
#[cfg(all(test, feature = "proto"))]
1462+
mod proto_capability_default_tests {
1463+
use std::sync::Arc;
1464+
1465+
use arrow::datatypes::Schema;
1466+
use datafusion_common::{DataFusionError, Result};
1467+
use datafusion_proto_models::protobuf::PhysicalExprNode;
1468+
1469+
use crate::physical_expr::PhysicalExpr;
1470+
use crate::physical_expr::proto_decode::{PhysicalExprDecode, PhysicalExprDecodeCtx};
1471+
use crate::physical_expr::proto_encode::{PhysicalExprEncode, PhysicalExprEncodeCtx};
1472+
1473+
struct DefaultOnlyEncoder;
1474+
1475+
impl PhysicalExprEncode for DefaultOnlyEncoder {
1476+
fn encode(&self, _expr: &Arc<dyn PhysicalExpr>) -> Result<PhysicalExprNode> {
1477+
unreachable!("child encoding must not be reached")
1478+
}
1479+
}
1480+
1481+
struct DefaultOnlyDecoder;
1482+
1483+
impl PhysicalExprDecode for DefaultOnlyDecoder {
1484+
fn decode(
1485+
&self,
1486+
_node: &PhysicalExprNode,
1487+
_schema: &Schema,
1488+
) -> Result<Arc<dyn PhysicalExpr>> {
1489+
unreachable!("child decoding must not be reached")
1490+
}
1491+
}
1492+
1493+
/// Stands in for a function type (e.g. `ScalarUDF`) the layer was never
1494+
/// taught about.
1495+
#[derive(Debug)]
1496+
struct NotAFunction;
1497+
1498+
#[test]
1499+
fn encode_function_default_errors_naming_requested_type() {
1500+
let encoder = DefaultOnlyEncoder;
1501+
let ctx = PhysicalExprEncodeCtx::new(&encoder);
1502+
1503+
let err = ctx.encode_function(&NotAFunction).unwrap_err();
1504+
assert!(matches!(
1505+
err,
1506+
DataFusionError::Internal(msg)
1507+
if msg.contains("does not support encoding function objects")
1508+
&& msg.contains("NotAFunction")
1509+
));
1510+
}
1511+
1512+
#[test]
1513+
fn decode_function_default_errors_naming_requested_type_and_name() {
1514+
let schema = Schema::empty();
1515+
let decoder = DefaultOnlyDecoder;
1516+
let ctx = PhysicalExprDecodeCtx::new(&schema, &decoder);
1517+
1518+
let err = ctx
1519+
.decode_function::<NotAFunction>("my_udf", None)
1520+
.unwrap_err();
1521+
assert!(matches!(
1522+
err,
1523+
DataFusionError::Internal(msg)
1524+
if msg.contains("does not support resolving function objects")
1525+
&& msg.contains("NotAFunction")
1526+
&& msg.contains("'my_udf'")
1527+
));
1528+
}
1529+
1530+
#[test]
1531+
fn config_options_default_errors() {
1532+
let schema = Schema::empty();
1533+
let decoder = DefaultOnlyDecoder;
1534+
let ctx = PhysicalExprDecodeCtx::new(&schema, &decoder);
1535+
1536+
let err = ctx.config_options().unwrap_err();
1537+
assert!(matches!(
1538+
err,
1539+
DataFusionError::Internal(msg)
1540+
if msg.contains("does not provide session configuration")
1541+
));
1542+
}
1543+
}

0 commit comments

Comments
 (0)