@@ -4581,3 +4581,128 @@ fn test_drop_constraints() {
4581
4581
snowflake ( ) . verified_stmt ( "ALTER TABLE tbl DROP FOREIGN KEY k1 RESTRICT" ) ;
4582
4582
snowflake ( ) . verified_stmt ( "ALTER TABLE tbl DROP CONSTRAINT c1 CASCADE" ) ;
4583
4583
}
4584
+
4585
+ #[ test]
4586
+ fn test_semantic_view_all_variants ( ) {
4587
+ let test_cases = [
4588
+ ( "SELECT * FROM SEMANTIC_VIEW(model)" , None ) ,
4589
+ (
4590
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1, dim2)" ,
4591
+ None ,
4592
+ ) ,
4593
+ (
4594
+ "SELECT * FROM SEMANTIC_VIEW(model METRICS met1, met2)" ,
4595
+ None ,
4596
+ ) ,
4597
+ (
4598
+ "SELECT * FROM SEMANTIC_VIEW(model FACTS fact1, fact2)" ,
4599
+ None ,
4600
+ ) ,
4601
+ (
4602
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 METRICS met1)" ,
4603
+ None ,
4604
+ ) ,
4605
+ (
4606
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 WHERE x > 0)" ,
4607
+ None ,
4608
+ ) ,
4609
+ (
4610
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1) AS sv" ,
4611
+ None ,
4612
+ ) ,
4613
+ (
4614
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS DATE_PART('year', col))" ,
4615
+ None ,
4616
+ ) ,
4617
+ (
4618
+ "SELECT * FROM SEMANTIC_VIEW(model METRICS SUM(col), AVG(col2))" ,
4619
+ None ,
4620
+ ) ,
4621
+ // We can parse in any order bu will always produce a result in a fixed order.
4622
+ (
4623
+ "SELECT * FROM SEMANTIC_VIEW(model METRICS met1 DIMENSIONS dim1)" ,
4624
+ Some ( "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 METRICS met1)" ) ,
4625
+ ) ,
4626
+ (
4627
+ "SELECT * FROM SEMANTIC_VIEW(model FACTS fact1 DIMENSIONS dim1)" ,
4628
+ Some ( "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 FACTS fact1)" ) ,
4629
+ ) ,
4630
+ ] ;
4631
+
4632
+ for ( input_sql, expected_sql) in test_cases {
4633
+ if let Some ( expected) = expected_sql {
4634
+ // Test that non-canonical order gets normalized
4635
+ let parsed = snowflake ( ) . parse_sql_statements ( input_sql) . unwrap ( ) ;
4636
+ let formatted = parsed[ 0 ] . to_string ( ) ;
4637
+ assert_eq ! ( formatted, expected, "Input: {}" , input_sql) ;
4638
+ } else {
4639
+ // Test round-trip parsing
4640
+ snowflake ( ) . verified_stmt ( input_sql) ;
4641
+ }
4642
+ }
4643
+ }
4644
+
4645
+ #[ test]
4646
+ fn test_semantic_view_negative_cases ( ) {
4647
+ // Test invalid syntax that should fail
4648
+ let invalid_sqls = [
4649
+ "SELECT * FROM SEMANTIC_VIEW(model WHERE x > 0 DIMENSIONS dim1)" ,
4650
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 WHERE x > 0 METRICS met1)" ,
4651
+ "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 DIMENSIONS dim2)" ,
4652
+ ] ;
4653
+
4654
+ for sql in invalid_sqls {
4655
+ let result = snowflake ( ) . parse_sql_statements ( sql) ;
4656
+ assert ! ( result. is_err( ) , "Expected error for invalid SQL: {}" , sql) ;
4657
+ }
4658
+ }
4659
+
4660
+ #[ test]
4661
+ fn test_semantic_view_ast_structure ( ) {
4662
+ // Test that we correctly parse into the expected AST structure
4663
+ let sql = r#"SELECT * FROM SEMANTIC_VIEW(
4664
+ my_model
4665
+ DIMENSIONS DATE_PART('year', date_col), region_name
4666
+ METRICS SUM(revenue), COUNT(*)
4667
+ WHERE active = true
4668
+ ) AS model_alias"# ;
4669
+
4670
+ let stmt = snowflake ( ) . parse_sql_statements ( sql) . unwrap ( ) ;
4671
+ match & stmt[ 0 ] {
4672
+ Statement :: Query ( q) => {
4673
+ if let SetExpr :: Select ( select) = q. body . as_ref ( ) {
4674
+ if let Some ( TableWithJoins { relation, .. } ) = select. from . first ( ) {
4675
+ match relation {
4676
+ TableFactor :: SemanticView {
4677
+ name,
4678
+ dimensions,
4679
+ metrics,
4680
+ facts,
4681
+ where_clause,
4682
+ alias,
4683
+ } => {
4684
+ assert_eq ! ( name. to_string( ) , "my_model" ) ;
4685
+ assert_eq ! ( dimensions. len( ) , 2 ) ;
4686
+ assert_eq ! ( dimensions[ 0 ] . to_string( ) , "DATE_PART('year', date_col)" ) ;
4687
+ assert_eq ! ( dimensions[ 1 ] . to_string( ) , "region_name" ) ;
4688
+ assert_eq ! ( metrics. len( ) , 2 ) ;
4689
+ assert_eq ! ( metrics[ 0 ] . to_string( ) , "SUM(revenue)" ) ;
4690
+ assert_eq ! ( metrics[ 1 ] . to_string( ) , "COUNT(*)" ) ;
4691
+ assert ! ( facts. is_empty( ) ) ;
4692
+ assert ! ( where_clause. is_some( ) ) ;
4693
+ assert_eq ! ( where_clause. as_ref( ) . unwrap( ) . to_string( ) , "active = true" ) ;
4694
+ assert ! ( alias. is_some( ) ) ;
4695
+ assert_eq ! ( alias. as_ref( ) . unwrap( ) . name. value, "model_alias" ) ;
4696
+ }
4697
+ _ => panic ! ( "Expected SemanticView table factor" ) ,
4698
+ }
4699
+ } else {
4700
+ panic ! ( "Expected table in FROM clause" ) ;
4701
+ }
4702
+ } else {
4703
+ panic ! ( "Expected SELECT statement" ) ;
4704
+ }
4705
+ }
4706
+ _ => panic ! ( "Expected Query statement" ) ,
4707
+ }
4708
+ }
0 commit comments