drill.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. # Licensed to the Apache Software Foundation (ASF) under one
  2. # or more contributor license agreements. See the NOTICE file
  3. # distributed with this work for additional information
  4. # regarding copyright ownership. The ASF licenses this file
  5. # to you under the Apache License, Version 2.0 (the
  6. # "License"); you may not use this file except in compliance
  7. # with the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing,
  12. # software distributed under the License is distributed on an
  13. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. # KIND, either express or implied. See the License for the
  15. # specific language governing permissions and limitations
  16. # under the License.
  17. from datetime import datetime
  18. from typing import Optional
  19. from urllib import parse
  20. from sqlalchemy.engine.url import URL
  21. from superset.db_engine_specs.base import BaseEngineSpec
  22. class DrillEngineSpec(BaseEngineSpec):
  23. """Engine spec for Apache Drill"""
  24. engine = "drill"
  25. _time_grain_functions = {
  26. None: "{col}",
  27. "PT1S": "NEARESTDATE({col}, 'SECOND')",
  28. "PT1M": "NEARESTDATE({col}, 'MINUTE')",
  29. "PT15M": "NEARESTDATE({col}, 'QUARTER_HOUR')",
  30. "PT0.5H": "NEARESTDATE({col}, 'HALF_HOUR')",
  31. "PT1H": "NEARESTDATE({col}, 'HOUR')",
  32. "P1D": "NEARESTDATE({col}, 'DAY')",
  33. "P1W": "NEARESTDATE({col}, 'WEEK_SUNDAY')",
  34. "P1M": "NEARESTDATE({col}, 'MONTH')",
  35. "P0.25Y": "NEARESTDATE({col}, 'QUARTER')",
  36. "P1Y": "NEARESTDATE({col}, 'YEAR')",
  37. }
  38. # Returns a function to convert a Unix timestamp in milliseconds to a date
  39. @classmethod
  40. def epoch_to_dttm(cls) -> str:
  41. return cls.epoch_ms_to_dttm().replace("{col}", "({col}*1000)")
  42. @classmethod
  43. def epoch_ms_to_dttm(cls) -> str:
  44. return "TO_DATE({col})"
  45. @classmethod
  46. def convert_dttm(cls, target_type: str, dttm: datetime) -> Optional[str]:
  47. tt = target_type.upper()
  48. if tt == "DATE":
  49. return f"TO_DATE('{dttm.date().isoformat()}', 'yyyy-MM-dd')"
  50. elif tt == "TIMESTAMP":
  51. return f"""TO_TIMESTAMP('{dttm.isoformat(sep=" ", timespec="seconds")}', 'yyyy-MM-dd HH:mm:ss')""" # pylint: disable=line-too-long
  52. return None
  53. @classmethod
  54. def adjust_database_uri(cls, uri: URL, selected_schema: Optional[str]) -> None:
  55. if selected_schema:
  56. uri.database = parse.quote(selected_schema, safe="")