diff --git a/src/Query/ADQL_parser.hxx b/src/Query/ADQL_parser.hxx index 2dcb681..1c147e9 100644 --- a/src/Query/ADQL_parser.hxx +++ b/src/Query/ADQL_parser.hxx @@ -230,6 +230,10 @@ struct ADQL_parser : boost::spirit::qi::grammar cast_function; + boost::spirit::qi::rule + position_function; + boost::spirit::qi::rule user_defined_function; diff --git a/src/Query/ADQL_parser/ADQL_parser/init_factor.cxx b/src/Query/ADQL_parser/ADQL_parser/init_factor.cxx index 714993e..8aba013 100644 --- a/src/Query/ADQL_parser/ADQL_parser/init_factor.cxx +++ b/src/Query/ADQL_parser/ADQL_parser/init_factor.cxx @@ -172,11 +172,17 @@ void ADQL_parser::init_factor() { -('(' > unsigned_integer > ')') >> ')']; cast_function.name("cast_function"); + position_function %= + hold[ascii::no_case["POSITION"] >> '(' >> character_string_literal >> + &no_skip[boost::spirit::qi::space] >> ascii::no_case["IN"] >> + &no_skip[boost::spirit::qi::space] >> column_reference >> ')']; + position_function.name("position_function"); + // FIXME: numeric_value_function should have // numeric_geometry_function numeric_value_function %= trig_function | math_function | cast_function | - non_predicate_geometry_function | user_defined_function | - sql_no_arg_function; + position_function | non_predicate_geometry_function | + user_defined_function | sql_no_arg_function; numeric_value_function.name("numeric_value_function"); // Flipped the order here, because a value_expression can match a // function name. @@ -214,6 +220,7 @@ void ADQL_parser::init_factor() { BOOST_SPIRIT_DEBUG_NODE(user_defined_function_param); BOOST_SPIRIT_DEBUG_NODE(user_defined_function); BOOST_SPIRIT_DEBUG_NODE(cast_function); + BOOST_SPIRIT_DEBUG_NODE(position_function); BOOST_SPIRIT_DEBUG_NODE(numeric_value_function); BOOST_SPIRIT_DEBUG_NODE(numeric_primary); BOOST_SPIRIT_DEBUG_NODE(factor); diff --git a/src/Query/Query_Specification/Factor/Numeric_Primary/Numeric_Value_Function.hxx b/src/Query/Query_Specification/Factor/Numeric_Primary/Numeric_Value_Function.hxx index 8a47556..d985062 100644 --- a/src/Query/Query_Specification/Factor/Numeric_Primary/Numeric_Value_Function.hxx +++ b/src/Query/Query_Specification/Factor/Numeric_Primary/Numeric_Value_Function.hxx @@ -4,6 +4,7 @@ #include "../../User_Defined_Function_Wrap.hxx" #include "Numeric_Value_Function/Cast_Function.hxx" #include "Numeric_Value_Function/Math_Function.hxx" +#include "Numeric_Value_Function/Position_Function.hxx" #include "Numeric_Value_Function/Trig_Function.hxx" #include @@ -12,8 +13,8 @@ namespace ADQL { class Numeric_Value_Function { public: typedef boost::variant + Position_Function, Non_Predicate_Geometry_Function, + User_Defined_Function_Wrap, std::string> Variant; Variant variant; bool empty() const; diff --git a/test/parse_adql.cxx b/test/parse_adql.cxx index 5a72a09..05f3aab 100644 --- a/test/parse_adql.cxx +++ b/test/parse_adql.cxx @@ -744,7 +744,17 @@ int main(int argc, char *argv[]) { // IRSA-5506 CAST as public.GEOGRAPHY "SELECT ST_Distance(CAST(ST_Point(22.81210,-16.78450) AS " "public.GEOGRAPHY), " - "COALESCE(p.poly, p.pt), 'f') as dist_to_point_meters FROM caom.plane p" + "COALESCE(p.poly, p.pt), 'f') as dist_to_point_meters FROM caom.plane p", + + // IRSA-7432 POSITION(string IN column_value) + "SELECT CASE WHEN POSITION('s3.amazonaws.com' IN a.uri) > 0 THEN a.uri " + "ELSE 'https://bacchus1.ipac.caltech.edu/' || regexp_replace(a.uri, " + "'https.*edu/', '') END as access_url FROM caom.artifact a", + + "SELECT POSITION('s3.amazonaws.com' IN a.uri) AS pos FROM caom.artifact a", + + "SELECT artifactid FROM caom.artifact a WHERE POSITION('s3.amazonaws.com' " + "IN a.uri) > 0" #endif // RUN_ALL };