vollt icon indicating copy to clipboard operation
vollt copied to clipboard

Geometry UDF not treated as such by ADQL parser?

Open mbtaylor opened this issue 1 year ago • 3 comments

Hi @gmantele. I noticed some ADQL queries using UDFs that are declared to return POINT values are not being parsed as I'd expect; if they are used as the argument of e.g. COORD1, the parsing reports a syntax error, though standard ADQL geometry functions can be used in such positions. This is the case even though the relevant FunctionDef.isGeometry() call returns true. I present a short program that demonstrates this:

import adql.db.FunctionDef;
import adql.parser.ADQLParser;
import adql.parser.feature.FeatureSet;
import adql.parser.feature.LanguageFeature;
import adql.parser.grammar.ParseException;

public class GeomUdfTest {
    public static void main(String[] args) throws Exception {

        // FeatureSet with some basic geometry functions.
        FeatureSet fset = new FeatureSet(false);
        fset.support(new LanguageFeature(LanguageFeature.TYPE_ADQL_GEO, "POINT", true));
        fset.support(new LanguageFeature(LanguageFeature.TYPE_ADQL_GEO, "COORD1", true));

        // Add a POINT-yielding and a DOUBLE-yielding UDF.
        // The POINT-yielding one is correctly identified as geometrical.
        String[] udfForms = {
            "POINT_UDF(x DOUBLE, y DOUBLE) -> POINT",
            "FLOAT_UDF(x DOUBLE, y DOUBLE) -> DOUBLE",
        };
        for (String form : udfForms) {
            FunctionDef fdef = FunctionDef.parse(form);
            System.out.println(fdef + "; isGeom: " + fdef.isGeometry());
            fset.support(fdef.toLanguageFeature());
        }

        // Set up a parser.
        ADQLParser parser = new ADQLParser(ADQLParser.ADQLVersion.V2_1);
        parser.setSupportedFeatures( fset );

        // Parse some queries.  The built-in geometry function is OK
        // as the argument of COORD1, but the geometry UDF is not.
        String[] queries = {
            "SELECT * FROM dual",
            "SELECT COORD1(POINT(ra, dec)) FROM dual",      // succeeds
            "SELECT COORD1(POINT_UDF(ra, dec)) FROM dual",  // fails
        };
        for (String q : queries) {
            System.out.println(q);
            try {
                parser.parseQuery(q);
                System.out.println(" --> OK");
            }
            catch (ParseException e) {
                System.out.println(" --> Fail: " + e);
            }
        }
    }
}

which produces the following output:

POINT_UDF(x DOUBLE, y DOUBLE) -> POINT; isGeom: true
FLOAT_UDF(x DOUBLE, y DOUBLE) -> DOUBLE; isGeom: false
SELECT * FROM dual
 --> OK
SELECT COORD1(POINT(ra, dec)) FROM dual
 --> OK
SELECT COORD1(POINT_UDF(ra, dec)) FROM dual
 --> Fail: adql.parser.grammar.ParseException:  Encountered "(". Was expecting one of: ")" "." "." ")" 

I am using adqlLib-2.0-beta.

Is this known/expected behaviour? Thanks.

mbtaylor avatar Feb 20 '24 13:02 mbtaylor