Skip to main content

Pipe Syntax Formatting

Pipe syntax (|>) is supported in BigQuery, Spark, and Databricks. Each pipe step starts on a new line with |> leading.

Behavior: The |> operator leads each pipe step on a new line, and the operation follows on that same line — always, whether or not it fits. What does not fit breaks inside the operation and indents one level under the step.

Internal formatting: Pipe operations follow the same formatting rules as their non-pipe equivalents:

  • |> SELECT items follow SELECT item style
  • |> WHERE conditions get AND/OR line-breaking
  • |> ORDER BY items follow ORDER BY item style

Subqueries: Pipe steps inside subqueries are indented along with the subquery.

Simple pipe query​

select 1 as x, 2 as y |> select *, x + y as z |> select x, z
select 1 as x, 2 as y |> select *, x + y as z |> select x, z

Pipe with WHERE​

from orders |> where status = 'active' |> select customer_id, total
from orders |> where status = 'active' |> select customer_id, total

Pipe with ORDER BY and LIMIT​

from orders |> where total > 100 |> order by total desc |> limit 10
from orders |> where total > 100 |> order by total desc |> limit 10

Pipe with aggregate​

from orders |> aggregate count(*) as cnt, sum(total) as total_sum group by customer_id
from orders
|> aggregate count(*) as cnt, sum(total) as total_sum group by customer_id

Single pipe step​

select a, b from t |> where a > 1
select a, b from t |> where a > 1

Pipe SELECT with many items ()​

from orders |> select customer_id, order_date, total, status, region
from orders |> select customer_id, order_date, total, status, region

Pipe SELECT with​

from orders |> select customer_id, total, status
from orders |> select customer_id, total, status

Pipe WHERE with AND/OR​

from orders |> where status = 'active' and total > 100 and region = 'US'
from orders |> where status = 'active' and total > 100 and region = 'US'

Pipe ORDER BY with multiple items ()​

from orders |> order by region asc, total desc, customer_id asc
from orders |> order by region asc, total desc, customer_id asc

Pipe in CTE subquery​

WITH active AS (FROM orders |> WHERE status = 'active' |> SELECT customer_id, total) SELECT * FROM active
WITH
    active AS (
        FROM orders
        |> WHERE status = 'active'
        |> SELECT customer_id, total
    )
SELECT *
FROM active

Pipe in inline subquery​

SELECT * FROM (FROM orders |> WHERE total > 100 |> SELECT customer_id, total) AS t
SELECT *
FROM (FROM orders |> WHERE total > 100 |> SELECT customer_id, total) AS t

Pipe AGGREGATE with multiple items ()​

from orders |> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total group by customer_id, region
from orders
|> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total
    group by customer_id, region

Pipe AGGREGATE with GROUP BY items​

from orders |> aggregate count(*) as cnt group by customer_id, region, status
from orders |> aggregate count(*) as cnt group by customer_id, region, status

Pipe AGGREGATE​

from orders |> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total group by customer_id
from orders
|> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total
    group by customer_id

Pipe DROP columns ()​

from orders |> drop customer_id, order_date, status
from orders |> drop customer_id, order_date, status

Pipe multi-step with internal formatting​

from orders |> where status = 'active' and total > 100 |> select customer_id, order_date, total |> order by total desc, order_date asc |> limit 10
from orders
|> where status = 'active' and total > 100
|> select customer_id, order_date, total
|> order by total desc, order_date asc
|> limit 10

The operator never stands alone​

|> is a separator, not a clause keyword: the clause is the where or the aggregate after it. So it stays on that clause's line however the clause breaks. A |> alone on a line names nothing and spends a line saying it.

What continues below takes one indent level from the step, rather than lining up under the operation's first word. The operator's width is not a layout fact worth propagating — Spark spells the same operator |, and aligning to it would move every continuation one column.

A level is earned by a line break, not by a keyword. The first |> where step holds one clause, and nothing breaks between |> and it, so its conditions are one level in from the step's line — where, at this width, they fit on one line. The aggregate step breaks under the step itself — group by is a second line of it — so the step earns its level for group by, and the list, which belongs to aggregate, sits a level further in.

from orders |> where status = 'complete' and total > 100 |> aggregate count(*) as order_count, sum(total) as revenue group by customer_id |> where order_count >= 5
from orders
|> where
    status = 'complete' and total > 100
|> aggregate
        count(*) as order_count,
        sum(total) as revenue
    group by customer_id
|> where order_count >= 5