| The seat | scalar | aggregate | window |
|---|---|---|---|
keep where ... |
stands | refused | refused |
add [name] as ... |
stands | stands | stands |
summarize [name] as ... |
refused | stands | refused |
sort ..., rank(...) |
refused | refused | refused |
fill_missing [x] as ... |
stands | refused | refused |
widen ... value ... |
stands | stands | refused |
Appendix F — Where each word can stand
Every word in the grammar says what the words are. This page says where they may stand.
Every seat below is a place in a step that takes a computed value. The grid is asked from the engine while this page is built, from the same table its checker answers to. So what you read here cannot drift from what the engine does. The engine’s own tests also run every cell through the parser and the checker. A cell that moved without its rule moving would fail those tests before it could mislead this page.
Read a row and you are reading what one seat is for.
A condition asks one row a question. A scalar can decide it and a group’s answer cannot, because the group’s answer does not exist until the rows are chosen.
A value in add is the one seat that accepts every kind of answer. A group’s total is repeated on every row of its group there, and a running total can walk the rows once a sort has said in what order.
A group’s answer in summarize must span its group. Its head is therefore an aggregate, and a scalar stands inside an aggregate’s argument.
An ordering position names a column and never an expression, in sort and inside rank alike. The computed key is one add away, and the grammar refuses to offer a second spelling of that add.
A filler in fill_missing holds one value, and only a scalar may stand there. A cell in widen takes a scalar or an aggregate, and the aggregate is the answer when two rows want the same cell. Neither seat takes a look along the rows, and for anything else that is refused, make it a column first.
Some cells carry one more sentence, and the engine says those too:
| The seat | The kind | What the cell says |
|---|---|---|
| keep where … | aggregate | summarize first, then keep |
| keep where … | window | add the place as a column, then keep |
| add [name] as … | aggregate | the whole table’s answer, or each group’s with by |
| add [name] as … | window | after a sort settles the order; rank names its own |
| summarize [name] as … | scalar | stands inside an aggregate’s argument |
| summarize [name] as … | aggregate | one level; an aggregate cannot hold another |
| sort …, rank(…) | scalar | an ordering position names a column; the computed key is an add away |
| sort …, rank(…) | aggregate | an ordering position names a column; the computed key is an add away |
| sort …, rank(…) | window | an ordering position names a column; the computed key is an add away |
| fill_missing [x] as … | aggregate | make it a column with add … by, then fill |
| fill_missing [x] as … | window | make it a column with sort then add, then fill |
| widen … value … | aggregate | the answer when two rows want one cell |
What the grid never says is useful. A sentence these seats accept is answered however strange it is. Well-formed and worthwhile are different judgments, and they belong to different people: the engine settles the first, always, and the second is yours. That split is a law of its own, and the laws show it working beside the rest.