Skip to content

Snowflake: Add support for ->> (pipe) operator for chaining SQL stmts - #2438

Open
BenSatori wants to merge 4 commits into
apache:mainfrom
BenSatori:snowflake-pipe-operator
Open

Snowflake: Add support for ->> (pipe) operator for chaining SQL stmts#2438
BenSatori wants to merge 4 commits into
apache:mainfrom
BenSatori:snowflake-pipe-operator

Conversation

@BenSatori

Copy link
Copy Markdown

The ->> (flow/pipe) operator chains multiple SQL statements in Snowflake.

Before: Parser rejected pipe chains like SELECT * FROM t1 ->> SELECT * FROM $1

After: Parser correctly handles:

  • Chained statements with ->> operator
  • Pipe result references ($1, $2, $3, etc.)
  • Round-trip SQL serialization

Example:

SELECT * FROM users WHERE active = true ->> SELECT COUNT(*) FROM $1

Changes:

  • Added Statement::Pipe AST variant for chained statements
  • Added TableFactor::PipeResultScan for $n result references
  • Extended Snowflake dialect with pipe operator support
  • Comprehensive test coverage (2 test functions, multiple edge cases)

Snowflake docs:
https://docs.snowflake.com/en/sql-reference/operators-flow#pipe

Comment thread src/dialect/mod.rs Outdated
false
}

/// Does the dialect support the Snowflake `-->` flow/pipe operator for chaining

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a typo

}

#[test]
fn test_snowflake_pipe_operator() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several cases that I am not sure are currently corrected supported, such as the following ones, should be added to the tests. These are ones from the Snowflake docs:

// Exact documented SHOW shape.
verified_stmt(
    r#"SHOW WAREHOUSES
       ->> SELECT "name", "state", "type", "size" FROM $1"#,
);

// A Snowflake dialect override that currently scans until EOF/semicolon.
verified_stmt("CREATE DATABASE d ->> SELECT 1");

// Existing happy path.
verified_stmt(
    "CREATE TABLE t (id INT)
     ->> INSERT INTO t VALUES (1)
     ->> SELECT * FROM $1"
);

// Error paths.
assert_parse_error("SELECT 1 ->>");
assert_parse_error("SELECT * FROM $0");

// GenericDialect ambiguity.
verified_generic_expr("SELECT payload ->> 'name'");
verified_generic_pipe("SELECT 1 ->> SELECT 2");

Comment thread src/parser/mod.rs Outdated
if self.dialect.supports_snowflake_pipe_operator() {
if let Token::Placeholder(ref s) = self.peek_token_ref().token.clone() {
if let Some(index_str) = s.strip_prefix('$') {
if let Ok(index) = index_str.parse::<u64>() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you are currently accepting $0, maybe replace with:

if let Ok(index @ 1..) = index_str.parse::<u64>() {

Comment thread tests/sqlparser_snowflake.rs Outdated
use sqlparser::dialect::GenericDialect;
use sqlparser::parser::Parser;
// In a generic dialect, ->> is a binary operator, not a pipe
let stmts = Parser::parse_sql(&GenericDialect {}, "SELECT 1").unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this even meant to test? Also, GenericDialect would generally be a dialect that supports all syntaxes, and should therefore likely also support this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants