[
https://issues.apache.org/jira/browse/JENA-763?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14093954#comment-14093954
]
Andy Seaborne edited comment on JENA-763 at 8/12/14 10:57 AM:
--------------------------------------------------------------
I'm not clear what the issue is here in detail -- is it the case of the quad
transform itself applied an algebra expression involving OpExt and also the
OpExt is quad sensitive or are there other transforms that would have state?
A real example would help.
>From the email thread, I don't understand about applying the quad
transform mid-optimization, after some local {{OpExt}} has been introduced.
Is there a reason not to do the quad transform first, then work entirely on
the quad form?
The quad transform state does not persist after the
transform is applied, but I think the only information lost is the exact
location of the {{(graph)}} ops although we could add a new algebra
operation to record that. In fact, there is something to do this already
-- {{OpLabel}} whose execution is simply to execute the sub-op. The idea
of "label" is to add info to the algebra tree without adding execution.
If the access to the quad transform class were opened up, an application
could write a subclass of the engine {{TransformQuadGraph}} and get access
to the state (needs to be made protected) and implement
{{transform(OpExt)}}. There is an interaction of the vistor/transform
pattern and subclassing from {{OpExt}} that means sometimes the transform
itself needs to deal with {{OpExt}}, not call {{OpExt.apply}}. It comes
down to the fact that visitor know all the types so it does not work with
class abstraction by subclassing {{OpExt}}. That's the way I envisaged
{{OpExt}} to be handled sometimes, not just via {{Transform.apply}}.
Better designs welcome!
* Is this specific to quad transformation or is there another real case?
* Is the assumption that the quad transform is done first not reasonable in
some use case?
was (Author: andy.seaborne):
I'm not clear what the issue is here in detail -- is it the case of the quad
transform itself applied an algebra expression involving OpExt and also the
OpExt is quad sensitive or are there other transforms that would have state?
A real example would help.
>From the email thread, I don't understand about applying the quad
transform mid-optimization, after some local {{OpExt}} has been introduced.
Is there a reason not to do the quad transform first, then work entirely on
the quad form?
The quad transform state does not persist after the
transform is applied, but I think the only information lost is the exact
location of the {{(graph))}} ops although we could add a new algebra
operation to record that. In fact, there is something to do this already
-- {{OpLabel}} whose execution is simply to execute the sub-op. The idea
of "label" is to add info to the algebra tree without adding execution.
If the access to the quad transform class were opened up, an application
could write a subclass of the engine {{TransformQuadGraph}} and get access
to the state (neess to be made protected) and implement
{{transform(OpExt)}}. There is an interaction of the vistor/transform
pattern and subclassing from {{OpExt}} that means sometimes the transform
itself needs to deal with {{OpExt}}, not call {{OpExt.apply}}. It comes
down to the fact that visitor know all the types so it does not work with
class abstraction by subclassing {{OpExt}}. That's the way I envisaged
{{OpExt}} to be handled sometimes, not just via {{Transform.apply}}.
Better designs welcome!
* Is this specific to quad transformation or is there another real case?
* Is the assumption that the quad transform is done first not reasonable in
some use case?
> Transforms should interact better with custom operators
> -------------------------------------------------------
>
> Key: JENA-763
> URL: https://issues.apache.org/jira/browse/JENA-763
> Project: Apache Jena
> Issue Type: Improvement
> Components: ARQ
> Affects Versions: Jena 2.12.0
> Reporter: Rob Vesse
>
> As already discussed briefly on the mailing list thread How to safely apply
> transforms to custom algebra operators?
> (http://s.apache.org/custom-algebra-transform) making some transforms pass
> correctly through custom algebra operators.
> {{TransformCopy}} defers the {{copy(OpExt ext)}} implementation back to the
> {{apply()}} method of {{OpExt}} which means a custom operator can do
> something simple like the following:
> {noformat}
> @Override
> public Op apply(Transform transform)
> {
> // This is required in order to not block optimizations
> return new CustomOperator(Transformer.transform(transform,
> this.subOp), this.customParams);
> }
> {noformat}
> Which will work correctly for stateless transforms but fails for transforms
> like {{Algebra.toQuadForm()}} which rely on external state. In the specific
> case of quad form transformation the external state is tracked by before and
> after visitors that are applied as the {{ApplyTransformVisitor}} works down
> the algebra with the state being used by the actual transform as it comes
> back up the algebra. However when passed through a custom operator there is
> no way to pass through the external state trackers and so inside the custom
> operator the transform may be accessing incorrect state.
> There are a couple of options for fixing this:
> # Fix this specific case by rewriting the quad form transform such that it
> does not rely on external state tracking (not sure that this is even feasible)
> # Revise the API for transforming {{OpExt}} so external state can also be
> passed where necessary
> Both options have difficulties and it may be possible to make simpler changes
> that allow the specific case of quad form transformations to be fixed without
> changing the public API.
> Another approach would be to have the quad form transform be a public class
> and provided public accessors to its external state such that a custom
> operator could specifically recognise it and special case it such that the
> external state tracking was passed onwards. More generally perhaps a marker
> interface {{StatefulTransform}} could be added which would provide a standard
> way to recognise transforms that may have this problem and provide access to
> the state trackers necessary to pass these through custom operators
> correctly. Additionally there could be overloads of
> {{Transformer.transform(Transform)}} i.e.
> {{Transformer.transform(StatefulTransform)}} that would wire things up
> appropriately allowing the existing basic approach for custom operators
> outlined above continue to work without special cases.
--
This message was sent by Atlassian JIRA
(v6.2#6252)