Search code examples
kdb

kdb: parse QSQL statement gives extra enlist in conditional clause


Running parse on a QSQL query string seems to give one extra enlist for the where phrase. Why is that?

q)show x: parse "select from t where a=1"
?
`t
,,(=;`a;1)                     / <----
0b
()

q)x[2]~enlist (=;`a;1)         / WAS EXPECTING THIS TO BE 1b
0b

q)x[2]~enlist enlist (=;`a;1)  / INSTEAD GIVES THIS
1b

Asking because if we enlist it twice, it doesn't work:

q)t:([]a:1 2);

q)?[`t;enlist(=;`a;1);0b;()]
a
-
1

q)?[`t;enlist enlist(=;`a;1);0b;()]
'type
  [0]  ?[`t;enlist enlist(=;`a;1);0b;()]
       ^


Solution

  • This topic is covered in detail in a whitepaper:

    https://code.kx.com/q/wp/parse-trees/#issues-converting-to-functional-form

    The key section:

    passing a select query to parse ...... each returned item is in unevaluated form. As discussed above, simply applying value to a parse tree does not work. However, if we evaluate each one of the arguments fully, then there would be no nested parse trees. We could then apply value to the result

    Parse trees are evaluated by eval but q) prompt uses value

    The nested parse trees as returned can be evaluated by eval:

    q)-1 .Q.s1 parse "select from t where a=1"
    (?;`t;,,(=;`a;1);0b;())
    
    q)eval (?;`t;enlist enlist(=;`a;1);0b;())
    a
    -
    1