Yes, there’s an attribute :block/parent
As for understanding datalog, if you know SQL think of datalog as follows, it is only 1 table which has a structure of 3 (there are more, but those are not needed for our purpose) columns. The first column is an id, the second is the attribute name (what in SQL would be your column name) and the third is the value of that attribute.
So select block_parent from blocks where block_id = 1
Would become [1 :block/parent _] in datalog _ is basically “any value”.
This is what helped me understand datalog coming from SQL myself
PS. Any ? is a variable.
Sorry didn’t test it
The difference is the variable names. ?b and ?p are reserved for block and pages. But sometimes Logseq gets confused about it for some weird reason… idk.
So yeah just giving those a different names solves the problem as you can see.