@@ -1393,3 +1393,64 @@ fn evaluate_expr(optimizer: &PlanNormalize, expr: Expr) -> Result<Expr> {
13931393 let mut const_evaluator = ConstEvaluator :: new ( execution_props) ;
13941394 expr. rewrite ( & mut const_evaluator)
13951395}
1396+
1397+ #[ cfg( test) ]
1398+ mod tests {
1399+ use super :: * ;
1400+ use crate :: compile:: test:: {
1401+ get_test_tenant_ctx, rewrite_engine:: create_test_postgresql_cube_context,
1402+ } ;
1403+ use datafusion:: {
1404+ arrow:: datatypes:: { DataType , Field , Schema } ,
1405+ logical_plan:: { col, lit, LogicalPlanBuilder } ,
1406+ } ;
1407+
1408+ /// Helper function to create a deeply nested OR expression.
1409+ /// This creates a chain like: col = 1 OR col = 2 OR col = 3 OR ... OR col = depth
1410+ fn create_deeply_nested_or_expr ( column_name : & str , depth : usize ) -> Expr {
1411+ if depth == 0 {
1412+ return col ( column_name) . eq ( lit ( 0i32 ) ) ;
1413+ }
1414+
1415+ let mut expr = col ( column_name) . eq ( lit ( 0i32 ) ) ;
1416+
1417+ for i in 1 ..depth {
1418+ expr = expr. or ( col ( column_name) . eq ( lit ( i as i32 ) ) ) ;
1419+ }
1420+
1421+ expr
1422+ }
1423+
1424+ #[ tokio:: test]
1425+ async fn test_stack_overflow_deeply_nested_or ( ) -> Result < ( ) > {
1426+ let meta = get_test_tenant_ctx ( ) ;
1427+ let cube_ctx = create_test_postgresql_cube_context ( meta)
1428+ . await
1429+ . expect ( "Failed to create cube context" ) ;
1430+
1431+ // Create a simple table
1432+ let schema = Schema :: new ( vec ! [
1433+ Field :: new( "id" , DataType :: Int32 , false ) ,
1434+ Field :: new( "value" , DataType :: Int32 , true ) ,
1435+ ] ) ;
1436+
1437+ let table_scan = LogicalPlanBuilder :: scan_empty ( Some ( "test_table" ) , & schema, None )
1438+ . expect ( "Failed to create table scan" )
1439+ . build ( )
1440+ . expect ( "Failed to build plan" ) ;
1441+
1442+ // Create a deeply nested OR expression (should cause stack overflow)
1443+ let deeply_nested_filter = create_deeply_nested_or_expr ( "value" , 1_000 ) ;
1444+
1445+ let plan = LogicalPlanBuilder :: from ( table_scan)
1446+ . filter ( deeply_nested_filter)
1447+ . expect ( "Failed to add filter" )
1448+ . build ( )
1449+ . expect ( "Failed to build plan" ) ;
1450+
1451+ let optimizer = PlanNormalize :: new ( & cube_ctx) ;
1452+ optimizer. optimize ( & plan, & OptimizerConfig :: new ( ) ) ?;
1453+
1454+ Ok ( ( ) )
1455+ }
1456+ }
0 commit comments