snowflake-data-validation 1.3.1__tar.gz → 1.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/PKG-INFO +2 -1
  2. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/pyproject.toml +10 -0
  3. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/__version__.py +1 -1
  4. snowflake_data_validation-1.3.2/src/snowflake/snowflake_data_validation/common_cli/cli_sync_validation.py +54 -0
  5. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/comparison_orchestrator.py +20 -1
  6. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/executor_factory.py +11 -0
  7. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/extractor/sql_queries_template_generator.py +2 -0
  8. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/validation_progress_reporter.py +38 -1
  9. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunks_md5_table_template.sql.j2 +1 -1
  10. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/redshift_cli.py +39 -0
  11. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_chunks_md5_table_template.sql.j2 +1 -1
  12. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/snowflake_cli.py +39 -0
  13. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/connector/connector_sql_server.py +70 -8
  14. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_chunks_md5_table_template.sql.j2 +1 -1
  15. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_compute_md5_sql.j2 +10 -0
  16. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/query/query_generator_sqlserver.py +10 -2
  17. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/sqlserver_cli.py +40 -3
  18. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_chunks_md5_table_template.sql.j2 +1 -1
  19. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/teradata_cli.py +40 -3
  20. snowflake_data_validation-1.3.2/src/snowflake/snowflake_data_validation/utils/configuration_file_synchronizer.py +102 -0
  21. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/constants.py +13 -0
  22. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database/sqlite_validation_connection.py +82 -54
  23. snowflake_data_validation-1.3.2/tests/unit/test_configuration_file_synchronizer.py +183 -0
  24. snowflake_data_validation-1.3.2/tests/unit/test_sqlserver_multi_version_support.py +619 -0
  25. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_progress_reporter.py +41 -12
  26. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/.gitignore +0 -0
  27. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/LICENSE +0 -0
  28. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/README.md +0 -0
  29. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/__init__.py +0 -0
  30. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/__main__.py +0 -0
  31. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/common_cli/cli_partitioning.py +0 -0
  32. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/__init__.py +0 -0
  33. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/configuration_loader.py +0 -0
  34. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/configuration_model.py +0 -0
  35. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/connection_types.py +0 -0
  36. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/connections/__init__.py +0 -0
  37. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/logging_configuration.py +0 -0
  38. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/table_configuration.py +0 -0
  39. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/validation_configuration.py +0 -0
  40. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/view_configuration.py +0 -0
  41. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/singleton.py +0 -0
  42. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/__init__.py +0 -0
  43. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/connector_base.py +0 -0
  44. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/connector_factory_base.py +0 -0
  45. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/connector_failure_tracker.py +0 -0
  46. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/__init__.py +0 -0
  47. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/async_generation_executor.py +0 -0
  48. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/async_validation_executor.py +0 -0
  49. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/base_validation_executor.py +0 -0
  50. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/extractor_types.py +0 -0
  51. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/source_validation_executor.py +0 -0
  52. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/sync_validation_executor.py +0 -0
  53. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/extractor/__init__.py +0 -0
  54. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/extractor/metadata_extractor_base.py +0 -0
  55. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/main_cli.py +0 -0
  56. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/console_progress_reporter.py +0 -0
  57. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/html_report/__init__.py +0 -0
  58. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/html_report/html_report_builder.py +0 -0
  59. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/html_report/report_metadata.py +0 -0
  60. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/parallel_execution_engine.py +0 -0
  61. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/table_metadata_processor.py +0 -0
  62. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/view_preprocessor.py +0 -0
  63. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/query/__init__.py +0 -0
  64. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/query/query_generator_base.py +0 -0
  65. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/__init__.py +0 -0
  66. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/connector/__init__.py +0 -0
  67. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/connector/connector_factory_redshift.py +0 -0
  68. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/connector/connector_redshift.py +0 -0
  69. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/metadata_extractor_redshift.py +0 -0
  70. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/redshift_cte_generator.py +0 -0
  71. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_concatenated_insert_template.sql.j2 +0 -0
  72. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_concatenated_table_template.sql.j2 +0 -0
  73. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_md5_insert_template.sql.j2 +0 -0
  74. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_md5_table_template.sql.j2 +0 -0
  75. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_column_metrics_templates.yaml +0 -0
  76. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_columns_cte_template.sql.j2 +0 -0
  77. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_datatypes_normalization_templates.yaml +0 -0
  78. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_extract_chunks_md5_table_template.sql.j2 +0 -0
  79. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_extract_md5_rows_chunk.sql.j2 +0 -0
  80. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_get_columns_metadata.sql.j2 +0 -0
  81. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_insert_chunk_row_md5_template.sql.j2 +0 -0
  82. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_row_count_query.sql.j2 +0 -0
  83. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_table_metadata_query.sql.j2 +0 -0
  84. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_to_snowflake_datatypes_mapping_template.yaml +0 -0
  85. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/model/__init__.py +0 -0
  86. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/model/redshift_credentials_connection.py +0 -0
  87. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/query/__init__.py +0 -0
  88. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/query/query_generator_redshift.py +0 -0
  89. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/redshift_arguments_manager.py +0 -0
  90. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/script_writer/__init__.py +0 -0
  91. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/script_writer/script_writer_redshift.py +0 -0
  92. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/script_writer/__init__.py +0 -0
  93. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/script_writer/script_writer_base.py +0 -0
  94. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/__init__.py +0 -0
  95. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/connector/connector_factory_snowflake.py +0 -0
  96. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/connector/connector_snowflake.py +0 -0
  97. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/metadata_extractor_snowflake.py +0 -0
  98. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/snowflake_cte_generator.py +0 -0
  99. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_chunk_row_concatenated_template.sql.j2 +0 -0
  100. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_chunk_row_md5_template.sql.j2 +0 -0
  101. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_column_metrics_templates.yaml +0 -0
  102. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_columns_cte_template.sql.j2 +0 -0
  103. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_datatypes_normalization_templates.yaml +0 -0
  104. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_extract_chunks_md5_table_template.sql.j2 +0 -0
  105. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_extract_md5_rows_chunk.sql.j2 +0 -0
  106. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_get_case_sensitive_columns.sql.j2 +0 -0
  107. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_get_columns_metadata.sql.j2 +0 -0
  108. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_insert_chunk_row_md5_template.sql.j2 +0 -0
  109. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_row_count_query.sql.j2 +0 -0
  110. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_table_metadata_query.sql.j2 +0 -0
  111. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_temporary_table_from_view_template.sql.j2 +0 -0
  112. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_to_snowflake_datatypes_mapping_template.yaml +0 -0
  113. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/__init__.py +0 -0
  114. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/snowflake_credentials_connection.py +0 -0
  115. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/snowflake_default_connection.py +0 -0
  116. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/snowflake_named_connection.py +0 -0
  117. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/query/__init__.py +0 -0
  118. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/query/query_generator_snowflake.py +0 -0
  119. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/script_writer/__init__.py +0 -0
  120. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/script_writer/script_writer_snowflake.py +0 -0
  121. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/snowflake_arguments_manager.py +0 -0
  122. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/__init__.py +0 -0
  123. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/connector/__init__.py +0 -0
  124. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/connector/connector_factory_sql_server.py +0 -0
  125. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/__init__.py +0 -0
  126. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/metadata_extractor_sqlserver.py +0 -0
  127. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/sqlserver_cte_generator.py +0 -0
  128. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_column_metrics_templates.yaml +0 -0
  129. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_columns_cte_template.sql.j2 +0 -0
  130. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_datatypes_normalization_templates.yaml +0 -0
  131. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_extract_chunks_md5_table_template.sql.j2 +0 -0
  132. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_extract_md5_rows_chunk.sql.j2 +0 -0
  133. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_get_columns_metadata.sql.j2 +0 -0
  134. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_get_temporary_table_internal_identifier_template.sql.j2 +0 -0
  135. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_row_count_query.sql.j2 +0 -0
  136. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_table_metadata_query.sql.j2 +0 -0
  137. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_temporary_table_from_view_template.sql.j2 +0 -0
  138. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_to_snowflake_datatypes_mapping_template.yaml +0 -0
  139. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/model/__init__.py +0 -0
  140. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/model/sqlserver_credentials_connection.py +0 -0
  141. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/query/__init__.py +0 -0
  142. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/script_writer/__init__.py +0 -0
  143. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/script_writer/script_writer_sqlserver.py +0 -0
  144. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/sqlserver_arguments_manager.py +0 -0
  145. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/table_partitioning_strategy.md +0 -0
  146. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/__init__.py +0 -0
  147. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/connector/__init__.py +0 -0
  148. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/connector/connector_factory_teradata.py +0 -0
  149. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/connector/connector_teradata.py +0 -0
  150. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/__init__.py +0 -0
  151. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/metadata_extractor_teradata.py +0 -0
  152. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_column_metrics_templates.yaml +0 -0
  153. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_columns_cte_template.sql.j2 +0 -0
  154. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_compute_md5_sql.j2 +0 -0
  155. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_create_row_concatenated.sql.j2 +0 -0
  156. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_create_row_md5.sql.j2 +0 -0
  157. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_datatypes_normalization_templates.yaml +0 -0
  158. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_extract_chunks_md5_table_template.sql.j2 +0 -0
  159. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_extract_md5_rows_chunk.sql.j2 +0 -0
  160. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_get_columns_metadata.sql.j2 +0 -0
  161. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_row_count_query.sql.j2 +0 -0
  162. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_table_metadata_query.sql.j2 +0 -0
  163. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_to_snowflake_datatypes_mapping_template.yaml +0 -0
  164. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/teradata_cte_generator.py +0 -0
  165. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/model/__init__.py +0 -0
  166. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/model/teradata_credentials_connection.py +0 -0
  167. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/query/__init__.py +0 -0
  168. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/query/query_generator_teradata.py +0 -0
  169. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/script_writer/__init__.py +0 -0
  170. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/script_writer/script_writer_teradata.py +0 -0
  171. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/teradata_arguments_manager.py +0 -0
  172. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/__init__.py +0 -0
  173. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/arguments_manager_base.py +0 -0
  174. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/arguments_manager_factory.py +0 -0
  175. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/base_output_handler.py +0 -0
  176. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/column_partitioning_strategy.py +0 -0
  177. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/configuration_file_editor.py +0 -0
  178. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/configuration_file_generator.py +0 -0
  179. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/connection_pool.py +0 -0
  180. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/connector_factory.py +0 -0
  181. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/console_output_handler.py +0 -0
  182. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/context.py +0 -0
  183. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/cpu_optimizer.py +0 -0
  184. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helper.py +0 -0
  185. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_database.py +0 -0
  186. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_dataframe.py +0 -0
  187. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_io.py +0 -0
  188. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_misc.py +0 -0
  189. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_query_result.py +0 -0
  190. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_templates.py +0 -0
  191. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/logging_config.py +0 -0
  192. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/logging_utils.py +0 -0
  193. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/chunk.py +0 -0
  194. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/column_metadata.py +0 -0
  195. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/table_column_metadata.py +0 -0
  196. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/table_context.py +0 -0
  197. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/templates_loader_manager.py +0 -0
  198. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/progress_reporter.py +0 -0
  199. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/row_partitioning_strategy.py +0 -0
  200. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/run_context.py +0 -0
  201. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/telemetry.py +0 -0
  202. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/templates/configuration_file_templates.py +0 -0
  203. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/thread_safe_singleton.py +0 -0
  204. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/validation_utils.py +0 -0
  205. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/__init__.py +0 -0
  206. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/data_validator_base.py +0 -0
  207. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/metrics_data_validator.py +0 -0
  208. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/results_summary_report.py +0 -0
  209. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/row_data_validator.py +0 -0
  210. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/row_validation_report_buffer.py +0 -0
  211. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/schema_data_validator.py +0 -0
  212. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database/__init__.py +0 -0
  213. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database/validation_database_connection_base.py +0 -0
  214. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database_manager.py +0 -0
  215. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_execution_context.py +0 -0
  216. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_report_buffer.py +0 -0
  217. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/.coveragerc +0 -0
  218. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/.coveragerc +0 -0
  219. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/Redshift/test_metadata_extractor_integration.py +0 -0
  220. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_async_generation_integration.py +0 -0
  221. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_async_validation_integration.py +0 -0
  222. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_reference_integration.py +0 -0
  223. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_source_validation_integration.py +0 -0
  224. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_sync_validation_integration.py +0 -0
  225. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_general.py +0 -0
  226. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_generate_validation_scripts.py +0 -0
  227. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_get_configuration_files.py +0 -0
  228. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_run_async_validation.py +0 -0
  229. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_run_validation.py +0 -0
  230. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_run_validation_ipc.py +0 -0
  231. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/model/test_redshift_credentials_connection.py +0 -0
  232. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/query/test_query_generator_redshift.py +0 -0
  233. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/script_writer/test_script_writer_redshift.py +0 -0
  234. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_connector_redshift.py +0 -0
  235. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_redshift_arguments_manager.py +0 -0
  236. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_redshift_cte_generator.py +0 -0
  237. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_redshift_metrics_templates.py +0 -0
  238. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_connector_teradata.py +0 -0
  239. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_metadata_extractor_teradata.py +0 -0
  240. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_query_generator_teradata.py +0 -0
  241. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_teradata_cli.py +0 -0
  242. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_teradata_metrics_validation.py +0 -0
  243. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/__init__.py +0 -0
  244. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/custom_templates_loader/snowflake_column_metrics_templates.yaml +0 -0
  245. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/custom_templates_loader/snowflake_datatypes_normalization_templates.yaml +0 -0
  246. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/custom_templates_loader/snowflake_table_metadata_query.sql.j2 +0 -0
  247. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_configuration_loader/test_load_configuration_model/conf.yaml +0 -0
  248. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_configuration_loader/test_load_configuration_model_reading_file_exception/conf.yaml +0 -0
  249. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_configuration_file.json +0 -0
  250. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_connection_source_db.toml +0 -0
  251. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_datatypes_normalization_template.yaml +0 -0
  252. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_datatypes_template.yaml +0 -0
  253. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_metrics_template.yaml +0 -0
  254. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_metrics_template_datatypes.yaml +0 -0
  255. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_template.csv +0 -0
  256. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/not_valid_format.yaml +0 -0
  257. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_templates_loader_manager/snowflake_column_metrics_templates.yaml +0 -0
  258. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_templates_loader_manager/snowflake_datatypes_normalization_templates.yaml +0 -0
  259. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_arguments_manager_base.py +0 -0
  260. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_arguments_manager_factory.py +0 -0
  261. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_column_metadata.py +0 -0
  262. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_column_partitioning_strategy.py +0 -0
  263. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_comparison_orchestrator.py +0 -0
  264. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_configuration_file_editor.py +0 -0
  265. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_configuration_loader.py +0 -0
  266. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_configuration_model.py +0 -0
  267. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_connection_pool.py +0 -0
  268. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_connector_failure_tracker.py +0 -0
  269. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_connector_snowflake.py +0 -0
  270. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_console_progress_reporter.py +0 -0
  271. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_cpu_optimizer.py +0 -0
  272. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_data_validator.py +0 -0
  273. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_executor_factory.py +0 -0
  274. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_helper_dataframe.py +0 -0
  275. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_helpers.py +0 -0
  276. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_html_report_builder.py +0 -0
  277. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_logging_config.py +0 -0
  278. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_metrics_templates.py +0 -0
  279. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_report_metadata.py +0 -0
  280. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_row_data_validator.py +0 -0
  281. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_row_partitioning_strategy.py +0 -0
  282. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_row_validation_report_buffer.py +0 -0
  283. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_snowflake_arguments_manager.py +0 -0
  284. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_snowflake_cli.py +0 -0
  285. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_source_validation_executor.py +0 -0
  286. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_sqlite_validation_connection.py +0 -0
  287. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_sqlserver_arguments_manager.py +0 -0
  288. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_sqlserver_cli.py +0 -0
  289. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_column_metadata_model.py +0 -0
  290. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_configuration.py +0 -0
  291. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_context.py +0 -0
  292. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_metadata_processor.py +0 -0
  293. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_telemetry.py +0 -0
  294. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_templates_loader_manager.py +0 -0
  295. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_configuration.py +0 -0
  296. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_database_connection.py +0 -0
  297. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_execution_context.py +0 -0
  298. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_report_buffer.py +0 -0
  299. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_view_configuration.py +0 -0
  300. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/utils/__init__.py +0 -0
  301. {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/utils/test_constants.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowflake-data-validation
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: Snowflake Data Validation
5
5
  Project-URL: Bug Tracker, https://github.com/snowflakedb/migrations-data-validation/issues
6
6
  Project-URL: Source code, https://github.com/snowflakedb/migrations-data-validation/
@@ -33,6 +33,7 @@ Requires-Dist: pandas>=2.2.3
33
33
  Requires-Dist: pyarrow>=14.0.0
34
34
  Requires-Dist: pydantic-yaml>=1.4.0
35
35
  Requires-Dist: pydantic>=2.0
36
+ Requires-Dist: ruamel-yaml>=0.18.0
36
37
  Requires-Dist: snowflake-connector-python>=4.0.0
37
38
  Requires-Dist: toml>=0.10.2
38
39
  Requires-Dist: typer>=0.15.3
@@ -31,6 +31,7 @@ dependencies = [
31
31
  "snowflake-connector-python>=4.0.0",
32
32
  "pandas>=2.2.3",
33
33
  "pyarrow>=14.0.0",
34
+ "ruamel.yaml>=0.18.0",
34
35
  "toml>=0.10.2",
35
36
  "jinja2>=3.1.6",
36
37
  "pydantic>=2.0",
@@ -111,6 +112,9 @@ packages = [
111
112
  "src/snowflake",
112
113
  ]
113
114
 
115
+ [tool.hatch.build.targets.wheel.force-include]
116
+ "../shared" = "shared"
117
+
114
118
  [tool.hatch.build.targets.sdist]
115
119
  directory = "dist"
116
120
  exclude = ["/.github", "/.idea"]
@@ -125,8 +129,14 @@ include = [
125
129
  [tool.hatch.envs.default]
126
130
  features = ["development", "sqlserver", "teradata", "redshift"]
127
131
  python = "3.12"
132
+ dependencies = [
133
+ "shared @ {root:uri}/../shared",
134
+ ]
128
135
 
129
136
  [tool.hatch.envs.test]
137
+ dependencies = [
138
+ "shared @ {root:uri}/../shared",
139
+ ]
130
140
 
131
141
  [tool.hatch.envs.test_all]
132
142
  template = 'test'
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- __version__ = "1.3.1"
16
+ __version__ = "1.3.2"
@@ -0,0 +1,54 @@
1
+ # Copyright 2026 Snowflake Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ """Shared CLI sync validation functions for data validation."""
14
+
15
+ import logging
16
+
17
+ import typer
18
+
19
+ from snowflake.snowflake_data_validation.utils import configuration_file_synchronizer
20
+
21
+
22
+ LOGGER = logging.getLogger(__name__)
23
+
24
+
25
+ def sync_validation_results(
26
+ configuration_file_path: str,
27
+ execution_summary_report_file_path: str,
28
+ ) -> None:
29
+ """Sync the configuration file with the execution summary report.
30
+
31
+ Remove tables and views that passed all validation levels.
32
+
33
+ Args:
34
+ configuration_file_path: Path to the configuration file.
35
+ execution_summary_report_file_path: Path to the execution summary report file.
36
+
37
+ """
38
+ try:
39
+ configuration_file_synchronizer.sync_configuration_file(
40
+ configuration_file_path=configuration_file_path,
41
+ execution_summary_report_file_path=execution_summary_report_file_path,
42
+ )
43
+ typer.secho(
44
+ "Configuration file updated successfully based on validation results.",
45
+ fg=typer.colors.GREEN,
46
+ )
47
+
48
+ LOGGER.info(
49
+ "Configuration file updated successfully based on validation results."
50
+ )
51
+
52
+ except Exception as e:
53
+ typer.secho(f"Error syncing configuration file: {e}", fg=typer.colors.RED)
54
+ LOGGER.error("Error syncing configuration file: %s", e)
@@ -15,6 +15,8 @@
15
15
 
16
16
  import logging
17
17
 
18
+ from collections.abc import Callable
19
+
18
20
  from snowflake.snowflake_data_validation.configuration.model.table_configuration import (
19
21
  TableConfiguration,
20
22
  )
@@ -68,6 +70,9 @@ class ComparisonOrchestrator:
68
70
  connection_pool_manager: ConnectionPoolManager,
69
71
  context: Context,
70
72
  max_threads: int,
73
+ progress_callback: (
74
+ Callable[[str, list[str], Context | None], None] | None
75
+ ) = None,
71
76
  ):
72
77
  """Initialize the orchestrator.
73
78
 
@@ -75,6 +80,10 @@ class ComparisonOrchestrator:
75
80
  connection_pool_manager: Connection pool manager for threaded processing
76
81
  context: Validation context containing configuration and runtime info
77
82
  max_threads: Maximum number of threads for parallel table processing
83
+ progress_callback: Optional callback for progress reporting. When
84
+ provided, it replaces the default stdout/pipe-based progress
85
+ reporting in ValidationProgressReporter.
86
+ Signature: (table_name: str, columns: list[str], context: Context | None) -> None
78
87
 
79
88
  """
80
89
  LOGGER.debug("Initializing ComparisonOrchestrator")
@@ -87,7 +96,9 @@ class ComparisonOrchestrator:
87
96
  # Initialize orchestration modules
88
97
  self.metadata_processor = TableMetadataProcessor()
89
98
  self.execution_engine = ParallelExecutionEngine(max_threads=self.max_threads)
90
- self.progress_reporter = ValidationProgressReporter()
99
+ self.progress_reporter = ValidationProgressReporter(
100
+ progress_callback=progress_callback,
101
+ )
91
102
  self.db_manager = ValidationDatabaseManager()
92
103
  self.console_progress_reporter = ConsoleProgressReporter(
93
104
  output_handler=self.context.output_handler
@@ -102,11 +113,18 @@ class ComparisonOrchestrator:
102
113
  def from_validation_environment(
103
114
  cls,
104
115
  validation_env: ValidationEnvironmentObject,
116
+ progress_callback: (
117
+ Callable[[str, list[str], Context | None], None] | None
118
+ ) = None,
105
119
  ) -> "ComparisonOrchestrator":
106
120
  """Create a ComparisonOrchestrator from a ValidationEnvironmentObject.
107
121
 
108
122
  Args:
109
123
  validation_env: ValidationEnvironmentObject instance containing all required components
124
+ progress_callback: Optional callback for progress reporting. When
125
+ provided, it replaces the default stdout/pipe-based progress
126
+ reporting in ValidationProgressReporter.
127
+ Signature: (table_name: str, columns: list[str], context: Context | None) -> None
110
128
 
111
129
  Returns:
112
130
  ComparisonOrchestrator: Configured orchestrator ready to run validation
@@ -140,6 +158,7 @@ class ComparisonOrchestrator:
140
158
  connection_pool_manager=connection_pool_manager,
141
159
  context=validation_env.context,
142
160
  max_threads=optimal_max_threads,
161
+ progress_callback=progress_callback,
143
162
  )
144
163
 
145
164
  @log
@@ -65,6 +65,9 @@ from snowflake.snowflake_data_validation.snowflake.query.query_generator_snowfla
65
65
  from snowflake.snowflake_data_validation.snowflake.script_writer.script_writer_snowflake import (
66
66
  ScriptWriterSnowflake,
67
67
  )
68
+ from snowflake.snowflake_data_validation.sqlserver.connector.connector_sql_server import (
69
+ ConnectorSqlServer,
70
+ )
68
71
  from snowflake.snowflake_data_validation.sqlserver.extractor.metadata_extractor_sqlserver import (
69
72
  MetadataExtractorSQLServer,
70
73
  )
@@ -253,6 +256,14 @@ class ExecutorFactory:
253
256
  query_generator = config.query_generator()
254
257
  LOGGER.debug("Created query generator for platform: %s", platform)
255
258
 
259
+ # Propagate SQL Server version capabilities to the query generator
260
+ if platform == Platform.SQLSERVER and isinstance(connector, ConnectorSqlServer):
261
+ query_generator.supports_string_agg = connector.supports_string_agg
262
+ LOGGER.debug(
263
+ "SQL Server query generator: supports_string_agg=%s",
264
+ connector.supports_string_agg,
265
+ )
266
+
256
267
  # Select the appropriate extractor class based on type
257
268
  if extractor_type == ExtractorType.METADATA_EXTRACTOR:
258
269
  extractor_class = config.metadata_extractor
@@ -285,6 +285,7 @@ class SQLQueriesTemplateGenerator:
285
285
  database_name: str,
286
286
  schema_name: str,
287
287
  table_id: int,
288
+ supports_string_agg: bool = True,
288
289
  ) -> str:
289
290
  template_file = f"{platform}_compute_md5_sql.j2"
290
291
  try:
@@ -305,6 +306,7 @@ class SQLQueriesTemplateGenerator:
305
306
  fetch=fetch,
306
307
  offset=offset,
307
308
  table_id=table_id,
309
+ supports_string_agg=supports_string_agg,
308
310
  )
309
311
  return sql
310
312
  except jinja2.exceptions.TemplateNotFound:
@@ -16,6 +16,8 @@
16
16
  import logging
17
17
  import os
18
18
 
19
+ from collections.abc import Callable
20
+
19
21
  import pandas as pd
20
22
 
21
23
  from snowflake.snowflake_data_validation.orchestration.html_report import (
@@ -74,7 +76,26 @@ def _apply_status_emoji(df: pd.DataFrame, column: str = "STATUS") -> pd.DataFram
74
76
 
75
77
 
76
78
  class ValidationProgressReporter:
77
- """Handles progress reporting and validation report management."""
79
+ """Handles progress reporting and validation report management.
80
+
81
+ Accepts an optional custom progress callback at construction time. When
82
+ provided, ``report_progress_for_table`` delegates to the custom callback
83
+ instead of the default stdout/pipe-based ``report_progress()`` mechanism.
84
+
85
+ Args:
86
+ progress_callback: Optional callback invoked for each table.
87
+ Signature: (table_name: str, columns: list[str], context: Context | None) -> None
88
+
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ progress_callback: (
94
+ Callable[[str, list[str], Context | None], None] | None
95
+ ) = None,
96
+ ):
97
+ """Initialize the reporter with an optional custom progress callback."""
98
+ self._progress_callback = progress_callback
78
99
 
79
100
  @log
80
101
  def report_progress_for_table(
@@ -85,12 +106,28 @@ class ValidationProgressReporter:
85
106
  ) -> None:
86
107
  """Report progress for a specific table.
87
108
 
109
+ If a custom progress callback was provided at construction, it is
110
+ called instead of the default reporting logic.
111
+
88
112
  Args:
89
113
  table_name: Name of the table being processed
90
114
  column_selection_list: List of columns being validated
91
115
  context: Validation context for run_id and run_start_time (optional)
92
116
 
93
117
  """
118
+ if self._progress_callback is not None:
119
+ try:
120
+ self._progress_callback(table_name, column_selection_list, context)
121
+ except Exception as e:
122
+ LOGGER.warning(
123
+ "Error in custom progress callback for table %s: %s. "
124
+ "This is non-critical and validation will continue.",
125
+ table_name,
126
+ str(e),
127
+ )
128
+ return
129
+
130
+ # Default behaviour: report via stdout/pipe (CLI IPC mode)
94
131
  # Only report progress if console output is not enabled
95
132
  if (
96
133
  context
@@ -1,4 +1,4 @@
1
1
  CREATE TEMPORARY TABLE IF NOT EXISTS "CHUNKS_MD5_{{ normalized_fully_qualified_name }}_{{ table_id }}"(
2
- CHUNK_ID VARCHAR(100),
2
+ CHUNK_ID VARCHAR(1000),
3
3
  CHUNK_MD5_VALUE VARCHAR(32)
4
4
  );
@@ -22,6 +22,9 @@ from snowflake.snowflake_data_validation.common_cli.cli_partitioning import (
22
22
  run_column_partitioning_helper,
23
23
  run_row_partitioning_helper,
24
24
  )
25
+ from snowflake.snowflake_data_validation.common_cli.cli_sync_validation import (
26
+ sync_validation_results,
27
+ )
25
28
  from snowflake.snowflake_data_validation.comparison_orchestrator import (
26
29
  ComparisonOrchestrator,
27
30
  )
@@ -692,3 +695,39 @@ def redshift_column_partitioning_helper():
692
695
  for each table.
693
696
  """
694
697
  run_column_partitioning_helper(Platform.REDSHIFT)
698
+
699
+
700
+ @redshift_app.command(
701
+ "sync-validation-results",
702
+ help=(
703
+ "Remove from the configuration file the tables and views that passed "
704
+ "all validations levels in the given execution summary report file"
705
+ ),
706
+ )
707
+ @handle_validation_errors
708
+ def redshift_sync_validation_results(
709
+ configuration_file_path: Annotated[
710
+ str,
711
+ typer.Option(
712
+ "--configuration-file-path",
713
+ "-cfp",
714
+ help="Path to the configuration file",
715
+ ),
716
+ ],
717
+ execution_summary_report_file_path: Annotated[
718
+ str,
719
+ typer.Option(
720
+ "--execution-summary-report-file-path",
721
+ "-esrfp",
722
+ help="Path to the execution summary report file",
723
+ ),
724
+ ],
725
+ ):
726
+ """Sync the configuration file with the execution summary report.
727
+
728
+ Remove tables and views that passed all validation levels.
729
+ """
730
+ sync_validation_results(
731
+ configuration_file_path=configuration_file_path,
732
+ execution_summary_report_file_path=execution_summary_report_file_path,
733
+ )
@@ -1,4 +1,4 @@
1
1
  CREATE OR REPLACE TEMPORARY TABLE {{ database_name }}.{{ schema_name }}."CHUNKS_MD5_{{ normalized_fully_qualified_name }}_{{ table_id }}"(
2
- CHUNK_ID VARCHAR(100),
2
+ CHUNK_ID VARCHAR(1000),
3
3
  CHUNK_MD5_VALUE VARCHAR(32)
4
4
  )
@@ -24,6 +24,9 @@ from snowflake.snowflake_data_validation.common_cli.cli_partitioning import (
24
24
  run_column_partitioning_helper,
25
25
  run_row_partitioning_helper,
26
26
  )
27
+ from snowflake.snowflake_data_validation.common_cli.cli_sync_validation import (
28
+ sync_validation_results,
29
+ )
27
30
  from snowflake.snowflake_data_validation.comparison_orchestrator import (
28
31
  ComparisonOrchestrator,
29
32
  )
@@ -649,3 +652,39 @@ def snowflake_column_partitioning_helper():
649
652
  for each table.
650
653
  """
651
654
  run_column_partitioning_helper(Platform.SNOWFLAKE)
655
+
656
+
657
+ @snowflake_app.command(
658
+ "sync-validation-results",
659
+ help=(
660
+ "Remove from the configuration file the tables and views that passed "
661
+ "all validations levels in the given execution summary report file"
662
+ ),
663
+ )
664
+ @handle_validation_errors
665
+ def snowflake_sync_validation_results(
666
+ configuration_file_path: Annotated[
667
+ str,
668
+ typer.Option(
669
+ "--configuration-file-path",
670
+ "-cfp",
671
+ help="Path to the configuration file",
672
+ ),
673
+ ],
674
+ execution_summary_report_file_path: Annotated[
675
+ str,
676
+ typer.Option(
677
+ "--execution-summary-report-file-path",
678
+ "-esrfp",
679
+ help="Path to the execution summary report file",
680
+ ),
681
+ ],
682
+ ):
683
+ """Sync the configuration file with the execution summary report.
684
+
685
+ Remove tables and views that passed all validation levels.
686
+ """
687
+ sync_validation_results(
688
+ configuration_file_path=configuration_file_path,
689
+ execution_summary_report_file_path=execution_summary_report_file_path,
690
+ )
@@ -19,6 +19,10 @@ import struct
19
19
 
20
20
  from typing import Literal
21
21
 
22
+ from shared.sqlserver.constants import SUPPORTED_ODBC_DRIVERS
23
+ from shared.sqlserver.odbc_driver_utils import get_best_sqlserver_driver
24
+ from shared.sqlserver.version_detection import detect_sql_server_version
25
+
22
26
  from snowflake.snowflake_data_validation.connector.connector_base import (
23
27
  ConnectorBase as BaseConnector,
24
28
  )
@@ -71,7 +75,7 @@ AZURE_SQL_SCOPE = "https://database.windows.net/.default"
71
75
 
72
76
  # SQL Server Authentication connection strings
73
77
  SQLSERVER_CONNECTION_STRING = (
74
- "DRIVER={{ODBC Driver 18 for SQL Server}};"
78
+ "DRIVER={{{driver}}};"
75
79
  "SERVER={server},{port};"
76
80
  "DATABASE={database};"
77
81
  "UID={user};"
@@ -81,7 +85,7 @@ SQLSERVER_CONNECTION_STRING = (
81
85
  )
82
86
 
83
87
  SQLSERVER_CONNECTION_STRING_NAMED = (
84
- "DRIVER={{ODBC Driver 18 for SQL Server}};"
88
+ "DRIVER={{{driver}}};"
85
89
  "SERVER={server};"
86
90
  "DATABASE={database};"
87
91
  "UID={user};"
@@ -92,7 +96,7 @@ SQLSERVER_CONNECTION_STRING_NAMED = (
92
96
 
93
97
  # Windows Authentication connection strings (Trusted Connection)
94
98
  SQLSERVER_CONNECTION_STRING_WIN_AUTH = (
95
- "DRIVER={{ODBC Driver 18 for SQL Server}};"
99
+ "DRIVER={{{driver}}};"
96
100
  "SERVER={server},{port};"
97
101
  "DATABASE={database};"
98
102
  "Trusted_Connection=yes;"
@@ -101,7 +105,7 @@ SQLSERVER_CONNECTION_STRING_WIN_AUTH = (
101
105
  )
102
106
 
103
107
  SQLSERVER_CONNECTION_STRING_WIN_AUTH_NAMED = (
104
- "DRIVER={{ODBC Driver 18 for SQL Server}};"
108
+ "DRIVER={{{driver}}};"
105
109
  "SERVER={server};"
106
110
  "DATABASE={database};"
107
111
  "Trusted_Connection=yes;"
@@ -111,7 +115,7 @@ SQLSERVER_CONNECTION_STRING_WIN_AUTH_NAMED = (
111
115
 
112
116
  # Azure Entra ID connection strings (token-based authentication)
113
117
  SQLSERVER_CONNECTION_STRING_AZURE_TOKEN = (
114
- "DRIVER={{ODBC Driver 18 for SQL Server}};"
118
+ "DRIVER={{{driver}}};"
115
119
  "SERVER={server},{port};"
116
120
  "DATABASE={database};"
117
121
  "TrustServerCertificate={trust_server_certificate};"
@@ -119,14 +123,13 @@ SQLSERVER_CONNECTION_STRING_AZURE_TOKEN = (
119
123
  )
120
124
 
121
125
  SQLSERVER_CONNECTION_STRING_AZURE_TOKEN_NAMED = (
122
- "DRIVER={{ODBC Driver 18 for SQL Server}};"
126
+ "DRIVER={{{driver}}};"
123
127
  "SERVER={server};"
124
128
  "DATABASE={database};"
125
129
  "TrustServerCertificate={trust_server_certificate};"
126
130
  "Encrypt={encrypt}"
127
131
  )
128
132
 
129
-
130
133
  class ConnectorSqlServer(BaseConnector):
131
134
  """Connector for SQL Server database."""
132
135
 
@@ -136,6 +139,52 @@ class ConnectorSqlServer(BaseConnector):
136
139
  self.connection: object | None = None
137
140
  self.pyodbc = import_mssql()
138
141
 
142
+ # SQL Server version detection properties (set after connection)
143
+ self.sql_server_major_version: int | None = None
144
+ self.is_azure_sql_db: bool = False
145
+ self.supports_string_agg: bool = True # Safe default for 2017+
146
+
147
+ def _detect_odbc_driver(self) -> str:
148
+ """Auto-detect the best available ODBC driver for SQL Server.
149
+
150
+ Delegates to shared.sqlserver.odbc_driver_utils.get_best_sqlserver_driver().
151
+
152
+ Returns:
153
+ str: The name of the detected ODBC driver.
154
+
155
+ Raises:
156
+ ConnectionError: If no compatible ODBC driver is found.
157
+
158
+ """
159
+ driver = get_best_sqlserver_driver()
160
+ if driver is None:
161
+ raise ConnectionError(
162
+ "No compatible ODBC driver found for SQL Server. "
163
+ "Please install one of the following:\n"
164
+ + "\n".join(f" - {d}" for d in SUPPORTED_ODBC_DRIVERS[:2])
165
+ + "\nSee: https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server"
166
+ )
167
+ LOGGER.info("Using %s (auto-detected)", driver)
168
+ return driver
169
+
170
+ def _detect_sql_server_version(self) -> None:
171
+ """Detect the SQL Server version and set capability flags.
172
+
173
+ Delegates to shared.sqlserver.version_detection.detect_sql_server_version().
174
+ Updates instance attributes based on the detected version info.
175
+
176
+ This method is called after connection verification and should not raise
177
+ exceptions — version detection failure defaults to supports_string_agg=True.
178
+
179
+ """
180
+ if self.connection is None:
181
+ return
182
+
183
+ version_info = detect_sql_server_version(self.connection)
184
+ self.sql_server_major_version = version_info.major_version
185
+ self.is_azure_sql_db = version_info.is_azure_sql_db
186
+ self.supports_string_agg = version_info.supports_string_agg
187
+
139
188
  def _get_azure_access_token(
140
189
  self,
141
190
  mode: SqlServerMode,
@@ -351,6 +400,9 @@ class ConnectorSqlServer(BaseConnector):
351
400
 
352
401
  """
353
402
  try:
403
+ # Auto-detect the ODBC driver
404
+ driver = self._detect_odbc_driver()
405
+
354
406
  # Determine if this is a named instance connection
355
407
  is_named_instance = (
356
408
  re.match(NAMED_INSTANCE_PATTERN_DETAILED, host) is not None
@@ -362,6 +414,7 @@ class ConnectorSqlServer(BaseConnector):
362
414
  # Windows Authentication (Trusted Connection)
363
415
  if is_named_instance and not is_custom_port:
364
416
  self.string_connection = SQLSERVER_CONNECTION_STRING_WIN_AUTH_NAMED.format(
417
+ driver=driver,
365
418
  server=host,
366
419
  port=port,
367
420
  database=database,
@@ -370,6 +423,7 @@ class ConnectorSqlServer(BaseConnector):
370
423
  )
371
424
  else:
372
425
  self.string_connection = SQLSERVER_CONNECTION_STRING_WIN_AUTH.format(
426
+ driver=driver,
373
427
  server=host,
374
428
  port=port,
375
429
  database=database,
@@ -386,6 +440,7 @@ class ConnectorSqlServer(BaseConnector):
386
440
  # Azure Entra ID Authentication (token-based)
387
441
  if is_named_instance and not is_custom_port:
388
442
  self.string_connection = SQLSERVER_CONNECTION_STRING_AZURE_TOKEN_NAMED.format(
443
+ driver=driver,
389
444
  server=host,
390
445
  port=port,
391
446
  database=database,
@@ -394,6 +449,7 @@ class ConnectorSqlServer(BaseConnector):
394
449
  )
395
450
  else:
396
451
  self.string_connection = SQLSERVER_CONNECTION_STRING_AZURE_TOKEN.format(
452
+ driver=driver,
397
453
  server=host,
398
454
  port=port,
399
455
  database=database,
@@ -426,6 +482,7 @@ class ConnectorSqlServer(BaseConnector):
426
482
  # SQL Server Authentication (username/password)
427
483
  if is_named_instance and not is_custom_port:
428
484
  self.string_connection = SQLSERVER_CONNECTION_STRING_NAMED.format(
485
+ driver=driver,
429
486
  server=host,
430
487
  port=port,
431
488
  database=database,
@@ -436,6 +493,7 @@ class ConnectorSqlServer(BaseConnector):
436
493
  )
437
494
  else:
438
495
  self.string_connection = SQLSERVER_CONNECTION_STRING.format(
496
+ driver=driver,
439
497
  server=host,
440
498
  port=port,
441
499
  database=database,
@@ -457,7 +515,7 @@ class ConnectorSqlServer(BaseConnector):
457
515
 
458
516
  @log
459
517
  def _verify_connection(self):
460
- """Verify the connection by executing a simple test query.
518
+ """Verify the connection by executing a simple test query and detect server version.
461
519
 
462
520
  Raises:
463
521
  ConnectionError: If connection verification fails
@@ -474,6 +532,10 @@ class ConnectorSqlServer(BaseConnector):
474
532
  cursor.execute("SELECT 1")
475
533
  cursor.fetchone()
476
534
  LOGGER.debug("SQL Server connection verified successfully")
535
+
536
+ # Detect SQL Server version after successful verification
537
+ self._detect_sql_server_version()
538
+
477
539
  except Exception as e:
478
540
  LOGGER.error("Failed to verify SQL Server connection: %s", str(e))
479
541
  self.connection = None
@@ -1,4 +1,4 @@
1
1
  CREATE TABLE "#CHUNKS_MD5_{{ normalized_fully_qualified_name }}_{{ table_id }}"(
2
- CHUNK_ID VARCHAR(100),
2
+ CHUNK_ID VARCHAR(1000),
3
3
  CHUNK_MD5_VALUE VARCHAR(32)
4
4
  );
@@ -49,7 +49,17 @@ SELECT
49
49
  FROM "#ROW_CONCATENATED_{{ chunk_id }}_{{ table_id }}";
50
50
 
51
51
  INSERT INTO "#CHUNKS_MD5_{{ normalized_fully_qualified_name }}_{{ table_id }}"
52
+ {% if supports_string_agg %}
52
53
  SELECT
53
54
  '{{ chunk_id }}',
54
55
  CONVERT(VARCHAR(32), HASHBYTES('MD5', STRING_AGG(CAST(ROW_MD5 AS VARCHAR(MAX)), '')), 2)
55
56
  FROM "#ROW_MD5_{{ chunk_id }}_{{ table_id }}";
57
+ {% else %}
58
+ SELECT
59
+ '{{ chunk_id }}',
60
+ CONVERT(VARCHAR(32), HASHBYTES('MD5',
61
+ (SELECT CAST(ROW_MD5 AS VARCHAR(MAX))
62
+ FROM "#ROW_MD5_{{ chunk_id }}_{{ table_id }}"
63
+ FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)')
64
+ ), 2);
65
+ {% endif %}
@@ -36,9 +36,16 @@ LOGGER = logging.getLogger(__name__)
36
36
  class QueryGeneratorSqlServer(QueryGeneratorBase):
37
37
  """SQL Server-specific implementation of query generator."""
38
38
 
39
- def __init__(self):
40
- """Initialize the SQL Server query generator."""
39
+ def __init__(self, supports_string_agg: bool = True):
40
+ """Initialize the SQL Server query generator.
41
+
42
+ Args:
43
+ supports_string_agg: Whether the target SQL Server supports STRING_AGG
44
+ (SQL Server 2017+ or Azure SQL DB). Defaults to True.
45
+
46
+ """
41
47
  super().__init__(platform=Platform.SQLSERVER)
48
+ self.supports_string_agg = supports_string_agg
42
49
 
43
50
  def cte_query_generator(
44
51
  self,
@@ -128,6 +135,7 @@ class QueryGeneratorSqlServer(QueryGeneratorBase):
128
135
  database_name=table_context.database_name,
129
136
  schema_name=table_context.schema_name,
130
137
  table_id=table_context.id,
138
+ supports_string_agg=self.supports_string_agg,
131
139
  )
132
140
 
133
141
  return query