Skip to content

Internals: jq Pipe operator

Nico Williams edited this page Jul 31, 2023 · 1 revision

The | operator in jq is implemented like this in the parser (src/parser.y):

Exp '|' Exp {
  $$ = block_join($1, $3);
} |

block_join() just joins two ASTs. That's it. That's the pipe operator.

It may appear like deep magic, but what's happening here is that jq has a stack, and the value at the top of the stack at any point in the execution of a jq program corresponds to what . would be at that point. The value at the top of the stack is:

  • the value output by the instruction that last executed,
  • and it is also the input to the next instruction.

Note that some instructions do a great deal more manipulation of the stack than merely popping an input value then pushing an output value.

So what block_join($1, $3) does here then is very simple: it arranges for the output of the left-hand side ($1) to be at the top of the stack so it can be the input to the right-hand side ($3). The cartesian product nature of | follows from the way the bytecode VM works.

Clone this wiki locally