90 | | where other binary comparison operators can be used. The same expressions can be used, which can be used in the {{{re}}} module. |
91 | | The {{{in}}} operator is similar to the {{{in}}} operator defined in SQL. To illustrate its usage, consider the following 2 semantic queries, |
92 | | which are semantically equivalent with each other. |
93 | | * mods.funs[name = a or name = b or name = c] |
94 | | * mods.funs[name in |a,b,c|] |
| 93 | where other binary comparison operators can be used. The same expressions can be used, which can be used in the {{{re}}} module. |
118 | | ''Example:'' you may be interested in all the module, whose name equals with one element of the following set : {a,b,c} |
119 | | {{{ |
120 | | mods[ name in |a,b,c| ] |
121 | | }}} |
| 116 | ==== Variables ==== |
| 117 | It is possible to bind property value to a variable for later use. All variable name begins with a capital letter, just like erlang variables. |
| 118 | |
| 119 | Usage of variables is only allowed in filters. Variables may only bind to properties. Once bound, a variable can be compared to other properties, variables or literals of the same type using {{{/=, ==, >, <}}} etc. operators. |
| 120 | |
| 121 | ''Example:'' to obtain all function that has the same name as its containing module use the following query: |
| 122 | {{{ |
| 123 | mods[name=A].funs[name==A] |
| 124 | }}} |
| 125 | Note that variables' semantics are different compared to erlang. In the example above, the value of variable {{{A}}} changes from module to module. |
| 126 | |
| 127 | More detailed description can be found at [SemanticQuery/Variables Variables]. |
| 148 | ===== In, any_in, all_in filters ===== |
| 149 | Entities can also be filtered by in conditions in filters. Their operands can be |
| 150 | lists, embedded queries or semantic queries. |
| 151 | {{{ |
| 152 | filter ::= (list | semantic_query | query_sequence) (all_in|any_in) query_sequence |
| 153 | filter ::= query_sequence (all_in|any_in) (list | semantic_query) |
| 154 | filter ::= (property | query_sequence) in (list | semantic_query) |
| 155 | filter ::= list in (property | query_sequence) |
| 156 | }}} |
| 157 | Any_in will evaluate its operands for every entity selected before the filter and returns true |
| 158 | if there is any value selected by the first operand that can also be found in the second operand's value list. |
| 159 | [[BR]][[BR]] |
| 160 | ''any_in:'' |
| 161 | {{{ |
| 162 | mods.funs[.exprs.sub.val all_in (mods.funs--.file.funs).exprs.sub.val] |
| 163 | }}} |
| 164 | The query returns functions with subexpression values which can all be found in other files functions. |
| 165 | [[BR]][[BR]] |
| 166 | ''any_in:'' |
| 167 | {{{ |
| 168 | mods.funs[.calls any_in mods[name=m1].funs] |
| 169 | }}} |
| 170 | This query will select every function that calls any function in module "m1". |
| 171 | [[BR]][[BR]] |
| 172 | All_in returns true only if all values of the first operand are also selected by the second operand. |
| 173 | [[BR]][[BR]] |
| 174 | ''all_in:'' |
| 175 | {{{ |
| 176 | mods[.funs.calls all_in mods[name=m1].funs] |
| 177 | }}} |
| 178 | The query will yield all modules that only call for m1's functions. |
| 179 | [[BR]][[BR]] |
| 180 | ''all_in:'' |
| 181 | {{{ |
| 182 | mods[.funs.name all_in @mod.funs.name] |
| 183 | }}} |
| 184 | Lists all modules whose functions names can also be found in the given module's functions names. |
| 185 | [[BR]][[BR]] |
| 186 | ''in:'' |
| 187 | In is mainly for checking if a property value can be found in a list or a semantic query's result. |
| 188 | For properties and lists this operator is symmetrical: "name in |e1, e2, ...|" means the same as "|e1, e2, ...| in name". |
| 189 | {{{ |
| 190 | mods.func[name in mods.funs.exprs.esub.macro_value] |
| 191 | }}} |
| 192 | The query gives back any function whose name has been defined as a macro value. |
| 193 | |
| 224 | |
| 225 | === Set operators === |
| 226 | |
| 227 | Set operators (and their operands) can take the place of query-sequences |
| 228 | or initial selectors. Operands are first evaluated (which can be semantic queries, |
| 229 | query-sequences or set operators themselves), then the result is calculated based on the given operator. |
| 230 | When the operands are not property-queries their results have to be of the same entity-type |
| 231 | or the operator throws a type-mismatch error. If the operands return properties, but |
| 232 | of different types, they would be converted to strings. Duplicates of the result entities |
| 233 | are filtered. |
| 234 | When the operator is nested or used as a semantic query, the enclosing parentheses can be ommited. |
| 235 | In the former case the evaluation order will be right to left. |
| 236 | |
| 237 | ''Example:'' |
| 238 | {{{ |
| 239 | mods[name in |m1, m2|].funs(.calls union .called_by).vars |
| 240 | }}} |
| 241 | The query above will list all variables defined in functions which call or are |
| 242 | called by any functions in modules named "m1" or "m2". |
| 243 | |
| 244 | ''Example:'' |
| 245 | {{{ |
| 246 | mods.funs(.calls minus @mod.funs)(.name union .exprs.macro_value) |
| 247 | }}} |
| 248 | This query lists all macro values and names for functions that aren't defined in the given |
| 249 | module and are called by any module in the database. |
| 250 | |
| 251 | == Specifying grouping of results == |
| 252 | |
| 253 | By default the results of queries are grouped by the second to last selector |
| 254 | (unless the result is a statistic or a list of chains). This behavior can be changed |
| 255 | by passing a groupby value to the semantic query (if the used interface supports the options list). |
| 256 | The option {groupby, n} sets the grouping to the n-th query-element(filters are not counted). |
| 257 | |
| 258 | ''Example:'' |
| 259 | {{{ |
| 260 | ri:q("mods.funs.vars", [{groupby, 1}]). |
| 261 | }}} |
| 262 | The results from the above example are grouped by the first selector i.e. modules. |