django-daiquiri / daiquiri

A framework for the publication of scientific databases
https://escience.aip.de/daiquiri
Apache License 2.0
26 stars 8 forks source link

BUG: IN Lists with only one elements fail in ADQL #41

Open olebole opened 5 years ago

olebole commented 5 years ago

When I do a query that uses the IN statement with only one list element, the parser returns an error:

>>> import pyvo
>>> s = pyvo.dal.TAPService('https://www.plate-archive.org/tap')
>>> s.run_sync("SELECT TOP 5 plate_id from applause_dr3.process WHERE plate_id in ('bla');")
WARNING: W20: None:2:0: W20: No version number specified in file.  Assuming 1.3 [astropy.io.votable.tree]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/pyvo/dal/tap.py", line 194, in run_sync
    **keywords).execute()
  File "/usr/lib/python3/dist-packages/pyvo/dal/tap.py", line 810, in execute
    return TAPResults(self.execute_votable(), url=self.queryurl)
  File "/usr/lib/python3/dist-packages/pyvo/dal/adhoc.py", line 96, in __init__
    super(AdhocServiceResultsMixin, self).__init__(votable, url=url)
  File "/usr/lib/python3/dist-packages/pyvo/dal/query.py", line 318, in __init__
    raise DALQueryError(self._status[1], self._status[0], url)
pyvo.dal.exceptions.DALQueryError: QUERY: {'messages': [ErrorDetail(string='There has been an error while translating your query.', code='invalid')], 'positions': ErrorDetail(string='[[1, 72, ")"]]', code='invalid')}

Single element lists are however valid ADQL, and also the grammar in queryparser seems to allow them: https://github.com/django-daiquiri/queryparser/blob/014b307cd62b412c10c8cef8d94d71b0dd8d20ff/src/queryparser/adql/ADQLParser.g4#L78

This also happens in the Web formular. It does not happen when PostgreSQL is used as language.

kimakan commented 2 years ago

As of now, the following queries were tested and are working:

SELECT TOP 5 plate_id from applause_dr3.process where plate_id in (27591);
SELECT TOP 5 plate_id from applause_dr3.process where plate_id in ('27591');

Your test query is still failing, but my guess is that it is due to the typecasting issues since plate_id is an integer.

olebole commented 2 years ago

I can confirm that it works now with numbers; so the original issue is probably fixed. The special case with non-convertible strings should however be handled correctly as well instead of returning an Internal Server Error.

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pyvo/dal/query.py", line 242, in execute_votable
    return votableparse(self.execute_stream(post=post).read)
  File "/usr/lib/python3/dist-packages/astropy/utils/decorators.py", line 546, in wrapper
    return function(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/astropy/io/votable/table.py", line 160, in parse
    config=config, pos=(1, 1)).parse(iterator, config)
  File "/usr/lib/python3/dist-packages/astropy/io/votable/tree.py", line 3600, in parse
    vo_raise(E19, (), config, pos)
  File "/usr/lib/python3/dist-packages/astropy/io/votable/exceptions.py", line 112, in vo_raise
    raise exception_class(args, config, pos)
astropy.io.votable.exceptions.E19: None:3:0: E19: File does not appear to be a VOTABLE

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/pyvo/dal/tap.py", line 248, in run_sync
    **keywords).execute()
  File "/usr/lib/python3/dist-packages/pyvo/dal/tap.py", line 942, in execute
    return TAPResults(self.execute_votable(), url=self.queryurl, session=self._session)
  File "/usr/lib/python3/dist-packages/pyvo/dal/query.py", line 244, in execute_votable
    self.raise_if_error()
  File "/usr/lib/python3/dist-packages/pyvo/dal/query.py", line 253, in raise_if_error
    raise DALServiceError.from_except(e, self.queryurl)
pyvo.dal.exceptions.DALServiceError: 500 Server Error: Internal Server Error for url: https://www.plate-archive.org/tap/sync