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:
|> SELECTitems follow SELECT item style|> WHEREconditions get AND/OR line-breaking|> ORDER BYitems 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, zselect 1 as x, 2 as y |> select *, x + y as z |> select x, zPipe with WHERE
from orders |> where status = 'active' |> select customer_id, totalfrom orders |> where status = 'active' |> select customer_id, totalPipe with ORDER BY and LIMIT
from orders |> where total > 100 |> order by total desc |> limit 10from orders |> where total > 100 |> order by total desc |> limit 10Pipe with aggregate
from orders |> aggregate count(*) as cnt, sum(total) as total_sum group by customer_idfrom orders
|> aggregate count(*) as cnt, sum(total) as total_sum group by customer_idSingle pipe step
select a, b from t |> where a > 1select a, b from t |> where a > 1Pipe SELECT with many items ()
from orders |> select customer_id, order_date, total, status, regionfrom orders |> select customer_id, order_date, total, status, regionPipe SELECT with
from orders |> select customer_id, total, statusfrom orders |> select customer_id, total, statusPipe 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 ascfrom orders |> order by region asc, total desc, customer_id ascPipe in CTE subquery
WITH active AS (FROM orders |> WHERE status = 'active' |> SELECT customer_id, total) SELECT * FROM activeWITH
active AS (
FROM orders
|> WHERE status = 'active'
|> SELECT customer_id, total
)
SELECT *
FROM activePipe in inline subquery
SELECT * FROM (FROM orders |> WHERE total > 100 |> SELECT customer_id, total) AS tSELECT *
FROM (FROM orders |> WHERE total > 100 |> SELECT customer_id, total) AS tPipe AGGREGATE with multiple items ()
from orders |> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total group by customer_id, regionfrom orders
|> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total
group by customer_id, regionPipe AGGREGATE with GROUP BY items
from orders |> aggregate count(*) as cnt group by customer_id, region, statusfrom orders |> aggregate count(*) as cnt group by customer_id, region, statusPipe AGGREGATE
from orders |> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total group by customer_idfrom orders
|> aggregate count(*) as cnt, sum(total) as total_sum, avg(total) as avg_total
group by customer_idPipe DROP columns ()
from orders |> drop customer_id, order_date, statusfrom orders |> drop customer_id, order_date, statusPipe 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 10from orders
|> where status = 'active' and total > 100
|> select customer_id, order_date, total
|> order by total desc, order_date asc
|> limit 10The 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 >= 5from orders
|> where
status = 'complete' and total > 100
|> aggregate
count(*) as order_count,
sum(total) as revenue
group by customer_id
|> where order_count >= 5