text: # Licensed to the Apache Software Foundation (ASF) under one
  # or more contributor license agreements.  See the NOTICE file
  # distributed with this work for additional information
  # regarding copyright ownership.  The ASF licenses this file
  # to you under the Apache License, Version 2.0 (the
  # "License"); you may not use this file except in compliance
  # with the License.  You may obtain a copy of the License at
  #
  #   http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing,
  # software distributed under the License is distributed on an
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  # KIND, either express or implied.  See the License for the
  # specific language governing permissions and limitations
  # under the License.
  
  # Targeted tests for date type.
  
  import pytest
  from tests.common.file_utils import create_table_and_copy_files
  from tests.common.impala_test_suite import ImpalaTestSuite
  from tests.common.skip import SkipIfS3, SkipIfABFS, SkipIfADLS, SkipIfLocal
  from tests.common.test_dimensions import (create_exec_option_dimension_from_dict,
      create_beeswax_hs2_dimension, hs2_parquet_constraint)
  from tests.shell.util import ImpalaShell
  
  
  class TestDateQueries(ImpalaTestSuite):
    @classmethod
    def get_workload(cls):
      return 'functional-query'
  
    @classmethod
    def add_test_dimensions(cls):
      super(TestDateQueries, cls).add_test_dimensions()
      cls.ImpalaTestMatrix.add_dimension(
        create_exec_option_dimension_from_dict({
          'batch_size': [0, 1],
          'disable_codegen': ['false', 'true'],
          'disable_codegen_rows_threshold': [0]}))
      # DATE type is only supported for text, parquet and avro fileformat on HDFS and HBASE.
      cls.ImpalaTestMatrix.add_constraint(lambda v:
          v.get_value('table_format').file_format in ('text', 'hbase', 'parquet')
          or (v.get_value('table_format').file_format == 'avro'
              and v.get_value('table_format').compression_codec == 'snap'))
  
      # Run these queries through both beeswax and HS2 to get coverage of date returned
      # via both protocols.
      cls.ImpalaTestMatrix.add_dimension(create_beeswax_hs2_dimension())
      cls.ImpalaTestMatrix.add_constraint(hs2_parquet_constraint)
  
    def test_queries(self, vector):
      if vector.get_value('table_format').file_format == 'avro':
        # Avro date test queries are in a separate test file.
        #  - Hive2 uses Julian Calendar for writing dates before 1582-10-15, whereas Impala
        #    uses proleptic Gregorian Calendar. This affects the results Impala gets when
        #    querying avro tables written by Hive2.
        #  - Hive3 on the other hand uses proleptic Gregorian Calendar to write dates.
        self.run_test_case('QueryTest/avro_date', vector)
      else:
        self.run_test_case('QueryTest/date', vector)
  
    def test_partitioning(self, vector, unique_database):
      """ Test partitioning by DATE. """
      # This test specifies databases explicitly. No need to execute it for anything other
      # than text fileformat.
      if vector.get_value('table_format').file_format != 'text':
        pytest.skip()
      self.run_test_case('QueryTest/date-partitioning', vector, use_db=unique_database)
  
    @SkipIfS3.qualified_path
    @SkipIfABFS.qualified_path
    @SkipIfADLS.qualified_path
    @SkipIfLocal.qualified_path
    def test_fileformat_support(self, vector, unique_database):
      """ Test that scanning and writing DATE is supported for text and parquet tables.
          Test that scanning DATE is supported for avro tables as well.
      """
      # This test specifies databases and locations explicitly. No need to execute it for
      # anything other than text fileformat on HDFS.
      if vector.get_value('table_format').file_format != 'text':
        pytest.skip()
  
      # Parquet table with date column.
      TABLE_NAME = "parquet_date_tbl"
      CREATE_SQL = "CREATE TABLE {0}.{1} (date_col DATE) STORED AS PARQUET".format(
          unique_database, TABLE_NAME)
      create_table_and_copy_files(self.client, CREATE_SQL, unique_database, TABLE_NAME,
          ["/testdata/data/date_tbl.parquet"])
      # Avro table with date column.
      TABLE_NAME = "avro_date_tbl"
      CREATE_SQL = "CREATE TABLE {0}.{1} (date_col DATE) STORED AS AVRO".format(
          unique_database, TABLE_NAME)
      create_table_and_copy_files(self.client, CREATE_SQL, unique_database, TABLE_NAME,
          ["/testdata/data/date_tbl.avro"])
      # Orc table with date column.
      TABLE_NAME = "orc_date_tbl"
      CREATE_SQL = "CREATE TABLE {0}.{1} (date_col DATE) STORED AS ORC".format(
          unique_database, TABLE_NAME)
      create_table_and_copy_files(self.client, CREATE_SQL, unique_database, TABLE_NAME,
          ["/testdata/data/date_tbl.orc"])
  
      # Partitioned table with parquet and avro partitions.
      TABLE_NAME = "date_tbl"
      CREATE_SQL = """CREATE TABLE {0}.{1} (date_col DATE)
          PARTITIONED BY (date_part DATE)""".format(unique_database, TABLE_NAME)
      self.client.execute(CREATE_SQL)
      # Add partitions.
      ADD_PART_SQL = """ALTER TABLE {0}.{1} ADD PARTITION (date_part='1899-12-31')
          LOCATION '/test-warehouse/{0}.db/parquet_date_tbl'
          PARTITION (date_part='1999-12-31')
          LOCATION '/test-warehouse/{0}.db/avro_date_tbl'
          """.format(unique_database, TABLE_NAME)
      self.client.execute(ADD_PART_SQL)
      # Parquet fileformat.
      SET_PART_FF_SQL = """ALTER TABLE {0}.{1} PARTITION (date_part='1899-12-31')
          SET FILEFORMAT PARQUET""".format(unique_database, TABLE_NAME)
      self.client.execute(SET_PART_FF_SQL)
      # Avro fileformat.
      SET_PART_FF_SQL = """ALTER TABLE {0}.{1} PARTITION (date_part='1999-12-31')
          SET FILEFORMAT AVRO""".format(unique_database, TABLE_NAME)
      self.client.execute(SET_PART_FF_SQL)
      # After adding the avro partition, metadata has to be invalidated, otherwise querying
      # the table will fail with stale metadata error.
      self.client.execute("INVALIDATE METADATA {0}.{1}".format(unique_database, TABLE_NAME))
  
      # Test scanning/writing tables with different fileformats.
      self.run_test_case('QueryTest/date-fileformat-support', vector,
          use_db=unique_database)
  