[Geoserver-devel] How to use "anonymous" OGC Filter Functions

Hi all, sorry for the cross-posting,

in porting GSIP-69 proposal to OGC Filter as per community feedback,
I'm following Andrea's suggestion of using anonymous inner classes
that implement Function to overcome the lack of Filter extensibility
other than through functions, for predicates that are to be executed
exclusively at runtime (can't be encoded to SQL, for example),and at
the same time without bloating the Function SPI with (GeoServer
Catalog) domain specific functions.

So, such a predicate can be:

public abstract class CatalogFunction<T extends CatalogInfo> extends
FunctionImpl implements
        Function, VolatileFunction {

    public CatalogFunction() {
        setName("DynamicGeoServerCatalogFunction");
    }

    public abstract Object evaluate(T object);

    public <C> C evaluate(T object, Class<C> context) {
        return (C) super.evaluate((Object) object, context);
    }
    @Override
    public Object evaluate(Object object) {
        return evaluate((T) object);
    }
}

....
        CatalogFunction<T> visible = new CatalogFunction<T>() {
            /**
             * Returns {@code false} if the catalog info shall be
hidden, {@code true} otherwise.
             */
            @Override
            public Object evaluate(T object) {
                WrapperPolicy policy = buildWrapperPolicy(user, object);
                AccessLevel accessLevel = policy.getAccessLevel();
                boolean visible = !AccessLevel.HIDDEN.equals(accessLevel);
                return Boolean.valueOf(visible);
            }
        };

FilterFactory ff = ...
Filter filter = ff.equals(ff.literal(true), visible);

This works ok except when it comes to use SimplifyingFilterVisitor
down in the call chain (an hence any DuplicatingFilterVisitor
specialization), because visit(Function) will try to return a new
instance looking up the function factory by name, which does not
exist.

For this reason, and in order to keep it as simple as possible, I
wonder if it would be ok to say that VolatileFunctions are not
"cloneable", and so instruct DuplicatingFilterVisitor.visit(Function,
Object) not to go through the SPI lookup for VolatileFunctions, but
return them directly.
Another possibility is to add a separate marker interface, but I would
rather avoid bloating the API.

Thoughts?

TIA,
Gabriel

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

This works ok except when it comes to use SimplifyingFilterVisitor

down in the call chain (an hence any DuplicatingFilterVisitor
specialization), because visit(Function) will try to return a new
instance looking up the function factory by name, which does not
exist.

Can you detect this case, and “reuse” the original function with warning?

For this reason, and in order to keep it as simple as possible, I

wonder if it would be ok to say that VolatileFunctions are not
“cloneable”, and so instruct DuplicatingFilterVisitor.visit(Function,
Object) not to go through the SPI lookup for VolatileFunctions, but
return them directly.

I have a hesitation there as that is not quite the meaning of VolatileFunction we were going for; but I see how it can work.

I will note, that if you cannot make a copy, then any simplifications made on the parameters to your function cannot be accepted.

Another possibility is to add a separate marker interface, but I would
rather avoid bloating the API.

See if you can detect the failure; and use a warning (avoids the API bloat without introducing a marker interface).

  1. Suggestion not just a marker interface but something that lets you duplicate:

interface class InternalFunction extends Function {
InternalFunction duplicate( Expression… params);
}

  1. Special case DuplicatingFilterVisitor - i.e. check for the marker interface “Clonable” and a public “clone” method you can call via reflection

Jody

On Sun, Jul 8, 2012 at 9:53 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

This works ok except when it comes to use SimplifyingFilterVisitor
down in the call chain (an hence any DuplicatingFilterVisitor
specialization), because visit(Function) will try to return a new
instance looking up the function factory by name, which does not
exist.

For this reason, and in order to keep it as simple as possible, I
wonder if it would be ok to say that VolatileFunctions are not
"cloneable", and so instruct DuplicatingFilterVisitor.visit(Function,
Object) not to go through the SPI lookup for VolatileFunctions, but
return them directly.
Another possibility is to add a separate marker interface, but I would
rather avoid bloating the API.

VolatileFunction javadoc says:

  Marker interface indicating that that the function return value can change
  during a single data access operation even if the argument values provided to
  it remain constant

The above has nothing to do with the function being clonable or not,
or encodable in sql or not, it just means the function cannot be simplified out
even if all it parameters are constants, I would avoid using it
outside of its semantics.

I see two different solutions depending on what you want to achieve.
Is the intention to hide the function from the capabilities documents and
from spi enumeration? If so a marker interface that hides the function from
the enumeration but still makes it possible to create it via SPI would do.

If instead the registration in SPI is not desired at all a InternalFunction
interface like the one Jody suggested seems a good fit, and it's probably
less risky system wide, and easier to implement.
Would also open the door to functions that are runtime made, such
as with bytecode generation, which in turn might make scripting
languages integration easier.

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

Ran up against this same issue with geoscript trying to come up with a nice api for integrating filter functions and I like the idea of a marker interface as well. At the time i did indeed go for implementing a full blown factory to get around this exact problem but the solution is quite messy since such functions truly are designed to be anonymous.

On Mon, Jul 9, 2012 at 3:00 AM, Andrea Aime <andrea.aime@anonymised.com> wrote:

On Sun, Jul 8, 2012 at 9:53 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

This works ok except when it comes to use SimplifyingFilterVisitor
down in the call chain (an hence any DuplicatingFilterVisitor
specialization), because visit(Function) will try to return a new
instance looking up the function factory by name, which does not
exist.

For this reason, and in order to keep it as simple as possible, I
wonder if it would be ok to say that VolatileFunctions are not
“cloneable”, and so instruct DuplicatingFilterVisitor.visit(Function,
Object) not to go through the SPI lookup for VolatileFunctions, but
return them directly.
Another possibility is to add a separate marker interface, but I would
rather avoid bloating the API.

VolatileFunction javadoc says:

Marker interface indicating that that the function return value can change
during a single data access operation even if the argument values provided to
it remain constant

The above has nothing to do with the function being clonable or not,
or encodable in sql or not, it just means the function cannot be simplified out
even if all it parameters are constants, I would avoid using it
outside of its semantics.

I see two different solutions depending on what you want to achieve.
Is the intention to hide the function from the capabilities documents and
from spi enumeration? If so a marker interface that hides the function from
the enumeration but still makes it possible to create it via SPI would do.

If instead the registration in SPI is not desired at all a InternalFunction
interface like the one Jody suggested seems a good fit, and it’s probably
less risky system wide, and easier to implement.
Would also open the door to functions that are runtime made, such
as with bytecode generation, which in turn might make scripting
languages integration easier.

Cheers
Andrea


Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf


Live Security Virtual Conference
Exclusive live event will cover all the ways today’s security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


Geoserver-devel mailing list
Geoserver-devel@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel


Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Alright, thanks all for the comments.
A separate interface was my preference as well but for some reason I
thought it would bring higher hesitation. Glad it doesn't.
So, for the time being I can go with InternalFunction as a marker interface.
I don't quite see the need for a clone like method, as it's purpose is
to easily allow for anonymous inner classes to be used as function and
hence I can't think of a use case where such an object wouldn't be
immutable given there's no FilterFactory that would return a different
implementation or anything like that?

Cheers,
Gabriel

On Mon, Jul 9, 2012 at 6:00 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Sun, Jul 8, 2012 at 9:53 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

This works ok except when it comes to use SimplifyingFilterVisitor
down in the call chain (an hence any DuplicatingFilterVisitor
specialization), because visit(Function) will try to return a new
instance looking up the function factory by name, which does not
exist.

For this reason, and in order to keep it as simple as possible, I
wonder if it would be ok to say that VolatileFunctions are not
"cloneable", and so instruct DuplicatingFilterVisitor.visit(Function,
Object) not to go through the SPI lookup for VolatileFunctions, but
return them directly.
Another possibility is to add a separate marker interface, but I would
rather avoid bloating the API.

VolatileFunction javadoc says:

  Marker interface indicating that that the function return value can change
  during a single data access operation even if the argument values provided to
  it remain constant

The above has nothing to do with the function being clonable or not,
or encodable in sql or not, it just means the function cannot be simplified out
even if all it parameters are constants, I would avoid using it
outside of its semantics.

I see two different solutions depending on what you want to achieve.
Is the intention to hide the function from the capabilities documents and
from spi enumeration? If so a marker interface that hides the function from
the enumeration but still makes it possible to create it via SPI would do.

If instead the registration in SPI is not desired at all a InternalFunction
interface like the one Jody suggested seems a good fit, and it's probably
less risky system wide, and easier to implement.
Would also open the door to functions that are runtime made, such
as with bytecode generation, which in turn might make scripting
languages integration easier.

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On Mon, Jul 9, 2012 at 11:08 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Alright, thanks all for the comments.
A separate interface was my preference as well but for some reason I
thought it would bring higher hesitation. Glad it doesn't.
So, for the time being I can go with InternalFunction as a marker interface.
I don't quite see the need for a clone like method, as it's purpose is
to easily allow for anonymous inner classes to be used as function and
hence I can't think of a use case where such an object wouldn't be
immutable given there's no FilterFactory that would return a different
implementation or anything like that?

The problem is not the immutability of the object itself, but the one of its
parameters. During simplification one might notice one of the parameters
is a constant and replace it with it, but if the function itself has to
be managed as immutable that simplification would be impossible.

This in turn might have runtime consequences, as constant value does
not mean no computation, for example, think of calling the cross filtering
functions over a layer, if you call them repeatedly they will do
a full data access for each call

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

On Tue, Jul 10, 2012 at 2:59 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Mon, Jul 9, 2012 at 11:08 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Alright, thanks all for the comments.
A separate interface was my preference as well but for some reason I
thought it would bring higher hesitation. Glad it doesn't.
So, for the time being I can go with InternalFunction as a marker interface.
I don't quite see the need for a clone like method, as it's purpose is
to easily allow for anonymous inner classes to be used as function and
hence I can't think of a use case where such an object wouldn't be
immutable given there's no FilterFactory that would return a different
implementation or anything like that?

The problem is not the immutability of the object itself, but the one of its
parameters. During simplification one might notice one of the parameters
is a constant and replace it with it, but if the function itself has to
be managed as immutable that simplification would be impossible.

right, but my use case doesn't involve any parameters at all. It's
just a convenience to write an arbitrary expression in-place. So that
new Predicate<LayerInfo>(){
public boolean apply(LayerInfo li){
   return something;
}
}
becomes:
ff.equals(Boolean.TRUE, new InternalFunction(){
public Object evaluate(Object o){
   return something;
}
}
);

If you still consider InternalFunction should work against its
parameters, I'd like to see an example. In any case I've no strong
position on whether to make it "cloneable" or not by means of a custom
method like Jody proposed, just doesn't fit with what I have in mind,
but could go with it if it seems generally useful for others.

Cheers,
Gabriel

This in turn might have runtime consequences, as constant value does
not mean no computation, for example, think of calling the cross filtering
functions over a layer, if you call them repeatedly they will do
a full data access for each call

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On Wed, Jul 11, 2012 at 1:49 AM, Gabriel Roldan <groldan@anonymised.com> wrote:

The problem is not the immutability of the object itself, but the one of its
parameters. During simplification one might notice one of the parameters
is a constant and replace it with it, but if the function itself has to
be managed as immutable that simplification would be impossible.

right, but my use case doesn't involve any parameters at all.

I understand your use case, but when rolling new public API stuff has
to make sense in general.

I believe what Jody suggested is a good general solution that also
addresses the issues that Justin saw with dynamic languages,
requires just a bit more effort in that you'll probably have to turn
your inner classes into package private ones

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

On Wed, Jul 11, 2012 at 10:40 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Wed, Jul 11, 2012 at 1:49 AM, Gabriel Roldan <groldan@anonymised.com> wrote:

The problem is not the immutability of the object itself, but the one of its
parameters. During simplification one might notice one of the parameters
is a constant and replace it with it, but if the function itself has to
be managed as immutable that simplification would be impossible.

right, but my use case doesn't involve any parameters at all.

I understand your use case, but when rolling new public API stuff has
to make sense in general.

I believe what Jody suggested is a good general solution that also
addresses the issues that Justin saw with dynamic languages,
requires just a bit more effort in that you'll probably have to turn
your inner classes into package private ones

Sounds good to me. That's the kind of feedback I was looking for, thanks all.
So, I'll create a jira issue and attach a patch in there for review.

Cheers,
Gabriel

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

Patch attached to <http://jira.codehaus.org/browse/GEOT-4205&gt;

Please review and comment at your earliest convenience.

Cheers,
Gabriel

On Wed, Jul 11, 2012 at 12:25 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

On Wed, Jul 11, 2012 at 10:40 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Wed, Jul 11, 2012 at 1:49 AM, Gabriel Roldan <groldan@anonymised.com> wrote:

The problem is not the immutability of the object itself, but the one of its
parameters. During simplification one might notice one of the parameters
is a constant and replace it with it, but if the function itself has to
be managed as immutable that simplification would be impossible.

right, but my use case doesn't involve any parameters at all.

I understand your use case, but when rolling new public API stuff has
to make sense in general.

I believe what Jody suggested is a good general solution that also
addresses the issues that Justin saw with dynamic languages,
requires just a bit more effort in that you'll probably have to turn
your inner classes into package private ones

Sounds good to me. That's the kind of feedback I was looking for, thanks all.
So, I'll create a jira issue and attach a patch in there for review.

Cheers,
Gabriel

Cheers
Andrea

--
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On Tue, Jul 17, 2012 at 3:58 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Patch attached to <http://jira.codehaus.org/browse/GEOT-4205>

Please review and comment at your earliest convenience.

Seems good, but the implementation of the InternalVolatileFunction seems
broken to me here:

/**

  • @see org.opengis.filter.expression.InternalFunction#duplicate(org.opengis.filter.expression.Expression)
    */
    @Override
    public InternalFunction duplicate(Expression… parameters) {
    return this;
    }

Say that foo is an internal volatile function, and you have foo(5 + 7),
the simplifier can legitimately turn 5 +7 into 12 and call duplicate
with just Literal(12) as the parameter, and you are going to ignore that.

Other duplicators we have around do reprojection of geometries in spatial
filters and the like, and they alter the geometry literals and wrap functions
with on the fly reprojectors, if one of this modification happens to hit
a parameter of your volatile internal function the above will simply ignore it,
which introduces a bug.

The duplicate method should be implemented function by function returning
a copy of the function with the appropriate parameters.

If the catalog related functions are parameter-less and you know that you
should probably create a base class that’s specific to those, and one that
throws an illegal argument exception if the parameter list passed to duplicate
is not empty

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


Hi Andrea,
thanks for the review.

I understand all of that. InternalVolatileFunction is an abstract base
class, and just chose the default implementation of duplicate to
return this. Another alternative is not to implement it at all and
force subclasses to do so.

Note however, in my mind the duplicate(Expression...) method is just a
factory method to overcome the deviation from SPI in InternalFunction.
It shall not be responsible of duplicating its arguments in any way,
that's what DuplicatingFilterVisitor does, and calls
duplicate(Expression...) with the already transformed arguments.
Mentioning this just because I can't be sure what your expectations
were from your comments.

So, as I understand it, whomever is going to implement
InternalFunction has to implement duplicate() so that the new instance
works upon the provided arguments.
VolatileInternalFunction is just an abstract base class for the common
case where you just want to implement evaluate(Object), but can also
override duplicate(Expression...) if appropriate (i.e. the
implementation do work with Expression arguments).

That said I've not a strong position on leaving that specific method
implemented that way by default, and possibly document better that you
should override it as appropriate, or leave it unimplemented.
Any preference? or there's anything else that I'm missing?

Cheers,
Gabriel
On Wed, Jul 18, 2012 at 4:35 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Tue, Jul 17, 2012 at 3:58 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Patch attached to <http://jira.codehaus.org/browse/GEOT-4205&gt;

Please review and comment at your earliest convenience.

Seems good, but the implementation of the InternalVolatileFunction seems
broken to me here:

/**
     * @see
org.opengis.filter.expression.InternalFunction#duplicate(org.opengis.filter.expression.Expression)
     */
    @Override
    public InternalFunction duplicate(Expression... parameters) {
        return this;
    }

Say that foo is an internal volatile function, and you have foo(5 + 7),
the simplifier can legitimately turn 5 +7 into 12 and call duplicate
with just Literal(12) as the parameter, and you are going to ignore that.

Other duplicators we have around do reprojection of geometries in spatial
filters and the like, and they alter the geometry literals and wrap
functions
with on the fly reprojectors, if one of this modification happens to hit
a parameter of your volatile internal function the above will simply ignore
it,
which introduces a bug.

The duplicate method should be implemented function by function returning
a copy of the function with the appropriate parameters.

If the catalog related functions are parameter-less and you know that you
should probably create a base class that's specific to those, and one that
throws an illegal argument exception if the parameter list passed to
duplicate
is not empty

Cheers
Andrea

--

Our support, Your Success! Visit http://opensdi.geo-solutions.it for more
information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it

-------------------------------------------------------

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On Wed, Jul 18, 2012 at 6:10 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Hi Andrea,
thanks for the review.

I understand all of that. InternalVolatileFunction is an abstract base
class, and just chose the default implementation of duplicate to
return this. Another alternative is not to implement it at all and
force subclasses to do so.

Note however, in my mind the duplicate(Expression…) method is just a
factory method to overcome the deviation from SPI in InternalFunction.
It shall not be responsible of duplicating its arguments in any way,
that’s what DuplicatingFilterVisitor does, and calls
duplicate(Expression…) with the already transformed arguments.
Mentioning this just because I can’t be sure what your expectations
were from your comments.

So, as I understand it, whomever is going to implement
InternalFunction has to implement duplicate() so that the new instance
works upon the provided arguments.
VolatileInternalFunction is just an abstract base class for the common
case where you just want to implement evaluate(Object), but can also
override duplicate(Expression…) if appropriate (i.e. the
implementation do work with Expression arguments).

That said I’ve not a strong position on leaving that specific method
implemented that way by default, and possibly document better that you
should override it as appropriate, or leave it unimplemented.
Any preference? or there’s anything else that I’m missing?

Making it clear is good, I guess throwing an exception in case the
function name reports there are parameters is even better (will
make sure people actually do read the docs)

Cheers
Andrea

==
Our support, Your Success! Visit http://opensdi.geo-solutions.it for more information.

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 339 8844549

http://www.geo-solutions.it
http://twitter.com/geosolutions_it


On Wed, Jul 18, 2012 at 1:24 PM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

Making it clear is good, I guess throwing an exception in case the
function name reports there are parameters is even better (will
make sure people actually do read the docs)

yeah, sounds good to me. Ping you back when the patch is updated.

Cheers,
Gabriel

Cheers

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.