Skip to content
  1. Oct 19, 2020
  2. Aug 21, 2020
  3. Jul 02, 2019
  4. May 10, 2019
    • Grégory Mantelet's avatar
      [ADQL,TAP] New parser for ADQL-2.1. · 89418d13
      Grégory Mantelet authored
      - Now, `ADQLParserFactory.createParser(...)` should be used to create a parser
      - Only the new function `LOWER` is supported for the moment
      - Not yet possible to manage the optional features _(next dev to come)_
      => 1st step for ADQL-Lib v2.0
      
      - TAP adapted so that using the last stable version of the ADQL language
        (i.e. 2.0 for the moment)
        - but not yet possible to set the ADQL version to use in the configuration
          file
      89418d13
  5. Mar 13, 2019
    • Grégory Mantelet's avatar
      [ADQL] Add to the parser a function attempting to quickly fix an ADQL query. · 15cd5944
      Grégory Mantelet authored
      This new function - ADQLParser.tryQuickFix(...) - fixes the most common issues
      with ADQL queries:
      
      - replace Unicode confusable characters by their ASCII/UTF-8 version,
      - double-quote SQL reserved words/terms (e.g. `public`, `year`, `date`),
      - double-quote ADQL function names used a column name/alias (e.g. `distance`,
        `min`, `avg`),
      - double-quote invalid regular identifiers (e.g. `_RAJ2000`, `2mass`).
      
      The last point is far from being perfect but should work at least for
      identifiers starting with a digit or an underscore, or an identifier including
      one of the following character: `?`, `!`, `$`, `@`, `#`, `{`, `}`, `[`, `]`,
      `~`, `^` and '`'.
      
      It should also been noted that double-quoting a column/table name will make it
      case-sensitive. Then, it is possible that the query does not pass even after the
      double-quote operation ; the case would have to be checked by the user.
      
      Finally, there is no attempt to fix column and table names (i.e. case
      sensitivity and/or typos) using tables/columns list/metadata. That could be a
      possible evolution of this function or an additional feature to implement in the
      parser.
      15cd5944
  6. Mar 05, 2019
  7. Mar 21, 2018
  8. Jan 12, 2018
    • gmantele's avatar
      [ADQL] Fix the parsing and translation of a concatenation expression. · e4f38c95
      gmantele authored
      * The parsing did not allow unsigned numerics and SQL SET functions as
        specified in the ADQL 2.0 grammar
      
      * It was even forbidden to put a column whose the type is not String.
      
      * The translation of a concatenation expression was always prefixed by the
        ADQLList's name: CONCAT_STR. Of course, no database likes that...
      
      Regarding this last point, this commit fixes the GitHub issue #54
      e4f38c95
  9. Nov 30, 2017
  10. Nov 10, 2017
    • gmantele's avatar
      [ADQL] Fix escaping of double quotes in delimited identifiers. · 239c7178
      gmantele authored
      A delimited identifier is any sequence of characters between a pair of
      double quotes. For instance: "123 I am a delimited identifier!".
      
      It is of course possible to have double quotes inside this kind of identifier,
      but they have to be doubled in order to not be mistaken with the end of the
      identifier. For instance: "Cool ""identifier""".
      
      However, this escape option was not taken into account by the ADQL library,
      though the same mechanism was already in place for string contants.
      239c7178
  11. Sep 13, 2017
    • gmantele's avatar
      [ADQL] Also append an HINT message in the ParseException message when a SQL · fe4c3e97
      gmantele authored
      reserved word is encountered instead of a column/table/schema name/alias.
      
      On the contrary to the previous commit, this time a list of SQL reserved words
      has been added into the ADQL grammar. In this way, the parser will ensure that
      no word of this list is used in an ADQL query. The raised error is then enriched
      of an HINT message stating that this word is part of SQL, is not supported
      by ADQL and must be written between double quotes if used as an identifier.
      
      The list of SQL reserved words comes from the ADQL-2.0 standard, after removal
      of all potentially used ADQL words, in order to avoid a conflict with the
      already existing tokens in the ADQL grammar.
      fe4c3e97
    • gmantele's avatar
      [ADQL] Append an HINT message in the ParseException message when an ADQL · db0dfdad
      gmantele authored
      reserved word is encountered instead of a column/table/schema name/alias.
      
      No list of ADQL reserved words has been added into the ADQL grammar.
      
      However, the ADQL grammar has been slightly changed in order to provide a more
      precise location of the REAL wrong part of the query.
      
      Before this commit, if an ADQL reserved word (e.g. 'point') was encountered
      outside of its normal syntax (e.g. 'point' no followed by an opening
      parenthesis), the next token was highlighted instead of this one. Hence a
      confusing error message.
      
      For instance, the following ADQL query:
      
      ```sql
      SELECT point
      FROM aTable
      ```
      
      returned the following error message:
      
      > Encountered "FROM". Was expecting: "("
      
      Now, it will return the following one:
      
      > Encountered "point". Was expecting one of: "*" <QUANTIFIER> "TOP" [...]
      > (HINT: "point" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)
      
      This error message highlights exactly the source of the problem and even provide
      to the user a clear explanation of why the query did not parse and how it could
      be solved.
      db0dfdad
    • gmantele's avatar
  12. Sep 11, 2017
  13. Sep 08, 2017
    • gmantele's avatar
      [ADQL] Fix the transformation of NATURAL JOIN and JOIN...USING of MS-SQLServer. · e03e5725
      gmantele authored
      In the resulting SQL query, if there are an alias on the joined tables, these
      aliases must be used in the ON clause (instead of the full table name).
      
      For instance, the following ADQL query:
      
      ```sql
        SELECT *
        FROM tableA AS a NATURAL JOIN tableB AS b;
      ```
      
      should be translated into the following SQL:
      
      ```sql
        SELECT *
        FROM tableA AS a
          INNER JOIN tableB AS b
            ON a.id = b.id
      ```
      
      This commit complete the resolution of the Pull Request #16
      (more details about the issue can be got in there)
      e03e5725
    • gmantele's avatar
      [ADQL] Throwing a ParseException instead of an Error · a382b251
      gmantele authored
      when an incorrect character that can not be interpreted by
      the JavaCC Token Manager is encountered.
      
      Actually, the TokenMgrError thrown by JavaCC is caught by all
      ADQLParser.parseQuery(...) functions, wrapped inside a ParseException
      which is finally thrown instead of the TokenMgrError. In this way,
      ADQL-Lib users just have to care about a single Throwable:
      ParseException.
      
      Besides the error message has been slightly modified from:
      
      > Lexical error at line 1, column 10.  Encountered: "\u00e9" (233), after : \"\"
      
      to:
      
      > Incorrect character encountered at l.1, c.10: \"\\u00e9\" ('é'), after : \"\"
      
      Thus, the error is more user-friendly, more easy to understand by users.
      Additionally, the incorrect character is displayed, as before, in its unicode
      expression, but also in its character form (instead of an integer value that
      nobody can really understand).
      
      This commit fixes the GitHub issue #17
      a382b251
  14. Jun 01, 2017
    • gmantele's avatar
      [ADQL] Fix nasty infinite loop when wrapping matches with SimpleReplaceHandler. · 66304427
      gmantele authored
      This infinite loop occured only when the replacement object is just
      a wrapping of the matching object ; after replacement, the new object was
      inspected for matching objects.
      
      Example: infinite loop if we want to wrap all foo(...) functions with
               the function ROUND in the following query:
          SELECT foo(foo(123)) FROM myTable
      	     Expected result:
          SELECT ROUND(foo(ROUND(foo(123)))) FROM myTable
      	     But generated result was:
          SELECT ROUND(ROUND(ROUND(......foo(foo(123))))) FROM myTable
      66304427
  15. May 10, 2017
  16. Apr 20, 2017
  17. Apr 04, 2017
  18. Apr 03, 2017
  19. Mar 15, 2017
  20. Mar 10, 2017
  21. Mar 02, 2017
  22. Feb 22, 2017
  23. Feb 20, 2017
  24. Sep 20, 2016
    • gmantele's avatar
      [ADQL] Fix the tree generated by the parsing of NATURAL JOINs. · 7ca49f81
      gmantele authored
      The "normal" JOIN:
          A JOIN B ON A.id = B.id JOIN C ON B.id = C.id
      is correctly interpreted as:
          ( (A JOIN B ON A.id = B.id) JOIN C ON B.id = C.id )
      But with a NATURAL JOIN, the tree is mirrored:
          A NATURAL JOIN B NATURAL JOIN C
      gives:
      	( A NATURAL JOIN (B NATURAL JOIN C) )
      instead of:
          ( (A NATURAL JOIN B) NATURAL JOIN C )
      This is not a problem when the SQL translation is identical to the ADQL
      expression, but for some DBMS a conversion into a INNER JOIN ON is necessary
      and in this case we got the following SQL:
          A JOIN B JOIN C ON A.id = B.id ON B.id = C.id
      Which seems to work, but is syntactically strange.
      
      This commit should fix the generated tree. A "normal" JOIN and a NATURAL JOIN
      should now have the same form. A JUnit test has been added into TestADQLParser
      to check that: testJoinTree().
      7ca49f81
  25. Jul 13, 2016
  26. May 25, 2016
    • gmantele's avatar
      [ADQL] Fix recursive replacement using SimpleReplaceHandler. · ad2acca3
      gmantele authored
      Before correction, if an ADQlObject (e.g. a function or a sub-query) contains
      another ADQLObject and that both (i.e. parent and child) are matching in a
      SimpleReplaceHandler and are asked to be replaced, only the parent
      seemed to have been replaced. However, the child has been replaced, but
      in the former instance of the parent ; and so its replacement is not
      visible in the final query.
      
      For instance:
      if all mathematical functions must be replaced by a dumb UDF named 'foo' in
      the ADQL query:
              "SELECT sqrt(abs(81)) FROM myTable"
      ,the result should be:
              "SELECT foo(foo(81)) FROM myTable"
      ,but before this correction it was:
              "SELECT foo(abs(81)) FROM myTable".
      ad2acca3
  27. Apr 20, 2016
  28. Mar 17, 2016
    • gmantele's avatar
      [ADQL] Add an ADQL translator for MS SQL Server. This particular translator · a2fb29ad
      gmantele authored
      deals with NATURAL JOINs and JOINs using the keyword USING so that being
      supported by SQL Server. Basically, they are translated as a list of ON
      conditions.
      Warning: This translator is just guaranteed to solve the NATURAL and USING
      issue. Support for datatypes conversion and case sensitivity has to be
      reviewed. Besides no geometrical function is translated for SQL Server.
      a2fb29ad
  29. Mar 04, 2016
    • gmantele's avatar
      [ADQL] Set a type to a query's resulting column when it is not originally a column. · 0003e343
      gmantele authored
      This is easily possible for concatenations, string constants and User Defined
      Functions having a FunctionDef. A new special datatype was needed for
      numeric functions and operations: UNKNOWN_NUMERIC. This special type
      can not be set with FunctionDef.parse(...) and it behaves exactly like the type
      UNKNOWN, except that DBType.isNumeric() returns true (as .isUnknown()).
      Thus, while writing the metadata of a result in TAP, nothing changes:
      an UNKNOWN_NUMERIC type will be processed similarly as an UNKNOWN type:
      to use the type returned from the database ResultSet or to set VARCHAR.
      (no modification of TAP was needed for that)
      0003e343