Ocular supports four Generic Filter Steps which can be added to any other step, and number of specific filter steps called Property Filter Steps which can be used on nodes of a certain type.
The Generic Filter Steps are where, whereNonEmpty, filter and filterNot. The Property Filter Steps for each node type correspond to the Property Directives it has defined.
We will look at the behaviour of each of these steps while analyzing a simple program named X42:
Property Filter Steps are Filter Steps which continue a traversal if the properties of the nodes they point to pass a certain criterion.
For example, to query the Code Property Graph for all CALL nodes which have the string exit as the value for their CODE property:
ocular> cpg.call.name("exit").code.l
res0:List[String]=List("exit(0)","exit(42)")
The criterion is unique to every Property Filter Step. In the case of the nameProperty Filter Step of the callNode-Type Step, its criterion is a string that represents a regular expression; that is, all following queries will deliver the same result for the X42 program:
ocular> cpg.call.name("exit").code.l
res0:List[String]=List("exit(0)","exit(42)")
ocular> cpg.call.name("[eE]xit").code.l
res1:List[String]=List("exit(0)","exit(42)")
ocular> cpg.call.name("ex.*").code.l
res2:List[String]=List("exit(0)","exit(42)")
Just like all other Filter Steps, Property Filter Steps can be chained together:
Unlike Property Directives, Property Filter Steps are usually greater in number than the properties defined on a node type. Most Property Filter Steps have their negated version available:
The whereStep is a Filter Step which continues a traversal for all nodes which pass its criterion. The criterion of the where step is represented by an expression which has one argument, a variable that points to the node matched in the previous step, and which returns a boolean. For example, suppose you'd like to query the Code Property Graph of the X42 program for all CALL nodes which have exit as the value of their NAME property, and return their CODE property in a list:
One helpful trick is to use the shorthand _ operator in where expressions, which points to the single argument that is passed into it, that is, the node.
Just like where, the filterStep is a Filter Step (ಠ~ಠ) which continues a traversal for all nodes which pass its criterion. The expression representing the criterion takes in one argument, a variable that represents the traversal of the previous step, and returns another traversal. Say you'd like to query the Code Property Graph of the X42 program again for all CALL nodes which have exit as the value of their NAME property, and return the value of their CODE property in a list: