@@ -4581,3 +4581,128 @@ fn test_drop_constraints() {
45814581 snowflake ( ) . verified_stmt ( "ALTER TABLE tbl DROP FOREIGN KEY k1 RESTRICT" ) ;
45824582 snowflake ( ) . verified_stmt ( "ALTER TABLE tbl DROP CONSTRAINT c1 CASCADE" ) ;
45834583}
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