Technically, a query consists of a single compound predicate. A compound predicate starts with an optional declaration of query variables. Its main part is a predicate list, which defines the properties of the compound predicate.
Queries and Compound Predicates | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
The in-parameter of a predicate list is the in-parameter of its first connected predicate which has an in-parameter, or the predicate list has no in-parameter if no such connected predicate exists. The out-parameter of the predicate list is the out-parameter of its last connected predicate which has an out-parameter, or the predicate list has no out-parameter if no such connected predicate exists.
A predicate list is fulfilled if and only if all of its contained connected predicates are fulfilled.
Context predicates and branch predicates inherit their in- and out-parameters from the contained predicate list. They are fulfilled if and only if the contained predicate list is fulfilled.
A place denotes a set of predicate parameters which are associated with each other. A place also has a set of associated query variables. One of these query variables may be the label of the place. One of these query variables is the main variable of the place. Places may be node places, main variables of node places are bound to nodes of the current extent (Chapter 3, Data Model Interface).
Initially, a place is created for each predicate parameter, and the parameter is associated with this place. Later on, places my be merged, resulting in a single place which contains all associations of the merged places. Places are merged in two cases:
If two places have the same label variable, they are merged.
A predicate list may merge places of neighbouring primary predicates (Section 17.3.3, “Connecting Primary Predicates”).
Like a predicate, a place imposes conditions on its query variables which have to be fulfilled for the place to match for a binding of the variables.
The main variable is determined as follows:
If the place is a node place and has a label variable
q
whose values have to be wrapped in order to be represented as
nodes (Section 3.1, “Compile-Time Model”), then an additional query variable
is declared and associated with the place.
It wraps the values of q
.
Its identifier is the identifier of q
with the single character $
prepended.
Its preliminary type
is determined by the invocation of the method
getWrapperClassFor
of the current
compile-time model (Section 3.1, “Compile-Time Model”) with the type
of q
as argument. The wrapper variable
is the main variable of the place. For a binding
of the query variables, the bound value of
q
must be equal to
the result of the invocation of the method
unwrap
A
on the
current run-time model (Section 3.2, “Run-Time Model”) with
the bound value of the wrapper variable as argument.
A
is the type affix
(Section 6.1, “Type Affixes and Type Letters”) of the type of q
.
Otherwise, if the place is a node place without label variable,
and if there are
associated predicate parameters whose values are not representable
as nodes, an unnamed variable is declared implicitly, its type
being the type of the first parameter (in order of association) which needs
a wrapper. Now one proceeds as before, with q
being replaced by the implicitly declared variable.
Otherwise, if the place is a node place,
the main variable is declared implicitly, its preliminary
type being Object
.
Otherwise, the place is not a node place. If the place has a label, the main variable is the label variable. If the place has no label, the main variable is declared implicitly, its preliminary type being the type of the first parameter (in order of association).
For each associated predicate parameter, there is a query variable of suitable type. Depending on the type of the predicate parameters, a single query variable is sufficient for all parameters, or the compiler has to provide several distinct, implicitly declared query variables. The query variable for the parameters are determined as follows:
If there exist parameters of numeric type,
let N
be the first (in order of
association) of these types.
If the place is a node place, it follows from the previous statements
that there is a wrapper variable which wraps a query variable
s
. Otherwise, if the place is not a node place,
let s
be the main variable.
If s
does not have a numeric type,
a compile-time error occurs. Now for each parameter having a numeric
type T
, its query variable is determined:
If T
and the type of
some query variable v
of the place
are assignable to int
,
or if there exists a query variable v
having type T
,
the query variable for the parameter is v
.
Otherwise, an implicit query variable t
is declared in the place,
its type being T
. This variable is the
query variable for the parameter. For a binding
of the query variables, the bound value of
t
, converted to the type
of s
by a casting conversion,
has to be equal to the bound value of s
in order for the place to match.
For each of the remaining parameters of non-numeric type
T
:
If the place has a wrapper variable and values of type
T
have to be wrapped,
the preliminary type of the wrapper variable is replaced
by the intersection (Section 6.2, “Intersection Types”)
of the preliminary type and
the type returned by the invocation of the method
getWrapperClassFor
of the current
compile-time model (Section 3.1, “Compile-Time Model”) with
T
as argument.
The preliminary type of the wrapped variable is replaced
by the intersection of the preliminary type and
T
. The wrapped variable is the query
variable for the parameter.
Otherwise, if the place has a wrapper variable, but values of type
T
need not be wrapped, or if the place
is not a node place,
the preliminary type of the main variable is replaced
by the intersection of the preliminary type and
T
. The main variable is the query
variable for the parameter.
Afterwards, the actual types of query variables are set to their preliminary types.
When we speak of the bound value of a predicate parameter in the context of a binding of query variables, the bound value of the query variable associated with this predicate parameter is to be understood.
A connected predicate is either a single
condition predicate, or a list of
primary predicates. If it is a condition predicate,
it has no in- and out-parameters, and it is fulfilled
if and only if the contained
expression evaluates to true
. It is a compile-time
error if the type of this expression is not boolean
.
If the connected predicate consists of a list of primary predicates, its in-parameter is the in-parameter of the first primary predicate which has an in-parameter and which is not a context predicate or a branch predicate, or it has no in-parameter if no such predicate exists. The same holds for the out-parameter, with the role of the first primary predicate replaced by the last primary predicate. A list of primary predicates is fulfilled if and only if all of its primary predicates are fulfilled.
A list of primary predicates also defines the node places: A place is a node place if and only if an in- or out-parameter of a primary predicate of a list is associated with the place.
A list of primary predicates is connected by a pairwise connection
of neighbouring primary predicates. The primary predicates of
an ordered pair (L
, R
)
are neighbouring if L
is not a branch predicate and
L
textually precedes R
with at most branch predicates inbetween. For every
ordered pair (L
, R
)
of neighbouring primary predicates,
the connection is established as follows:
If L
has a closed out-parameter and
R
has a closed in-parameter,
an implicit standard edge predicate
(Section 17.5.5, “Standard Edge Predicates”) is inserted.
If R
is a branch predicate, the standard edge is a forward branch edge, otherwise
it is a forward successor edge.
The in-parameter of the edge predicate is associated
with the place of L
's out-parameter,
the out-parameter of the edge predicate is associated with the
place of R
's in-parameter.
Otherwise, if L
has an out-parameter and
R
has an in-parameter, their places
are merged to a single place.
Otherwise, if L
has an open out-parameter and
R
has no in-parameter,
or if L
has no out-parameter and
R
has an open in-parameter,
a compile-time error occurs.
Otherwise, L
and R
are not connected.