From e1aa3bb20b6a330ae9d073f45db481ff647086c8 Mon Sep 17 00:00:00 2001 From: DuckLabs GitHub Bot Date: Tue, 22 Sep 2026 13:19:08 +0000 Subject: [PATCH 1/6] Update vendored DuckDB sources to d4e72566aa --- CMakeLists.txt | 2 +- .../aggregate/distributive/bitagg.cpp | 6 +- .../aggregate/distributive/sum.cpp | 16 +- .../aggregate/holistic/mode.cpp | 11 +- .../variant/variant_group_object.cpp | 2 + .../aggregate/distributive_functions.hpp | 6 +- .../aggregate/holistic_functions.hpp | 4 +- .../aggregate/nested_functions.hpp | 2 +- .../core_functions/scalar/date_functions.hpp | 4 +- .../core_functions/scalar/debug_functions.hpp | 2 +- .../scalar/generic_functions.hpp | 4 +- .../core_functions/scalar/list_functions.hpp | 14 +- .../core_functions/scalar/math_functions.hpp | 2 +- .../scalar/operators_functions.hpp | 4 +- .../scalar/string_functions.hpp | 4 +- .../core_functions/scalar/blob/encode.cpp | 2 +- .../scalar/debug/vector_type.cpp | 1 + .../core_functions/scalar/generic/alias.cpp | 35 +- .../core_functions/scalar/generic/binning.cpp | 2 +- .../scalar/generic/cast_to_type.cpp | 3 +- .../core_functions/scalar/generic/least.cpp | 9 +- .../scalar/list/array_slice.cpp | 42 +- .../scalar/list/list_aggregates.cpp | 7 + .../core_functions/scalar/list/list_sort.cpp | 128 +- .../core_functions/scalar/list/list_value.cpp | 1 + .../core_functions/scalar/string/to_base.cpp | 23 +- .../scalar/struct/struct_insert.cpp | 23 + .../scalar/union/union_extract.cpp | 4 +- src/duckdb/extension/icu/icu-dateadd.cpp | 28 +- .../json/json_functions/json_create.cpp | 24 +- .../json_functions/read_single_json_file.cpp | 6 +- .../extension/parquet/column_writer.cpp | 23 + .../delta_length_byte_array_decoder.cpp | 46 +- .../parquet/include/column_writer.hpp | 5 + .../delta_length_byte_array_decoder.hpp | 2 +- .../parquet/include/parquet_reader.hpp | 4 +- .../parquet/include/parquet_statistics.hpp | 3 + .../parquet/include/thrift_tools.hpp | 4 +- .../writer/parquet_write_operators.hpp | 16 +- .../include/writer/parquet_write_stats.hpp | 8 +- .../writer/templated_column_writer.hpp | 13 +- .../include/writer/variant_column_writer.hpp | 3 + .../extension/parquet/parquet_extension.cpp | 8 +- .../parquet/parquet_file_metadata_cache.cpp | 12 +- .../extension/parquet/parquet_metadata.cpp | 5 + .../extension/parquet/parquet_reader.cpp | 18 +- .../extension/parquet/parquet_statistics.cpp | 17 +- .../extension/parquet/parquet_writer.cpp | 2 +- .../parquet/reader/string_column_reader.cpp | 2 +- .../variant/parquet_variant_shredding.cpp | 2 +- .../parquet/reader/variant_column_reader.cpp | 2 +- .../writer/primitive_column_writer.cpp | 12 +- .../writer/variant/convert_variant.cpp | 950 +- ...nerated_extension_loader_package_build.cpp | 1 - src/duckdb/src/catalog/catalog.cpp | 29 +- .../aggregate_function_catalog_entry.cpp | 6 +- .../catalog_entry/duck_index_entry.cpp | 9 +- .../scalar_function_catalog_entry.cpp | 4 +- .../table_function_catalog_entry.cpp | 11 +- .../window_function_catalog_entry.cpp | 6 +- .../src/catalog/catalog_entry_retriever.cpp | 5 +- .../src/catalog/catalog_search_path.cpp | 2 +- src/duckdb/src/common/adbc/adbc.cpp | 2 - .../src/common/arrow/arrow_appender.cpp | 11 +- .../src/common/arrow/arrow_query_result.cpp | 4 + .../src/common/arrow/arrow_type_extension.cpp | 224 + src/duckdb/src/common/arrow/arrow_wrapper.cpp | 104 +- src/duckdb/src/common/clustered_aggregate.cpp | 41 +- .../src/common/compressed_file_system.cpp | 23 +- src/duckdb/src/common/enum_util.cpp | 243 +- .../src/common/enums/statement_type.cpp | 1 + src/duckdb/src/common/file_system.cpp | 8 + src/duckdb/src/common/gzip_file_system.cpp | 183 +- src/duckdb/src/common/hive_partitioning.cpp | 32 + src/duckdb/src/common/local_file_system.cpp | 76 +- .../multi_file/multi_file_column_mapper.cpp | 24 +- .../common/multi_file/multi_file_function.cpp | 9 +- .../src/common/multi_file/multi_file_list.cpp | 8 - .../common/multi_file/multi_file_reader.cpp | 42 +- .../multi_file/table_function_multi_file.cpp | 129 +- .../src/common/multi_file/union_by_name.cpp | 2 +- src/duckdb/src/common/open_file_info.cpp | 77 +- src/duckdb/src/common/opener_file_system.cpp | 7 + .../src/common/operator/cast_operators.cpp | 2 +- src/duckdb/src/common/sort/sort.cpp | 51 +- src/duckdb/src/common/types.cpp | 26 + .../src/common/types/conflict_manager.cpp | 30 +- src/duckdb/src/common/types/timestamp.cpp | 7 +- src/duckdb/src/common/types/type_manager.cpp | 7 +- .../variant/parquet_variant_encoding.cpp | 910 ++ .../variant/parquet_variant_iterator.cpp | 17 +- .../types}/variant/variant_binary_decoder.cpp | 2 +- .../src/common/vector/struct_vector.cpp | 2 +- src/duckdb/src/common/virtual_file_system.cpp | 4 + .../src/execution/expression_executor.cpp | 2 +- src/duckdb/src/execution/ie_join_union.cpp | 363 + .../execution/index/fixed_size_allocator.cpp | 1 + .../execution/mark_join_row_comparison.cpp | 110 + .../nested_loop_join_mark.cpp | 20 +- .../aggregate/physical_limited_distinct.cpp | 20 +- .../physical_perfecthash_aggregate.cpp | 15 + .../physical_ungrouped_aggregate.cpp | 17 + .../operator/aggregate/physical_window.cpp | 7 +- .../csv_scanner/sniffer/csv_sniffer.cpp | 2 +- .../table_function/csv_file_scanner.cpp | 26 +- .../table_function/csv_multi_file_info.cpp | 490 - .../table_function/csv_schema_discovery.cpp | 115 + .../table_function/global_csv_state.cpp | 66 +- .../table_function/read_single_csv_file.cpp | 500 + .../operator/csv_scanner/util/csv_error.cpp | 10 +- .../helper/launch_external_resource.cpp | 29 +- .../helper/physical_batch_collector.cpp | 6 +- .../operator/helper/physical_connect.cpp | 93 +- .../helper/physical_external_resource.cpp | 13 +- .../helper/physical_limit_percent.cpp | 24 +- .../helper/physical_reservoir_sample.cpp | 30 + .../helper/physical_result_collector.cpp | 5 +- .../operator/helper/physical_result_sink.cpp | 54 +- .../operator/join/outer_join_marker.cpp | 12 + .../join/physical_blockwise_nl_join.cpp | 4 + .../operator/join/physical_hash_join.cpp | 2 +- .../operator/join/physical_iejoin.cpp | 536 +- .../join/physical_nested_loop_join.cpp | 105 +- .../join/physical_piecewise_merge_join.cpp | 14 + .../join/physical_positional_join.cpp | 20 +- .../operator/join/physical_range_join.cpp | 2 +- .../operator/order/physical_top_n.cpp | 13 + .../operator/persistent/csv_rejects_table.cpp | 32 +- .../persistent/physical_copy_database.cpp | 5 +- .../persistent/physical_copy_to_file.cpp | 185 +- .../operator/persistent/physical_insert.cpp | 16 +- .../operator/scan/physical_table_scan.cpp | 2 +- .../operator/schema/physical_attach.cpp | 98 +- .../operator/schema/physical_create_index.cpp | 37 +- .../execution/operator/set/physical_cte.cpp | 6 +- .../execution/perfect_aggregate_hashtable.cpp | 2 +- .../physical_plan/plan_copy_to_file.cpp | 1 + .../src/execution/sample/reservoir_sample.cpp | 9 + .../function/aggregate/distributive/count.cpp | 18 +- .../aggregate/distributive/first_last_any.cpp | 19 +- .../aggregate/distributive/minmax.cpp | 9 +- .../src/function/aggregate_function.cpp | 9 +- .../src/function/cast/cast_statistics.cpp | 12 +- src/duckdb/src/function/cast/enum_casts.cpp | 7 +- .../function/cast/variant/from_variant.cpp | 14 +- src/duckdb/src/function/function.cpp | 3 +- src/duckdb/src/function/function_binder.cpp | 9 + src/duckdb/src/function/function_list.cpp | 2 + .../function/scalar/comparison/between.cpp | 6 +- .../compress_geometry.cpp | 10 + .../compress_integral.cpp | 10 + .../compress_string.cpp | 10 + .../compressed_materialization_utils.cpp | 40 + .../src/function/scalar/create_sort_key.cpp | 85 +- .../src/function/scalar/generic/invoke.cpp | 16 +- .../src/function/scalar/list/list_extract.cpp | 3 + .../function/scalar/operator/arithmetic.cpp | 12 +- .../src/function/scalar/operator/cast.cpp | 11 +- .../src/function/scalar/operator/multiply.cpp | 12 +- .../function/scalar/string/caseconvert.cpp | 9 +- .../string/hive_partition_component.cpp | 33 + .../function/scalar/struct/remap_struct.cpp | 5 + .../scalar/system/aggregate_export.cpp | 4 + .../scalar/variant/variant_extract.cpp | 15 +- .../scalar/variant/variant_extract_string.cpp | 2 +- .../scalar/variant/variant_typeof.cpp | 2 + src/duckdb/src/function/scalar_function.cpp | 23 +- src/duckdb/src/function/table/arrow.cpp | 37 +- .../table/arrow/arrow_duck_schema.cpp | 13 +- .../src/function/table/arrow_conversion.cpp | 10 +- src/duckdb/src/function/table/copy_csv.cpp | 5 +- .../src/function/table/direct_file_reader.cpp | 37 +- src/duckdb/src/function/table/range.cpp | 2 +- src/duckdb/src/function/table/read_csv.cpp | 38 +- src/duckdb/src/function/table/read_file.cpp | 7 +- src/duckdb/src/function/table/repeat.cpp | 15 +- src/duckdb/src/function/table/repeat_row.cpp | 24 +- src/duckdb/src/function/table/sniff_csv.cpp | 2 +- .../table/system/duckdb_functions.cpp | 15 +- .../function/table/system/duckdb_keywords.cpp | 20 +- .../table/system/external_resources.cpp | 3 +- src/duckdb/src/function/table/table_scan.cpp | 9 +- .../function/table/version/pragma_version.cpp | 6 +- src/duckdb/src/function/table_function.cpp | 22 +- .../function/window/window_value_function.cpp | 39 +- src/duckdb/src/function/window_function.cpp | 6 +- src/duckdb/src/include/duckdb.hpp | 1 + .../aggregate_function_catalog_entry.hpp | 2 + .../catalog_entry/duck_index_entry.hpp | 4 +- .../table_function_catalog_entry.hpp | 4 + .../src/include/duckdb/catalog/dependency.hpp | 4 +- .../common/arrow/arrow_query_result.hpp | 1 + .../common/arrow/result_arrow_wrapper.hpp | 8 + .../duckdb/common/clustered_aggregate.hpp | 45 +- .../duckdb/common/compressed_file_system.hpp | 1 + .../common/enable_shared_from_this_ipp.hpp | 2 +- .../src/include/duckdb/common/enum_util.hpp | 78 +- .../enums/debug_progress_verification.hpp | 26 + ...xecution_result.hpp => file_sync_mode.hpp} | 11 +- ...esult.hpp => query_result_memory_type.hpp} | 13 +- .../common/enums/query_result_state.hpp | 29 + .../duckdb/common/enums/result_eagerness.hpp | 20 + .../duckdb/common/enums/statement_type.hpp | 15 +- .../duckdb/common/extra_operator_info.hpp | 28 +- .../src/include/duckdb/common/file_system.hpp | 3 + .../duckdb/common/local_file_system.hpp | 2 + .../common/multi_file/multi_file_function.hpp | 46 +- .../common/multi_file/multi_file_list.hpp | 1 - .../common/multi_file/multi_file_options.hpp | 10 +- .../common/multi_file/multi_file_states.hpp | 2 + .../multi_file/table_function_multi_file.hpp | 21 +- .../include/duckdb/common/open_file_info.hpp | 9 +- .../duckdb/common/opener_file_system.hpp | 15 +- .../common/operator/aggregate_operators.hpp | 43 + .../duckdb/common/query_parameters.hpp | 33 - .../include/duckdb/common/shared_ptr_ipp.hpp | 6 +- .../src/include/duckdb/common/string_util.hpp | 2 +- .../src/include/duckdb/common/types.hpp | 2 + .../common/types/batched_data_collection.hpp | 2 +- .../duckdb/common/types/conflict_manager.hpp | 36 +- .../src/include/duckdb/common/types/value.hpp | 6 +- .../variant/parquet_variant_iterator.hpp | 58 +- .../types}/variant/variant_binary_decoder.hpp | 6 +- .../common/types/variant/variant_builder.hpp | 155 +- .../duckdb/common/types/variant_visitor.hpp | 24 +- .../duckdb/common/vector/vector_writer.hpp | 2 +- .../vector_operations/aggregate_executor.hpp | 66 +- .../duckdb/common/virtual_file_system.hpp | 2 + .../src/include/duckdb/common/winapi.hpp | 2 +- .../src/include/duckdb/execution/executor.hpp | 40 +- .../duckdb/execution/ie_join_union.hpp | 209 + .../execution/mark_join_row_comparison.hpp | 16 +- .../aggregate/physical_limited_distinct.hpp | 3 + .../physical_perfecthash_aggregate.hpp | 2 + .../physical_ungrouped_aggregate.hpp | 2 + .../operator/csv_scanner/csv_error.hpp | 2 +- .../operator/csv_scanner/csv_file_scanner.hpp | 45 +- .../csv_scanner/csv_multi_file_info.hpp | 71 - .../operator/csv_scanner/csv_option.hpp | 2 +- .../operator/csv_scanner/csv_schema.hpp | 5 + .../csv_scanner/csv_schema_discovery.hpp | 27 + .../operator/csv_scanner/global_csv_state.hpp | 18 +- .../helper/physical_limit_percent.hpp | 3 + .../helper/physical_reservoir_sample.hpp | 3 + .../helper/physical_result_collector.hpp | 9 +- .../operator/helper/physical_result_sink.hpp | 13 +- .../operator/join/outer_join_marker.hpp | 4 + .../join/physical_blockwise_nl_join.hpp | 1 + .../join/physical_nested_loop_join.hpp | 5 + .../join/physical_piecewise_merge_join.hpp | 1 + .../join/physical_positional_join.hpp | 3 + .../operator/join/physical_range_join.hpp | 4 +- .../operator/order/physical_top_n.hpp | 1 + .../operator/persistent/csv_rejects_table.hpp | 14 +- .../persistent/physical_copy_to_file.hpp | 3 + .../operator/persistent/physical_insert.hpp | 2 + .../execution/perfect_aggregate_hashtable.hpp | 4 + .../duckdb/execution/reservoir_sample.hpp | 1 + .../aggregate/distributive_functions.hpp | 6 +- .../function/aggregate/list_aggregate.hpp | 3 +- .../duckdb/function/aggregate_function.hpp | 9 +- .../cast/variant/primitive_to_variant.hpp | 2 +- .../function/cast/variant/to_variant_fwd.hpp | 11 + .../cast/variant/variant_to_variant.hpp | 9 +- .../include/duckdb/function/copy_function.hpp | 3 +- .../duckdb/function/create_sort_key.hpp | 5 + .../src/include/duckdb/function/function.hpp | 84 +- .../function/function_serialization.hpp | 81 +- .../duckdb/function/function_set_base.hpp | 2 +- .../compressed_materialization_functions.hpp | 52 +- .../compressed_materialization_utils.hpp | 9 + .../duckdb/function/scalar/generic_common.hpp | 1 + .../function/scalar/generic_functions.hpp | 4 +- .../duckdb/function/scalar/list_functions.hpp | 4 +- .../function/scalar/operator_functions.hpp | 14 +- .../function/scalar/sequence_functions.hpp | 2 +- .../function/scalar/string_functions.hpp | 22 +- .../function/scalar/struct_functions.hpp | 8 +- .../function/scalar/system_functions.hpp | 2 +- .../function/scalar/tablefilter_functions.hpp | 10 +- .../duckdb/function/scalar_function.hpp | 25 +- .../include/duckdb/function/table/arrow.hpp | 22 +- .../duckdb/function/table/read_csv.hpp | 6 +- .../duckdb/function/table/read_file.hpp | 1 + .../duckdb/function/table_function.hpp | 44 +- .../function/window/value_functions.hpp | 4 +- .../duckdb/function/window_function.hpp | 20 +- .../src/include/duckdb/logging/log_type.hpp | 13 + .../src/include/duckdb/logging/logger.hpp | 2 +- .../include/duckdb/main/attached_database.hpp | 31 + .../buffered_data/batched_buffered_data.hpp | 35 +- .../main/buffered_data/buffered_data.hpp | 50 +- .../buffered_data/simple_buffered_data.hpp | 17 +- .../duckdb/main/capi/capi_internal.hpp | 50 +- .../duckdb/main/capi_v2/capi_v2_internal.hpp | 118 +- .../main/capi_v2/capi_v2_result_internal.hpp | 31 +- .../duckdb/main/capi_v2/extension_api_v2.hpp | 226 +- .../chunk_scan_state/query_result_stream.hpp | 36 + .../src/include/duckdb/main/client_config.hpp | 4 +- .../include/duckdb/main/client_context.hpp | 132 +- .../duckdb/main/client_context_state.hpp | 1 - .../src/include/duckdb/main/client_data.hpp | 3 + src/duckdb/src/include/duckdb/main/config.hpp | 10 + .../src/include/duckdb/main/connection.hpp | 70 +- .../src/include/duckdb/main/database.hpp | 13 + .../include/duckdb/main/database_manager.hpp | 33 +- .../include/duckdb/main/db_instance_cache.hpp | 5 + .../src/include/duckdb/main/error_manager.hpp | 2 +- .../include/duckdb/main/extension_entries.hpp | 5 +- .../duckdb/main/http/http_client_pool.hpp | 5 +- .../duckdb/main/http/http_retry_budget.hpp | 6 +- .../main/http/http_transport_manager.hpp | 10 +- .../duckdb/main/materialized_query_result.hpp | 67 - .../duckdb/main/pending_query_result.hpp | 70 - .../duckdb/main/prepared_statement.hpp | 39 +- .../duckdb/main/prepared_statement_data.hpp | 3 +- .../include/duckdb/main/query_parameters.hpp | 30 + .../src/include/duckdb/main/query_result.hpp | 118 +- .../duckdb/main/query_result_stream.hpp | 87 + .../src/include/duckdb/main/relation.hpp | 3 + .../main/relation/table_function_relation.hpp | 9 +- .../src/include/duckdb/main/result_unit.hpp | 59 + .../src/include/duckdb/main/secret/secret.hpp | 4 +- .../src/include/duckdb/main/settings.hpp | 575 +- .../duckdb/main/stream_query_result.hpp | 86 - .../optimizer/aggregate_rewrite_helper.hpp | 4 + .../duckdb/optimizer/cte_filter_pusher.hpp | 6 + .../optimizer/remote_pushdown_optimizer.hpp | 19 +- .../optimizer/remove_unused_columns.hpp | 12 + .../duckdb/optimizer/type_pushdown.hpp | 4 + .../src/include/duckdb/parallel/pipeline.hpp | 14 + .../duckdb/parallel/pipeline_executor.hpp | 4 + .../duckdb/parallel/progress_verifier.hpp | 116 + .../duckdb/parallel/scan_read_ahead.hpp | 3 + .../parser/parsed_data/alter_table_info.hpp | 14 +- .../duckdb/parser/parsed_data/attach_info.hpp | 3 + .../parser/parsed_data/connect_info.hpp | 3 + .../parsed_data/external_resource_options.hpp | 43 + .../duckdb/parser/parsed_data/parse_info.hpp | 10 + .../include/duckdb/parser/parser_options.hpp | 1 - .../parser/peg/ast/add_column_entry.hpp | 4 +- .../peg/autocomplete_catalog_provider.hpp | 1 - .../duckdb/parser/peg/compiled_grammar.hpp | 6 +- .../duckdb/parser/peg/dialect_extension.hpp | 2 +- .../parser/peg/grammar_literal_table.hpp | 41 + .../duckdb/parser/peg/inlined_grammar.hpp | 5449 +++---- .../duckdb/parser/peg/keyword_categories.hpp | 63 + .../duckdb/parser/peg/keyword_helper.hpp | 25 +- .../keyword_helper/default_keyword_maps.hpp | 12 +- .../keyword_helper/duckdb_keyword_helper.hpp | 13 +- .../parsed_grammar_keyword_helper.hpp | 8 +- .../duckdb/parser/peg/literal_info.hpp | 58 + .../src/include/duckdb/parser/peg/matcher.hpp | 7 +- .../parser/peg/matcher/identifier_matcher.hpp | 31 +- .../parser/peg/matcher/keyword_matcher.hpp | 21 +- .../peg/matcher/literal_choice_matcher.hpp | 21 + .../parser/peg/matcher/operator_matcher.hpp | 50 +- .../duckdb/parser/peg/matcher_factory.hpp | 3 +- .../duckdb/parser/peg/matcher_token.hpp | 17 + .../duckdb/parser/peg/parsed_grammar.hpp | 1 + .../include/duckdb/parser/peg/peg_parser.hpp | 2 +- .../duckdb/parser/peg/tokenizer/tokenizer.hpp | 2 +- .../peg/transformer/peg_transformer.hpp | 2221 +-- .../duckdb/parser/simplified_token.hpp | 5 +- .../parser/tableref/table_function_ref.hpp | 6 + .../include/duckdb/parser/token_iterator.hpp | 6 + .../src/include/duckdb/planner/binder.hpp | 15 + .../src/include/duckdb/planner/expression.hpp | 7 +- .../expression/bound_constant_expression.hpp | 6 +- .../expression/bound_window_expression.hpp | 17 + .../logical_plan_verification_result.hpp | 4 +- .../planner/operator/logical_copy_to_file.hpp | 2 + .../duckdb/planner/operator/logical_get.hpp | 5 + .../duckdb/planner/operator/logical_limit.hpp | 2 + .../operator/logical_materialized_cte.hpp | 12 + .../planner/operator/logical_secure_view.hpp | 25 + .../duckdb/planner/operator/logical_top_n.hpp | 2 + .../duckdb/planner/sql_export_helpers.hpp | 19 + .../include/duckdb/planner/table_binding.hpp | 5 + .../duckdb/storage/buffer/block_handle.hpp | 6 +- .../storage/compression/alp/alp_utils.hpp | 25 +- .../src/include/duckdb/storage/data_table.hpp | 6 +- .../caching_file_system.hpp | 5 +- .../caching_file_system_wrapper.hpp | 2 + .../duckdb/storage/optimistic_data_writer.hpp | 2 + .../storage/standard_buffer_manager.hpp | 2 +- .../storage/statistics/numeric_stats.hpp | 2 +- .../storage/statistics/stats_writer.hpp | 58 +- .../duckdb/storage/table/index_entry.hpp | 8 +- .../duckdb/storage/table/row_group.hpp | 2 +- .../storage/table/row_version_manager.hpp | 6 +- .../duckdb/storage/table/scan_state.hpp | 7 +- .../duckdb/storage/table/segment_base.hpp | 2 +- .../duckdb/storage/table/table_index_list.hpp | 11 +- .../duckdb/transaction/commit_state.hpp | 4 +- .../duckdb/transaction/undo_buffer.hpp | 2 +- src/duckdb/src/include/duckdb_extension_v2.h | 313 +- src/duckdb/src/include/duckdb_v2.h | 1380 +- src/duckdb/src/logging/log_manager.cpp | 1 + src/duckdb/src/logging/log_types.cpp | 28 + src/duckdb/src/main/attached_database.cpp | 57 +- .../buffered_data/batched_buffered_data.cpp | 80 +- .../src/main/buffered_data/buffered_data.cpp | 90 +- .../buffered_data/simple_buffered_data.cpp | 56 +- src/duckdb/src/main/capi/v1/arrow-c.cpp | 55 +- src/duckdb/src/main/capi/v1/pending-c.cpp | 60 +- src/duckdb/src/main/capi/v1/prepared-c.cpp | 13 +- src/duckdb/src/main/capi/v1/result-c.cpp | 111 +- src/duckdb/src/main/capi/v1/stream-c.cpp | 14 +- src/duckdb/src/main/capi/v1/value-c.cpp | 3 +- src/duckdb/src/main/capi/v2/capi_v2.cpp | 55 +- .../v2/capi_v2_column_data_collection.cpp | 8 - .../src/main/capi/v2/capi_v2_connection.cpp | 118 +- .../src/main/capi/v2/capi_v2_database.cpp | 120 - .../src/main/capi/v2/capi_v2_environment.cpp | 14 +- src/duckdb/src/main/capi/v2/capi_v2_error.cpp | 8 +- .../src/main/capi/v2/capi_v2_func_copy.cpp | 7 +- .../src/main/capi/v2/capi_v2_func_table.cpp | 403 +- .../src/main/capi/v2/capi_v2_instance.cpp | 358 + .../src/main/capi/v2/capi_v2_option.cpp | 50 +- .../main/capi/v2/capi_v2_replacement_scan.cpp | 20 +- .../src/main/capi/v2/capi_v2_result.cpp | 196 +- src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp | 14 + .../src/main/capi/v2/capi_v2_vector.cpp | 11 +- .../main/chunk_scan_state/query_result.cpp | 9 +- .../chunk_scan_state/query_result_stream.cpp | 65 + src/duckdb/src/main/client_context.cpp | 481 +- src/duckdb/src/main/client_data.cpp | 1 + src/duckdb/src/main/client_verify.cpp | 6 +- src/duckdb/src/main/config.cpp | 36 +- src/duckdb/src/main/connection.cpp | 86 +- src/duckdb/src/main/database.cpp | 56 +- src/duckdb/src/main/database_manager.cpp | 147 +- src/duckdb/src/main/db_instance_cache.cpp | 5 + .../src/main/extension/extension_loader.cpp | 2 +- src/duckdb/src/main/http/http_client_pool.cpp | 24 +- .../src/main/http/http_retry_budget.cpp | 7 + .../src/main/http/http_transport_manager.cpp | 49 +- .../src/main/materialized_query_result.cpp | 107 - src/duckdb/src/main/pending_query_result.cpp | 121 - src/duckdb/src/main/prepared_statement.cpp | 32 +- src/duckdb/src/main/query_result.cpp | 305 +- src/duckdb/src/main/query_result_stream.cpp | 224 + src/duckdb/src/main/relation.cpp | 2 +- .../src/main/relation/read_csv_relation.cpp | 21 +- .../main/relation/table_function_relation.cpp | 16 +- src/duckdb/src/main/result_unit.cpp | 15 + .../main/settings/autogenerated_settings.cpp | 20 + .../src/main/settings/custom_settings.cpp | 76 +- src/duckdb/src/main/stream_query_result.cpp | 272 - .../optimizer/aggregate_rewrite_helper.cpp | 14 + .../src/optimizer/column_binding_replacer.cpp | 11 + .../optimizer/common_subplan_optimizer.cpp | 5 + .../optimizer/compressed_materialization.cpp | 10 +- .../src/optimizer/cte_filter_pusher.cpp | 58 +- .../src/optimizer/expression_rewriter.cpp | 5 + .../src/optimizer/grouping_sets_optimizer.cpp | 7 +- .../multi_stage_aggregate_rewriter.cpp | 6 +- src/duckdb/src/optimizer/optimizer.cpp | 8 + .../pushdown/pushdown_secure_view.cpp | 37 +- .../src/optimizer/remove_unused_columns.cpp | 212 +- src/duckdb/src/optimizer/row_group_pruner.cpp | 3 + .../rule/arithmetic_simplification.cpp | 14 +- .../optimizer/rule/case_simplification.cpp | 2 +- .../rule/constant_order_normalization.cpp | 2 +- .../optimizer/rule/empty_needle_removal.cpp | 4 +- .../rule/least_greatest_simplification.cpp | 2 +- .../src/optimizer/rule/move_constants.cpp | 23 +- .../src/optimizer/scalar_fn_pushdown.cpp | 8 +- .../expression/propagate_function.cpp | 4 + .../expression/propagate_operator.cpp | 2 +- .../operator/propagate_secure_view.cpp | 33 +- .../src/optimizer/statistics_propagator.cpp | 4 + src/duckdb/src/optimizer/topn_optimizer.cpp | 1 + src/duckdb/src/optimizer/type_pushdown.cpp | 12 +- src/duckdb/src/parallel/executor.cpp | 151 +- src/duckdb/src/parallel/pipeline.cpp | 37 +- src/duckdb/src/parallel/pipeline_executor.cpp | 22 + src/duckdb/src/parallel/progress_verifier.cpp | 374 + src/duckdb/src/parallel/scan_read_ahead.cpp | 4 + src/duckdb/src/parser/keyword_helper.cpp | 21 +- .../parser/parsed_data/alter_table_info.cpp | 15 +- .../src/parser/parsed_data/attach_info.cpp | 28 +- .../src/parser/parsed_data/connect_info.cpp | 20 +- .../parsed_data/external_resource_options.cpp | 49 + .../src/parser/parsed_data/parse_info.cpp | 19 + src/duckdb/src/parser/parser.cpp | 16 +- .../src/parser/peg/autocomplete_core.cpp | 3 +- .../src/parser/peg/compiled_grammar.cpp | 15 +- .../src/parser/peg/dialect_extension.cpp | 2 +- .../keyword_helper/default_keyword_maps.cpp | 101 +- .../keyword_helper/duckdb_keyword_helper.cpp | 16 +- .../keyword_helper/grammar_literal_table.cpp | 50 + .../parsed_grammar_keyword_helper.cpp | 12 +- src/duckdb/src/parser/peg/keyword_map.cpp | 8 +- src/duckdb/src/parser/peg/matcher.cpp | 34 +- src/duckdb/src/parser/peg/matcher_factory.cpp | 39 +- src/duckdb/src/parser/peg/matcher_process.cpp | 21 +- .../src/parser/peg/operator_matcher.cpp | 30 + src/duckdb/src/parser/peg/peg_parser.cpp | 1 + .../parser/peg/tokenizer/base_tokenizer.cpp | 93 +- .../peg/transformer/peg_transformer.cpp | 26 +- .../transformer/peg_transformer_factory.cpp | 88 +- .../peg/transformer/transform_alter.cpp | 45 +- .../peg/transformer/transform_comment.cpp | 12 +- .../parser/peg/transformer/transform_copy.cpp | 11 +- .../transformer/transform_create_table.cpp | 5 - .../peg/transformer/transform_expression.cpp | 86 +- .../transform_external_resource.cpp | 11 +- .../transform_external_resource_source.cpp | 70 + .../peg/transformer/transform_generated.cpp | 12045 ---------------- .../transform_generated_trampoline.cpp | 559 +- .../transform_generic_copy_option.cpp | 46 +- .../peg/transformer/transform_pivot.cpp | 152 - .../peg/transformer/transform_select.cpp | 143 +- .../src/parser/tableref/table_function.cpp | 10 +- src/duckdb/src/parser/token_iterator.cpp | 7 + src/duckdb/src/planner/binder.cpp | 2 +- .../expression/bind_aggregate_expression.cpp | 4 + .../expression/bind_operator_expression.cpp | 19 +- .../expression/bind_star_expression.cpp | 159 + .../expression/bind_window_expression.cpp | 14 + .../query_node/bind_recursive_cte_node.cpp | 9 +- .../query_node/bind_trigger_expansion.cpp | 6 +- .../planner/binder/statement/bind_attach.cpp | 21 +- .../planner/binder/statement/bind_call.cpp | 2 +- .../planner/binder/statement/bind_connect.cpp | 9 +- .../planner/binder/statement/bind_copy.cpp | 109 +- .../binder/statement/bind_copy_database.cpp | 2 +- .../planner/binder/statement/bind_create.cpp | 16 +- .../binder/statement/bind_create_table.cpp | 2 +- .../planner/binder/statement/bind_delete.cpp | 2 +- .../planner/binder/statement/bind_detach.cpp | 2 +- .../planner/binder/statement/bind_drop.cpp | 2 +- .../planner/binder/statement/bind_execute.cpp | 6 +- .../planner/binder/statement/bind_export.cpp | 2 +- .../statement/bind_external_resource.cpp | 29 +- .../planner/binder/statement/bind_insert.cpp | 2 +- .../planner/binder/statement/bind_load.cpp | 2 +- .../binder/statement/bind_logical_plan.cpp | 2 +- .../binder/statement/bind_merge_into.cpp | 2 +- .../planner/binder/statement/bind_prepare.cpp | 2 +- .../planner/binder/statement/bind_select.cpp | 2 +- .../planner/binder/statement/bind_update.cpp | 2 +- .../binder/tableref/bind_basetableref.cpp | 6 +- .../tableref/bind_expressionlistref.cpp | 30 +- .../planner/binder/tableref/bind_joinref.cpp | 12 + .../binder/tableref/bind_table_function.cpp | 2 + .../planner/binder/tableref/plan_joinref.cpp | 12 +- .../planner/bound_expression_sql_exporter.cpp | 3 +- src/duckdb/src/planner/expression.cpp | 7 + .../expression/bound_aggregate_expression.cpp | 4 +- .../expression/bound_constant_expression.cpp | 15 + .../expression/bound_function_expression.cpp | 44 +- .../expression/bound_window_expression.cpp | 26 + .../planner/logical_operator_deep_copy.cpp | 29 + .../logical_plan_verification_result.cpp | 3 +- .../planner/operator/logical_copy_to_file.cpp | 6 + .../src/planner/operator/logical_get.cpp | 23 +- .../planner/operator/logical_secure_view.cpp | 75 +- .../subquery/delim_join_cte_rewriter.cpp | 67 + src/duckdb/src/planner/table_binding.cpp | 8 + .../src/storage/buffer/block_handle.cpp | 12 +- src/duckdb/src/storage/buffer/buffer_pool.cpp | 16 +- src/duckdb/src/storage/checkpoint_manager.cpp | 25 +- .../src/storage/compression/bitpacking.cpp | 2 +- .../compression/dict_fsst/decompression.cpp | 2 +- src/duckdb/src/storage/compression/rle.cpp | 18 +- src/duckdb/src/storage/data_table.cpp | 12 +- .../caching_file_system.cpp | 4 +- .../caching_file_system_wrapper.cpp | 5 + src/duckdb/src/storage/index_entry.cpp | 15 +- src/duckdb/src/storage/local_storage.cpp | 9 +- .../src/storage/optimistic_data_writer.cpp | 7 + .../serialize_logical_operator.cpp | 22 + .../storage/serialization/serialize_nodes.cpp | 4 + .../serialization/serialize_parse_info.cpp | 10 +- .../serialization/serialize_tableref.cpp | 2 +- .../src/storage/standard_buffer_manager.cpp | 20 +- .../src/storage/statistics/numeric_stats.cpp | 33 +- .../src/storage/statistics/variant_stats.cpp | 2 +- src/duckdb/src/storage/storage_manager.cpp | 13 +- src/duckdb/src/storage/table/column_data.cpp | 2 +- src/duckdb/src/storage/table/row_group.cpp | 16 +- .../storage/table/row_group_collection.cpp | 7 +- .../src/storage/table/row_id_column_data.cpp | 2 +- .../src/storage/table/row_version_manager.cpp | 28 +- src/duckdb/src/storage/table/scan_state.cpp | 41 +- src/duckdb/src/storage/table_index_list.cpp | 80 +- .../src/storage/temporary_file_manager.cpp | 4 +- src/duckdb/src/storage/wal_replay.cpp | 32 +- src/duckdb/src/storage/write_ahead_log.cpp | 20 +- src/duckdb/src/transaction/commit_state.cpp | 6 +- .../transaction/duck_transaction_manager.cpp | 8 + src/duckdb/src/transaction/rollback_state.cpp | 12 +- src/duckdb/src/transaction/undo_buffer.cpp | 49 +- .../third_party/parquet/parquet_types.cpp | 27 +- .../third_party/parquet/parquet_types.h | 12 +- .../third_party/utf8proc/utf8proc_wrapper.cpp | 13 +- .../ub_extension_parquet_reader_variant.cpp | 6 - src/duckdb/ub_src_common_types_variant.cpp | 6 + src/duckdb/ub_src_execution.cpp | 2 + ...on_operator_csv_scanner_table_function.cpp | 4 +- src/duckdb/ub_src_function_scalar_string.cpp | 2 + src/duckdb/ub_src_main.cpp | 10 +- src/duckdb/ub_src_main_capi_v2.cpp | 6 +- src/duckdb/ub_src_main_chunk_scan_state.cpp | 2 + src/duckdb/ub_src_parallel.cpp | 2 + src/duckdb/ub_src_parser_parsed_data.cpp | 2 + src/duckdb/ub_src_parser_peg.cpp | 2 + .../ub_src_parser_peg_keyword_helper.cpp | 2 + src/duckdb/ub_src_parser_peg_transformer.cpp | 2 +- 612 files changed, 17944 insertions(+), 24593 deletions(-) create mode 100644 src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp rename src/duckdb/{extension/parquet/reader => src/common/types}/variant/parquet_variant_iterator.cpp (97%) rename src/duckdb/{extension/parquet/reader => src/common/types}/variant/variant_binary_decoder.cpp (98%) create mode 100644 src/duckdb/src/execution/ie_join_union.cpp delete mode 100644 src/duckdb/src/execution/operator/csv_scanner/table_function/csv_multi_file_info.cpp create mode 100644 src/duckdb/src/execution/operator/csv_scanner/table_function/csv_schema_discovery.cpp create mode 100644 src/duckdb/src/execution/operator/csv_scanner/table_function/read_single_csv_file.cpp create mode 100644 src/duckdb/src/function/scalar/string/hive_partition_component.cpp create mode 100644 src/duckdb/src/include/duckdb/common/enums/debug_progress_verification.hpp rename src/duckdb/src/include/duckdb/common/enums/{pending_execution_result.hpp => file_sync_mode.hpp} (59%) rename src/duckdb/src/include/duckdb/common/enums/{stream_execution_result.hpp => query_result_memory_type.hpp} (57%) create mode 100644 src/duckdb/src/include/duckdb/common/enums/query_result_state.hpp create mode 100644 src/duckdb/src/include/duckdb/common/enums/result_eagerness.hpp delete mode 100644 src/duckdb/src/include/duckdb/common/query_parameters.hpp rename src/duckdb/{extension/parquet/include/reader => src/include/duckdb/common/types}/variant/parquet_variant_iterator.hpp (79%) rename src/duckdb/{extension/parquet/include/reader => src/include/duckdb/common/types}/variant/variant_binary_decoder.hpp (92%) create mode 100644 src/duckdb/src/include/duckdb/execution/ie_join_union.hpp delete mode 100644 src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp create mode 100644 src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp create mode 100644 src/duckdb/src/include/duckdb/main/chunk_scan_state/query_result_stream.hpp delete mode 100644 src/duckdb/src/include/duckdb/main/materialized_query_result.hpp delete mode 100644 src/duckdb/src/include/duckdb/main/pending_query_result.hpp create mode 100644 src/duckdb/src/include/duckdb/main/query_parameters.hpp create mode 100644 src/duckdb/src/include/duckdb/main/query_result_stream.hpp create mode 100644 src/duckdb/src/include/duckdb/main/result_unit.hpp delete mode 100644 src/duckdb/src/include/duckdb/main/stream_query_result.hpp create mode 100644 src/duckdb/src/include/duckdb/parallel/progress_verifier.hpp create mode 100644 src/duckdb/src/include/duckdb/parser/parsed_data/external_resource_options.hpp create mode 100644 src/duckdb/src/include/duckdb/parser/peg/grammar_literal_table.hpp create mode 100644 src/duckdb/src/include/duckdb/parser/peg/keyword_categories.hpp create mode 100644 src/duckdb/src/include/duckdb/parser/peg/literal_info.hpp create mode 100644 src/duckdb/src/include/duckdb/parser/peg/matcher/literal_choice_matcher.hpp delete mode 100644 src/duckdb/src/main/capi/v2/capi_v2_database.cpp create mode 100644 src/duckdb/src/main/capi/v2/capi_v2_instance.cpp create mode 100644 src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp create mode 100644 src/duckdb/src/main/chunk_scan_state/query_result_stream.cpp delete mode 100644 src/duckdb/src/main/materialized_query_result.cpp delete mode 100644 src/duckdb/src/main/pending_query_result.cpp create mode 100644 src/duckdb/src/main/query_result_stream.cpp create mode 100644 src/duckdb/src/main/result_unit.cpp delete mode 100644 src/duckdb/src/main/stream_query_result.cpp create mode 100644 src/duckdb/src/parallel/progress_verifier.cpp create mode 100644 src/duckdb/src/parser/parsed_data/external_resource_options.cpp create mode 100644 src/duckdb/src/parser/peg/keyword_helper/grammar_literal_table.cpp create mode 100644 src/duckdb/src/parser/peg/operator_matcher.cpp create mode 100644 src/duckdb/src/parser/peg/transformer/transform_external_resource_source.cpp delete mode 100644 src/duckdb/src/parser/peg/transformer/transform_generated.cpp delete mode 100644 src/duckdb/ub_extension_parquet_reader_variant.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 910082e16..ca5e677c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,7 @@ set(DUCKDB_SRC_FILES src/duckdb/extension/parquet/parquet_statistics.cpp src/duckdb/extension/parquet/parquet_timestamp.cpp src/duckdb/extension/parquet/parquet_writer.cpp + src/duckdb/extension/parquet/reader/variant/parquet_variant_shredding.cpp src/duckdb/extension/parquet/serialize_parquet.cpp src/duckdb/extension/parquet/zstd_file_system.cpp src/duckdb/generated_extension_loader_package_build.cpp @@ -371,7 +372,6 @@ set(DUCKDB_SRC_FILES src/duckdb/ub_extension_json_json_functions.cpp src/duckdb/ub_extension_parquet_decoder.cpp src/duckdb/ub_extension_parquet_reader.cpp - src/duckdb/ub_extension_parquet_reader_variant.cpp src/duckdb/ub_extension_parquet_writer.cpp src/duckdb/ub_extension_parquet_writer_variant.cpp src/duckdb/ub_src_catalog.cpp diff --git a/src/duckdb/extension/core_functions/aggregate/distributive/bitagg.cpp b/src/duckdb/extension/core_functions/aggregate/distributive/bitagg.cpp index ef7f2f19b..e2e94fbee 100644 --- a/src/duckdb/extension/core_functions/aggregate/distributive/bitagg.cpp +++ b/src/duckdb/extension/core_functions/aggregate/distributive/bitagg.cpp @@ -24,7 +24,7 @@ static AggregateFunction NameArgParameter(AggregateFunction fun) { } template -AggregateFunction GetBitfieldUnaryAggregate(LogicalType type) { +AggregateFunction GetBitfieldUnaryAggregate(const LogicalType &type) { switch (type.id()) { case LogicalTypeId::TINYINT: return NameArgParameter(AggregateFunction::UnaryAggregate, int8_t, int8_t, OP>(type, type)); @@ -111,7 +111,9 @@ struct BitwiseOperation { }; template -struct NumericBitwiseOperation : public BitwiseOperation, public ClusteredStateCopy { +struct NumericBitwiseOperation // NOLINT(bugprone-crtp-constructor-accessibility) + : public BitwiseOperation, + public ClusteredStateCopy { template static void UpdateClusteredLocal(STATE &local, const INPUT_TYPE &input) { if (!local.is_set) { diff --git a/src/duckdb/extension/core_functions/aggregate/distributive/sum.cpp b/src/duckdb/extension/core_functions/aggregate/distributive/sum.cpp index a2ec57f6d..f84271134 100644 --- a/src/duckdb/extension/core_functions/aggregate/distributive/sum.cpp +++ b/src/duckdb/extension/core_functions/aggregate/distributive/sum.cpp @@ -95,10 +95,10 @@ struct ClusteredSumOperation : public ClusteredSumStateCopy { static void ExecuteFlatI64HugeintSum(const INPUT_TYPE *vals, const ClusteredAggr &clustered, const SelectionVector *isel, const sel_t *cluster_iter) { idx_t pos = 0; - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); - const auto *run_sel = clustered.group_runs[r].sel; - const idx_t run_count = clustered.group_runs[r].count; + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); + const auto *run_sel = run.sel; + const idx_t run_count = run.count; if (run_count == 0) { continue; } @@ -144,10 +144,10 @@ struct ClusteredSumOperation : public ClusteredSumStateCopy { input.ToUnifiedFormat(idata); const auto *dict_sel = idata.sel->data(); auto &validity = idata.validity; - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); - const auto *run_sel = clustered.group_runs[r].sel; - const idx_t run_count = clustered.group_runs[r].count; + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); + const auto *run_sel = run.sel; + const idx_t run_count = run.count; int64_t local64 = 0; if (run_sel) { for (idx_t k = 0; k < run_count; k++) { diff --git a/src/duckdb/extension/core_functions/aggregate/holistic/mode.cpp b/src/duckdb/extension/core_functions/aggregate/holistic/mode.cpp index 13c36ecb2..e90046f7e 100644 --- a/src/duckdb/extension/core_functions/aggregate/holistic/mode.cpp +++ b/src/duckdb/extension/core_functions/aggregate/holistic/mode.cpp @@ -127,7 +127,7 @@ struct ModeStandard { return Equals::Operation(left, right); } - static T *Update(T *mode, uint32_t &, const T &key, AggregateInputData &) { + static T *Update(T *mode, idx_t &, const T &key, AggregateInputData &) { if (!mode) { mode = new T(key); } @@ -156,7 +156,7 @@ struct ModeString { return Equals::Operation(left, right); } - static string_t *Update(string_t *mode, uint32_t &alloc_size, const string_t &key, + static string_t *Update(string_t *mode, idx_t &alloc_size, const string_t &key, AggregateInputData &aggr_input_data) { if (key.IsInlined()) { if (!mode) { @@ -168,14 +168,14 @@ struct ModeString { } // non-inlined string, need to allocate space for it somehow - const auto len = UnsafeNumericCast(key.GetSize()); + const auto len = key.GetSize(); char *ptr; if (mode && alloc_size >= len) { // this fits into the current arena allocation - reuse it ptr = mode->GetDataWriteable(); } else { // round up so repeatedly growing keys don't churn through a new arena allocation every time - alloc_size = UnsafeNumericCast(NextPowerOfTwo(len)); + alloc_size = NextPowerOfTwo(len); ptr = char_ptr_cast(aggr_input_data.allocator.Allocate(alloc_size)); if (!mode) { mode = new string_t(nullptr, 0); @@ -197,7 +197,8 @@ struct ModeState { SubFrames prevs; Counts *frequency_map = nullptr; KEY_TYPE *mode = nullptr; - uint32_t mode_alloc_size = 0; + //! Must be wide enough for NextPowerOfTwo(MAX_STRING_SIZE), which does not fit in a uint32_t + idx_t mode_alloc_size = 0; size_t nonzero = 0; bool valid = false; size_t count = 0; diff --git a/src/duckdb/extension/core_functions/aggregate/variant/variant_group_object.cpp b/src/duckdb/extension/core_functions/aggregate/variant/variant_group_object.cpp index da6268ba7..9a88aca86 100644 --- a/src/duckdb/extension/core_functions/aggregate/variant/variant_group_object.cpp +++ b/src/duckdb/extension/core_functions/aggregate/variant/variant_group_object.cpp @@ -186,6 +186,8 @@ AggregateFunction VariantGroupObjectFun::GetFunction() { AggregateFunction::StateSize, AggregateFunction::StateInitialize, VariantObjUpdate, ListCombineFunction, VariantObjFinalize, VariantObjClusterUpdate); + function.GetSignature().GetParameter(0).SetName("key"); + function.GetSignature().GetParameter(1).SetName("value"); function.SetStructStateExport(VariantObjStateLayout); return function; } diff --git a/src/duckdb/extension/core_functions/include/core_functions/aggregate/distributive_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/aggregate/distributive_functions.hpp index 4add0a00d..b35c0efcb 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/aggregate/distributive_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/aggregate/distributive_functions.hpp @@ -27,7 +27,7 @@ struct ApproxCountDistinctFun { struct ArgMinFun { static constexpr const char *Name = "arg_min"; - static constexpr const char *Parameters = "arg,val"; + static constexpr const char *Parameters = "arg,val,N"; static constexpr const char *Description = "Finds the row with the minimum val. Calculates the non-NULL arg expression at that row."; static constexpr const char *Example = "arg_min(A, B)"; static constexpr const char *Categories = ""; @@ -69,7 +69,7 @@ struct ArgMinNullsLastFun { struct ArgMaxFun { static constexpr const char *Name = "arg_max"; - static constexpr const char *Parameters = "arg,val"; + static constexpr const char *Parameters = "arg,val,N"; static constexpr const char *Description = "Finds the row with the maximum val. Calculates the non-NULL arg expression at that row."; static constexpr const char *Example = "arg_max(A, B)"; static constexpr const char *Categories = ""; @@ -141,7 +141,7 @@ struct BitXorFun { struct BitstringAggFun { static constexpr const char *Name = "bitstring_agg"; - static constexpr const char *Parameters = "arg"; + static constexpr const char *Parameters = "arg,min,max"; static constexpr const char *Description = "Returns a bitstring with bits set for each distinct value."; static constexpr const char *Example = "bitstring_agg(A)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/aggregate/holistic_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/aggregate/holistic_functions.hpp index 44a487106..871f9c2b9 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/aggregate/holistic_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/aggregate/holistic_functions.hpp @@ -57,7 +57,7 @@ struct ModeFun { struct QuantileDiscFun { static constexpr const char *Name = "quantile_disc"; - static constexpr const char *Parameters = "x,pos"; + static constexpr const char *Parameters = "x,quantile"; static constexpr const char *Description = "Returns the exact quantile number between 0 and 1 . If pos is a LIST of FLOATs, then the result is a LIST of the corresponding exact quantiles."; static constexpr const char *Example = "quantile_disc(x, 0.5)"; static constexpr const char *Categories = ""; @@ -73,7 +73,7 @@ struct QuantileFun { struct QuantileContFun { static constexpr const char *Name = "quantile_cont"; - static constexpr const char *Parameters = "x,pos"; + static constexpr const char *Parameters = "x,quantile"; static constexpr const char *Description = "Returns the interpolated quantile number between 0 and 1 . If pos is a LIST of FLOATs, then the result is a LIST of the corresponding interpolated quantiles. "; static constexpr const char *Example = "quantile_cont(x, 0.5)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/aggregate/nested_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/aggregate/nested_functions.hpp index 84bd4ad6b..8863ac602 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/aggregate/nested_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/aggregate/nested_functions.hpp @@ -17,7 +17,7 @@ namespace duckdb { struct HistogramFun { static constexpr const char *Name = "histogram"; - static constexpr const char *Parameters = "arg"; + static constexpr const char *Parameters = "arg,bins"; static constexpr const char *Description = "Returns a LIST of STRUCTs with the fields bucket and count."; static constexpr const char *Example = "histogram(A)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/date_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/date_functions.hpp index e0d4c5fda..b58842cd4 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/date_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/date_functions.hpp @@ -17,7 +17,7 @@ namespace duckdb { struct AgeFun { static constexpr const char *Name = "age"; - static constexpr const char *Parameters = "timestamp,timestamp"; + static constexpr const char *Parameters = "timestamp1,timestamp2"; static constexpr const char *Description = "Subtract arguments, resulting in the time difference between the two timestamps"; static constexpr const char *Example = "age(TIMESTAMP '2001-04-10', TIMESTAMP '1992-09-20')"; static constexpr const char *Categories = ""; @@ -53,7 +53,7 @@ struct DatediffFun { struct DatePartFun { static constexpr const char *Name = "date_part"; - static constexpr const char *Parameters = "ts"; + static constexpr const char *Parameters = "part,ts"; static constexpr const char *Description = "Get subfield (equivalent to extract)"; static constexpr const char *Example = "date_part('minute', TIMESTAMP '1992-09-20 20:38:40')"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/debug_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/debug_functions.hpp index ab6b7cb9d..b5ab6002d 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/debug_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/debug_functions.hpp @@ -37,7 +37,7 @@ struct SleepMsFun { struct IndexKeyFun { static constexpr const char *Name = "index_key"; - static constexpr const char *Parameters = "path,name,[key_column_1,key_column_2,...]"; + static constexpr const char *Parameters = "path,name,..."; static constexpr const char *Description = "Generate index keys for a named index on a table (specified by a path struct with required 'table' and optional 'catalog'/'schema' fields) from key column arguments. Currently only supports ART indexes."; static constexpr const char *Example = "index_key({'schema': 'main', 'table': 'tbl3'}, 'tbl3_idx', key1, key2, key3)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/generic_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/generic_functions.hpp index f8642e689..bab3b7f07 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/generic_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/generic_functions.hpp @@ -47,7 +47,7 @@ struct HashFun { struct LeastFun { static constexpr const char *Name = "least"; - static constexpr const char *Parameters = "arg1,arg2,..."; + static constexpr const char *Parameters = "arg1,..."; static constexpr const char *Description = "Returns the smallest value. For strings lexicographical ordering is used. Note that uppercase characters are considered “smaller” than lowercase characters, and collations are not supported."; static constexpr const char *Example = "least(42, 84)\002least('abc', 'bcd', 'cde', 'EFG')"; static constexpr const char *Categories = "string,numeric,date,timestamp,aggregate"; @@ -57,7 +57,7 @@ struct LeastFun { struct GreatestFun { static constexpr const char *Name = "greatest"; - static constexpr const char *Parameters = "arg1,arg2,..."; + static constexpr const char *Parameters = "arg1,..."; static constexpr const char *Description = "Returns the largest value. For strings lexicographical ordering is used. Note that lowercase characters are considered “larger” than uppercase characters and collations are not supported."; static constexpr const char *Example = "greatest(42, 84)\002greatest('abc', 'bcd', 'cde', 'EFG')"; static constexpr const char *Categories = "string,numeric,date,timestamp,aggregate"; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/list_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/list_functions.hpp index 96ffd39c2..c06f4cf94 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/list_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/list_functions.hpp @@ -93,7 +93,7 @@ struct ArrayUniqueFun { struct ListValueFun { static constexpr const char *Name = "list_value"; - static constexpr const char *Parameters = "any,..."; + static constexpr const char *Parameters = "value,..."; static constexpr const char *Description = "Creates a LIST containing the argument values."; static constexpr const char *Example = "list_value(4, 5, 6)"; static constexpr const char *Categories = "list"; @@ -125,7 +125,7 @@ struct ArraySliceFun { struct ListSortFun { static constexpr const char *Name = "list_sort"; - static constexpr const char *Parameters = "list"; + static constexpr const char *Parameters = "list,sort_order,null_order"; static constexpr const char *Description = "Sorts the elements of the list."; static constexpr const char *Example = "list_sort([3, 6, 1, 2])"; static constexpr const char *Categories = "list"; @@ -141,7 +141,7 @@ struct ArraySortFun { struct ListGradeUpFun { static constexpr const char *Name = "list_grade_up"; - static constexpr const char *Parameters = "list"; + static constexpr const char *Parameters = "list,sort_order,null_order"; static constexpr const char *Description = "Works like list_sort, but the results are the indexes that correspond to the position in the original list instead of the actual values."; static constexpr const char *Example = "list_grade_up([3, 6, 1, 2])"; static constexpr const char *Categories = "list"; @@ -163,7 +163,7 @@ struct GradeUpFun { struct ListReverseSortFun { static constexpr const char *Name = "list_reverse_sort"; - static constexpr const char *Parameters = "list"; + static constexpr const char *Parameters = "list,null_order"; static constexpr const char *Description = "Sorts the elements of the list in reverse order."; static constexpr const char *Example = "list_reverse_sort([3, 6, 1, 2])"; static constexpr const char *Categories = "list"; @@ -179,7 +179,7 @@ struct ArrayReverseSortFun { struct ListTransformFun { static constexpr const char *Name = "list_transform"; - static constexpr const char *Parameters = "list,lambda(x)"; + static constexpr const char *Parameters = "list,lambda"; static constexpr const char *Description = "Returns a list that is the result of applying the `lambda` function to each element of the input `list`. The return type is defined by the return type of the `lambda` function."; static constexpr const char *Example = "list_transform([1, 2, 3], lambda x : x + 1)"; static constexpr const char *Categories = "list,lambda"; @@ -213,7 +213,7 @@ struct ApplyFun { struct ListFilterFun { static constexpr const char *Name = "list_filter"; - static constexpr const char *Parameters = "list,lambda(x)"; + static constexpr const char *Parameters = "list,lambda"; static constexpr const char *Description = "Constructs a list from those elements of the input `list` for which the `lambda` function returns `true`. DuckDB must be able to cast the `lambda` function's return type to `BOOL`. The return type of `list_filter` is the same as the input list's."; static constexpr const char *Example = "list_filter([3, 4, 5], lambda x : x > 4)"; static constexpr const char *Categories = "list,lambda"; @@ -235,7 +235,7 @@ struct FilterFun { struct ListReduceFun { static constexpr const char *Name = "list_reduce"; - static constexpr const char *Parameters = "list,lambda(x,y),initial_value"; + static constexpr const char *Parameters = "list,lambda,initial_value"; static constexpr const char *Description = "Reduces all elements of the input `list` into a single scalar value by executing the `lambda` function on a running result and the next list element. The `lambda` function has an optional `initial_value` argument."; static constexpr const char *Example = "list_reduce([1, 2, 3], lambda x, y : x + y)"; static constexpr const char *Categories = "list,lambda"; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/math_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/math_functions.hpp index ee55fa553..ade64790f 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/math_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/math_functions.hpp @@ -451,7 +451,7 @@ struct TanFun { struct TruncFun { static constexpr const char *Name = "trunc"; - static constexpr const char *Parameters = "x"; + static constexpr const char *Parameters = "x,precision"; static constexpr const char *Description = "Truncates the number"; static constexpr const char *Example = "trunc(17.4)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/operators_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/operators_functions.hpp index a92258f0a..2764eecad 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/operators_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/operators_functions.hpp @@ -47,7 +47,7 @@ struct BitwiseNotFun { struct LeftShiftFun { static constexpr const char *Name = "<<"; - static constexpr const char *Parameters = "input"; + static constexpr const char *Parameters = "input,shift"; static constexpr const char *Description = "Bitwise shift left"; static constexpr const char *Example = "1 << 4"; static constexpr const char *Categories = ""; @@ -57,7 +57,7 @@ struct LeftShiftFun { struct RightShiftFun { static constexpr const char *Name = ">>"; - static constexpr const char *Parameters = "input"; + static constexpr const char *Parameters = "input,shift"; static constexpr const char *Description = "Bitwise shift right"; static constexpr const char *Example = "8 >> 2"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/extension/core_functions/include/core_functions/scalar/string_functions.hpp b/src/duckdb/extension/core_functions/include/core_functions/scalar/string_functions.hpp index 81b33c693..63ccd516b 100644 --- a/src/duckdb/extension/core_functions/include/core_functions/scalar/string_functions.hpp +++ b/src/duckdb/extension/core_functions/include/core_functions/scalar/string_functions.hpp @@ -89,7 +89,7 @@ struct DamerauLevenshteinFun { struct FormatFun { static constexpr const char *Name = "format"; - static constexpr const char *Parameters = "format,parameters..."; + static constexpr const char *Parameters = "format,..."; static constexpr const char *Description = "Formats a string using the fmt syntax."; static constexpr const char *Example = "format('Benchmark \"{}\" took {} seconds', 'CSV', 42)"; static constexpr const char *Categories = "string"; @@ -315,7 +315,7 @@ struct ParsePathFun { struct PrintfFun { static constexpr const char *Name = "printf"; - static constexpr const char *Parameters = "format,parameters..."; + static constexpr const char *Parameters = "format,..."; static constexpr const char *Description = "Formats a `string` using printf syntax."; static constexpr const char *Example = "printf('Benchmark \"%s\" took %d seconds', 'CSV', 42)"; static constexpr const char *Categories = "string"; diff --git a/src/duckdb/extension/core_functions/scalar/blob/encode.cpp b/src/duckdb/extension/core_functions/scalar/blob/encode.cpp index 05eba11df..9eb915131 100644 --- a/src/duckdb/extension/core_functions/scalar/blob/encode.cpp +++ b/src/duckdb/extension/core_functions/scalar/blob/encode.cpp @@ -82,7 +82,7 @@ void BinaryDecodeFunction(DataChunk &args, ExpressionState &state, Vector &resul auto new_str = Utf8Proc::RemoveInvalid(input_data, input_length); auto target = StringVector::EmptyString(result, new_str.size()); auto output = target.GetDataWriteable(); - memcpy(output, new_str.data(), new_str.size()); + memcpy(output, new_str.data(), new_str.size()); // NOLINT(bugprone-not-null-terminated-result) target.Finalize(); return target; } diff --git a/src/duckdb/extension/core_functions/scalar/debug/vector_type.cpp b/src/duckdb/extension/core_functions/scalar/debug/vector_type.cpp index f99e10358..51730f141 100644 --- a/src/duckdb/extension/core_functions/scalar/debug/vector_type.cpp +++ b/src/duckdb/extension/core_functions/scalar/debug/vector_type.cpp @@ -17,6 +17,7 @@ ScalarFunction VectorTypeFun::GetFunction() { auto vector_type_fun = ScalarFunction({}, LogicalType::VARCHAR, VectorTypeFunction); vector_type_fun.GetSignature().AddParameter("col", LogicalType::ANY); vector_type_fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); + vector_type_fun.SetStability(FunctionStability::VOLATILE); return vector_type_fun; } diff --git a/src/duckdb/extension/core_functions/scalar/generic/alias.cpp b/src/duckdb/extension/core_functions/scalar/generic/alias.cpp index 722c4d42f..9ea3fc3f9 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/alias.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/alias.cpp @@ -1,10 +1,16 @@ #include "core_functions/scalar/generic_functions.hpp" +#include "duckdb/common/serializer/serializer.hpp" +#include "duckdb/common/serializer/deserializer.hpp" #include "duckdb/planner/expression/bound_function_expression.hpp" +#include "duckdb/parser/expression/case_expression.hpp" +#include "duckdb/parser/expression/constant_expression.hpp" +#include "duckdb/parser/expression/function_expression.hpp" +#include "duckdb/parser/expression/operator_expression.hpp" namespace duckdb { namespace { -struct AliasBindData : public FunctionData { +struct AliasBindData final : public FunctionData { explicit AliasBindData(Identifier alias_p) : alias(std::move(alias_p)) { } @@ -23,6 +29,30 @@ struct AliasBindData : public FunctionData { unique_ptr AliasBind(BindScalarFunctionInput &input) { return make_uniq(input.GetArguments()[0]->GetName()); } + +void AliasSerialize(Serializer &serializer, const optional_ptr data, const BoundScalarFunction &) { + serializer.WriteProperty(100, "alias", data->Cast().alias); +} + +unique_ptr AliasDeserialize(Deserializer &deserializer, BoundScalarFunction &) { + return make_uniq(deserializer.ReadProperty(100, "alias")); +} +unique_ptr AliasUnbind(FunctionUnbindInput &input) { + auto &expression = input.expression; + if (input.children.size() != 1 || (expression.GetAlias().empty() && !expression.BindInfo())) { + return nullptr; + } + auto value = Value(expression.GetAlias().empty() ? expression.BindInfo()->Cast().alias + : expression.GetAlias()); + auto call = make_uniq(expression.Function().GetDefinition()->GetQualifiedName(), + std::move(input.children)); + auto result = make_uniq(); + result->CaseChecksMutable().push_back( + {make_uniq(ExpressionType::OPERATOR_IS_NULL, std::move(call)), + ConstantExpression::FromValue(value)}); + result->ElseMutable() = ConstantExpression::FromValue(value); + return std::move(result); +} } // namespace static void AliasFunction(DataChunk &args, ExpressionState &state, Vector &result) { @@ -37,6 +67,9 @@ ScalarFunction AliasFun::GetFunction() { fun.GetSignature().AddParameter("expr", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.GetProperties().SetRequiresExpressionNames(true); + fun.SetSerializeCallback(AliasSerialize); + fun.SetDeserializeCallback(AliasDeserialize); + fun.SetUnbindCallback(AliasUnbind); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/generic/binning.cpp b/src/duckdb/extension/core_functions/scalar/generic/binning.cpp index 76a6c48ee..94d83f5d3 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/binning.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/binning.cpp @@ -496,7 +496,7 @@ unique_ptr EquiWidthBinDeserialize(Deserializer &deserializer, Bou static void AddEquiWidthBinFunction(ScalarFunctionSet &functions, const LogicalType &min_max_type, scalar_function_t function) { - ScalarFunction fun({}, LogicalType::LIST(LogicalType::ANY), function, BindEquiWidthFunction); + ScalarFunction fun({}, LogicalType::LIST(LogicalType::ANY), std::move(function), BindEquiWidthFunction); fun.GetSignature() .AddParameter("min", min_max_type) .AddParameter("max", min_max_type) diff --git a/src/duckdb/extension/core_functions/scalar/generic/cast_to_type.cpp b/src/duckdb/extension/core_functions/scalar/generic/cast_to_type.cpp index 5db338cc4..dae0f1d78 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/cast_to_type.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/cast_to_type.cpp @@ -18,7 +18,8 @@ unique_ptr BindCastToTypeFunction(FunctionBindExpressionInput &input if (return_type.id() == LogicalTypeId::SQLNULL) { throw InvalidInputException("cast_to_type cannot be used to cast to NULL"); } - return BoundCastExpression::AddCastToType(input.context, std::move(input.children[0]), return_type); + auto result = BoundCastExpression::AddCastToType(input.context, std::move(input.children[0]), return_type); + return Expression::PreserveReturnType(return_type, std::move(result)); } } // namespace diff --git a/src/duckdb/extension/core_functions/scalar/generic/least.cpp b/src/duckdb/extension/core_functions/scalar/generic/least.cpp index 109897987..11d5fe262 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/least.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/least.cpp @@ -223,8 +223,13 @@ unique_ptr PropagateLeastGreatestStats(ClientContext &context, F } auto result = NumericStats::CreateEmpty(return_type); - NumericStats::SetMin(result, IS_LEAST ? std::move(loose) : std::move(anchored)); - NumericStats::SetMax(result, IS_LEAST ? std::move(anchored) : std::move(loose)); + if constexpr (IS_LEAST) { + NumericStats::SetMin(result, std::move(loose)); + NumericStats::SetMax(result, std::move(anchored)); + } else { + NumericStats::SetMin(result, std::move(anchored)); + NumericStats::SetMax(result, std::move(loose)); + } result.Set(StatsInfo::CAN_HAVE_VALID_VALUES); if (!has_nonnull_input) { // the result is NULL only if all inputs are NULL diff --git a/src/duckdb/extension/core_functions/scalar/list/array_slice.cpp b/src/duckdb/extension/core_functions/scalar/list/array_slice.cpp index 51f965218..8367be8f5 100644 --- a/src/duckdb/extension/core_functions/scalar/list/array_slice.cpp +++ b/src/duckdb/extension/core_functions/scalar/list/array_slice.cpp @@ -1,3 +1,4 @@ +#include "duckdb/planner/expression/bound_constant_expression.hpp" #include "core_functions/scalar/list_functions.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/common/swap.hpp" @@ -6,13 +7,11 @@ #include "duckdb/function/scalar/string_functions.hpp" #include "duckdb/function/scalar/string_common.hpp" #include "duckdb/planner/expression/bound_function_expression.hpp" -#include "duckdb/planner/expression/bound_constant_expression.hpp" #include "duckdb/planner/expression/bound_cast_expression.hpp" +#include "duckdb/parser/expression/operator_expression.hpp" namespace duckdb { -namespace { - struct ListSliceBindData : public FunctionData { ListSliceBindData(const LogicalType &return_type_p, bool begin_is_empty_p, bool end_is_empty_p) : return_type(return_type_p), begin_is_empty(begin_is_empty_p), end_is_empty(end_is_empty_p) { @@ -36,6 +35,8 @@ unique_ptr ListSliceBindData::Copy() const { return make_uniq(return_type, begin_is_empty, end_is_empty); } +namespace { + template idx_t CalculateSliceLength(idx_t begin, idx_t end, INDEX_TYPE step, bool svalid) { if (step < 0) { @@ -419,6 +420,40 @@ unique_ptr ArraySlicePropagateStats(ClientContext &context, Func return PropagateStringSliceStats(input, start_character_index, character_count); } +unique_ptr ArraySliceUnbind(FunctionUnbindInput &input) { + if ((input.children.size() != 3 && input.children.size() != 4) || !input.expression.BindInfo()) { + return nullptr; + } + auto &data = input.expression.BindInfo()->Cast(); + for (idx_t i = 1; i < 3; i++) { + auto &child = *input.expression.GetChildren()[i]; + if (child.GetReturnType().id() != LogicalTypeId::LIST) { + continue; + } + if (child.GetExpressionClass() == ExpressionClass::BOUND_CONSTANT) { + auto &value = child.Cast().GetValue(); + if (!value.IsNull() && ListValue::GetChildren(value).empty()) { + continue; + } + } else if (child.GetExpressionClass() == ExpressionClass::BOUND_FUNCTION) { + auto &function = child.Cast(); + auto &definition = function.Function().GetDefinition(); + if (definition && definition->GetQualifiedName() == QualifiedName("system", "main", "list_value") && + function.GetChildren().empty()) { + continue; + } + } + return nullptr; + } + if (data.begin_is_empty) { + input.children[1] = OperatorExpression::EmptySliceBound(); + } + if (data.end_is_empty) { + input.children[2] = OperatorExpression::EmptySliceBound(); + } + return make_uniq(ExpressionType::ARRAY_SLICE, std::move(input.children)); +} + } // namespace ScalarFunctionSet ListSliceFun::GetFunctions() { // the arguments and return types are actually set in the binder function @@ -428,6 +463,7 @@ ScalarFunctionSet ListSliceFun::GetFunctions() { .AddParameter("begin", LogicalType::ANY) .AddParameter("end", LogicalType::ANY); fun.SetStatisticsCallback(ArraySlicePropagateStats); + fun.SetUnbindCallback(ArraySliceUnbind); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.SetFallible(); ScalarFunctionSet set; diff --git a/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp b/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp index f6a4315b8..17bf7fd03 100644 --- a/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp +++ b/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp @@ -437,6 +437,13 @@ unique_ptr ListAggregatesBindFunction(ClientContext &context, Boun child = make_uniq(ExpressionExecutor::EvaluateScalar(context, *child)); } + // Preserve folded SQL arguments without evaluating them again. + if (aggr_children.size() + 1 == bound_function.GetLogicalArguments().size()) { + for (idx_t child_idx = 1; child_idx < aggr_children.size(); child_idx++) { + arguments.push_back(aggr_children[child_idx]->Copy()); + } + } + return make_uniq(bound_function.GetReturnType(), std::move(bound_aggr_function)); } diff --git a/src/duckdb/extension/core_functions/scalar/list/list_sort.cpp b/src/duckdb/extension/core_functions/scalar/list/list_sort.cpp index 255717fe1..21d56892e 100644 --- a/src/duckdb/extension/core_functions/scalar/list/list_sort.cpp +++ b/src/duckdb/extension/core_functions/scalar/list/list_sort.cpp @@ -1,13 +1,21 @@ +#include "duckdb/common/type_visitor.hpp" +#include "duckdb/parser/expression/function_expression.hpp" +#include "duckdb/parser/expression/constant_expression.hpp" +#include "duckdb/planner/bound_expression_sql_exporter.hpp" +#include "duckdb/planner/expression/bound_constant_expression.hpp" #include "duckdb/common/vector/list_vector.hpp" #include "duckdb/main/client_context.hpp" #include "core_functions/scalar/list_functions.hpp" #include "duckdb/common/enum_util.hpp" #include "duckdb/common/numeric_utils.hpp" +#include "duckdb/common/serializer/deserializer.hpp" +#include "duckdb/common/serializer/serializer.hpp" #include "duckdb/planner/expression/bound_function_expression.hpp" #include "duckdb/planner/expression/bound_cast_expression.hpp" #include "duckdb/execution/expression_executor.hpp" #include "duckdb/planner/expression/bound_reference_expression.hpp" #include "duckdb/main/config.hpp" +#include "duckdb/main/settings.hpp" #include "duckdb/common/sorting/sort.hpp" #include "duckdb/planner/expression_binder.hpp" #include "duckdb/parallel/thread_context.hpp" @@ -16,7 +24,8 @@ namespace duckdb { struct ListSortBindData : public FunctionData { ListSortBindData(OrderType order_type_p, OrderByNullType null_order_p, bool is_grade_up, - const LogicalType &return_type_p, const LogicalType &child_type_p, ClientContext &context_p); + const LogicalType &return_type_p, const LogicalType &child_type_p, ClientContext &context_p, + unique_ptr sort_key_p = nullptr, optional default_collation_p = {}); ~ListSortBindData() override; OrderType order_type; @@ -28,18 +37,24 @@ struct ListSortBindData : public FunctionData { vector types; ClientContext &context; + unique_ptr sort_key; + optional default_collation; unique_ptr sort; public: bool Equals(const FunctionData &other_p) const override; unique_ptr Copy() const override; + static void Serialize(Serializer &serializer, const optional_ptr bind_data, + const BoundScalarFunction &); + static unique_ptr Deserialize(Deserializer &deserializer, BoundScalarFunction &); }; ListSortBindData::ListSortBindData(OrderType order_type_p, OrderByNullType null_order_p, bool is_grade_up_p, const LogicalType &return_type_p, const LogicalType &child_type_p, - ClientContext &context_p) + ClientContext &context_p, unique_ptr sort_key_p, + optional default_collation_p) : order_type(order_type_p), null_order(null_order_p), return_type(return_type_p), child_type(child_type_p), - is_grade_up(is_grade_up_p), context(context_p) { + is_grade_up(is_grade_up_p), context(context_p), default_collation(std::move(default_collation_p)) { // get the vector types types.emplace_back(LogicalType::USMALLINT); types.emplace_back(child_type); @@ -48,28 +63,60 @@ ListSortBindData::ListSortBindData(OrderType order_type_p, OrderByNullType null_ // get the BoundOrderByNode auto idx_col_expr = make_uniq_base(LogicalType::USMALLINT, 0U); - auto lists_col_expr = make_uniq_base(child_type, 1U); - // Normalize the sort key without changing the sorted values (#25108): push the - // type's collation (for INTERVAL this wraps the expression in - // normalized_interval(...), the same normalization comparison operators, ORDER BY - // and aggregates apply) onto the key expression BEFORE constructing its - // BoundOrderByNode. The key then byte-compares like ORDER BY, while the list - // payload keeps the original (non-normalized) values. - ExpressionBinder::PushCollation(context, lists_col_expr, child_type); + if (!sort_key_p) { + default_collation = Settings::Get(context); + sort_key_p = make_uniq_base(child_type, 1U); + // Normalize the sort key without changing the sorted values (#25108): push the + // type's collation (for INTERVAL this wraps the expression in + // normalized_interval(...), the same normalization comparison operators, ORDER BY + // and aggregates apply) onto the key expression BEFORE constructing its + // BoundOrderByNode. The key then byte-compares like ORDER BY, while the list + // payload keeps the original (non-normalized) values. + ExpressionBinder::PushCollation(context, sort_key_p, child_type); + } + sort_key = sort_key_p->Copy(); vector orders; orders.emplace_back(OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, std::move(idx_col_expr)); - orders.emplace_back(order_type, null_order, std::move(lists_col_expr)); + orders.emplace_back(order_type, null_order, std::move(sort_key_p)); sort = unique_ptr(new Sort(context, orders, {LogicalType::USMALLINT, child_type, LogicalType::UINTEGER}, {2})); } unique_ptr ListSortBindData::Copy() const { - return make_uniq(order_type, null_order, is_grade_up, return_type, child_type, context); + return make_uniq(order_type, null_order, is_grade_up, return_type, child_type, context, + sort_key->Copy(), default_collation); } bool ListSortBindData::Equals(const FunctionData &other_p) const { auto &other = other_p.Cast(); - return order_type == other.order_type && null_order == other.null_order && is_grade_up == other.is_grade_up; + return order_type == other.order_type && null_order == other.null_order && return_type == other.return_type && + child_type == other.child_type && is_grade_up == other.is_grade_up && + Expression::Equals(sort_key, other.sort_key) && default_collation == other.default_collation; +} + +void ListSortBindData::Serialize(Serializer &serializer, const optional_ptr bind_data, + const BoundScalarFunction &) { + auto &data = bind_data->Cast(); + serializer.WriteProperty(100, "order_type", data.order_type); + serializer.WriteProperty(101, "null_order", data.null_order); + serializer.WriteProperty(102, "return_type", data.return_type); + serializer.WriteProperty(103, "child_type", data.child_type); + serializer.WriteProperty(104, "is_grade_up", data.is_grade_up); + serializer.WriteProperty(105, "sort_key", data.sort_key); + serializer.WritePropertyWithDefault(106, "default_collation", data.default_collation); +} + +unique_ptr ListSortBindData::Deserialize(Deserializer &deserializer, BoundScalarFunction &) { + auto order_type = deserializer.ReadProperty(100, "order_type"); + auto null_order = deserializer.ReadProperty(101, "null_order"); + auto return_type = deserializer.ReadProperty(102, "return_type"); + auto child_type = deserializer.ReadProperty(103, "child_type"); + auto is_grade_up = deserializer.ReadProperty(104, "is_grade_up"); + auto sort_key = deserializer.ReadProperty>(105, "sort_key"); + auto default_collation = deserializer.ReadPropertyWithDefault>(106, "default_collation"); + auto &context = deserializer.Get(); + return make_uniq(order_type, null_order, is_grade_up, return_type, child_type, context, + std::move(sort_key), std::move(default_collation)); } ListSortBindData::~ListSortBindData() { @@ -360,6 +407,51 @@ static unique_ptr ListReverseSortBind(BindScalarFunctionInput &inp return ListSortBind(context, bound_function, arguments, order, null_order); } +static unique_ptr ListSortUnbind(FunctionUnbindInput &input) { + if (input.children.empty() || !input.expression.BindInfo()) { + return nullptr; + } + auto &data = input.expression.BindInfo()->Cast(); + if (!data.default_collation || + TypeVisitor::Contains(data.child_type, [](const LogicalType &type) { return type.HasAlias(); })) { + return nullptr; + } + auto type = TypeVisitor::VisitReplace(data.child_type, [&](const LogicalType &child) { + if (child.id() == LogicalTypeId::VARCHAR && StringType::GetCollation(child).empty()) { + return LogicalType::VARCHAR_COLLATION(data.default_collation->empty() ? "binary" : *data.default_collation); + } + return child; + }); + auto witness = BoundExpressionSQLExporter::Export(BoundConstantExpression(Value(LogicalType::LIST(type))), {}); + if (witness.HasError()) { + return nullptr; + } + vector> cast_children; + cast_children.push_back(std::move(input.children[0])); + cast_children.push_back(std::move(witness.GetValue())); + vector> children; + children.push_back( + make_uniq(QualifiedName("system", "main", "cast_to_type"), std::move(cast_children))); + children.push_back(ConstantExpression::String(data.order_type == OrderType::ASCENDING ? "ASC" : "DESC")); + children.push_back( + ConstantExpression::String(data.null_order == OrderByNullType::NULLS_FIRST ? "NULLS FIRST" : "NULLS LAST")); + auto result_type = BoundExpressionSQLExporter::Export(BoundConstantExpression(Value(data.return_type)), {}); + if (result_type.HasError()) { + return nullptr; + } + vector> result; + result.push_back(make_uniq( + QualifiedName("system", "main", data.is_grade_up ? "list_grade_up" : "list_sort"), std::move(children))); + result.push_back(std::move(result_type.GetValue())); + return make_uniq(QualifiedName("system", "main", "cast_to_type"), std::move(result)); +} + +static void SetListSortSerialization(ScalarFunction &function) { + function.SetUnbindCallback(ListSortUnbind); + function.SetSerializeCallback(ListSortBindData::Serialize); + function.SetDeserializeCallback(ListSortBindData::Deserialize); +} + ScalarFunctionSet ListSortFun::GetFunctions() { // one parameter: list ScalarFunction sort({}, LogicalType::LIST(LogicalType::ANY), ListSortFunction, ListNormalSortBind); @@ -377,6 +469,9 @@ ScalarFunctionSet ListSortFun::GetFunctions() { .AddParameter("list", LogicalType::LIST(LogicalType::ANY)) .AddParameter("sort_order", LogicalType::VARCHAR) .AddParameter("null_order", LogicalType::VARCHAR); + SetListSortSerialization(sort); + SetListSortSerialization(sort_order); + SetListSortSerialization(sort_orders); ScalarFunctionSet list_sort; list_sort.AddFunction(sort); @@ -402,6 +497,9 @@ ScalarFunctionSet ListGradeUpFun::GetFunctions() { .AddParameter("list", LogicalType::LIST(LogicalType::ANY)) .AddParameter("sort_order", LogicalType::VARCHAR) .AddParameter("null_order", LogicalType::VARCHAR); + SetListSortSerialization(sort); + SetListSortSerialization(sort_order); + SetListSortSerialization(sort_orders); ScalarFunctionSet list_grade_up; list_grade_up.AddFunction(sort); @@ -421,6 +519,8 @@ ScalarFunctionSet ListReverseSortFun::GetFunctions() { sort_reverse_null_order.GetSignature() .AddParameter("list", LogicalType::LIST(LogicalType::ANY)) .AddParameter("null_order", LogicalType::VARCHAR); + SetListSortSerialization(sort_reverse); + SetListSortSerialization(sort_reverse_null_order); ScalarFunctionSet list_reverse_sort; list_reverse_sort.AddFunction(sort_reverse); diff --git a/src/duckdb/extension/core_functions/scalar/list/list_value.cpp b/src/duckdb/extension/core_functions/scalar/list/list_value.cpp index 7a4211fea..6040b8bec 100644 --- a/src/duckdb/extension/core_functions/scalar/list/list_value.cpp +++ b/src/duckdb/extension/core_functions/scalar/list/list_value.cpp @@ -316,6 +316,7 @@ ScalarFunctionSet ListValueFun::GetFunctions() { auto element_type = LogicalType::TEMPLATE("T"); ScalarFunction value_fun({element_type}, LogicalType::LIST(element_type), ListValueFunction, ListValueBind, ListValueStats); + value_fun.GetSignature().GetParameter(0).SetName("value"); value_fun.SetVarArgs(element_type); value_fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); set.AddFunction(value_fun); diff --git a/src/duckdb/extension/core_functions/scalar/string/to_base.cpp b/src/duckdb/extension/core_functions/scalar/string/to_base.cpp index e75a3bfbb..2c76139a4 100644 --- a/src/duckdb/extension/core_functions/scalar/string/to_base.cpp +++ b/src/duckdb/extension/core_functions/scalar/string/to_base.cpp @@ -1,22 +1,10 @@ #include "core_functions/scalar/string_functions.hpp" #include "duckdb/common/vector_operations/vector_operations.hpp" -#include "duckdb/planner/expression/bound_constant_expression.hpp" namespace duckdb { static const char alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static unique_ptr ToBaseBind(BindScalarFunctionInput &input) { - auto &arguments = input.GetArguments(); - // If no min_length is specified, default to 0 - D_ASSERT(arguments.size() == 2 || arguments.size() == 3); - if (arguments.size() == 2) { - arguments.push_back(make_uniq_base(Value::INTEGER(0))); - input.GetBoundFunction().GetArguments().push_back(LogicalType::INTEGER); - } - return nullptr; -} - static void ToBaseFunction(DataChunk &args, ExpressionState &state, Vector &result) { const auto &input = args.data[0]; const auto &radix = args.data[1]; @@ -56,16 +44,13 @@ static void ToBaseFunction(DataChunk &args, ExpressionState &state, Vector &resu ScalarFunctionSet ToBaseFun::GetFunctions() { ScalarFunctionSet set("to_base"); - ScalarFunction to_base({}, LogicalType::VARCHAR, ToBaseFunction, ToBaseBind); - to_base.GetSignature().AddParameter("number", LogicalType::BIGINT).AddParameter("radix", LogicalType::INTEGER); - set.AddFunction(to_base); - - ScalarFunction to_base_padded({}, LogicalType::VARCHAR, ToBaseFunction, ToBaseBind); - to_base_padded.GetSignature() + auto function = ScalarFunction({}, LogicalType::VARCHAR, ToBaseFunction); + function.GetSignature() .AddParameter("number", LogicalType::BIGINT) .AddParameter("radix", LogicalType::INTEGER) .AddParameter("min_length", LogicalType::INTEGER); - set.AddFunction(to_base_padded); + function.GetSignature().GetParameter(2).SetDefaultValue(Value::INTEGER(0)); + set.AddFunction(std::move(function)); // throws if the number, radix or min_length are out of range set.SetFallible(); diff --git a/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp b/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp index f09874b19..e1fa99a61 100644 --- a/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp +++ b/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp @@ -7,6 +7,7 @@ #include "duckdb/common/case_insensitive_map.hpp" #include "duckdb/storage/statistics/struct_stats.hpp" #include "duckdb/planner/expression_binder.hpp" +#include "duckdb/parser/expression/function_expression.hpp" namespace duckdb { @@ -89,6 +90,27 @@ static unique_ptr StructInsertStats(ClientContext &context, Func return new_stats.ToUnique(); } +static unique_ptr StructInsertUnbind(FunctionUnbindInput &input) { + auto &function = input.expression.Function(); + auto &types = function.GetLogicalArguments(); + auto &return_type = function.GetLogicalReturnType(); + if (types.empty() || types[0].id() != LogicalTypeId::STRUCT || return_type.id() != LogicalTypeId::STRUCT || + input.children.size() != types.size()) { + return nullptr; + } + auto existing_count = StructType::GetChildCount(types[0]); + auto &return_children = StructType::GetChildTypes(return_type); + if (return_children.size() != existing_count + types.size() - 1) { + return nullptr; + } + vector arguments; + arguments.emplace_back(std::move(input.children[0])); + for (idx_t i = 1; i < input.children.size(); i++) { + arguments.emplace_back(return_children[existing_count + i - 1].first, std::move(input.children[i])); + } + return make_uniq(function.GetDefinition()->GetQualifiedName(), std::move(arguments)); +} + ScalarFunction StructInsertFun::GetFunction() { ScalarFunction fun({}, LogicalTypeId::STRUCT, StructInsertFunction, StructInsertBind, StructInsertStats); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); @@ -96,6 +118,7 @@ ScalarFunction StructInsertFun::GetFunction() { fun.GetProperties().SetRequiresExpressionNames(true); fun.SetSerializeCallback(VariableReturnBindData::Serialize); fun.SetDeserializeCallback(VariableReturnBindData::Deserialize); + fun.SetUnbindCallback(StructInsertUnbind); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/union/union_extract.cpp b/src/duckdb/extension/core_functions/scalar/union/union_extract.cpp index ff578b38e..f26c7d31e 100644 --- a/src/duckdb/extension/core_functions/scalar/union/union_extract.cpp +++ b/src/duckdb/extension/core_functions/scalar/union/union_extract.cpp @@ -10,8 +10,8 @@ namespace duckdb { namespace { struct UnionExtractBindData : public FunctionData { - UnionExtractBindData(Identifier key, idx_t index, LogicalType type) - : key(std::move(key)), index(index), type(std::move(type)) { + UnionExtractBindData(const Identifier &key, idx_t index, LogicalType type) + : key(key), index(index), type(std::move(type)) { } string key; diff --git a/src/duckdb/extension/icu/icu-dateadd.cpp b/src/duckdb/extension/icu/icu-dateadd.cpp index 370ca6125..f45a38136 100644 --- a/src/duckdb/extension/icu/icu-dateadd.cpp +++ b/src/duckdb/extension/icu/icu-dateadd.cpp @@ -263,10 +263,16 @@ struct ICUDateAdd : public ICUDateFunc { static void AddDateAddOperators(const Identifier &name, ExtensionLoader &loader) { // temporal + interval ScalarFunctionSet set {name}; - set.AddFunction(GetDateAddFunction(LogicalType::TIMESTAMP_TZ, - LogicalType::INTERVAL)); - set.AddFunction(GetDateAddFunction(LogicalType::INTERVAL, - LogicalType::TIMESTAMP_TZ)); + auto tstz_interval_fun = GetDateAddFunction( + LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL); + tstz_interval_fun.GetSignature().GetParameter(0).SetName("left"); + tstz_interval_fun.GetSignature().GetParameter(1).SetName("right"); + set.AddFunction(tstz_interval_fun); + auto interval_tstz_fun = GetDateAddFunction( + LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ); + interval_tstz_fun.GetSignature().GetParameter(0).SetName("left"); + interval_tstz_fun.GetSignature().GetParameter(1).SetName("right"); + set.AddFunction(interval_tstz_fun); // throws for dates that overflow the timestamp range set.SetFallible(); loader.RegisterFunction(set); @@ -285,12 +291,18 @@ struct ICUDateAdd : public ICUDateFunc { static void AddDateSubOperators(const Identifier &name, ExtensionLoader &loader) { // temporal - interval ScalarFunctionSet set {name}; - set.AddFunction(GetDateAddFunction(LogicalType::TIMESTAMP_TZ, - LogicalType::INTERVAL)); + auto tstz_interval_fun = GetDateAddFunction( + LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL); + tstz_interval_fun.GetSignature().GetParameter(0).SetName("left"); + tstz_interval_fun.GetSignature().GetParameter(1).SetName("right"); + set.AddFunction(tstz_interval_fun); // temporal - temporal - set.AddFunction(GetBinaryAgeFunction( - LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ)); + auto tstz_tstz_fun = GetBinaryAgeFunction( + LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ); + tstz_tstz_fun.GetSignature().GetParameter(0).SetName("left"); + tstz_tstz_fun.GetSignature().GetParameter(1).SetName("right"); + set.AddFunction(tstz_tstz_fun); // throws for dates that overflow the timestamp range set.SetFallible(); loader.RegisterFunction(set); diff --git a/src/duckdb/extension/json/json_functions/json_create.cpp b/src/duckdb/extension/json/json_functions/json_create.cpp index fc9b4cc10..de016cf6d 100644 --- a/src/duckdb/extension/json/json_functions/json_create.cpp +++ b/src/duckdb/extension/json/json_functions/json_create.cpp @@ -31,12 +31,6 @@ struct StructNames { values[name] = make_uniq(Value(name), count_t(0ULL)); } - Vector &Get(const string &name, idx_t count) const { - auto &result = *values.at(name); - FlatVector::SetSize(result, count); - return result; - } - StructNames Copy() const { StructNames result; // Have to do this because we can't implicitly copy Vector @@ -626,7 +620,8 @@ static void CreateValuesStruct(const StructNames &names, yyjson_mut_doc *doc, yy // Add the key/value pairs to the values auto &entries = StructVector::GetEntries(value_v); for (idx_t entry_i = 0; entry_i < entries.size(); entry_i++) { - auto &struct_key_v = names.Get(StructType::GetChildName(value_v.GetType(), entry_i).GetIdentifierName(), count); + Vector struct_key_v(Value(StructType::GetChildName(value_v.GetType(), entry_i).GetIdentifierName()), + count_t(count)); auto &struct_val_v = entries[entry_i]; CreateKeyValuePairs(names, doc, vals, nested_vals, struct_key_v, struct_val_v, count, options); } @@ -733,8 +728,8 @@ static void CreateValuesUnion(const StructNames &names, yyjson_mut_doc *doc, yyj // Add the key/value pairs to the values for (idx_t member_idx = 0; member_idx < UnionType::GetMemberCount(value_v.GetType()); member_idx++) { auto &member_val_v = UnionVector::GetMember(value_v, member_idx); - auto &member_key_v = - names.Get(UnionType::GetMemberName(value_v.GetType(), member_idx).GetIdentifierName(), count); + Vector member_key_v(Value(UnionType::GetMemberName(value_v.GetType(), member_idx).GetIdentifierName()), + count_t(count)); // This implementation is not optimal since we convert the entire member vector, // and then skip the rows not matching the tag afterwards. @@ -1277,7 +1272,7 @@ static void JSONCopyToGeoJSONFunction(DataChunk &args, ExpressionState &state, V } for (const auto property_index : info.property_indices) { - auto &key_v = names.Get(StructType::GetChildName(payload_type, property_index).GetIdentifierName(), count); + Vector key_v(Value(StructType::GetChildName(payload_type, property_index).GetIdentifierName()), count_t(count)); CreateKeyValuePairs(names, doc, properties, nested_vals, key_v, entries[property_index], count, options); } for (idx_t i = 0; i < count; i++) { @@ -1508,6 +1503,9 @@ ScalarFunction JSONFunctions::GetJSONCopyToJSONFunction() { ScalarFunction fun(JSON_COPY_TO_JSON_INTERNAL_NAME, {LogicalType::ANY, LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::JSON(), JSONCopyToJSONFunction, JSONCopyToJSONBind, nullptr, JSONFunctionLocalState::Init); + fun.GetSignature().GetParameter(0).SetName("value"); + fun.GetSignature().GetParameter(1).SetName("date_format"); + fun.GetSignature().GetParameter(2).SetName("timestamp_format"); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.SetSerializeCallback(JSONCopyToJSONSerialize); fun.SetDeserializeCallback(JSONCopyToJSONDeserialize); @@ -1520,6 +1518,12 @@ ScalarFunction JSONFunctions::GetJSONCopyToGeoJSONFunction() { LogicalType::VARCHAR, LogicalType::BOOLEAN}, LogicalType::JSON(), JSONCopyToGeoJSONFunction, JSONCopyToGeoJSONBind, nullptr, JSONFunctionLocalState::Init); + fun.GetSignature().GetParameter(0).SetName("value"); + fun.GetSignature().GetParameter(1).SetName("date_format"); + fun.GetSignature().GetParameter(2).SetName("timestamp_format"); + fun.GetSignature().GetParameter(3).SetName("geometry_column"); + fun.GetSignature().GetParameter(4).SetName("id_column"); + fun.GetSignature().GetParameter(5).SetName("write_bbox"); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return fun; } diff --git a/src/duckdb/extension/json/json_functions/read_single_json_file.cpp b/src/duckdb/extension/json/json_functions/read_single_json_file.cpp index dcedcbf5a..558cd8069 100644 --- a/src/duckdb/extension/json/json_functions/read_single_json_file.cpp +++ b/src/duckdb/extension/json/json_functions/read_single_json_file.cpp @@ -272,6 +272,9 @@ static unique_ptr ReadSingleJSONFileCombineSchema(ClientContext &c } // the date/timestamp formats that were settled on while detecting the structure are carried over result->date_format_map = make_uniq(*first_file->date_format_map); + // the merged structure describes the schema of the scan by itself + return_types.clear(); + names.clear(); JSONScan::StructureToColumns(context, result->options, merged, result->feature_columns, return_types, names); // the JSON reader looks columns up by their exact key, so the keys are kept before the column names that are @@ -327,7 +330,8 @@ TableFunction JSONFunctions::GetJSONTableFunction(Identifier name, shared_ptr 0); + column_schema.max_define--; + for (auto &child : child_writers) { + child->DecrementMaxDefineRecursive(); + } +} + bool ColumnWriter::TryExportPreparedShreddingType(ShreddingType &result) const { bool has_shredding = false; auto writer_shredding_type = ShreddingType(Type()); diff --git a/src/duckdb/extension/parquet/decoder/delta_length_byte_array_decoder.cpp b/src/duckdb/extension/parquet/decoder/delta_length_byte_array_decoder.cpp index 6ded4d5f4..e4992abdb 100644 --- a/src/duckdb/extension/parquet/decoder/delta_length_byte_array_decoder.cpp +++ b/src/duckdb/extension/parquet/decoder/delta_length_byte_array_decoder.cpp @@ -41,27 +41,29 @@ void DeltaLengthByteArrayDecoder::InitializePage() { length_idx = 0; } +bool IsContinuationByte(uint8_t b) { + return (b & 0xC0) == 0x80; +} + +bool TouchesUtf8Boundary(const char *data, uint32_t len) { + if (len == 0) { + return false; + } + const uint8_t first = static_cast(data[0]); + const uint8_t last = static_cast(data[len - 1]); + return IsContinuationByte(first) || (last & 0x80) != 0; +} + void DeltaLengthByteArrayDecoder::Read(shared_ptr &block_ref, uint8_t *defines, idx_t read_count, Vector &result, idx_t result_offset) { - bool validate_individually = - reader.Type().IsJSONType() || reader.Cast().reader.parquet_options.utf8_validation_option != - StringColumnReader::Utf8ValidationOption::STRICT_UTF8; if (defines) { - if (validate_individually) { - ReadInternal(block_ref, defines, read_count, result, result_offset); - } else { - ReadInternal(block_ref, defines, read_count, result, result_offset); - } + ReadInternal(block_ref, defines, read_count, result, result_offset); } else { - if (validate_individually) { - ReadInternal(block_ref, defines, read_count, result, result_offset); - } else { - ReadInternal(block_ref, defines, read_count, result, result_offset); - } + ReadInternal(block_ref, defines, read_count, result, result_offset); } } -template +template void DeltaLengthByteArrayDecoder::ReadInternal(shared_ptr &block_ref, uint8_t *const defines, const idx_t read_count, Vector &result, const idx_t result_offset) { auto &block = *block_ref; @@ -80,8 +82,15 @@ void DeltaLengthByteArrayDecoder::ReadInternal(shared_ptr &blo const auto &string_column_reader = reader.Cast(); string_column_reader.SetCurrentResult(result); + // JSON and non-strict modes require individual validation: bytes are rewritten and the fast path discards its + // return value so it can't sanitize + const bool needs_full_individual_validation = + reader.Type().IsJSONType() || reader.Cast().reader.parquet_options.utf8_validation_option != + StringColumnReader::Utf8ValidationOption::STRICT_UTF8; + const auto start_ptr = block.ptr; auto result_data = FlatVector::Writer(result, read_count, result_offset); + for (idx_t row_idx = 0; row_idx < read_count; row_idx++) { const auto result_idx = result_offset + row_idx; if (HAS_DEFINES) { @@ -97,19 +106,22 @@ void DeltaLengthByteArrayDecoder::ReadInternal(shared_ptr &blo } } const auto &str_len = length_data[length_idx++]; - if (VALIDATE_INDIVIDUAL_STRINGS) { + + if (needs_full_individual_validation) { auto verified = string_column_reader.VerifyString(char_ptr_cast(block.ptr), str_len); result_data.WriteValue(verified); } else { + if (TouchesUtf8Boundary(char_ptr_cast(block.ptr), str_len)) { + string_column_reader.VerifyString(char_ptr_cast(block.ptr), str_len); + } result_data.WriteValue(string_t(char_ptr_cast(block.ptr), str_len)); } block.unsafe_inc(str_len); } - if (!VALIDATE_INDIVIDUAL_STRINGS) { + if (!needs_full_individual_validation) { string_column_reader.VerifyString(char_ptr_cast(start_ptr), NumericCast(block.ptr - start_ptr)); } - StringColumnReader::ReferenceBlock(result, block_ref); } diff --git a/src/duckdb/extension/parquet/include/column_writer.hpp b/src/duckdb/extension/parquet/include/column_writer.hpp index 00309aaea..612567f53 100644 --- a/src/duckdb/extension/parquet/include/column_writer.hpp +++ b/src/duckdb/extension/parquet/include/column_writer.hpp @@ -163,6 +163,9 @@ class ColumnWriter { return child_writers; } + //! Mark this writer (and descendants) as REQUIRED in the Parquet schema + void MarkRepetitionRequired(); + virtual void AnalyzeSchema(ParquetAnalyzeSchemaState &state, Vector &input, idx_t count) { throw NotImplementedException("Writer doesn't require an AnalyzeSchema pass"); } @@ -228,6 +231,8 @@ class ColumnWriter { void CompressPage(MemoryStream &temp_writer, size_t &compressed_size, data_ptr_t &compressed_data, AllocatedData &compressed_buf); + void DecrementMaxDefineRecursive(); + public: ParquetWriter &writer; //! The parent writer (if this is a nested field) diff --git a/src/duckdb/extension/parquet/include/decoder/delta_length_byte_array_decoder.hpp b/src/duckdb/extension/parquet/include/decoder/delta_length_byte_array_decoder.hpp index fdc379053..d3d64def2 100644 --- a/src/duckdb/extension/parquet/include/decoder/delta_length_byte_array_decoder.hpp +++ b/src/duckdb/extension/parquet/include/decoder/delta_length_byte_array_decoder.hpp @@ -33,7 +33,7 @@ class DeltaLengthByteArrayDecoder { void Skip(uint8_t *defines, idx_t skip_count); private: - template + template void ReadInternal(shared_ptr &block, uint8_t *defines, idx_t read_count, Vector &result, idx_t result_offset); template diff --git a/src/duckdb/extension/parquet/include/parquet_reader.hpp b/src/duckdb/extension/parquet/include/parquet_reader.hpp index 1cb449813..20dcf1a1c 100644 --- a/src/duckdb/extension/parquet/include/parquet_reader.hpp +++ b/src/duckdb/extension/parquet/include/parquet_reader.hpp @@ -282,7 +282,7 @@ struct ParquetOptions { vector schema; idx_t explicit_cardinality = 0; - bool can_have_nan = false; // if floats or doubles can contain NaN values + bool can_have_nan = false; // if floats or doubles can contain NaN values (ignored if nan_count is present) ParquetPrefetchStrategyOption prefetch_strategy = ParquetPrefetchStrategyOption::AUTO; StringColumnReader::Utf8ValidationOption utf8_validation_option = StringColumnReader::Utf8ValidationOption::STRICT_UTF8; @@ -352,7 +352,7 @@ class ParquetReader : public BaseFileReader { shared_ptr encryption_util; bool can_use_metadata_statistics = false; //! How many rows have been read from this file - atomic rows_read; + atomic rows_read {0}; ParquetIntervalBloomFilterVersion interval_bloom_filter_version {}; //! Storage indices of columns where expressions like strlen/octet_length are pushed down unordered_map projection_expressions; diff --git a/src/duckdb/extension/parquet/include/parquet_statistics.hpp b/src/duckdb/extension/parquet/include/parquet_statistics.hpp index 993a0447f..d5ab0f5c8 100644 --- a/src/duckdb/extension/parquet/include/parquet_statistics.hpp +++ b/src/duckdb/extension/parquet/include/parquet_statistics.hpp @@ -64,6 +64,9 @@ struct ParquetStatisticsUtils { const duckdb_parquet::Statistics &parquet_stats, bool can_have_nan, optional_ptr column_chunk = nullptr); + //! Whether the column can contain NaN values - uses nan_count if present, otherwise the can_have_nan option + static bool CanHaveNaN(const duckdb_parquet::Statistics &parquet_stats, bool can_have_nan); + static Value ConvertValue(const LogicalType &type, const ParquetColumnSchema &schema_ele, const std::string &stats); static ParquetIntervalBloomFilterVersion diff --git a/src/duckdb/extension/parquet/include/thrift_tools.hpp b/src/duckdb/extension/parquet/include/thrift_tools.hpp index 942aee22f..5b2e0aa8c 100644 --- a/src/duckdb/extension/parquet/include/thrift_tools.hpp +++ b/src/duckdb/extension/parquet/include/thrift_tools.hpp @@ -148,7 +148,9 @@ struct ReadAheadBuffer { // Prefetch all read heads void Prefetch() { for (auto &read_head : read_heads) { - read_head->Fetch(file_handle); + if (!read_head->data_isset) { + read_head->Fetch(file_handle); + } } } }; diff --git a/src/duckdb/extension/parquet/include/writer/parquet_write_operators.hpp b/src/duckdb/extension/parquet/include/writer/parquet_write_operators.hpp index fe6e196dd..73fee68ba 100644 --- a/src/duckdb/extension/parquet/include/writer/parquet_write_operators.hpp +++ b/src/duckdb/extension/parquet/include/writer/parquet_write_operators.hpp @@ -96,14 +96,14 @@ struct FloatingPointOperator : public BaseParquetOperator { static void HandleStats(ColumnWriterStatistics *stats, TGT target_value) { auto &numeric_stats = stats->Cast>(); if (Value::IsNan(target_value)) { - numeric_stats.has_nan = true; - } else { - if (LessThan::Operation(target_value, numeric_stats.min)) { - numeric_stats.min = target_value; - } - if (GreaterThan::Operation(target_value, numeric_stats.max)) { - numeric_stats.max = target_value; - } + numeric_stats.nan_count++; + return; + } + if (LessThan::Operation(target_value, numeric_stats.min)) { + numeric_stats.min = target_value; + } + if (GreaterThan::Operation(target_value, numeric_stats.max)) { + numeric_stats.max = target_value; } } }; diff --git a/src/duckdb/extension/parquet/include/writer/parquet_write_stats.hpp b/src/duckdb/extension/parquet/include/writer/parquet_write_stats.hpp index dc42ce211..5df142dbf 100644 --- a/src/duckdb/extension/parquet/include/writer/parquet_write_stats.hpp +++ b/src/duckdb/extension/parquet/include/writer/parquet_write_stats.hpp @@ -24,6 +24,7 @@ class ColumnWriterStatistics { virtual string GetMaxValue(); virtual bool CanHaveNaN(); virtual bool HasNaN(); + virtual idx_t GetNaNCount(); virtual bool MinIsExact(); virtual bool MaxIsExact(); @@ -75,14 +76,17 @@ class NumericStatisticsState : public ColumnWriterStatistics { template class FloatingPointStatisticsState : public NumericStatisticsState { public: - bool has_nan = false; + idx_t nan_count = 0; public: bool CanHaveNaN() override { return true; } bool HasNaN() override { - return has_nan; + return nan_count != 0; + } + idx_t GetNaNCount() override { + return nan_count; } }; diff --git a/src/duckdb/extension/parquet/include/writer/templated_column_writer.hpp b/src/duckdb/extension/parquet/include/writer/templated_column_writer.hpp index 45094d880..656b89a25 100644 --- a/src/duckdb/extension/parquet/include/writer/templated_column_writer.hpp +++ b/src/duckdb/extension/parquet/include/writer/templated_column_writer.hpp @@ -124,6 +124,10 @@ class StandardColumnWriter : public PrimitiveColumnWriter { } ~StandardColumnWriter() override = default; + //! Dictionary encoding normally updates the statistics once per distinct dictionary value. + //! Floating point statistics include nan_count, which counts every NaN value written, so they are updated per row. + static constexpr bool STATS_PER_OCCURRENCE = std::is_same::value; + public: unique_ptr InitializeWriteState(duckdb_parquet::RowGroup &row_group) override { auto result = make_uniq>(writer, row_group, row_group.columns.size()); @@ -302,8 +306,10 @@ class StandardColumnWriter : public PrimitiveColumnWriter { } state.dictionary.IterateValues([&](const SRC &src_value, const TGT &tgt_value) { - // update the statistics - OP::template HandleStats(stats, tgt_value); + if (!STATS_PER_OCCURRENCE) { + // update the statistics + OP::template HandleStats(stats, tgt_value); + } if (state.bloom_filter) { // update the bloom filter auto hash = OP::template XXHash64(tgt_value); @@ -366,6 +372,9 @@ class StandardColumnWriter : public PrimitiveColumnWriter { continue; } const auto &src_value = data_ptr[r]; + if (STATS_PER_OCCURRENCE) { + OP::template HandleStats(stats, OP::template Operation(src_value)); + } const auto value_index = page_state.dictionary.GetIndex(src_value); page_state.dict_encoder.WriteValue(temp_writer, value_index); } diff --git a/src/duckdb/extension/parquet/include/writer/variant_column_writer.hpp b/src/duckdb/extension/parquet/include/writer/variant_column_writer.hpp index 16d66bc7e..e8235e82d 100644 --- a/src/duckdb/extension/parquet/include/writer/variant_column_writer.hpp +++ b/src/duckdb/extension/parquet/include/writer/variant_column_writer.hpp @@ -108,6 +108,9 @@ class VariantColumnWriter : public StructColumnWriter { public: static ScalarFunction GetTransformFunction(); + //! 'variant_bytes_to_variant': decode a binary Variant value (metadata followed by value) + //! into a VARIANT. The inverse of 'variant_to_parquet_variant'. + static ScalarFunction GetBytesToVariantFunction(); static LogicalType TransformTypedValueRecursive(const LogicalType &type); private: diff --git a/src/duckdb/extension/parquet/parquet_extension.cpp b/src/duckdb/extension/parquet/parquet_extension.cpp index 410fcdcf7..fcaa8010d 100644 --- a/src/duckdb/extension/parquet/parquet_extension.cpp +++ b/src/duckdb/extension/parquet/parquet_extension.cpp @@ -78,7 +78,7 @@ #include "duckdb/storage/storage_info.hpp" #include "parquet_field_id.hpp" #include "parquet_types.h" -#include "reader/variant/parquet_variant_iterator.hpp" +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" namespace duckdb { class ClientContext; @@ -878,7 +878,7 @@ static void ParquetWriteFlushBatch(ClientContext &context, FunctionData &bind_da //===--------------------------------------------------------------------===// // Desired Batch Size //===--------------------------------------------------------------------===// -static idx_t ParquetWriteDesiredBatchSize(ClientContext &context, FunctionData &bind_data_p) { +static optional_idx ParquetWriteDesiredBatchSize(ClientContext &context, FunctionData &bind_data_p) { auto &bind_data = bind_data_p.Cast(); return bind_data.row_group_size; } @@ -1040,7 +1040,7 @@ static void LoadInternal(ExtensionLoader &loader) { loader.RegisterFunction(VariantColumnWriter::GetTransformFunction()); // bytes_to_variant - loader.RegisterFunction(ParquetVariantConversion::GetBytesToVariantFunction()); + loader.RegisterFunction(VariantColumnWriter::GetBytesToVariantFunction()); CopyFunction function("parquet"); function.copy_to_select = ParquetWriteSelect; @@ -1115,11 +1115,9 @@ std::string ParquetExtension::Version() const { } // namespace duckdb -#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION extern "C" { DUCKDB_CPP_EXTENSION_ENTRY(parquet, loader) { // NOLINT duckdb::LoadInternal(loader); } } -#endif diff --git a/src/duckdb/extension/parquet/parquet_file_metadata_cache.cpp b/src/duckdb/extension/parquet/parquet_file_metadata_cache.cpp index ce6548e58..83b44764b 100644 --- a/src/duckdb/extension/parquet/parquet_file_metadata_cache.cpp +++ b/src/duckdb/extension/parquet/parquet_file_metadata_cache.cpp @@ -104,17 +104,13 @@ ParquetCacheValidity ParquetFileMetadataCache::IsValid(const OpenFileInfo &info, return ParquetCacheValidity::UNKNOWN; } - const auto &open_options = info.extended_info->options; - const auto lm_entry = open_options.find("last_modified"); - if (lm_entry == open_options.end()) { + const auto &extended_info = *info.extended_info; + timestamp_t new_last_modified; + if (!extended_info.TryGetOption("last_modified", new_last_modified)) { return ParquetCacheValidity::UNKNOWN; } - auto new_last_modified = lm_entry->second.GetValue(); string new_etag; - const auto etag_entry = open_options.find("etag"); - if (etag_entry != open_options.end()) { - new_etag = StringValue::Get(etag_entry->second); - } + extended_info.TryGetOption("etag", new_etag); if (ExternalFileCache::IsValid(/*validate=*/true, version_tag, last_modified, new_etag, new_last_modified)) { return ParquetCacheValidity::VALID; diff --git a/src/duckdb/extension/parquet/parquet_metadata.cpp b/src/duckdb/extension/parquet/parquet_metadata.cpp index 7c0dcb4c9..85cef8c52 100644 --- a/src/duckdb/extension/parquet/parquet_metadata.cpp +++ b/src/duckdb/extension/parquet/parquet_metadata.cpp @@ -361,6 +361,9 @@ void ParquetMetaDataOperator::BindSchema {"encoding", LogicalType::VARCHAR}, {"count", LogicalType::INTEGER}, }))); + + names.emplace_back("stats_nan_count"); + return_types.emplace_back(LogicalType::BIGINT); } static Value ConvertParquetStats(const LogicalType &type, const ParquetColumnSchema &schema_ele, bool stats_is_set, @@ -556,6 +559,8 @@ void ParquetRowGroupMetadataProcessor::ReadRow(vector> &output // encoding_stats, LogicalType::LIST(LogicalType::STRUCT(...)) output[31].get().Append(ConvertParquetEncodingStats(col_meta)); + // stats_nan_count + output[32].get().Append(ParquetElementBigint(stats.nan_count, stats.__isset.nan_count)); } //===--------------------------------------------------------------------===// diff --git a/src/duckdb/extension/parquet/parquet_reader.cpp b/src/duckdb/extension/parquet/parquet_reader.cpp index 745c2c023..ae8c51f40 100644 --- a/src/duckdb/extension/parquet/parquet_reader.cpp +++ b/src/duckdb/extension/parquet/parquet_reader.cpp @@ -864,7 +864,7 @@ unique_ptr ParquetReader::CreateReaderRecursive(ClientContext &con // Create the VariantColumnReader with the column index, so we can perform the extract at Read auto column_reader = make_uniq(context, *this, schema, std::move(children), column_id); - auto scan_type = column_id.GetScanType(); + const auto &scan_type = column_id.GetScanType(); if (scan_type.id() == LogicalTypeId::VARIANT) { return std::move(column_reader); } @@ -1244,7 +1244,7 @@ ParquetOptions::ParquetOptions(ClientContext &context) { if (context.TryGetCurrentSetting("binary_as_string", lookup_value)) { binary_as_string = lookup_value.GetValue(); } - if (context.TryGetCurrentSetting("__delta_only_variant_encoding_enabled", lookup_value)) { + if (context.TryGetCurrentSetting("debug_delta_only_variant_encoding_enabled", lookup_value)) { variant_legacy_encoding = lookup_value.GetValue(); } } @@ -1909,7 +1909,8 @@ void ParquetReader::PrepareRowGroupBuffer(ClientContext &context, ParquetReaderS if (!is_expression && !is_generated_column && has_min_max && (column_reader.Type().id() == LogicalTypeId::FLOAT || column_reader.Type().id() == LogicalTypeId::DOUBLE) && - parquet_options.can_have_nan) { + ParquetStatisticsUtils::CanHaveNaN(group.columns[schema_column_index].meta_data.statistics, + parquet_options.can_have_nan)) { // floating point columns can have NaN values in addition to the min/max bounds defined in the file // in order to do optimal pruning - we prune based on the [min, max] of the file followed by pruning // based on nan @@ -1951,7 +1952,8 @@ void ParquetReader::PrepareRowGroupBuffer(ClientContext &context, ParquetReaderS if (prune_result == FilterPropagateResult::FILTER_ALWAYS_FALSE || prune_result == FilterPropagateResult::FILTER_FALSE_OR_NULL) { - // this effectively will skip this chunk + // this effectively will skip this chunk - count the skipped rows towards the progress + rows_read += row_group_num_rows - state.offset_in_group; state.offset_in_group = group.num_rows; return; } @@ -2105,8 +2107,10 @@ struct ParquetPartitionRowGroup : public PartitionRowGroup { unique_ptr GetColumnStatistics(const StorageIndex &storage_index) override { const idx_t primary_index = storage_index.GetPrimaryIndex(); + if (primary_index >= root_schema->children.size()) { + return nullptr; + } D_ASSERT(metadata.row_groups.size() > row_group_idx); - D_ASSERT(root_schema->children.size() > primary_index); const auto &row_group = metadata.row_groups[row_group_idx]; const auto &column_schema = root_schema->children[primary_index]; @@ -2119,8 +2123,10 @@ struct ParquetPartitionRowGroup : public PartitionRowGroup { bool MinMaxIsExact(const StorageIndex &storage_index) override { const idx_t primary_index = storage_index.GetPrimaryIndex(); + if (primary_index >= root_schema->children.size()) { + return false; + } D_ASSERT(metadata.row_groups.size() > row_group_idx); - D_ASSERT(root_schema->children.size() > primary_index); // Special handle generated columns. const auto &column_schema = root_schema->children[primary_index]; diff --git a/src/duckdb/extension/parquet/parquet_statistics.cpp b/src/duckdb/extension/parquet/parquet_statistics.cpp index b6913db14..b53a329d5 100644 --- a/src/duckdb/extension/parquet/parquet_statistics.cpp +++ b/src/duckdb/extension/parquet/parquet_statistics.cpp @@ -111,6 +111,13 @@ static unique_ptr CreateFloatingPointStats(const LogicalType &ty return stats.ToUnique(); } +bool ParquetStatisticsUtils::CanHaveNaN(const duckdb_parquet::Statistics &parquet_stats, bool can_have_nan) { + if (parquet_stats.__isset.nan_count) { + return parquet_stats.nan_count != 0; + } + return can_have_nan; +} + Value ParquetStatisticsUtils::ConvertValue(const LogicalType &type, const ParquetColumnSchema &schema_ele, const std::string &stats) { string error; @@ -506,14 +513,12 @@ ParquetStatisticsUtils::TransformParquetStatistics(const LogicalType &type, cons return CreateNumericStats(type, schema, parquet_stats); case LogicalTypeId::FLOAT: case LogicalTypeId::DOUBLE: - if (can_have_nan) { - // Since parquet doesn't tell us if the column has NaN values, if the user has explicitly declared that it - // does, we create stats without an upper max value, as NaN compares larger than anything else. + if (CanHaveNaN(parquet_stats, can_have_nan)) { + // The column can contain NaN values - create stats without an upper max value, as NaN compares larger than + // anything else and is not included in the Parquet min/max return CreateFloatingPointStats(type, schema, parquet_stats); } else { - // Otherwise we use the numeric stats as usual, which might lead to "wrong" pruning if the column contains - // NaN values. The parquet spec is not clear on how to handle NaN values in statistics, and so this is - // probably the best we can do for now. + // Otherwise we use the numeric stats as usual return CreateNumericStats(type, schema, parquet_stats); } break; diff --git a/src/duckdb/extension/parquet/parquet_writer.cpp b/src/duckdb/extension/parquet/parquet_writer.cpp index 1eef8853e..bd77c1184 100644 --- a/src/duckdb/extension/parquet/parquet_writer.cpp +++ b/src/duckdb/extension/parquet/parquet_writer.cpp @@ -482,7 +482,7 @@ class ParquetStatsAccumulator { ParquetWriteTransformData::ParquetWriteTransformData(ClientContext &context, const vector &types, vector> expressions_p) - : buffer(context, types, ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR), types(std::move(types)), + : buffer(context, types, ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR), types(types), expressions(std::move(expressions_p)), executor(context, expressions) { chunk.Initialize(buffer.GetAllocator(), this->types); } diff --git a/src/duckdb/extension/parquet/reader/string_column_reader.cpp b/src/duckdb/extension/parquet/reader/string_column_reader.cpp index ba290f5ff..ef02f2777 100644 --- a/src/duckdb/extension/parquet/reader/string_column_reader.cpp +++ b/src/duckdb/extension/parquet/reader/string_column_reader.cpp @@ -78,7 +78,7 @@ string_t StringColumnReader::VerifyString(const char *str_data, uint32_t str_len auto new_str = Utf8Proc::RemoveInvalid(str_data, str_len); auto target = StringVector::EmptyString(*current_plain_result, new_str.size()); auto output = target.GetDataWriteable(); - memcpy(output, new_str.data(), new_str.size()); + memcpy(output, new_str.data(), new_str.size()); // NOLINT(bugprone-not-null-terminated-result) target.Finalize(); return target; } diff --git a/src/duckdb/extension/parquet/reader/variant/parquet_variant_shredding.cpp b/src/duckdb/extension/parquet/reader/variant/parquet_variant_shredding.cpp index 7ce888427..cc30f65eb 100644 --- a/src/duckdb/extension/parquet/reader/variant/parquet_variant_shredding.cpp +++ b/src/duckdb/extension/parquet/reader/variant/parquet_variant_shredding.cpp @@ -1,4 +1,4 @@ -#include "reader/variant/parquet_variant_iterator.hpp" +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" #include "reader/variant_column_reader.hpp" #include "duckdb/common/types/variant/variant_builder.hpp" diff --git a/src/duckdb/extension/parquet/reader/variant_column_reader.cpp b/src/duckdb/extension/parquet/reader/variant_column_reader.cpp index d471f5df1..00112d7a0 100644 --- a/src/duckdb/extension/parquet/reader/variant_column_reader.cpp +++ b/src/duckdb/extension/parquet/reader/variant_column_reader.cpp @@ -6,7 +6,7 @@ #include "duckdb/common/vector/struct_vector.hpp" #include "reader/variant_column_reader.hpp" -#include "reader/variant/parquet_variant_iterator.hpp" +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" #include "column_reader.hpp" #include "duckdb/common/assert.hpp" #include "duckdb/common/constants.hpp" diff --git a/src/duckdb/extension/parquet/writer/primitive_column_writer.cpp b/src/duckdb/extension/parquet/writer/primitive_column_writer.cpp index 652199ac6..315dea0fd 100644 --- a/src/duckdb/extension/parquet/writer/primitive_column_writer.cpp +++ b/src/duckdb/extension/parquet/writer/primitive_column_writer.cpp @@ -133,11 +133,8 @@ void PrimitiveColumnWriter::Prepare(ColumnWriterState &state_p, ColumnWriterStat } if (validity.RowIsValid(vector_index)) { page_info.estimated_page_size += GetRowSize(vector, vector_index, state); - if (page_info.estimated_page_size >= page_size_limit) { - if (!vector_can_span_multiple_pages && i != 0) { - // Vector is not allowed to span multiple pages, and we already started writing it - continue; - } + // a vector that cannot span multiple pages stays on the page it started on + if (page_info.estimated_page_size >= page_size_limit && (vector_can_span_multiple_pages || i == 0)) { PageInformation new_info; new_info.offset = page_info.offset + page_info.row_count; state.page_info.push_back(new_info); @@ -382,6 +379,11 @@ void PrimitiveColumnWriter::SetParquetStatistics(PrimitiveColumnWriterState &sta column_chunk.meta_data.statistics.null_count = NumericCast(null_count); column_chunk.meta_data.statistics.__isset.null_count = true; column_chunk.meta_data.__isset.statistics = true; + if (column_chunk.meta_data.type == duckdb_parquet::Type::FLOAT || + column_chunk.meta_data.type == duckdb_parquet::Type::DOUBLE) { + column_chunk.meta_data.statistics.nan_count = NumericCast(state.stats_state->GetNaNCount()); + column_chunk.meta_data.statistics.__isset.nan_count = true; + } // if we have NaN values - don't write the min/max here if (!state.stats_state->HasNaN()) { diff --git a/src/duckdb/extension/parquet/writer/variant/convert_variant.cpp b/src/duckdb/extension/parquet/writer/variant/convert_variant.cpp index e65e97257..d7bce7dfc 100644 --- a/src/duckdb/extension/parquet/writer/variant/convert_variant.cpp +++ b/src/duckdb/extension/parquet/writer/variant/convert_variant.cpp @@ -1,925 +1,54 @@ -#include -#include #include -#include #include #include -#include "duckdb/common/vector/struct_vector.hpp" #include "writer/variant_column_writer.hpp" -#include "duckdb/common/types/variant.hpp" -#include "duckdb/function/scalar/variant_utils.hpp" -#include "reader/variant/variant_binary_decoder.hpp" -#include "duckdb/function/variant/variant_shredding.hpp" -#include "duckdb/planner/expression_binder.hpp" -#include "duckdb/execution/expression_executor.hpp" -#include "duckdb/common/operator/cast_operators.hpp" #include "column_writer.hpp" -#include "duckdb/common/assert.hpp" -#include "duckdb/common/enum_util.hpp" -#include "duckdb/common/exception.hpp" +#include "parquet_column_schema.hpp" +#include "parquet_types.h" +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" #include "duckdb/common/exception/binder_exception.hpp" -#include "duckdb/common/helper.hpp" -#include "duckdb/common/hugeint.hpp" -#include "duckdb/common/limits.hpp" #include "duckdb/common/numeric_utils.hpp" -#include "duckdb/common/optional_idx.hpp" -#include "duckdb/common/optional_ptr.hpp" -#include "duckdb/common/string.hpp" -#include "duckdb/common/string_map_set.hpp" -#include "duckdb/common/typedefs.hpp" #include "duckdb/common/types.hpp" #include "duckdb/common/types/data_chunk.hpp" -#include "duckdb/common/types/selection_vector.hpp" -#include "duckdb/common/types/string_type.hpp" -#include "duckdb/common/types/uuid.hpp" -#include "duckdb/common/types/validity_mask.hpp" -#include "duckdb/common/types/value.hpp" #include "duckdb/common/types/vector.hpp" -#include "duckdb/common/uhugeint.hpp" -#include "duckdb/common/unique_ptr.hpp" -#include "duckdb/common/vector.hpp" -#include "duckdb/common/vector/flat_vector.hpp" -#include "duckdb/common/vector/string_vector.hpp" -#include "duckdb/common/vector/unified_vector_format.hpp" -#include "duckdb/function/function.hpp" #include "duckdb/function/scalar_function.hpp" -#include "duckdb/planner/expression.hpp" -#include "parquet_column_schema.hpp" -#include "parquet_types.h" +#include "duckdb/planner/expression_binder.hpp" namespace duckdb { -class ClientContext; -struct ExpressionState; - -static idx_t CalculateByteLength(idx_t value) { - if (value == 0) { - return 1; - } - auto value_data = reinterpret_cast(&value); - idx_t irrelevant_bytes = 0; - //! Check how many of the most significant bytes are 0 - for (idx_t i = sizeof(idx_t); i > 0 && value_data[i - 1] == 0; i--) { - irrelevant_bytes++; - } - return sizeof(idx_t) - irrelevant_bytes; -} - -static uint8_t EncodeMetadataHeader(idx_t byte_length) { - D_ASSERT(byte_length <= 4); - - uint8_t header_byte = 0; - //! Set 'version' to 1 - header_byte |= static_cast(1); - //! NOTE: keep 'sorted_strings' at 0, we don't always sort the key strings - //! Set 'offset_size_minus_one' to byte_length-1 - header_byte |= (static_cast(byte_length) - 1) << 6; - -#ifdef DEBUG - auto decoded_header = VariantMetadataHeader::FromHeaderByte(header_byte); - D_ASSERT(decoded_header.offset_size == byte_length); -#endif - - return header_byte; -} - -static void CreateMetadata(UnifiedVariantVectorData &variant, Vector &metadata, idx_t count) { - //! NOTE: the parquet variant is limited to a max dictionary size of NumericLimits::Maximum() - //! Whereas we can have NumericLimits::Maximum() *per* string in DuckDB - auto metadata_data = FlatVector::GetDataMutable(metadata); - for (idx_t row = 0; row < count; row++) { - uint64_t dictionary_count = 0; - if (variant.RowIsValid(row)) { - dictionary_count = variant.GetKeysCount(row); - } - idx_t dictionary_size = 0; - for (idx_t i = 0; i < dictionary_count; i++) { - auto &key = variant.GetKey(row, i); - dictionary_size += key.GetSize(); - } - if (dictionary_size >= NumericLimits::Maximum()) { - throw InvalidInputException("The total length of the dictionary exceeds a 4 byte value (uint32_t), failed " - "to export VARIANT to Parquet"); - } - - auto byte_length = CalculateByteLength(dictionary_size); - auto total_length = 1 + (byte_length * (dictionary_count + 2)) + dictionary_size; - - metadata_data[row] = StringVector::EmptyString(metadata, total_length); - auto &metadata_blob = metadata_data[row]; - auto metadata_blob_data = metadata_blob.GetDataWriteable(); - - metadata_blob_data[0] = static_cast(EncodeMetadataHeader(byte_length)); - memcpy(metadata_blob_data + 1, const_data_ptr_cast(&dictionary_count), byte_length); - - auto offset_ptr = metadata_blob_data + 1 + byte_length; - auto string_ptr = - metadata_blob_data + 1 + byte_length + (NumericCast(dictionary_count + 1) * byte_length); - idx_t total_offset = 0; - for (idx_t i = 0; i < dictionary_count; i++) { - memcpy(offset_ptr + (i * byte_length), const_data_ptr_cast(&total_offset), byte_length); - auto &key = variant.GetKey(row, i); - - memcpy(string_ptr + total_offset, key.GetData(), key.GetSize()); - total_offset += key.GetSize(); - } - memcpy(offset_ptr + (NumericCast(dictionary_count) * byte_length), const_data_ptr_cast(&total_offset), - byte_length); - D_ASSERT(offset_ptr + (NumericCast(dictionary_count + 1) * byte_length) == string_ptr); - D_ASSERT(string_ptr + total_offset == metadata_blob_data + total_length); - metadata_blob.SetSizeAndFinalize(total_length, total_length); - -#ifdef DEBUG - auto decoded_metadata = VariantMetadata(metadata_blob); - D_ASSERT(decoded_metadata.strings.size() == dictionary_count); - for (idx_t i = 0; i < dictionary_count; i++) { - D_ASSERT(decoded_metadata.strings[i] == variant.GetKey(row, i).GetString()); - } -#endif - } -} - -namespace { - -static unordered_set GetVariantType(const LogicalType &type) { - if (type.id() == LogicalTypeId::ANY) { - return {}; - } - switch (type.id()) { - case LogicalTypeId::STRUCT: - return {VariantLogicalType::OBJECT}; - case LogicalTypeId::LIST: - return {VariantLogicalType::ARRAY}; - case LogicalTypeId::BOOLEAN: - return {VariantLogicalType::BOOL_TRUE, VariantLogicalType::BOOL_FALSE}; - case LogicalTypeId::TINYINT: - return {VariantLogicalType::INT8}; - case LogicalTypeId::SMALLINT: - return {VariantLogicalType::INT16}; - case LogicalTypeId::INTEGER: - return {VariantLogicalType::INT32}; - case LogicalTypeId::BIGINT: - return {VariantLogicalType::INT64}; - case LogicalTypeId::FLOAT: - return {VariantLogicalType::FLOAT}; - case LogicalTypeId::DOUBLE: - return {VariantLogicalType::DOUBLE}; - case LogicalTypeId::DECIMAL: - return {VariantLogicalType::DECIMAL}; - case LogicalTypeId::DATE: - return {VariantLogicalType::DATE}; - case LogicalTypeId::TIME: - return {VariantLogicalType::TIME_MICROS}; - case LogicalTypeId::TIMESTAMP_TZ: - return {VariantLogicalType::TIMESTAMP_MICROS_TZ}; - case LogicalTypeId::TIMESTAMP_TZ_NS: - return {VariantLogicalType::TIMESTAMP_NANOS_TZ}; - case LogicalTypeId::TIMESTAMP: - return {VariantLogicalType::TIMESTAMP_MICROS}; - case LogicalTypeId::TIMESTAMP_NS: - return {VariantLogicalType::TIMESTAMP_NANOS}; - case LogicalTypeId::BLOB: - return {VariantLogicalType::BLOB}; - case LogicalTypeId::VARCHAR: - return {VariantLogicalType::VARCHAR}; - case LogicalTypeId::UUID: - return {VariantLogicalType::UUID}; - default: - throw BinderException("Type '%s' can't be translated to a VARIANT type", type.ToString()); - } -} - -struct ParquetVariantShreddingState : public VariantShreddingState { -public: - ParquetVariantShreddingState(const LogicalType &type, idx_t total_count) - : VariantShreddingState(type, total_count), variant_types(GetVariantType(type)) { - } - -public: - const unordered_set &GetVariantTypes() override { - return variant_types; - } - -private: - unordered_set variant_types; -}; - -struct ParquetVariantShredding : public VariantShredding { - ParquetVariantShredding() { - // for parquet untyped ("value") comes before typed ("typed_value") - untyped_value_index = 0; - typed_value_index = 1; - } - - void WriteVariantValues(UnifiedVariantVectorData &variant, Vector &result, optional_ptr sel, - optional_ptr value_index_sel, - optional_ptr result_sel, idx_t count) override; - -protected: - void WriteMissingField(Vector &vector, idx_t index) override; -}; - -} // namespace - -vector GetChildIndices(const UnifiedVariantVectorData &variant, idx_t row, const VariantNestedData &nested_data, - optional_ptr shredding_state) { - vector child_indices; - if (!shredding_state || shredding_state->type.id() != LogicalTypeId::STRUCT) { - for (idx_t i = 0; i < nested_data.child_count; i++) { - child_indices.push_back(i); - } - return child_indices; - } - auto shredded_fields = shredding_state->ObjectFields(); - - for (idx_t i = 0; i < nested_data.child_count; i++) { - auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); - auto &key = variant.GetKey(row, keys_index); - - if (shredded_fields.count(key.GetString())) { - //! This field is shredded on, omit it from the value - continue; - } - child_indices.push_back(i); - } - return child_indices; -} - -static idx_t AnalyzeValueData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_index, - vector &offsets, optional_ptr shredding_state) { - idx_t total_size = 0; - //! Every value has at least a value header - total_size++; - - idx_t offset_size = offsets.size(); - VariantLogicalType type_id = VariantLogicalType::VARIANT_NULL; - if (variant.RowIsValid(row)) { - type_id = variant.GetTypeId(row, values_index); - } - switch (type_id) { - case VariantLogicalType::OBJECT: { - auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); - - //! Calculate value and key offsets for all children - idx_t total_offset = 0; - uint32_t highest_keys_index = 0; - - auto child_indices = GetChildIndices(variant, row, nested_data, shredding_state); - if (nested_data.child_count && child_indices.empty()) { - //! All fields of the object are shredded, omit the object entirely - return 0; - } - - auto num_elements = child_indices.size(); - offsets.resize(offset_size + num_elements + 1); - - for (idx_t entry = 0; entry < child_indices.size(); entry++) { - auto i = child_indices[entry]; - auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); - auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); - offsets[offset_size + entry] = total_offset; - - total_offset += AnalyzeValueData(variant, row, values_index, offsets, nullptr); - highest_keys_index = MaxValue(highest_keys_index, keys_index); - } - offsets[offset_size + num_elements] = total_offset; - - //! Calculate the sizes for the objects value data - auto field_id_size = CalculateByteLength(highest_keys_index); - auto field_offset_size = CalculateByteLength(total_offset); - const bool is_large = num_elements > NumericLimits::Maximum(); - - //! Now add the sizes for the objects value data - if (is_large) { - total_size += sizeof(uint32_t); - } else { - total_size += sizeof(uint8_t); - } - total_size += num_elements * field_id_size; - total_size += (num_elements + 1) * field_offset_size; - total_size += total_offset; - break; - } - case VariantLogicalType::ARRAY: { - auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); - - idx_t total_offset = 0; - offsets.resize(offset_size + nested_data.child_count + 1); - for (idx_t i = 0; i < nested_data.child_count; i++) { - auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); - offsets[offset_size + i] = total_offset; - - total_offset += AnalyzeValueData(variant, row, values_index, offsets, nullptr); - } - offsets[offset_size + nested_data.child_count] = total_offset; - - auto field_offset_size = CalculateByteLength(total_offset); - auto num_elements = nested_data.child_count; - const bool is_large = num_elements > NumericLimits::Maximum(); - - if (is_large) { - total_size += sizeof(uint32_t); - } else { - total_size += sizeof(uint8_t); - } - total_size += (num_elements + 1) * field_offset_size; - total_size += total_offset; - break; - } - case VariantLogicalType::BLOB: - case VariantLogicalType::VARCHAR: { - auto string_value = VariantUtils::DecodeStringData(variant, row, values_index); - total_size += string_value.GetSize(); - if (type_id == VariantLogicalType::BLOB || string_value.GetSize() > 64) { - //! Save as regular string value - total_size += sizeof(uint32_t); - } - break; - } - case VariantLogicalType::VARIANT_NULL: - case VariantLogicalType::BOOL_TRUE: - case VariantLogicalType::BOOL_FALSE: - break; - case VariantLogicalType::INT8: - total_size += sizeof(uint8_t); - break; - case VariantLogicalType::INT16: - total_size += sizeof(uint16_t); - break; - case VariantLogicalType::INT32: - total_size += sizeof(uint32_t); - break; - case VariantLogicalType::INT64: - total_size += sizeof(uint64_t); - break; - case VariantLogicalType::FLOAT: - total_size += sizeof(float); - break; - case VariantLogicalType::DOUBLE: - total_size += sizeof(double); - break; - case VariantLogicalType::DECIMAL: { - auto decimal_data = VariantUtils::DecodeDecimalData(variant, row, values_index); - total_size += 1; - if (decimal_data.width <= 9) { - total_size += sizeof(int32_t); - } else if (decimal_data.width <= 18) { - total_size += sizeof(int64_t); - } else if (decimal_data.width <= 38) { - total_size += sizeof(uhugeint_t); - } else { - throw InvalidInputException("Can't convert VARIANT DECIMAL(%d, %d) to Parquet VARIANT", decimal_data.width, - decimal_data.scale); - } - break; - } - case VariantLogicalType::UUID: - total_size += sizeof(uhugeint_t); - break; - case VariantLogicalType::DATE: - total_size += sizeof(uint32_t); - break; - case VariantLogicalType::TIME_MICROS: - case VariantLogicalType::TIMESTAMP_MICROS: - case VariantLogicalType::TIMESTAMP_NANOS: - case VariantLogicalType::TIMESTAMP_MICROS_TZ: - total_size += sizeof(uint64_t); - break; - case VariantLogicalType::UINT8: - // store as int16_t - total_size += sizeof(int16_t); - break; - case VariantLogicalType::UINT16: - // store as int32_t - total_size += sizeof(int32_t); - break; - case VariantLogicalType::UINT32: - case VariantLogicalType::UINT64: - case VariantLogicalType::UINT128: - case VariantLogicalType::INT128: - // try to store as int64_t - fail if it doesn't fit - total_size += sizeof(int64_t); - break; - case VariantLogicalType::INTERVAL: - case VariantLogicalType::BIGNUM: - case VariantLogicalType::BITSTRING: - case VariantLogicalType::TIMESTAMP_MILIS: - case VariantLogicalType::TIMESTAMP_SEC: - case VariantLogicalType::TIME_MICROS_TZ: - case VariantLogicalType::TIME_NANOS: - default: - throw InvalidInputException("Can't convert VARIANT of type '%s' to Parquet VARIANT", - EnumUtil::ToString(type_id)); - } - - return total_size; -} - -template -void WritePrimitiveTypeHeader(data_ptr_t &value_data) { - uint8_t value_header = 0; - value_header |= static_cast(VariantBasicType::PRIMITIVE); - value_header |= static_cast(TYPE_ID) << 2; - - *value_data = value_header; - value_data++; -} - -struct VariantSimpleCopy { - template - static void CopyValue(const_data_ptr_t source, data_ptr_t target) { - memcpy(target, source, sizeof(T)); - } -}; - -template -struct VariantSimpleConversion { - template - static void CopyValue(const_data_ptr_t source, data_ptr_t target) { - auto src = Load(source); - Store(static_cast(src), target); - } -}; -template -struct VariantTryConvert { - template - static void CopyValue(const_data_ptr_t source, data_ptr_t target) { - auto src = Load(source); - Store(Cast::Operation(src), target); - } -}; - -template -void CopySimplePrimitiveData(const UnifiedVariantVectorData &variant, data_ptr_t &value_data, idx_t row, - uint32_t values_index) { - auto byte_offset = variant.GetByteOffset(row, values_index); - auto data = const_data_ptr_cast(variant.GetData(row).GetData()); - auto ptr = data + byte_offset; - OP::template CopyValue(ptr, value_data); - value_data += sizeof(T); -} - -void CopyUUIDData(const UnifiedVariantVectorData &variant, data_ptr_t &value_data, idx_t row, uint32_t values_index) { - auto byte_offset = variant.GetByteOffset(row, values_index); - auto data = const_data_ptr_cast(variant.GetData(row).GetData()); - auto ptr = data + byte_offset; - - auto uuid = Load(ptr); - BaseUUID::ToBlob(uuid, value_data); - value_data += sizeof(uhugeint_t); -} - -static void WritePrimitiveValueData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_index, - data_ptr_t &value_data, const vector &offsets, idx_t &offset_index) { - VariantLogicalType type_id = VariantLogicalType::VARIANT_NULL; - if (variant.RowIsValid(row)) { - type_id = variant.GetTypeId(row, values_index); - } - - D_ASSERT(type_id != VariantLogicalType::OBJECT && type_id != VariantLogicalType::ARRAY); - switch (type_id) { - case VariantLogicalType::BLOB: - case VariantLogicalType::VARCHAR: { - auto string_value = VariantUtils::DecodeStringData(variant, row, values_index); - auto string_size = string_value.GetSize(); - if (type_id == VariantLogicalType::BLOB || string_size > 64) { - if (type_id == VariantLogicalType::BLOB) { - WritePrimitiveTypeHeader(value_data); - } else { - WritePrimitiveTypeHeader(value_data); - } - Store(string_size, value_data); - value_data += sizeof(uint32_t); - } else { - uint8_t value_header = 0; - value_header |= static_cast(VariantBasicType::SHORT_STRING); - value_header |= static_cast(string_size) << 2; - - *value_data = value_header; - value_data++; - } - memcpy(value_data, reinterpret_cast(string_value.GetData()), string_size); - value_data += string_size; - break; - } - case VariantLogicalType::VARIANT_NULL: - WritePrimitiveTypeHeader(value_data); - break; - case VariantLogicalType::BOOL_TRUE: - WritePrimitiveTypeHeader(value_data); - break; - case VariantLogicalType::BOOL_FALSE: - WritePrimitiveTypeHeader(value_data); - break; - case VariantLogicalType::INT8: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::INT16: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::INT32: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::INT64: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::FLOAT: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::DOUBLE: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::UUID: - WritePrimitiveTypeHeader(value_data); - CopyUUIDData(variant, value_data, row, values_index); - break; - case VariantLogicalType::DATE: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::TIME_MICROS: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::TIMESTAMP_MICROS: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::TIMESTAMP_NANOS: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::TIMESTAMP_MICROS_TZ: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData(variant, value_data, row, values_index); - break; - case VariantLogicalType::DECIMAL: { - auto decimal_data = VariantUtils::DecodeDecimalData(variant, row, values_index); - - if (decimal_data.width > 38) { - throw InvalidInputException("Can't convert VARIANT DECIMAL(%d, %d) to Parquet VARIANT", decimal_data.width, - decimal_data.scale); - } else if (decimal_data.width <= 4) { - // DuckDB uses INT16 to store small decimals, but parquet only supports DECIMAL4 at minimum, so here we - // promote to INT32. - WritePrimitiveTypeHeader(value_data); - Store(NumericCast(decimal_data.scale), value_data); - value_data++; - const int32_t promoted = Load(decimal_data.value_ptr); - Store(promoted, value_data); - value_data += sizeof(int32_t); - } else if (decimal_data.width <= 9) { - WritePrimitiveTypeHeader(value_data); - Store(NumericCast(decimal_data.scale), value_data); - value_data++; - memcpy(value_data, decimal_data.value_ptr, sizeof(int32_t)); - value_data += sizeof(int32_t); - } else if (decimal_data.width <= 18) { - WritePrimitiveTypeHeader(value_data); - Store(NumericCast(decimal_data.scale), value_data); - value_data++; - memcpy(value_data, decimal_data.value_ptr, sizeof(int64_t)); - value_data += sizeof(int64_t); - } else if (decimal_data.width <= 38) { - WritePrimitiveTypeHeader(value_data); - Store(NumericCast(decimal_data.scale), value_data); - value_data++; - memcpy(value_data, decimal_data.value_ptr, sizeof(hugeint_t)); - value_data += sizeof(hugeint_t); - } else { - throw InternalException( - "Uncovered VARIANT(DECIMAL) -> Parquet VARIANT conversion for type 'DECIMAL(%d, %d)'", - decimal_data.width, decimal_data.scale); - } - break; - } - case VariantLogicalType::UINT8: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData>(variant, value_data, row, values_index); - break; - case VariantLogicalType::UINT16: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData>(variant, value_data, row, values_index); - break; - case VariantLogicalType::UINT32: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData>(variant, value_data, row, values_index); - break; - case VariantLogicalType::UINT64: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData>(variant, value_data, row, values_index); - break; - case VariantLogicalType::UINT128: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData>(variant, value_data, row, values_index); - break; - case VariantLogicalType::INT128: - WritePrimitiveTypeHeader(value_data); - CopySimplePrimitiveData>(variant, value_data, row, values_index); - break; - case VariantLogicalType::INTERVAL: - case VariantLogicalType::BIGNUM: - case VariantLogicalType::BITSTRING: - case VariantLogicalType::TIMESTAMP_MILIS: - case VariantLogicalType::TIMESTAMP_SEC: - case VariantLogicalType::TIME_MICROS_TZ: - case VariantLogicalType::TIME_NANOS: - default: - throw InvalidInputException("Can't convert VARIANT of type '%s' to Parquet VARIANT", - EnumUtil::ToString(type_id)); - } -} - -static void WriteValueData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_index, - data_ptr_t &value_data, const vector &offsets, idx_t &offset_index, - optional_ptr shredding_state) { - VariantLogicalType type_id = VariantLogicalType::VARIANT_NULL; - if (variant.RowIsValid(row)) { - type_id = variant.GetTypeId(row, values_index); - } - if (type_id == VariantLogicalType::OBJECT) { - auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); - - //! -- Object value header -- - - auto child_indices = GetChildIndices(variant, row, nested_data, shredding_state); - if (nested_data.child_count && child_indices.empty()) { - throw InternalException( - "The entire should be omitted, should have been handled by the Analyze step already"); - } - auto num_elements = child_indices.size(); - - //! Determine the 'field_id_size' - uint32_t highest_keys_index = 0; - for (auto &i : child_indices) { - auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); - highest_keys_index = MaxValue(highest_keys_index, keys_index); - } - auto field_id_size = CalculateByteLength(highest_keys_index); - - uint32_t last_offset = 0; - if (num_elements) { - last_offset = offsets[offset_index + num_elements]; - } - offset_index += num_elements + 1; - auto field_offset_size = CalculateByteLength(last_offset); - - const bool is_large = num_elements > NumericLimits::Maximum(); - - uint8_t value_header = 0; - value_header |= static_cast(VariantBasicType::OBJECT); - value_header |= static_cast(is_large) << 6; - value_header |= (static_cast(field_id_size) - 1) << 4; - value_header |= (static_cast(field_offset_size) - 1) << 2; - -#ifdef DEBUG - auto object_value_header = VariantValueMetadata::FromHeaderByte(value_header); - D_ASSERT(object_value_header.basic_type == VariantBasicType::OBJECT); - D_ASSERT(object_value_header.is_large == is_large); - D_ASSERT(object_value_header.field_offset_size == field_offset_size); - D_ASSERT(object_value_header.field_id_size == field_id_size); -#endif - - *value_data = value_header; - value_data++; - - //! Write the 'num_elements' - if (is_large) { - Store(static_cast(num_elements), value_data); - value_data += sizeof(uint32_t); - } else { - Store(static_cast(num_elements), value_data); - value_data += sizeof(uint8_t); - } - - //! Write the 'field_id' entries - for (auto &i : child_indices) { - auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); - memcpy(value_data, reinterpret_cast(&keys_index), field_id_size); - value_data += field_id_size; - } - - //! Write the 'field_offset' entries and the child 'value's - auto children_ptr = value_data + ((num_elements + 1) * field_offset_size); - idx_t total_offset = 0; - for (auto &i : child_indices) { - auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); - - memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); - value_data += field_offset_size; - auto start_ptr = children_ptr; - WriteValueData(variant, row, values_index, children_ptr, offsets, offset_index, nullptr); - total_offset += (children_ptr - start_ptr); - } - memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); - value_data += field_offset_size; - D_ASSERT(children_ptr - total_offset == value_data); - value_data = children_ptr; - } else if (type_id == VariantLogicalType::ARRAY) { - auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); - - //! -- Array value header -- - - uint32_t last_offset = 0; - if (nested_data.child_count) { - last_offset = offsets[offset_index + nested_data.child_count]; - } - offset_index += nested_data.child_count + 1; - auto field_offset_size = CalculateByteLength(last_offset); - - auto num_elements = nested_data.child_count; - const bool is_large = num_elements > NumericLimits::Maximum(); - - uint8_t value_header = 0; - value_header |= static_cast(VariantBasicType::ARRAY); - value_header |= static_cast(is_large) << 4; - value_header |= (static_cast(field_offset_size) - 1) << 2; - -#ifdef DEBUG - auto array_value_header = VariantValueMetadata::FromHeaderByte(value_header); - D_ASSERT(array_value_header.basic_type == VariantBasicType::ARRAY); - D_ASSERT(array_value_header.is_large == is_large); - D_ASSERT(array_value_header.field_offset_size == field_offset_size); -#endif - - *value_data = value_header; - value_data++; - - //! Write the 'num_elements' - if (is_large) { - Store(static_cast(num_elements), value_data); - value_data += sizeof(uint32_t); - } else { - Store(static_cast(num_elements), value_data); - value_data += sizeof(uint8_t); - } - - //! Write the 'field_offset' entries and the child 'value's - auto children_ptr = value_data + ((num_elements + 1) * field_offset_size); - idx_t total_offset = 0; - for (idx_t i = 0; i < nested_data.child_count; i++) { - auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); - - memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); - value_data += field_offset_size; - auto start_ptr = children_ptr; - WriteValueData(variant, row, values_index, children_ptr, offsets, offset_index, nullptr); - total_offset += (children_ptr - start_ptr); +static optional_ptr FindChildWriterByName(ColumnWriter &parent, const char *name) { + for (auto &child : parent.ChildWriters()) { + if (child->Schema().name == name) { + return *child; } - memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); - value_data += field_offset_size; - D_ASSERT(children_ptr - total_offset == value_data); - value_data = children_ptr; - } else { - WritePrimitiveValueData(variant, row, values_index, value_data, offsets, offset_index); } + return nullptr; } -static void CreateValues(UnifiedVariantVectorData &variant, Vector &value, optional_ptr sel, - optional_ptr value_index_sel, - optional_ptr result_sel, - optional_ptr shredding_state, idx_t count) { - auto &validity = FlatVector::ValidityMutable(value); - auto value_data = FlatVector::GetDataMutable(value); - - for (idx_t i = 0; i < count; i++) { - idx_t value_index = 0; - if (value_index_sel) { - value_index = value_index_sel->get_index(i); - } - - idx_t row = i; - if (sel) { - row = sel->get_index(i); - } +static void MarkTypedValueShreddingGroupsRequired(ColumnWriter &typed_value); - idx_t result_index = i; - if (result_sel) { - result_index = result_sel->get_index(i); - } - - bool is_shredded = false; - if (variant.RowIsValid(row) && shredding_state && shredding_state->ValueIsShredded(variant, row, value_index)) { - shredding_state->SetShredded(row, value_index, result_index); - is_shredded = true; - if (shredding_state->type.id() != LogicalTypeId::STRUCT) { - //! Value is shredded, directly write a NULL to the 'value' if the type is not an OBJECT - //! When the type is OBJECT, all excess fields would still need to be written to the 'value' - validity.SetInvalid(result_index); - continue; - } - } - - //! The (relative) offsets for each value, in the case of nesting - vector offsets; - //! Determine the size of this 'value' blob - idx_t blob_length = AnalyzeValueData(variant, row, value_index, offsets, shredding_state); - if (!blob_length) { - //! This is only allowed to happen for a shredded OBJECT, where there are no excess fields to write for the - //! OBJECT - (void)is_shredded; - D_ASSERT(is_shredded); - validity.SetInvalid(result_index); - continue; - } - value_data[result_index] = StringVector::EmptyString(value, blob_length); - auto &value_blob = value_data[result_index]; - auto value_blob_data = reinterpret_cast(value_blob.GetDataWriteable()); - - idx_t offset_index = 0; - WriteValueData(variant, row, value_index, value_blob_data, offsets, offset_index, shredding_state); - D_ASSERT(data_ptr_cast(value_blob.GetDataWriteable() + blob_length) == value_blob_data); - value_blob.SetSizeAndFinalize(blob_length, blob_length); +// Field/element group: mark REQUIRED, then recurse into nested typed_value if present +static void MarkShreddedGroupRequired(ColumnWriter &group) { + D_ASSERT(StructType::IsStruct(group.Type().id())); + group.MarkRepetitionRequired(); + auto nested_typed_value = FindChildWriterByName(group, "typed_value"); + if (nested_typed_value) { + MarkTypedValueShreddingGroupsRequired(*nested_typed_value); } } -void ParquetVariantShredding::WriteMissingField(Vector &vector, idx_t index) { - //! The field is missing, set it to null - FlatVector::SetNull(vector, index, true); -} - -void ParquetVariantShredding::WriteVariantValues(UnifiedVariantVectorData &variant, Vector &result, - optional_ptr sel, - optional_ptr value_index_sel, - optional_ptr result_sel, idx_t count) { - optional_ptr value; - optional_ptr typed_value; - - auto &result_type = result.GetType(); - D_ASSERT(result_type.id() == LogicalTypeId::STRUCT); - auto &child_types = StructType::GetChildTypes(result_type); - auto &child_vectors = StructVector::GetEntries(result); - D_ASSERT(child_types.size() == child_vectors.size()); - for (idx_t i = 0; i < child_types.size(); i++) { - auto &name = child_types[i].first; - if (name == "value") { - value = &child_vectors[i]; - } else if (name == "typed_value") { - typed_value = &child_vectors[i]; +// Field/element groups under typed_value must be REQUIRED (VariantShredding.md) +static void MarkTypedValueShreddingGroupsRequired(ColumnWriter &typed_value) { + auto type_id = typed_value.Type().id(); + if (StructType::IsStruct(type_id)) { + for (auto &field_group : typed_value.ChildWriters()) { + MarkShreddedGroupRequired(*field_group); } + } else if (type_id == LogicalTypeId::LIST || type_id == LogicalTypeId::ARRAY) { + D_ASSERT(typed_value.ChildWriters().size() == 1); + MarkShreddedGroupRequired(*typed_value.ChildWriters()[0]); } - - if (typed_value) { - ParquetVariantShreddingState shredding_state(typed_value->GetType(), count); - CreateValues(variant, *value, sel, value_index_sel, result_sel, &shredding_state, count); - - SelectionVector null_values; - if (shredding_state.count) { - WriteTypedValues(variant, *typed_value, shredding_state.shredded_sel, shredding_state.values_index_sel, - shredding_state.result_sel, shredding_state.count); - //! 'shredding_state.result_sel' will always be a subset of 'result_sel', set the rows not in the subset to - //! NULL - idx_t sel_idx = 0; - for (idx_t i = 0; i < count; i++) { - auto original_index = result_sel ? result_sel->get_index(i) : i; - if (sel_idx < shredding_state.count && shredding_state.result_sel[sel_idx] == original_index) { - sel_idx++; - continue; - } - FlatVector::SetNull(*typed_value, original_index, true); - } - } else { - //! Set all rows of the typed_value to NULL, nothing is shredded on - for (idx_t i = 0; i < count; i++) { - FlatVector::SetNull(*typed_value, result_sel ? result_sel->get_index(i) : i, true); - } - } - } else { - CreateValues(variant, *value, sel, value_index_sel, result_sel, nullptr, count); - } -} - -static void ToParquetVariant(DataChunk &input, ExpressionState &state, Vector &result) { - // DuckDB Variant: - // - keys = VARCHAR[] - // - children = STRUCT(keys_index UINTEGER, values_index UINTEGER)[] - // - values = STRUCT(type_id UTINYINT, byte_offset UINTEGER)[] - // - data = BLOB - - // Parquet VARIANT: - // - metadata = BLOB - // - value = BLOB - - const auto &variant_vec = input.data[0]; - auto count = input.size(); - - RecursiveUnifiedVectorFormat recursive_format; - Vector::RecursiveToUnifiedFormat(variant_vec, recursive_format); - UnifiedVariantVectorData variant(recursive_format); - - auto &result_vectors = StructVector::GetEntries(result); - auto &metadata = result_vectors[0]; - CreateMetadata(variant, metadata, count); - - ParquetVariantShredding shredding; - shredding.WriteVariantValues(variant, result, nullptr, nullptr, nullptr, count); } idx_t VariantColumnWriter::FinalizeSchema(vector &schemas) { @@ -932,6 +61,12 @@ idx_t VariantColumnWriter::FinalizeSchema(vector auto &name = schema.name; auto &field_id = schema.field_id; + // Mark shredded field/element groups REQUIRED (reserved Parquet names only) + auto typed_value = FindChildWriterByName(*this, "typed_value"); + if (typed_value) { + MarkTypedValueShreddingGroupsRequired(*typed_value); + } + // variant group duckdb_parquet::SchemaElement top_element; top_element.repetition_type = repetition_type; @@ -1029,8 +164,15 @@ static unique_ptr BindTransform(BindScalarFunctionInput &input) { return nullptr; } +//! The conversion itself lives in core (ParquetVariantConversion::ToParquetVariant), so the +//! arrow.parquet.variant extension type can call it directly without going through the binder. +static void ToParquetVariantFunction(DataChunk &input, ExpressionState &state, Vector &result) { + ParquetVariantConversion::ToParquetVariant(input.data[0], input.size(), result); +} + ScalarFunction VariantColumnWriter::GetTransformFunction() { - ScalarFunction transform("variant_to_parquet_variant", {}, LogicalType::ANY, ToParquetVariant, BindTransform); + ScalarFunction transform("variant_to_parquet_variant", {}, LogicalType::ANY, ToParquetVariantFunction, + BindTransform); transform.GetSignature().AddParameter("variant", LogicalType::VARIANT()); transform.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); // throws for values that are out of range for the parquet variant encoding @@ -1038,4 +180,16 @@ ScalarFunction VariantColumnWriter::GetTransformFunction() { return transform; } +static void VariantBytesToVariantFunction(DataChunk &input, ExpressionState &state, Vector &result) { + ParquetVariantConversion::ConvertBinary(input.data[0], result, input.size()); +} + +ScalarFunction VariantColumnWriter::GetBytesToVariantFunction() { + ScalarFunction function("variant_bytes_to_variant", {}, LogicalType::VARIANT(), VariantBytesToVariantFunction); + function.GetSignature().AddParameter("blob", LogicalType::BLOB); + function.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); + function.SetFallible(); + return function; +} + } // namespace duckdb diff --git a/src/duckdb/generated_extension_loader_package_build.cpp b/src/duckdb/generated_extension_loader_package_build.cpp index 9f7c4d329..2ff26a8ce 100644 --- a/src/duckdb/generated_extension_loader_package_build.cpp +++ b/src/duckdb/generated_extension_loader_package_build.cpp @@ -31,7 +31,6 @@ #include "duckdb/main/config.hpp" #include "duckdb/main/database.hpp" -// jdbc_update_marker_1 namespace duckdb { diff --git a/src/duckdb/src/catalog/catalog.cpp b/src/duckdb/src/catalog/catalog.cpp index dd8fe6f53..18bd31655 100644 --- a/src/duckdb/src/catalog/catalog.cpp +++ b/src/duckdb/src/catalog/catalog.cpp @@ -77,8 +77,9 @@ Catalog &Catalog::GetSystemCatalog(ClientContext &context) { return Catalog::GetSystemCatalog(*context.db); } +//! The default catalog for lookups; empty when no database is attached, in which case the lookup finds nothing there. Identifier GetDefaultCatalog(CatalogEntryRetriever &retriever) { - return DatabaseManager::GetDefaultDatabase(retriever.GetContext()); + return DatabaseManager::TryGetDefaultDatabase(retriever.GetContext()); } optional_ptr Catalog::GetCatalogEntry(CatalogEntryRetriever &retriever, const Identifier &catalog_name) { @@ -590,8 +591,9 @@ vector GetCatalogEntries(CatalogEntryRetriever &retriever, c auto &default_entry = search_path.GetDefault(); if (!IsInvalidCatalog(default_entry.GetCatalog())) { entries.emplace_back(default_entry.GetCatalog(), schema); - } else { - entries.emplace_back(DatabaseManager::GetDefaultDatabase(context), schema); + } else if (auto default_database = DatabaseManager::TryGetDefaultDatabase(context); + !IsInvalidCatalog(default_database)) { + entries.emplace_back(std::move(default_database), schema); } } } else if (IsInvalidSchema(schema)) { @@ -998,12 +1000,16 @@ CatalogEntryLookup Catalog::TryLookupEntryAcrossCatalogs(CatalogEntryRetriever & lookups.reserve(entries.size()); for (auto &entry : entries) { optional_ptr catalog_entry; - if (if_not_found == OnEntryNotFound::RETURN_NULL) { + if (if_not_found == OnEntryNotFound::RETURN_NULL || IsInvalidCatalog(entry.GetCatalog())) { catalog_entry = Catalog::GetCatalogEntry(retriever, entry.GetCatalog()); } else { catalog_entry = &Catalog::GetCatalog(retriever, entry.GetCatalog()); } if (!catalog_entry) { + if (IsInvalidCatalog(entry.GetCatalog())) { + // the search path's default-database entry, with no database attached: nothing to search there + continue; + } return {nullptr, nullptr, ErrorData()}; } D_ASSERT(catalog_entry); @@ -1396,12 +1402,19 @@ vector> Catalog::GetSchemas(CatalogEntryRetriever auto &search_path = retriever.GetSearchPath(); for (auto &entry : search_path.Get()) { - auto &catalog = Catalog::GetCatalog(retriever, entry.GetCatalog()); - if (inserted_catalogs.find(catalog) != inserted_catalogs.end()) { + auto catalog = Catalog::GetCatalogEntry(retriever, entry.GetCatalog()); + if (!catalog) { + if (IsInvalidCatalog(entry.GetCatalog())) { + // the search path's default-database entry, with no database attached + continue; + } + throw BinderException("Catalog %s does not exist!", entry.GetCatalog()); + } + if (inserted_catalogs.find(*catalog) != inserted_catalogs.end()) { continue; } - inserted_catalogs.insert(catalog); - catalogs.push_back(catalog); + inserted_catalogs.insert(*catalog); + catalogs.push_back(*catalog); } } else { catalogs.push_back(Catalog::GetCatalog(retriever, Identifier(catalog_name))); diff --git a/src/duckdb/src/catalog/catalog_entry/aggregate_function_catalog_entry.cpp b/src/duckdb/src/catalog/catalog_entry/aggregate_function_catalog_entry.cpp index fd4ecc286..9debae64b 100644 --- a/src/duckdb/src/catalog/catalog_entry/aggregate_function_catalog_entry.cpp +++ b/src/duckdb/src/catalog/catalog_entry/aggregate_function_catalog_entry.cpp @@ -9,10 +9,8 @@ namespace duckdb { AggregateFunctionCatalogEntry::AggregateFunctionCatalogEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateAggregateFunctionInfo &info) : FunctionEntry(CatalogType::AGGREGATE_FUNCTION_ENTRY, catalog, schema, info), functions(info.functions) { - functions.ApplyToFunctions([&](AggregateFunction &function) { - function.SetCatalogName(catalog.GetAttached().GetName()); - function.SetSchemaName(schema.name); - }); + functions.ApplyToFunctions( + [&](AggregateFunction &function) { function.SetQualifiedName(schema.GetQualifiedName(name)); }); } } // namespace duckdb diff --git a/src/duckdb/src/catalog/catalog_entry/duck_index_entry.cpp b/src/duckdb/src/catalog/catalog_entry/duck_index_entry.cpp index 5f81bab17..5855aca6d 100644 --- a/src/duckdb/src/catalog/catalog_entry/duck_index_entry.cpp +++ b/src/duckdb/src/catalog/catalog_entry/duck_index_entry.cpp @@ -7,8 +7,7 @@ namespace duckdb { -IndexDataTableInfo::IndexDataTableInfo(shared_ptr info_p, const Identifier &index_name_p) - : info(std::move(info_p)), index_name(index_name_p) { +IndexDataTableInfo::IndexDataTableInfo(shared_ptr info_p) : info(std::move(info_p)) { } void DuckIndexEntry::Rollback(CatalogEntry &) { @@ -18,7 +17,7 @@ void DuckIndexEntry::Rollback(CatalogEntry &) { if (!info->info) { return; } - info->info->GetIndexes().RemoveIndex(name); + info->info->GetIndexes().RemoveIndex(oid); } DuckIndexEntry::DuckIndexEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateIndexInfo &create_info, @@ -26,7 +25,7 @@ DuckIndexEntry::DuckIndexEntry(Catalog &catalog, SchemaCatalogEntry &schema, Cre : IndexCatalogEntry(catalog, schema, create_info), initial_index_size(0) { auto &table = table_p.Cast(); auto &storage = table.GetStorage(); - info = make_shared_ptr(storage.GetDataTableInfo(), name); + info = make_shared_ptr(storage.GetDataTableInfo()); } DuckIndexEntry::DuckIndexEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateIndexInfo &create_info, @@ -58,7 +57,7 @@ DataTableInfo &DuckIndexEntry::GetDataTableInfo() const { void DuckIndexEntry::CommitDrop(CommitDropState &drop_state) { D_ASSERT(info); - drop_state.RemoveIndex(GetDataTableInfo().GetIndexes(), name); + drop_state.RemoveIndex(GetDataTableInfo().GetIndexes(), oid); } } // namespace duckdb diff --git a/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp b/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp index dd89850cb..e51e22270 100644 --- a/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +++ b/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp @@ -20,9 +20,7 @@ ScalarFunctionCatalogEntry::ScalarFunctionCatalogEntry(Catalog &catalog, SchemaC shared_ptr ScalarFunctionCatalogEntry::FinalizeFunction(ScalarFunction function) const { auto result = make_shared_ptr(std::move(function)); - result->SetName(name); - result->SetCatalogName(catalog.GetAttached().GetName()); - result->SetSchemaName(schema.name); + result->SetQualifiedName(schema.GetQualifiedName(name)); return result; } diff --git a/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp b/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp index cceb88859..0c2ce5615 100644 --- a/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +++ b/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp @@ -13,10 +13,12 @@ TableFunctionCatalogEntry::TableFunctionCatalogEntry(Catalog &catalog, SchemaCat CreateTableFunctionInfo &info) : FunctionEntry(CatalogType::TABLE_FUNCTION_ENTRY, catalog, schema, info), functions(std::move(info.functions)) { D_ASSERT(this->functions.Size() > 0); - functions.ApplyToFunctions([&](TableFunction &function) { - function.SetCatalogName(catalog.GetAttached().GetName()); - function.SetSchemaName(schema.name); - }); + functions.name = name; + functions.ApplyToFunctions([&](TableFunction &function) { FinalizeFunction(function); }); +} + +void TableFunctionCatalogEntry::FinalizeFunction(TableFunction &function) const { + function.SetQualifiedName(schema.GetQualifiedName(name)); } unique_ptr TableFunctionCatalogEntry::AlterEntry(CatalogTransaction transaction, AlterInfo &info) { @@ -35,6 +37,7 @@ unique_ptr TableFunctionCatalogEntry::AlterEntry(CatalogTransactio throw BinderException("Failed to add new function overloads to function \"%s\": function already exists", name); } CreateTableFunctionInfo new_info(std::move(new_set)); + new_info.internal = internal; return make_uniq(catalog, schema, new_info); } diff --git a/src/duckdb/src/catalog/catalog_entry/window_function_catalog_entry.cpp b/src/duckdb/src/catalog/catalog_entry/window_function_catalog_entry.cpp index 55ef448da..3a1ea819e 100644 --- a/src/duckdb/src/catalog/catalog_entry/window_function_catalog_entry.cpp +++ b/src/duckdb/src/catalog/catalog_entry/window_function_catalog_entry.cpp @@ -10,10 +10,8 @@ namespace duckdb { WindowFunctionCatalogEntry::WindowFunctionCatalogEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateWindowFunctionInfo &info) : FunctionEntry(Type, catalog, schema, info), functions(info.functions) { - functions.ApplyToFunctions([&](WindowFunction &function) { - function.SetCatalogName(catalog.GetAttached().GetName()); - function.SetSchemaName(schema.name); - }); + functions.ApplyToFunctions( + [&](WindowFunction &function) { function.SetQualifiedName(schema.GetQualifiedName(name)); }); } } // namespace duckdb diff --git a/src/duckdb/src/catalog/catalog_entry_retriever.cpp b/src/duckdb/src/catalog/catalog_entry_retriever.cpp index f1ca9f1b4..ec5298ea3 100644 --- a/src/duckdb/src/catalog/catalog_entry_retriever.cpp +++ b/src/duckdb/src/catalog/catalog_entry_retriever.cpp @@ -116,7 +116,10 @@ void CatalogEntryRetriever::SetSearchPath(vector entries) { auto &set_paths = client_search_path.GetSetPaths(); for (auto path : set_paths) { if (IsInvalidCatalog(path.GetCatalog())) { - path.SetCatalog(DatabaseManager::GetDefaultDatabase(context)); + path.SetCatalog(DatabaseManager::TryGetDefaultDatabase(context)); + if (IsInvalidCatalog(path.GetCatalog())) { + continue; + } } new_path.push_back(std::move(path)); } diff --git a/src/duckdb/src/catalog/catalog_search_path.cpp b/src/duckdb/src/catalog/catalog_search_path.cpp index 33473bb15..9786c4751 100644 --- a/src/duckdb/src/catalog/catalog_search_path.cpp +++ b/src/duckdb/src/catalog/catalog_search_path.cpp @@ -364,7 +364,7 @@ bool CatalogSearchPath::SchemaInSearchPath(ClientContext &context, const Identif if (path.GetCatalog() == catalog_name) { return true; } - if (IsInvalidCatalog(path.GetCatalog()) && catalog_name == DatabaseManager::GetDefaultDatabase(context)) { + if (IsInvalidCatalog(path.GetCatalog()) && catalog_name == DatabaseManager::TryGetDefaultDatabase(context)) { return true; } } diff --git a/src/duckdb/src/common/adbc/adbc.cpp b/src/duckdb/src/common/adbc/adbc.cpp index 68a90ef50..c53db168d 100644 --- a/src/duckdb/src/common/adbc/adbc.cpp +++ b/src/duckdb/src/common/adbc/adbc.cpp @@ -30,8 +30,6 @@ struct DuckDBErrorDetails { #include -#include "duckdb/main/materialized_query_result.hpp" - #include "duckdb/parser/keyword_helper.hpp" // We must leak the symbols of the init function diff --git a/src/duckdb/src/common/arrow/arrow_appender.cpp b/src/duckdb/src/common/arrow/arrow_appender.cpp index 296178990..3057f994d 100644 --- a/src/duckdb/src/common/arrow/arrow_appender.cpp +++ b/src/duckdb/src/common/arrow/arrow_appender.cpp @@ -88,7 +88,16 @@ ArrowArray *ArrowAppender::FinalizeChild(const LogicalType &type, unique_ptrbuffers[0] = append_data.GetValidityBuffer().data(); if (append_data.finalize) { - append_data.finalize(append_data, type, result.get()); + // An extension type's appender tree was initialized (and appended) with the extension's INTERNAL + // (storage) type — see InitializeChild — so it must also be finalized with that type: a nested + // finalizer (struct/list/map) sizes its child walk from the type it is given, and the LOGICAL + // type's shape need not match the storage-built child_data (e.g. a canonical Arrow extension over + // struct storage whose logical type has a different child count). + if (append_data.extension_data) { + append_data.finalize(append_data, append_data.extension_data->GetInternalType(), result.get()); + } else { + append_data.finalize(append_data, type, result.get()); + } } append_data.array = std::move(result); diff --git a/src/duckdb/src/common/arrow/arrow_query_result.cpp b/src/duckdb/src/common/arrow/arrow_query_result.cpp index 40d9b09d5..03bbefc5f 100644 --- a/src/duckdb/src/common/arrow/arrow_query_result.cpp +++ b/src/duckdb/src/common/arrow/arrow_query_result.cpp @@ -27,6 +27,10 @@ string ArrowQueryResult::ToString() { return ""; } +string ArrowQueryResult::ToBox(BoxRendererContext &context, const BoxRendererConfig &config) { + return ToString(); +} + vector> ArrowQueryResult::ConsumeArrays() { if (HasError()) { throw InvalidInputException("Attempting to fetch ArrowArrays from an unsuccessful query result: Error %s", diff --git a/src/duckdb/src/common/arrow/arrow_type_extension.cpp b/src/duckdb/src/common/arrow/arrow_type_extension.cpp index e7baa48ec..71f9bec85 100644 --- a/src/duckdb/src/common/arrow/arrow_type_extension.cpp +++ b/src/duckdb/src/common/arrow/arrow_type_extension.cpp @@ -2,12 +2,15 @@ #include "duckdb/common/types/hash.hpp" #include "duckdb/main/config.hpp" #include "duckdb/function/table/arrow/arrow_duck_schema.hpp" +#include "duckdb/function/table/arrow/arrow_type_info.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/common/arrow/arrow_converter.hpp" #include "duckdb/common/arrow/schema_metadata.hpp" #include "duckdb/common/types/vector.hpp" #include "duckdb/common/types/geometry_crs.hpp" #include "duckdb/common/json_document.hpp" +#include "duckdb/common/vector/struct_vector.hpp" +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" namespace duckdb { @@ -523,6 +526,222 @@ struct ArrowGeometry { } }; +struct ArrowVariant { + //! VARIANT travels as the canonical `arrow.parquet.variant` extension: the Variant spec's binary + //! encoding in a struct storage type. The values convert through + //! ParquetVariantConversion's encode/decode directly — never through the binder, since a conversion + //! can run without a valid transaction (e.g. duckdb_result_arrow_array over a materialized result). + + static LogicalType StorageType() { + child_list_t children; + children.emplace_back("metadata", LogicalType::BLOB); + children.emplace_back("value", LogicalType::BLOB); + return LogicalType::STRUCT(std::move(children)); + } + + //! Declares the storage schema: struct, tagged with the canonical + //! extension name. + static void PopulateSchema(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &schema, const LogicalType &type, + ClientContext &context, const ArrowTypeExtension &extension) { + const auto schema_metadata = ArrowSchemaMetadata::ArrowCanonicalType(extension.GetInfo().GetExtensionName()); + root_holder.metadata_info.emplace_back(schema_metadata.SerializeMetadata()); + schema.metadata = root_holder.metadata_info.back().get(); + + auto release_child = [](ArrowSchema *child) { + child->release = nullptr; + }; + + schema.format = "+s"; + schema.n_children = 2; + root_holder.nested_children.emplace_back(); + root_holder.nested_children.back().resize(2); + root_holder.nested_children_ptr.emplace_back(); + root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[0]); + root_holder.nested_children_ptr.back().push_back(&root_holder.nested_children.back()[1]); + schema.children = root_holder.nested_children_ptr.back().data(); + + // The appender picks the binary layout from the session settings — declare the same one, or the + // schema and the produced buffers disagree (same rule as SetArrowFormat's BLOB case). + const auto options = context.GetClientProperties(); + const char *binary_format; + if (options.arrow_output_version >= ArrowFormatVersion::V1_4) { + binary_format = "vz"; + } else if (options.arrow_offset_size == ArrowOffsetSize::LARGE) { + binary_format = "Z"; + } else { + binary_format = "z"; + } + + const char *child_names[] = {"metadata", "value"}; + for (idx_t i = 0; i < 2; i++) { + auto &child = *schema.children[i]; + child.format = binary_format; + child.name = child_names[i]; + // the spec requires `metadata` non-nullable; `value` stays nullable (it may be absent per row + // once shredding exists) + child.flags = i == 0 ? 0 : ARROW_FLAG_NULLABLE; + child.release = release_child; + } + } + + //! Maps a tagged schema back: the VARIANT logical type, with type info describing the storage struct + //! for the reader's buffer walk. The spec allows the fields in ANY order, in any binary layout + //! (binary / large binary / view), and dictionary- or run-end-encoded — so the fields are resolved by + //! NAME and the children are parsed from the actual schema. The resolved order is recorded on a + //! per-column ArrowTypeExtensionData whose internal type is the storage struct in the schema's OWN + //! field order (the buffer walk is positional), so the conversion can normalize by name. + static unique_ptr GetType(ClientContext &context, const ArrowSchema &schema, + const ArrowSchemaMetadata &schema_metadata) { + if (!schema.format || string(schema.format) != "+s") { + throw InvalidInputException("arrow.parquet.variant column must have a struct storage type, got format '%s'", + schema.format ? schema.format : "(none)"); + } + idx_t metadata_idx = DConstants::INVALID_INDEX; + idx_t value_idx = DConstants::INVALID_INDEX; + for (idx_t i = 0; i < NumericCast(schema.n_children); i++) { + const string name = schema.children[i]->name ? schema.children[i]->name : ""; + if (name == "metadata" && metadata_idx == DConstants::INVALID_INDEX) { + metadata_idx = i; + } else if (name == "value" && value_idx == DConstants::INVALID_INDEX) { + value_idx = i; + } else if (name == "typed_value") { + // TODO: support shredded variants — the value has to be re-assembled from typed_value + // (and, when both are present, merged with the residual value field). + throw NotImplementedException( + "arrow.parquet.variant column with a 'typed_value' field (a shredded variant) is not supported " + "yet"); + } else { + throw InvalidInputException( + "arrow.parquet.variant column has an unexpected or duplicate field '%s' (expected 'metadata' and " + "'value')", + name); + } + } + if (metadata_idx == DConstants::INVALID_INDEX || value_idx == DConstants::INVALID_INDEX) { + throw InvalidInputException( + "arrow.parquet.variant column must have a 'metadata' and a 'value' field, got %lld children", + schema.n_children); + } + vector> children; + child_list_t storage_children; + for (idx_t i = 0; i < NumericCast(schema.n_children); i++) { + // GetArrowLogicalType, not GetTypeFromSchema: a dictionary-encoded child carries its value + // type in schema.dictionary, which only this entry point resolves. + children.push_back(ArrowType::GetArrowLogicalType(context, *schema.children[i])); + // Both fields are binary by the spec. Without this check a non-binary field would be + // declared BLOB storage here and then reinterpreted as bytes by the decode. + const auto child_type = children.back()->GetDuckType(true); + if (child_type.id() != LogicalTypeId::BLOB) { + throw InvalidInputException("arrow.parquet.variant field '%s' must be a binary type, got %s", + schema.children[i]->name, child_type.ToString()); + } + storage_children.emplace_back(schema.children[i]->name, LogicalType::BLOB); + } + auto result = make_uniq(LogicalType::VARIANT(), make_uniq(std::move(children))); + result->extension_data = make_shared_ptr( + LogicalType::VARIANT(), LogicalType::STRUCT(std::move(storage_children)), ArrowToDuck, DuckToArrow); + return result; + } + + //! DuckDB -> Arrow: convert VARIANT values into the storage struct via the Parquet Variant encode + //! (the result vector declares no typed_value child, so the result is the unshredded + //! struct). + static void DuckToArrow(ClientContext &, const Vector &source, Vector &result, idx_t count) { + Vector transformed(StorageType(), count); + ParquetVariantConversion::ToParquetVariant(source, count, transformed); + + // The transform encodes a SQL NULL as a Variant-null VALUE (the parquet writer's convention, where + // nullability lives at the column level) — over Arrow the SQL NULL must stay a top-level null, so + // the mask comes from the SOURCE's validity. + UnifiedVectorFormat source_format; + source.ToUnifiedFormat(source_format); + bool has_nulls = false; + for (idx_t i = 0; i < count; i++) { + if (!source_format.validity.RowIsValid(source_format.sel->get_index(i)) || + FlatVector::IsNull(transformed, i)) { + FlatVector::SetNull(result, i, true); + has_nulls = true; + } + } + + // Move the encoded data over child-wise so `result` (the extension's declared storage type) + // shares the encode's buffers where possible. + auto &result_entries = StructVector::GetEntries(result); + auto &transformed_entries = StructVector::GetEntries(transformed); + if (!has_nulls) { + result_entries[0].Reference(transformed_entries[0]); + result_entries[1].Reference(transformed_entries[1]); + return; + } + // `metadata` is declared non-nullable, as the spec requires — so a NULL row's child slots carry + // the minimal valid encoding (v1 empty-dictionary metadata + a Variant null value) instead of the + // child-level NULLs a strict consumer would reject. Copy into the result's OWN children rather + // than patching buffers shared with the transform's output. + static constexpr const char MINIMAL_METADATA[] = "\x01\x00\x00"; + static constexpr const char VARIANT_NULL_VALUE[] = "\x00"; + transformed_entries[0].Flatten(); + transformed_entries[1].Flatten(); + auto src_metadata = FlatVector::GetData(transformed_entries[0]); + auto src_value = FlatVector::GetData(transformed_entries[1]); + auto &metadata_entry = result_entries[0]; + auto &value_entry = result_entries[1]; + auto dst_metadata = FlatVector::GetDataMutable(metadata_entry); + auto dst_value = FlatVector::GetDataMutable(value_entry); + for (idx_t i = 0; i < count; i++) { + if (FlatVector::IsNull(result, i)) { + dst_metadata[i] = string_t(MINIMAL_METADATA, 3); + dst_value[i] = string_t(VARIANT_NULL_VALUE, 1); + } else { + dst_metadata[i] = StringVector::AddStringOrBlob(metadata_entry, src_metadata[i]); + dst_value[i] = StringVector::AddStringOrBlob(value_entry, src_value[i]); + } + } + FlatVector::ValidityMutable(metadata_entry).SetAllValid(count); + FlatVector::ValidityMutable(value_entry).SetAllValid(count); + } + + //! Arrow -> DuckDB: concatenate each row's metadata and value bytes (the self-delimiting Variant + //! binary form) and decode through the Parquet Variant binary decode. + static void ArrowToDuck(ClientContext &, Vector &source, Vector &result, idx_t count) { + source.Flatten(); + // The storage vector's type records the incoming schema's own field order (see GetType, + // which already established that these are exactly the two fields) - so only their order + // is open here, the spec allowing them either way round. + auto &source_children = StructType::GetChildTypes(source.GetType()); + const idx_t metadata_idx = source_children[0].first == "metadata" ? 0 : 1; + const idx_t value_idx = 1 - metadata_idx; + auto &entries = StructVector::GetEntries(source); + Vector &metadata = entries[metadata_idx]; + Vector &value = entries[value_idx]; + metadata.Flatten(); + value.Flatten(); + + Vector blob(LogicalType::BLOB, count); + auto blob_data = FlatVector::GetDataMutable(blob); + auto metadata_data = FlatVector::GetData(metadata); + auto value_data = FlatVector::GetData(value); + for (idx_t i = 0; i < count; i++) { + if (FlatVector::IsNull(source, i) || FlatVector::IsNull(metadata, i) || FlatVector::IsNull(value, i)) { + // The decode reads the blob's validity and answers a Variant null for an invalid + // row, so the slot itself is never read. + FlatVector::SetNull(blob, i, true); + continue; + } + auto &metadata_bytes = metadata_data[i]; + auto &value_bytes = value_data[i]; + auto total_size = metadata_bytes.GetSize() + value_bytes.GetSize(); + auto target = StringVector::EmptyString(blob, total_size); + auto target_ptr = target.GetDataWriteable(); + memcpy(target_ptr, metadata_bytes.GetData(), metadata_bytes.GetSize()); + memcpy(target_ptr + metadata_bytes.GetSize(), value_bytes.GetData(), value_bytes.GetSize()); + target.Finalize(); + blob_data[i] = target; + } + + ParquetVariantConversion::ConvertBinary(blob, result, count); + } +}; + void ArrowTypeExtensionSet::Initialize(const DBConfig &config) { // Types that are 1:1 config.RegisterArrowExtension({"arrow.uuid", "w:16", make_shared_ptr(LogicalType::UUID)}); @@ -552,5 +771,10 @@ void ArrowTypeExtensionSet::Initialize(const DBConfig &config) { config.RegisterArrowExtension({"DuckDB", "bignum", &ArrowBignum::PopulateSchema, &ArrowBignum::GetType, make_shared_ptr(LogicalType::BIGNUM), nullptr, nullptr}); + + config.RegisterArrowExtension( + {"arrow.parquet.variant", &ArrowVariant::PopulateSchema, &ArrowVariant::GetType, + make_shared_ptr(LogicalType::VARIANT(), ArrowVariant::StorageType(), + ArrowVariant::ArrowToDuck, ArrowVariant::DuckToArrow)}); } } // namespace duckdb diff --git a/src/duckdb/src/common/arrow/arrow_wrapper.cpp b/src/duckdb/src/common/arrow/arrow_wrapper.cpp index f739e09a3..51475b707 100644 --- a/src/duckdb/src/common/arrow/arrow_wrapper.cpp +++ b/src/duckdb/src/common/arrow/arrow_wrapper.cpp @@ -5,12 +5,12 @@ #include "duckdb/common/assert.hpp" #include "duckdb/common/exception.hpp" -#include "duckdb/main/stream_query_result.hpp" - #include "duckdb/common/arrow/result_arrow_wrapper.hpp" #include "duckdb/common/arrow/arrow_appender.hpp" #include "duckdb/main/query_result.hpp" #include "duckdb/main/chunk_scan_state/query_result.hpp" +#include "duckdb/main/chunk_scan_state/query_result_stream.hpp" +#include "duckdb/main/buffered_data/buffered_data.hpp" #include "duckdb/function/table/arrow/arrow_duck_schema.hpp" namespace duckdb { @@ -70,37 +70,19 @@ int ResultArrowArrayStreamWrapper::MyStreamGetSchema(struct ArrowArrayStream *st } out->release = nullptr; auto my_stream = reinterpret_cast(stream->private_data); - if (!my_stream->column_types.empty()) { - try { - ArrowConverter::ToArrowSchema(out, my_stream->column_types, my_stream->column_names, - my_stream->result->client_properties); - } catch (std::runtime_error &e) { - my_stream->last_error = ErrorData(e); - return -1; - } - return 0; - } - - auto &result = *my_stream->result; - if (result.HasError()) { - my_stream->last_error = result.GetErrorObject(); + auto &scan_state = *my_stream->scan_state; + if (scan_state.HasError()) { + my_stream->last_error = scan_state.GetError(); return -1; } - if (result.GetResultType() == QueryResultType::STREAM_RESULT) { - auto &stream_result = result.Cast(); - if (!stream_result.IsOpen()) { - my_stream->last_error = ErrorData("Query Stream is closed"); - return -1; - } - } if (my_stream->column_types.empty()) { - my_stream->column_types = result.GetTypes(); - my_stream->column_names = IdentifiersToStrings(result.GetNames()); + my_stream->column_types = scan_state.Types(); + my_stream->column_names = IdentifiersToStrings(scan_state.Names()); } try { ArrowConverter::ToArrowSchema(out, my_stream->column_types, my_stream->column_names, - my_stream->result->client_properties); - } catch (std::runtime_error &e) { + my_stream->client_properties); + } catch (std::exception &e) { my_stream->last_error = ErrorData(e); return -1; } @@ -112,30 +94,33 @@ int ResultArrowArrayStreamWrapper::MyStreamGetNext(struct ArrowArrayStream *stre return -1; } auto my_stream = reinterpret_cast(stream->private_data); - auto &result = *my_stream->result; auto &scan_state = *my_stream->scan_state; - if (result.HasError()) { - my_stream->last_error = result.GetErrorObject(); + if (scan_state.HasError()) { + my_stream->last_error = scan_state.GetError(); return -1; } - if (result.GetResultType() == QueryResultType::STREAM_RESULT) { - auto &stream_result = result.Cast(); - if (!stream_result.IsOpen()) { - // Nothing to output + if (my_stream->stream_result) { + // A stream ended by another statement has not been asked yet; Poll records that as its error + if (my_stream->stream_result->Poll() == QueryResultState::EXECUTION_ERROR) { + my_stream->last_error = my_stream->stream_result->GetErrorObject(); + return -1; + } + if (!my_stream->stream_result->IsOpen()) { + // The ended stream released its context, which converting a batch would need out->release = nullptr; return 0; } } if (my_stream->column_types.empty()) { - my_stream->column_types = result.GetTypes(); - my_stream->column_names = IdentifiersToStrings(result.GetNames()); + my_stream->column_types = scan_state.Types(); + my_stream->column_names = IdentifiersToStrings(scan_state.Names()); } try { idx_t result_count; ErrorData error; - if (!ArrowUtil::TryFetchChunk(scan_state, result.client_properties, my_stream->batch_size, out, result_count, - error, my_stream->extension_types)) { + if (!ArrowUtil::TryFetchChunk(scan_state, my_stream->client_properties, my_stream->batch_size, out, + result_count, error, my_stream->extension_types)) { D_ASSERT(error.HasError()); my_stream->last_error = error; return -1; @@ -169,23 +154,48 @@ const char *ResultArrowArrayStreamWrapper::MyStreamGetLastError(struct ArrowArra return my_stream->last_error.Message().c_str(); } +static bool CanDrain(QueryResult &result) { + if (result.HasError()) { + return false; + } + if (result.GetStatementProperties().result_eagerness == ResultEagerness::FORCED) { + return false; + } + if (!result.HasBufferedData()) { + return false; + } + return result.GetBufferedData().Lifetime() != ResultLifetime::RETAINED; +} + +static ClientProperties PropertiesOf(unique_ptr &result) { + if (!result) { + throw InvalidInputException("Attempting to export a query result that does not exist as an Arrow stream"); + } + return result->client_properties; +} + ResultArrowArrayStreamWrapper::ResultArrowArrayStreamWrapper(unique_ptr result_p, idx_t batch_size_p) - : result(std::move(result_p)), scan_state(make_uniq(*result)) { - //! We first initialize the private data of the stream - stream.private_data = this; - //! Ceil Approx_Batch_Size/STANDARD_VECTOR_SIZE + : client_properties(PropertiesOf(result_p)), batch_size(batch_size_p) { if (batch_size_p == 0) { throw std::runtime_error("Approximate Batch Size of Record Batch MUST be higher than 0"); } - batch_size = batch_size_p; - //! We initialize the stream functions + if (CanDrain(*result_p)) { + stream_result = make_uniq(std::move(result_p)); + scan_state = make_uniq(*stream_result); + } else { + result = std::move(result_p); + scan_state = make_uniq(*result); + } + if (client_properties.client_context) { + extension_types = + ArrowTypeExtensionData::GetExtensionTypes(*client_properties.client_context, scan_state->Types()); + } + + stream.private_data = this; stream.get_schema = ResultArrowArrayStreamWrapper::MyStreamGetSchema; stream.get_next = ResultArrowArrayStreamWrapper::MyStreamGetNext; stream.release = ResultArrowArrayStreamWrapper::MyStreamRelease; stream.get_last_error = ResultArrowArrayStreamWrapper::MyStreamGetLastError; - - extension_types = - ArrowTypeExtensionData::GetExtensionTypes(*result->client_properties.client_context, result->GetTypes()); } } // namespace duckdb diff --git a/src/duckdb/src/common/clustered_aggregate.cpp b/src/duckdb/src/common/clustered_aggregate.cpp index ba8ac0ddb..8225d4acc 100644 --- a/src/duckdb/src/common/clustered_aggregate.cpp +++ b/src/duckdb/src/common/clustered_aggregate.cpp @@ -89,7 +89,10 @@ static inline uint64_t slot_hash(uint64_t gid) { return ((gid * 3217161767) ^ (gid >> ClusteredAggr::HASHTAB_LOG2)) & (ClusteredAggr::HASHTAB_SZ - 1); } -bool ClusteredAggr::TryClustered(const uint64_t *group_ids, sel_t count, sel_t *arena, uint64_t *slots) { +bool ClusteredAggr::TryClustered(const uint64_t *group_ids, sel_t count, sel_t *arena, uint64_t *slots, + GroupRun *runs) { + group_runs = runs; + constexpr sel_t HALF_VEC = STANDARD_VECTOR_SIZE / 2; constexpr idx_t MAX_HOT_PER_CURSOR = MAX_HOTKEYS / 2; idx_t tuples_in_large = 0; @@ -240,9 +243,10 @@ bool ClusteredAggr::TryClustered(const uint64_t *group_ids, sel_t count, sel_t * return (5 * tuples_in_large >= 4 * static_cast(count)); // require >=80% of tuples in long-enough runs } -void ClusteredAggr::SetSingleRun(data_ptr_t state, idx_t count) { +void ClusteredAggr::SetSingleRun(data_ptr_t state_ptr, idx_t count) { + D_ASSERT(group_runs == &single_run); n_group_runs = 1; - group_runs[0].state = state; + group_runs[0].state = state_ptr; group_runs[0].sel = nullptr; group_runs[0].gid = 0; group_runs[0].count = count; @@ -255,7 +259,7 @@ void ClusteredAggr::AdvanceStates(idx_t payload_size) { } } -const sel_t *ClusteredAggr::ClusterIter(const Vector &input, idx_t count) const { +const sel_t *ClusteredAggr::ClusterIter(const Vector &input) const { if (input.GetVectorType() != VectorType::DICTIONARY_VECTOR) { return nullptr; } @@ -263,23 +267,29 @@ const sel_t *ClusteredAggr::ClusterIter(const Vector &input, idx_t count) const if (child.GetVectorType() != VectorType::FLAT_VECTOR) { return nullptr; } - auto &dict_sel = DictionaryVector::SelVector(input); - const sel_t *dict_data = dict_sel.data(); + const sel_t *dict_data = DictionaryVector::SelVector(input).data(); if (dict_data == nullptr) { return nullptr; } + auto run_range = runs(); + if (run_range.size() == 1 && run_range[0].sel == nullptr) { + return dict_data; + } + D_ASSERT(state); if (cached_dict_sel == dict_data) { - return composed_sel_data; + return state->composed_sel_data.get(); } + if (!state->composed_sel_data) { + state->composed_sel_data = make_unsafe_uniq_array_uninitialized(STANDARD_VECTOR_SIZE); + } + auto composed_sel_data = state->composed_sel_data.get(); idx_t pos = 0; - for (idx_t r = 0; r < n_group_runs; r++) { - const auto *run_sel = group_runs[r].sel; - const auto run_count = group_runs[r].count; - for (idx_t k = 0; k < run_count; k++) { - auto idx = run_sel ? run_sel[k] : k; + for (auto &run : run_range) { + for (idx_t k = 0; k < run.count; k++) { + auto idx = run.sel ? run.sel[k] : k; composed_sel_data[pos + k] = dict_data[idx]; } - pos += run_count; + pos += run.count; } cached_dict_sel = dict_data; return composed_sel_data; @@ -290,13 +300,14 @@ void ClusteredAggrState::Initialize() { // Total = 2 * (MAX_HOTKEYS/2 + 1) * HALF_VEC = (MAX_HOTKEYS/2 + 1) * STANDARD_VECTOR_SIZE. arena = make_unsafe_uniq_array_uninitialized((ClusteredAggr::MAX_HOTKEYS / 2 + 1) * STANDARD_VECTOR_SIZE); slots = make_unsafe_uniq_array_uninitialized(2 * ClusteredAggr::HASHTAB_SZ); + group_runs = make_unsafe_uniq_array_uninitialized(ClusteredAggr::MAX_RUNS); std::fill_n(slots.get(), 2 * ClusteredAggr::HASHTAB_SZ, ClusteredAggr::FREE_SLOT); skipped_opportunities = 0; retry_backoff = 1; } bool ClusteredAggrState::TryBuild(ClusteredAggr &clustered, const uint64_t *group_ids, idx_t count) { - if (!arena) { + if (!arena || !group_runs) { return false; } if (skipped_opportunities > 0) { @@ -304,7 +315,7 @@ bool ClusteredAggrState::TryBuild(ClusteredAggr &clustered, const uint64_t *grou return false; } if (count >= ClusteredAggr::SAMPLE_SIZE && - clustered.TryClustered(group_ids, static_cast(count), arena.get(), slots.get())) { + clustered.TryClustered(group_ids, static_cast(count), arena.get(), slots.get(), group_runs.get())) { clustered.state = this; skipped_opportunities = 0; retry_backoff = 1; diff --git a/src/duckdb/src/common/compressed_file_system.cpp b/src/duckdb/src/common/compressed_file_system.cpp index bc25e788c..3060eac5b 100644 --- a/src/duckdb/src/common/compressed_file_system.cpp +++ b/src/duckdb/src/common/compressed_file_system.cpp @@ -8,6 +8,9 @@ namespace duckdb { StreamWrapper::~StreamWrapper() { } +void StreamWrapper::FinalizeRead(StreamData &) { +} + void StreamWrapper::AbortWrite() { Close(); } @@ -112,22 +115,6 @@ int64_t CompressedFile::ReadData(void *buffer, int64_t remaining) { D_ASSERT(stream_data.in_buff_start <= stream_data.in_buff_end); D_ASSERT(stream_data.in_buff_end <= stream_data.in_buff_start + stream_data.in_buf_size); - // read more input when requested and still data in the input stream - if (stream_data.refresh && (stream_data.in_buff_end == stream_data.in_buff.get() + stream_data.in_buf_size)) { - auto bufrem = stream_data.in_buff_end - stream_data.in_buff_start; - // buffer not empty, move remaining bytes to the beginning - memmove(stream_data.in_buff.get(), stream_data.in_buff_start, UnsafeNumericCast(bufrem)); - stream_data.in_buff_start = stream_data.in_buff.get(); - // refill the rest of input buffer - auto sz = child_handle->Read(context, stream_data.in_buff_start + bufrem, - stream_data.in_buf_size - UnsafeNumericCast(bufrem)); - stream_data.in_buff_end = stream_data.in_buff_start + bufrem + sz; - if (sz <= 0) { - stream_wrapper.reset(); - break; - } - } - // read more input if none available if (stream_data.in_buff_start == stream_data.in_buff_end) { // empty input buffer: refill from the start @@ -135,10 +122,12 @@ int64_t CompressedFile::ReadData(void *buffer, int64_t remaining) { stream_data.in_buff_end = stream_data.in_buff_start; auto sz = child_handle->Read(context, stream_data.in_buff.get(), stream_data.in_buf_size); if (sz <= 0) { + stream_wrapper->FinalizeRead(stream_data); stream_wrapper.reset(); break; + } else { + stream_data.in_buff_end = stream_data.in_buff_start + sz; } - stream_data.in_buff_end = stream_data.in_buff_start + sz; } auto finished = stream_wrapper->Read(stream_data); diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp index 52a511e4b..7219f8a9b 100644 --- a/src/duckdb/src/common/enum_util.cpp +++ b/src/duckdb/src/common/enum_util.cpp @@ -31,6 +31,7 @@ #include "duckdb/common/enums/date_part_specifier.hpp" #include "duckdb/common/enums/debug_initialize.hpp" #include "duckdb/common/enums/debug_order_verification.hpp" +#include "duckdb/common/enums/debug_progress_verification.hpp" #include "duckdb/common/enums/debug_statement_verification.hpp" #include "duckdb/common/enums/debug_vector_verification.hpp" #include "duckdb/common/enums/debug_verification_mode.hpp" @@ -38,6 +39,7 @@ #include "duckdb/common/enums/dialect_compatibility_mode.hpp" #include "duckdb/common/enums/expression_type.hpp" #include "duckdb/common/enums/file_glob_options.hpp" +#include "duckdb/common/enums/file_sync_mode.hpp" #include "duckdb/common/enums/file_write_mode.hpp" #include "duckdb/common/enums/filter_propagate_result.hpp" #include "duckdb/common/enums/function_errors.hpp" @@ -58,14 +60,16 @@ #include "duckdb/common/enums/order_type.hpp" #include "duckdb/common/enums/ordinality_request_type.hpp" #include "duckdb/common/enums/output_type.hpp" -#include "duckdb/common/enums/pending_execution_result.hpp" #include "duckdb/common/enums/physical_operator_type.hpp" #include "duckdb/common/enums/prepared_statement_mode.hpp" #include "duckdb/common/enums/preserve_order.hpp" #include "duckdb/common/enums/profiling_coverage.hpp" #include "duckdb/common/enums/quantile_enum.hpp" +#include "duckdb/common/enums/query_result_memory_type.hpp" +#include "duckdb/common/enums/query_result_state.hpp" #include "duckdb/common/enums/regex_match_operator_semantics.hpp" #include "duckdb/common/enums/relation_type.hpp" +#include "duckdb/common/enums/result_eagerness.hpp" #include "duckdb/common/enums/result_lifetime.hpp" #include "duckdb/common/enums/row_group_append_mode.hpp" #include "duckdb/common/enums/row_id_handling.hpp" @@ -75,7 +79,6 @@ #include "duckdb/common/enums/show_behavior.hpp" #include "duckdb/common/enums/statement_type.hpp" #include "duckdb/common/enums/storage_block_prefetch.hpp" -#include "duckdb/common/enums/stream_execution_result.hpp" #include "duckdb/common/enums/subquery_type.hpp" #include "duckdb/common/enums/table_function_identifier_conversion.hpp" #include "duckdb/common/enums/tableref_type.hpp" @@ -100,7 +103,6 @@ #include "duckdb/common/multi_file/multi_file_states.hpp" #include "duckdb/common/operator/decimal_cast_operators.hpp" #include "duckdb/common/printer.hpp" -#include "duckdb/common/query_parameters.hpp" #include "duckdb/common/sorting/sort_key.hpp" #include "duckdb/common/types.hpp" #include "duckdb/common/types/column/column_data_scan_states.hpp" @@ -181,6 +183,7 @@ #include "duckdb/parallel/pipeline.hpp" #include "duckdb/parallel/pipeline_broadcast_exchange.hpp" #include "duckdb/parallel/pipeline_schedule.hpp" +#include "duckdb/parallel/progress_verifier.hpp" #include "duckdb/parallel/scan_read_ahead.hpp" #include "duckdb/parallel/task.hpp" #include "duckdb/parser/constraint.hpp" @@ -203,8 +206,8 @@ #include "duckdb/parser/parsed_data/sample_options.hpp" #include "duckdb/parser/parsed_data/transaction_info.hpp" #include "duckdb/parser/parser_extension.hpp" -#include "duckdb/parser/peg/keyword_helper.hpp" #include "duckdb/parser/peg/matcher.hpp" +#include "duckdb/parser/peg/matcher/operator_matcher.hpp" #include "duckdb/parser/peg/sql_formatter.hpp" #include "duckdb/parser/peg/transformer/parse_result.hpp" #include "duckdb/parser/peg/transformer/peg_transformer.hpp" @@ -222,6 +225,7 @@ #include "duckdb/planner/filter/table_filter_functions.hpp" #include "duckdb/planner/logical_operator_repeatability.hpp" #include "duckdb/planner/table_filter.hpp" +#include "duckdb/storage/buffer/block_handle.hpp" #include "duckdb/storage/buffer/buffer_pool_reservation.hpp" #include "duckdb/storage/caching_mode.hpp" #include "duckdb/storage/compression/bitpacking.hpp" @@ -1116,6 +1120,26 @@ CachingMode EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetCachingModeValues(), 3, "CachingMode", value)); } +const StringUtil::EnumStringLiteral *GetCanUnloadResultValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(CanUnloadResult::CAN_UNLOAD), "CAN_UNLOAD" }, + { static_cast(CanUnloadResult::ALREADY_UNLOADED), "ALREADY_UNLOADED" }, + { static_cast(CanUnloadResult::PINNED), "PINNED" }, + { static_cast(CanUnloadResult::NO_TEMP_DIRECTORY), "NO_TEMP_DIRECTORY" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(CanUnloadResult value) { + return StringUtil::EnumToString(GetCanUnloadResultValues(), 4, "CanUnloadResult", static_cast(value)); +} + +template<> +CanUnloadResult EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetCanUnloadResultValues(), 4, "CanUnloadResult", value)); +} + const StringUtil::EnumStringLiteral *GetCatalogLookupBehaviorValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(CatalogLookupBehavior::STANDARD), "STANDARD" }, @@ -1697,6 +1721,25 @@ DebugOrderVerification EnumUtil::FromString(const char * return static_cast(StringUtil::StringToEnum(GetDebugOrderVerificationValues(), 3, "DebugOrderVerification", value)); } +const StringUtil::EnumStringLiteral *GetDebugProgressVerificationValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(DebugProgressVerification::NONE), "NONE" }, + { static_cast(DebugProgressVerification::LOG), "LOG" }, + { static_cast(DebugProgressVerification::ERROR), "ERROR" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(DebugProgressVerification value) { + return StringUtil::EnumToString(GetDebugProgressVerificationValues(), 3, "DebugProgressVerification", static_cast(value)); +} + +template<> +DebugProgressVerification EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetDebugProgressVerificationValues(), 3, "DebugProgressVerification", value)); +} + const StringUtil::EnumStringLiteral *GetDebugStatementVerificationValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(DebugStatementVerification::NONE), "NONE" }, @@ -2584,6 +2627,25 @@ FileNameSegmentType EnumUtil::FromString(const char *value) return static_cast(StringUtil::StringToEnum(GetFileNameSegmentTypeValues(), 4, "FileNameSegmentType", value)); } +const StringUtil::EnumStringLiteral *GetFileSyncModeValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(FileSyncMode::STANDARD), "STANDARD" }, + { static_cast(FileSyncMode::NONE), "NONE" }, + { static_cast(FileSyncMode::FULL), "FULL" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(FileSyncMode value) { + return StringUtil::EnumToString(GetFileSyncModeValues(), 3, "FileSyncMode", static_cast(value)); +} + +template<> +FileSyncMode EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetFileSyncModeValues(), 3, "FileSyncMode", value)); +} + const StringUtil::EnumStringLiteral *GetFileWriteModeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(FileWriteMode::SEQUENTIAL), "SEQUENTIAL" }, @@ -3230,19 +3292,20 @@ const StringUtil::EnumStringLiteral *GetKeywordCategoryValues() { { static_cast(KeywordCategory::KEYWORD_UNRESERVED), "KEYWORD_UNRESERVED" }, { static_cast(KeywordCategory::KEYWORD_TYPE_FUNC), "KEYWORD_TYPE_FUNC" }, { static_cast(KeywordCategory::KEYWORD_COL_NAME), "KEYWORD_COL_NAME" }, - { static_cast(KeywordCategory::KEYWORD_NONE), "KEYWORD_NONE" } + { static_cast(KeywordCategory::KEYWORD_NONE), "KEYWORD_NONE" }, + { static_cast(KeywordCategory::KEYWORD_TYPE_NAME), "KEYWORD_TYPE_NAME" } }; return values; } template<> const char* EnumUtil::ToChars(KeywordCategory value) { - return StringUtil::EnumToString(GetKeywordCategoryValues(), 5, "KeywordCategory", static_cast(value)); + return StringUtil::EnumToString(GetKeywordCategoryValues(), 6, "KeywordCategory", static_cast(value)); } template<> KeywordCategory EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetKeywordCategoryValues(), 5, "KeywordCategory", value)); + return static_cast(StringUtil::StringToEnum(GetKeywordCategoryValues(), 6, "KeywordCategory", value)); } const StringUtil::EnumStringLiteral *GetLambdaSyntaxValues() { @@ -4068,6 +4131,24 @@ OperatorFinalizeResultType EnumUtil::FromString(cons return static_cast(StringUtil::StringToEnum(GetOperatorFinalizeResultTypeValues(), 2, "OperatorFinalizeResultType", value)); } +const StringUtil::EnumStringLiteral *GetOperatorMatcherModeValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(OperatorMatcherMode::GENERIC_PRECEDENCE), "GENERIC_PRECEDENCE" }, + { static_cast(OperatorMatcherMode::ALL_OPERATORS), "ALL_OPERATORS" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(OperatorMatcherMode value) { + return StringUtil::EnumToString(GetOperatorMatcherModeValues(), 2, "OperatorMatcherMode", static_cast(value)); +} + +template<> +OperatorMatcherMode EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetOperatorMatcherModeValues(), 2, "OperatorMatcherMode", value)); +} + const StringUtil::EnumStringLiteral *GetOperatorResultTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(OperatorResultType::NEED_MORE_INPUT), "NEED_MORE_INPUT" }, @@ -4287,28 +4368,6 @@ OutputStream EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetOutputStreamValues(), 2, "OutputStream", value)); } -const StringUtil::EnumStringLiteral *GetPEGKeywordCategoryValues() { - static constexpr StringUtil::EnumStringLiteral values[] { - { static_cast(PEGKeywordCategory::KEYWORD_NONE), "KEYWORD_NONE" }, - { static_cast(PEGKeywordCategory::KEYWORD_UNRESERVED), "KEYWORD_UNRESERVED" }, - { static_cast(PEGKeywordCategory::KEYWORD_RESERVED), "KEYWORD_RESERVED" }, - { static_cast(PEGKeywordCategory::KEYWORD_TYPE_FUNC), "KEYWORD_TYPE_FUNC" }, - { static_cast(PEGKeywordCategory::KEYWORD_COL_NAME), "KEYWORD_COL_NAME" }, - { static_cast(PEGKeywordCategory::KEYWORD_TYPE_NAME), "KEYWORD_TYPE_NAME" } - }; - return values; -} - -template<> -const char* EnumUtil::ToChars(PEGKeywordCategory value) { - return StringUtil::EnumToString(GetPEGKeywordCategoryValues(), 6, "PEGKeywordCategory", static_cast(value)); -} - -template<> -PEGKeywordCategory EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetPEGKeywordCategoryValues(), 6, "PEGKeywordCategory", value)); -} - const StringUtil::EnumStringLiteral *GetParseInfoTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(ParseInfoType::ALTER_INFO), "ALTER_INFO" }, @@ -4448,28 +4507,6 @@ PatternMatchType EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetPatternMatchTypeValues(), 2, "PatternMatchType", value)); } -const StringUtil::EnumStringLiteral *GetPendingExecutionResultValues() { - static constexpr StringUtil::EnumStringLiteral values[] { - { static_cast(PendingExecutionResult::RESULT_READY), "RESULT_READY" }, - { static_cast(PendingExecutionResult::RESULT_NOT_READY), "RESULT_NOT_READY" }, - { static_cast(PendingExecutionResult::EXECUTION_ERROR), "EXECUTION_ERROR" }, - { static_cast(PendingExecutionResult::BLOCKED), "BLOCKED" }, - { static_cast(PendingExecutionResult::NO_TASKS_AVAILABLE), "NO_TASKS_AVAILABLE" }, - { static_cast(PendingExecutionResult::EXECUTION_FINISHED), "EXECUTION_FINISHED" } - }; - return values; -} - -template<> -const char* EnumUtil::ToChars(PendingExecutionResult value) { - return StringUtil::EnumToString(GetPendingExecutionResultValues(), 6, "PendingExecutionResult", static_cast(value)); -} - -template<> -PendingExecutionResult EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetPendingExecutionResultValues(), 6, "PendingExecutionResult", value)); -} - const StringUtil::EnumStringLiteral *GetPhysicalOperatorTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(PhysicalOperatorType::INVALID), "INVALID" }, @@ -4861,6 +4898,30 @@ ProfilingParameterNames EnumUtil::FromString(const char return static_cast(StringUtil::StringToEnum(GetProfilingParameterNamesValues(), 5, "ProfilingParameterNames", value)); } +const StringUtil::EnumStringLiteral *GetProgressInvariantValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(ProgressInvariant::UNSUPPORTED_SOURCE), "UNSUPPORTED_SOURCE" }, + { static_cast(ProgressInvariant::UNSUPPORTED_SINK), "UNSUPPORTED_SINK" }, + { static_cast(ProgressInvariant::MALFORMED_SOURCE), "MALFORMED_SOURCE" }, + { static_cast(ProgressInvariant::MALFORMED_SINK), "MALFORMED_SINK" }, + { static_cast(ProgressInvariant::NON_MONOTONIC), "NON_MONOTONIC" }, + { static_cast(ProgressInvariant::INCOMPLETE), "INCOMPLETE" }, + { static_cast(ProgressInvariant::STALLED), "STALLED" }, + { static_cast(ProgressInvariant::INACCURATE), "INACCURATE" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(ProgressInvariant value) { + return StringUtil::EnumToString(GetProgressInvariantValues(), 8, "ProgressInvariant", static_cast(value)); +} + +template<> +ProgressInvariant EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetProgressInvariantValues(), 8, "ProgressInvariant", value)); +} + const StringUtil::EnumStringLiteral *GetPushdownExtractSupportValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(PushdownExtractSupport::UNCHECKED), "UNCHECKED" }, @@ -4964,29 +5025,31 @@ QueryResultMemoryType EnumUtil::FromString(const char *va return static_cast(StringUtil::StringToEnum(GetQueryResultMemoryTypeValues(), 2, "QueryResultMemoryType", value)); } -const StringUtil::EnumStringLiteral *GetQueryResultOutputTypeValues() { +const StringUtil::EnumStringLiteral *GetQueryResultStateValues() { static constexpr StringUtil::EnumStringLiteral values[] { - { static_cast(QueryResultOutputType::FORCE_MATERIALIZED), "FORCE_MATERIALIZED" }, - { static_cast(QueryResultOutputType::ALLOW_STREAMING), "ALLOW_STREAMING" } + { static_cast(QueryResultState::READY), "READY" }, + { static_cast(QueryResultState::NOT_READY), "NOT_READY" }, + { static_cast(QueryResultState::BLOCKED), "BLOCKED" }, + { static_cast(QueryResultState::NO_TASKS_AVAILABLE), "NO_TASKS_AVAILABLE" }, + { static_cast(QueryResultState::FINISHED), "FINISHED" }, + { static_cast(QueryResultState::EXECUTION_ERROR), "EXECUTION_ERROR" } }; return values; } template<> -const char* EnumUtil::ToChars(QueryResultOutputType value) { - return StringUtil::EnumToString(GetQueryResultOutputTypeValues(), 2, "QueryResultOutputType", static_cast(value)); +const char* EnumUtil::ToChars(QueryResultState value) { + return StringUtil::EnumToString(GetQueryResultStateValues(), 6, "QueryResultState", static_cast(value)); } template<> -QueryResultOutputType EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetQueryResultOutputTypeValues(), 2, "QueryResultOutputType", value)); +QueryResultState EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetQueryResultStateValues(), 6, "QueryResultState", value)); } const StringUtil::EnumStringLiteral *GetQueryResultTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(QueryResultType::MATERIALIZED_RESULT), "MATERIALIZED_RESULT" }, - { static_cast(QueryResultType::STREAM_RESULT), "STREAM_RESULT" }, - { static_cast(QueryResultType::PENDING_RESULT), "PENDING_RESULT" }, { static_cast(QueryResultType::ARROW_RESULT), "ARROW_RESULT" } }; return values; @@ -4994,12 +5057,12 @@ const StringUtil::EnumStringLiteral *GetQueryResultTypeValues() { template<> const char* EnumUtil::ToChars(QueryResultType value) { - return StringUtil::EnumToString(GetQueryResultTypeValues(), 4, "QueryResultType", static_cast(value)); + return StringUtil::EnumToString(GetQueryResultTypeValues(), 2, "QueryResultType", static_cast(value)); } template<> QueryResultType EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetQueryResultTypeValues(), 4, "QueryResultType", value)); + return static_cast(StringUtil::StringToEnum(GetQueryResultTypeValues(), 2, "QueryResultType", value)); } const StringUtil::EnumStringLiteral *GetRecoveryModeValues() { @@ -5220,6 +5283,24 @@ RequestType EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetRequestTypeValues(), 6, "RequestType", value)); } +const StringUtil::EnumStringLiteral *GetResultEagernessValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(ResultEagerness::FORCED), "FORCED" }, + { static_cast(ResultEagerness::AUTO), "AUTO" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(ResultEagerness value) { + return StringUtil::EnumToString(GetResultEagernessValues(), 2, "ResultEagerness", static_cast(value)); +} + +template<> +ResultEagerness EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetResultEagernessValues(), 2, "ResultEagerness", value)); +} + const StringUtil::EnumStringLiteral *GetResultLifetimeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(ResultLifetime::UNDECIDED), "UNDECIDED" }, @@ -5947,19 +6028,20 @@ const StringUtil::EnumStringLiteral *GetStatementTypeValues() { { static_cast(StatementType::MERGE_INTO_STATEMENT), "MERGE_INTO_STATEMENT" }, { static_cast(StatementType::CONNECT_STATEMENT), "CONNECT_STATEMENT" }, { static_cast(StatementType::DISCONNECT_STATEMENT), "DISCONNECT_STATEMENT" }, - { static_cast(StatementType::EXTERNAL_RESOURCE_STATEMENT), "EXTERNAL_RESOURCE_STATEMENT" } + { static_cast(StatementType::EXTERNAL_RESOURCE_STATEMENT), "EXTERNAL_RESOURCE_STATEMENT" }, + { static_cast(StatementType::ENUM_SIZE), "ENUM_SIZE" } }; return values; } template<> const char* EnumUtil::ToChars(StatementType value) { - return StringUtil::EnumToString(GetStatementTypeValues(), 34, "StatementType", static_cast(value)); + return StringUtil::EnumToString(GetStatementTypeValues(), static_cast(StatementType::ENUM_SIZE), "StatementType", static_cast(value)); } template<> StatementType EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetStatementTypeValues(), 34, "StatementType", value)); + return static_cast(StringUtil::StringToEnum(GetStatementTypeValues(), static_cast(StatementType::ENUM_SIZE), "StatementType", value)); } const StringUtil::EnumStringLiteral *GetStatisticsPropagationModeValues() { @@ -6202,29 +6284,6 @@ StrTimeSpecifier EnumUtil::FromString(const char *value) { return static_cast(StringUtil::StringToEnum(GetStrTimeSpecifierValues(), 36, "StrTimeSpecifier", value)); } -const StringUtil::EnumStringLiteral *GetStreamExecutionResultValues() { - static constexpr StringUtil::EnumStringLiteral values[] { - { static_cast(StreamExecutionResult::CHUNK_READY), "CHUNK_READY" }, - { static_cast(StreamExecutionResult::CHUNK_NOT_READY), "CHUNK_NOT_READY" }, - { static_cast(StreamExecutionResult::EXECUTION_ERROR), "EXECUTION_ERROR" }, - { static_cast(StreamExecutionResult::EXECUTION_CANCELLED), "EXECUTION_CANCELLED" }, - { static_cast(StreamExecutionResult::BLOCKED), "BLOCKED" }, - { static_cast(StreamExecutionResult::NO_TASKS_AVAILABLE), "NO_TASKS_AVAILABLE" }, - { static_cast(StreamExecutionResult::EXECUTION_FINISHED), "EXECUTION_FINISHED" } - }; - return values; -} - -template<> -const char* EnumUtil::ToChars(StreamExecutionResult value) { - return StringUtil::EnumToString(GetStreamExecutionResultValues(), 7, "StreamExecutionResult", static_cast(value)); -} - -template<> -StreamExecutionResult EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetStreamExecutionResultValues(), 7, "StreamExecutionResult", value)); -} - const StringUtil::EnumStringLiteral *GetSubqueryTypeValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(SubqueryType::INVALID), "INVALID" }, @@ -6458,12 +6517,12 @@ const StringUtil::EnumStringLiteral *GetTaskSchedulerTypeValues() { template<> const char* EnumUtil::ToChars(TaskSchedulerType value) { - return StringUtil::EnumToString(GetTaskSchedulerTypeValues(), 3, "TaskSchedulerType", static_cast(value)); + return StringUtil::EnumToString(GetTaskSchedulerTypeValues(), static_cast(TaskSchedulerType::ENUM_SIZE), "TaskSchedulerType", static_cast(value)); } template<> TaskSchedulerType EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetTaskSchedulerTypeValues(), 3, "TaskSchedulerType", value)); + return static_cast(StringUtil::StringToEnum(GetTaskSchedulerTypeValues(), static_cast(TaskSchedulerType::ENUM_SIZE), "TaskSchedulerType", value)); } const StringUtil::EnumStringLiteral *GetTemporaryBufferSizeValues() { @@ -6885,12 +6944,12 @@ const StringUtil::EnumStringLiteral *GetVariantLogicalTypeValues() { template<> const char* EnumUtil::ToChars(VariantLogicalType value) { - return StringUtil::EnumToString(GetVariantLogicalTypeValues(), 36, "VariantLogicalType", static_cast(value)); + return StringUtil::EnumToString(GetVariantLogicalTypeValues(), static_cast(VariantLogicalType::ENUM_SIZE), "VariantLogicalType", static_cast(value)); } template<> VariantLogicalType EnumUtil::FromString(const char *value) { - return static_cast(StringUtil::StringToEnum(GetVariantLogicalTypeValues(), 36, "VariantLogicalType", value)); + return static_cast(StringUtil::StringToEnum(GetVariantLogicalTypeValues(), static_cast(VariantLogicalType::ENUM_SIZE), "VariantLogicalType", value)); } const StringUtil::EnumStringLiteral *GetVariantStatsShreddingStateValues() { diff --git a/src/duckdb/src/common/enums/statement_type.cpp b/src/duckdb/src/common/enums/statement_type.cpp index eaf414b88..c3c6ac632 100644 --- a/src/duckdb/src/common/enums/statement_type.cpp +++ b/src/duckdb/src/common/enums/statement_type.cpp @@ -74,6 +74,7 @@ string StatementTypeToString(StatementType type) { case StatementType::EXTERNAL_RESOURCE_STATEMENT: return "EXTERNAL_RESOURCE"; case StatementType::INVALID_STATEMENT: + case StatementType::ENUM_SIZE: break; } return "INVALID"; diff --git a/src/duckdb/src/common/file_system.cpp b/src/duckdb/src/common/file_system.cpp index b25387561..5eed10a6f 100644 --- a/src/duckdb/src/common/file_system.cpp +++ b/src/duckdb/src/common/file_system.cpp @@ -503,6 +503,14 @@ FileMetadata FileSystem::Stats(FileHandle &handle) { return metadata; } +optional FileSystem::GetStatsIfExists(const OpenFileInfo &file, optional_ptr opener) { + auto handle = OpenFile(file, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_NULL_IF_NOT_EXISTS, opener); + if (!handle) { + return nullopt; + } + return Stats(*handle); +} + void FileSystem::Truncate(FileHandle &handle, int64_t new_size) { throw NotImplementedException("%s: Truncate is not implemented!", GetName()); } diff --git a/src/duckdb/src/common/gzip_file_system.cpp b/src/duckdb/src/common/gzip_file_system.cpp index ea0e70c1e..edd1c265e 100644 --- a/src/duckdb/src/common/gzip_file_system.cpp +++ b/src/duckdb/src/common/gzip_file_system.cpp @@ -69,6 +69,20 @@ idx_t GZipConsumeString(QueryContext context, FileHandle &input) { return size; } +idx_t GZipReadExact(QueryContext context, FileHandle &input, data_ptr_t buffer, idx_t size) { + idx_t total_read = 0; + while (total_read < size) { + auto read_count = input.Read(context, buffer + total_read, size - total_read); + if (read_count <= 0) { + break; + } + total_read += NumericCast(read_count); + } + return total_read; +} + +enum class GZipReadState : uint8_t { DEFLATE, FOOTER, HEADER, EXTRA_LENGTH, EXTRA_DATA, FILE_NAME }; + struct MiniZStreamWrapper : public StreamWrapper { ~MiniZStreamWrapper() override; @@ -77,17 +91,27 @@ struct MiniZStreamWrapper : public StreamWrapper { bool writing = false; duckdb_miniz::mz_ulong crc; idx_t total_size; + GZipReadState read_state = GZipReadState::DEFLATE; + idx_t state_bytes_remaining = 0; + idx_t gzip_header_size = 0; + idx_t gzip_header_bytes = 0; + uint8_t gzip_header[GZIP_HEADER_MINSIZE]; + idx_t gzip_xlen_bytes = 0; + uint8_t gzip_xlen[2]; public: void Initialize(QueryContext context, CompressedFile &file, bool write) override; bool Read(StreamData &stream_data) override; + void FinalizeRead(StreamData &stream_data) override; void Write(CompressedFile &file, StreamData &stream_data, data_ptr_t buffer, int64_t nr_bytes) override; void Close() override; void AbortWrite() override; void FlushStream() const; + bool ReadNextMemberHeader(StreamData &stream_data); + void InitializeInflator(); }; MiniZStreamWrapper::~MiniZStreamWrapper() { @@ -136,13 +160,15 @@ void MiniZStreamWrapper::Initialize(QueryContext context, CompressedFile &file, } } else { idx_t data_start = GZIP_HEADER_MINSIZE; - auto read_count = file.child_handle->Read(context, gzip_hdr, GZIP_HEADER_MINSIZE); - GZipFileSystem::VerifyGZIPHeader(gzip_hdr, NumericCast(read_count), &file); + auto read_count = GZipReadExact(context, *file.child_handle, gzip_hdr, GZIP_HEADER_MINSIZE); + GZipFileSystem::VerifyGZIPHeader(gzip_hdr, read_count, &file); // Skip over the extra field if necessary if (gzip_hdr[3] & GZIP_FLAG_EXTRA) { uint8_t gzip_xlen[2]; file.child_handle->Seek(data_start); - file.child_handle->Read(context, gzip_xlen, 2); + if (GZipReadExact(context, *file.child_handle, gzip_xlen, 2) != 2) { + throw IOException("Input is not a GZIP stream: %s", file.path); + } auto xlen = NumericCast((uint8_t)gzip_xlen[0] | (uint8_t)gzip_xlen[1] << 8); data_start += xlen + 2; } @@ -153,58 +179,124 @@ void MiniZStreamWrapper::Initialize(QueryContext context, CompressedFile &file, } file.child_handle->Seek(data_start); // stream is now set to beginning of payload data - auto ret = duckdb_miniz::mz_inflateInit2(mz_stream_ptr.get(), -MZ_DEFAULT_WINDOW_BITS); - if (ret != duckdb_miniz::MZ_OK) { - throw InternalException("Failed to initialize miniz"); - } + InitializeInflator(); } } -bool MiniZStreamWrapper::Read(StreamData &sd) { - // Handling for the concatenated files - if (sd.refresh) { - auto available = static_cast(sd.in_buff_end - sd.in_buff_start); - if (available <= GZIP_FOOTER_SIZE) { - // Only footer is available so we just close and return finished - Close(); - return true; - } +void MiniZStreamWrapper::InitializeInflator() { + auto ret = duckdb_miniz::mz_inflateInit2(mz_stream_ptr.get(), -MZ_DEFAULT_WINDOW_BITS); + if (ret != duckdb_miniz::MZ_OK) { + throw InternalException("Failed to initialize miniz"); + } +} - sd.refresh = false; - auto body_ptr = sd.in_buff_start + GZIP_FOOTER_SIZE; - uint8_t gzip_hdr[GZIP_HEADER_MINSIZE]; - memcpy(gzip_hdr, body_ptr, GZIP_HEADER_MINSIZE); - GZipFileSystem::VerifyGZIPHeader(gzip_hdr, GZIP_HEADER_MINSIZE, nullptr); - body_ptr += GZIP_HEADER_MINSIZE; - if (gzip_hdr[3] & GZIP_FLAG_EXTRA) { - auto xlen = NumericCast((uint8_t)*body_ptr | (uint8_t) * (body_ptr + 1) << 8); - body_ptr += xlen + 2; - if (GZIP_FOOTER_SIZE + GZIP_HEADER_MINSIZE + 2 + xlen >= GZIP_HEADER_MAXSIZE) { +bool MiniZStreamWrapper::ReadNextMemberHeader(StreamData &sd) { + while (sd.in_buff_start < sd.in_buff_end) { + auto available = NumericCast(sd.in_buff_end - sd.in_buff_start); + switch (read_state) { + case GZipReadState::FOOTER: { + auto consume_count = MinValue(available, state_bytes_remaining); + sd.in_buff_start += consume_count; + state_bytes_remaining -= consume_count; + if (state_bytes_remaining > 0) { + return false; + } + read_state = GZipReadState::HEADER; + gzip_header_size = GZIP_FOOTER_SIZE; + gzip_header_bytes = 0; + break; + } + case GZipReadState::HEADER: { + auto consume_count = MinValue(available, GZIP_HEADER_MINSIZE - gzip_header_bytes); + memcpy(gzip_header + gzip_header_bytes, sd.in_buff_start, consume_count); + sd.in_buff_start += consume_count; + gzip_header_bytes += consume_count; + gzip_header_size += consume_count; + if (gzip_header_bytes < GZIP_HEADER_MINSIZE) { + return false; + } + GZipFileSystem::VerifyGZIPHeader(gzip_header, GZIP_HEADER_MINSIZE, nullptr); + if (gzip_header[3] & GZIP_FLAG_EXTRA) { + read_state = GZipReadState::EXTRA_LENGTH; + gzip_xlen_bytes = 0; + } else if (gzip_header[3] & GZIP_FLAG_NAME) { + read_state = GZipReadState::FILE_NAME; + } else { + read_state = GZipReadState::DEFLATE; + return true; + } + break; + } + case GZipReadState::EXTRA_LENGTH: { + auto consume_count = MinValue(available, 2 - gzip_xlen_bytes); + memcpy(gzip_xlen + gzip_xlen_bytes, sd.in_buff_start, consume_count); + sd.in_buff_start += consume_count; + gzip_xlen_bytes += consume_count; + gzip_header_size += consume_count; + if (gzip_xlen_bytes < 2) { + return false; + } + state_bytes_remaining = NumericCast((uint8_t)gzip_xlen[0] | (uint8_t)gzip_xlen[1] << 8); + if (gzip_header_size + state_bytes_remaining >= GZIP_HEADER_MAXSIZE) { throw InternalException("Extra field resulting in GZIP header larger than defined maximum (%d)", GZIP_HEADER_MAXSIZE); } + read_state = GZipReadState::EXTRA_DATA; + break; } - if (gzip_hdr[3] & GZIP_FLAG_NAME) { - char c; - do { - c = UnsafeNumericCast(*body_ptr); - body_ptr++; - } while (c != '\0' && body_ptr < sd.in_buff_end); - if (static_cast(body_ptr - sd.in_buff_start) >= GZIP_HEADER_MAXSIZE) { - throw InternalException("Filename resulting in GZIP header larger than defined maximum (%d)", - GZIP_HEADER_MAXSIZE); + case GZipReadState::EXTRA_DATA: { + auto consume_count = MinValue(available, state_bytes_remaining); + sd.in_buff_start += consume_count; + state_bytes_remaining -= consume_count; + gzip_header_size += consume_count; + if (state_bytes_remaining > 0) { + return false; } + if (gzip_header[3] & GZIP_FLAG_NAME) { + read_state = GZipReadState::FILE_NAME; + } else { + read_state = GZipReadState::DEFLATE; + return true; + } + break; } - sd.in_buff_start = body_ptr; - if (sd.in_buff_end - sd.in_buff_start < 1) { - Close(); + case GZipReadState::FILE_NAME: + while (sd.in_buff_start < sd.in_buff_end) { + auto c = *sd.in_buff_start++; + gzip_header_size++; + if (gzip_header_size >= GZIP_HEADER_MAXSIZE) { + throw InternalException("Filename resulting in GZIP header larger than defined maximum (%d)", + GZIP_HEADER_MAXSIZE); + } + if (c == '\0') { + read_state = GZipReadState::DEFLATE; + return true; + } + } + return false; + case GZipReadState::DEFLATE: return true; } - duckdb_miniz::mz_inflateEnd(mz_stream_ptr.get()); - auto sta = duckdb_miniz::mz_inflateInit2(mz_stream_ptr.get(), -MZ_DEFAULT_WINDOW_BITS); - if (sta != duckdb_miniz::MZ_OK) { - throw InternalException("Failed to initialize miniz"); + } + return false; +} + +bool MiniZStreamWrapper::Read(StreamData &sd) { + // Handling for the concatenated files + if (sd.refresh && read_state == GZipReadState::DEFLATE) { + read_state = GZipReadState::FOOTER; + state_bytes_remaining = GZIP_FOOTER_SIZE; + } + if (read_state != GZipReadState::DEFLATE) { + if (!ReadNextMemberHeader(sd)) { + return false; } + sd.refresh = false; + duckdb_miniz::mz_inflateEnd(mz_stream_ptr.get()); + InitializeInflator(); + } + if (sd.in_buff_start == sd.in_buff_end) { + return false; } // actually decompress @@ -231,6 +323,13 @@ bool MiniZStreamWrapper::Read(StreamData &sd) { return false; } +void MiniZStreamWrapper::FinalizeRead(StreamData &) { + if (read_state == GZipReadState::HEADER && gzip_header_bytes == 0) { + return; + } + throw IOException("Unexpected end of GZIP stream: %s", file->path); +} + void MiniZStreamWrapper::Write(CompressedFile &file, StreamData &sd, data_ptr_t uncompressed_data, int64_t uncompressed_size) { // update the src and the total size diff --git a/src/duckdb/src/common/hive_partitioning.cpp b/src/duckdb/src/common/hive_partitioning.cpp index bff0d0c5b..594b6ff2f 100644 --- a/src/duckdb/src/common/hive_partitioning.cpp +++ b/src/duckdb/src/common/hive_partitioning.cpp @@ -192,6 +192,10 @@ void HivePartitioning::ApplyFiltersToFileList(ClientContext &context, vector>(); + } + for (idx_t i = 0; i < files.size(); i++) { auto &file = files[i]; bool should_prune_file = false; @@ -229,6 +233,34 @@ void HivePartitioning::ApplyFiltersToFileList(ClientContext &context, vector= pruned_filters.size()); + for (idx_t i = 0; i < filters.size() && info.extra_info.file_filter_expressions; i++) { + if (have_preserved_filter[i]) { + continue; + } + auto retained = filters[i]->Copy(); + bool representable = true; + ExpressionIterator::VisitExpressionMutable( + retained, [&](auto &column, unique_ptr &) { + auto binding = column.Binding(); + if (column.Depth() != 0 || binding.table_index != table_index || + binding.column_index.GetIndex() >= info.column_indexes.size()) { + representable = false; + return; + } + auto &index = info.column_indexes[binding.column_index.GetIndex()]; + if (index.IsVirtualColumn() || index.IsPushdownExtract() || index.HasType()) { + representable = false; + return; + } + column.BindingMutable() = ColumnBinding(TableIndex(0), ProjectionIndex(index.GetPrimaryIndex())); + }); + if (!representable) { + info.extra_info.file_filter_expressions.reset(); + break; + } + info.extra_info.file_filter_expressions->push_back(std::move(retained)); + } + info.extra_info.total_files = files.size(); info.extra_info.filtered_files = pruned_files.size(); diff --git a/src/duckdb/src/common/local_file_system.cpp b/src/duckdb/src/common/local_file_system.cpp index b6098b457..87ba23c52 100644 --- a/src/duckdb/src/common/local_file_system.cpp +++ b/src/duckdb/src/common/local_file_system.cpp @@ -1,6 +1,7 @@ #include "duckdb/common/local_file_system.hpp" #include "duckdb/common/checksum.hpp" +#include "duckdb/common/enums/file_sync_mode.hpp" #include "duckdb/common/exception.hpp" #include "duckdb/common/file_opener.hpp" #include "duckdb/common/helper.hpp" @@ -619,6 +620,26 @@ FileMetadata LocalFileSystem::Stats(FileHandle &handle) { return file_metadata; } +optional LocalFileSystem::GetStatsIfExists(const OpenFileInfo &file, optional_ptr opener) { + const auto &path_p = file.path; + if (path_p.empty()) { + return nullopt; + } + auto path = ExpandPath(path_p, opener); + struct stat status; + if (stat(path.c_str(), &status) != 0) { + auto retained_errno = errno; + if (retained_errno == ENOENT || retained_errno == ENOTDIR) { + return nullopt; + } + throw IOException({{"errno", std::to_string(retained_errno)}}, "Failed to get stats for path \"%s\": %s", + path_p, strerror(retained_errno)); + } + auto file_metadata = StatsFromStruct(status); + file_metadata.version_tag = VersionTagFromMetadata(file_metadata); + return file_metadata; +} + void LocalFileSystem::Truncate(FileHandle &handle, int64_t new_size) { int fd = handle.Cast().fd; if (ftruncate(fd, new_size) != 0) { @@ -794,21 +815,26 @@ bool LocalFileSystem::ListFilesExtended(const string &directory, } void LocalFileSystem::FileSync(FileHandle &handle) { - int fd = handle.Cast().fd; + auto &unix_handle = handle.Cast(); + auto fsync_mode = unix_handle.db ? Settings::Get(*unix_handle.db) : FileSyncMode::STANDARD; + if (fsync_mode == FileSyncMode::NONE) { + return; + } + int fd = unix_handle.fd; -#if HAVE_FULLFSYNC +#ifdef F_FULLFSYNC // On macOS and iOS, fsync() doesn't guarantee durability past power failures. fcntl(F_FULLFSYNC) is required for // that purpose. Some filesystems don't support fcntl(F_FULLFSYNC), and require a fallback to fsync(). - if (::fcntl(fd, F_FULLFSYNC) == 0) { + if (fsync_mode == FileSyncMode::FULL && ::fcntl(fd, F_FULLFSYNC) == 0) { return; } -#endif // HAVE_FULLFSYNC +#endif // F_FULLFSYNC -#if HAVE_FDATASYNC +#ifdef DUCKDB_HAVE_FDATASYNC bool sync_success = ::fdatasync(fd) == 0; #else bool sync_success = ::fsync(fd) == 0; -#endif // HAVE_FDATASYNC +#endif // DUCKDB_HAVE_FDATASYNC if (sync_success) { return; @@ -1110,8 +1136,9 @@ static FileMetadata StatsFromDirInfo(const FILE_ID_BOTH_DIR_INFO &entry) { struct WindowsFileHandle : public FileHandle { public: - WindowsFileHandle(FileSystem &file_system, string path, HANDLE fd, FileOpenFlags flags) - : FileHandle(file_system, path, flags), position(0), fd(fd) { + WindowsFileHandle(FileSystem &file_system, string path, HANDLE fd, FileOpenFlags flags, + optional_ptr db) + : FileHandle(file_system, path, flags), position(0), fd(fd), db(db) { } ~WindowsFileHandle() override { Close(); @@ -1119,6 +1146,7 @@ struct WindowsFileHandle : public FileHandle { idx_t position; HANDLE fd; + optional_ptr db; public: void Close() override { @@ -1269,7 +1297,7 @@ unique_ptr LocalFileSystem::OpenFile(const string &path_p, FileOpenF auto abs_path = WindowsUtil::UnicodeToUTF8(unicode_path.c_str()); throw IOException("Cannot open file \"%s\": %s%s", abs_path, error, extended_error); } - auto handle = make_uniq(*this, path.c_str(), hFile, flags); + auto handle = make_uniq(*this, path.c_str(), hFile, flags, FileOpener::TryGetDatabase(opener)); if (flags.OpenForAppending()) { auto file_size = GetFileSize(*handle); SetFilePointer(*handle, file_size); @@ -1585,7 +1613,12 @@ bool LocalFileSystem::ListFilesExtended(const string &directory, } void LocalFileSystem::FileSync(FileHandle &handle) { - HANDLE hFile = handle.Cast().fd; + auto &windows_handle = handle.Cast(); + auto fsync_mode = windows_handle.db ? Settings::Get(*windows_handle.db) : FileSyncMode::STANDARD; + if (fsync_mode == FileSyncMode::NONE) { + return; + } + HANDLE hFile = windows_handle.fd; if (FlushFileBuffers(hFile) == 0) { throw IOException("Could not flush file handle to disk!"); } @@ -1653,6 +1686,29 @@ FileMetadata LocalFileSystem::Stats(FileHandle &handle) { return file_metadata; } +optional LocalFileSystem::GetStatsIfExists(const OpenFileInfo &file, optional_ptr opener) { + const auto &path_p = file.path; + if (path_p.empty()) { + return nullopt; + } + auto unicode_path = NormalizePathAndConvertToUnicode(*this, path_p, opener); + auto raw_handle = CreateFileW(unicode_path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (raw_handle == INVALID_HANDLE_VALUE) { + auto error_code = GetLastError(); + if (error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_PATH_NOT_FOUND) { + return nullopt; + } + SetLastError(error_code); + throw IOException("Failed to get stats for path \"%s\": %s", path_p, GetLastErrorAsString()); + } + unique_ptr handle(raw_handle, CloseHandle); + + auto file_metadata = StatsInternal(handle.get(), path_p); + file_metadata.version_tag = VersionTagFromMetadata(file_metadata); + return file_metadata; +} + bool LocalFileSystem::TryCanonicalizeExistingPath(string &input) { auto unicode_path = ConvertPathToUnicode(input); HANDLE handle = CreateFileW(unicode_path.c_str(), diff --git a/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp b/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp index 4625309d4..b43e6b42b 100644 --- a/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp +++ b/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp @@ -322,6 +322,9 @@ static ColumnMapResult MapColumnList(ClientContext &context, const MultiFileColu result.default_value = BindBuiltinScalarFunction(context, StructPackFun::Name, std::move(default_expressions)); } result.column_index = make_uniq(local_id.GetIndex(), std::move(child_indexes)); + if (global_index.HasType()) { + result.column_index->SetType(global_column.type); + } result.mapping = std::move(mapping); return result; } @@ -446,6 +449,9 @@ static ColumnMapResult MapColumnMap(ClientContext &context, const MultiFileColum map_indexes.emplace_back(0, std::move(child_indexes)); result.column_index = make_uniq(local_id.GetIndex(), std::move(map_indexes)); + if (global_index.HasType()) { + result.column_index->SetType(global_column.type); + } result.mapping = std::move(mapping); return result; } @@ -569,10 +575,19 @@ static ColumnMapResult MapColumn(ClientContext &context, const MultiFileColumnDe } // the field exists! get the local column auto &local_column = local_columns[local_idx]; + if (local_column.type.id() == LogicalTypeId::SQLNULL) { + // An explicitly NULL field can represent any result type, including a nested field. + // Do not feed it into remap_struct, which requires matching nested source types. + auto &type = (is_root || global_index.IsPushdownExtract()) && global_index.HasType() + ? global_index.GetScanType() + : global_column.type; + result.default_value = make_uniq(Value(type)); + return result; + } auto mapping_idx = is_root ? top_level_index : local_idx; auto mapping = make_uniq(mapping_idx); - if (global_column.children.empty()) { - // not a struct - map the column directly + if (global_column.children.empty() || !local_column.type.IsNested()) { + // Map directly when no child remapping is needed or the source requires a scalar cast. result.column_map = Value(local_column.name); result.column_index = make_uniq(global_index.RemapRootIndex(local_idx.GetIndex())); result.mapping = std::move(mapping); @@ -582,6 +597,11 @@ static ColumnMapResult MapColumn(ClientContext &context, const MultiFileColumnDe // nested type - check if the field identifiers match and if we need to remap D_ASSERT(global_column.type.IsNested()); + if (global_column.type.id() != local_column.type.id()) { + throw BinderException("Failed to map file-column of type '%s' to result-column of type '%s'", local_column.type, + global_column.type); + } + switch (global_column.type.id()) { case LogicalTypeId::STRUCT: return MapColumnStruct(context, global_column, global_index, local_column, local_idx, mapper, diff --git a/src/duckdb/src/common/multi_file/multi_file_function.cpp b/src/duckdb/src/common/multi_file/multi_file_function.cpp index 8608bd6c0..b3f906a69 100644 --- a/src/duckdb/src/common/multi_file/multi_file_function.cpp +++ b/src/duckdb/src/common/multi_file/multi_file_function.cpp @@ -12,7 +12,12 @@ MultiFileGlobalState::MultiFileGlobalState(unique_ptr owned_file_ : file_list(*owned_file_list_p), owned_file_list(std::move(owned_file_list_p)) { } -MultiFileGlobalState::~MultiFileGlobalState() = default; +MultiFileGlobalState::~MultiFileGlobalState() { + if (read_ahead) { + // the file opens scheduled on the async pool reference this state - wait for them before it goes away + read_ahead->CancelAndDrain(); + } +} MultiFileReaderInterface::~MultiFileReaderInterface() { } @@ -42,7 +47,7 @@ optional_idx MultiFileReaderInterface::MaxThreads(ClientContext &context, const } void MultiFileReaderInterface::CombineSchemas(ClientContext &context, - const vector> &union_data, + const vector> &union_data, bool union_by_name, vector &return_types, vector &names) { identifier_map_t union_names_map; for (auto &data : union_data) { diff --git a/src/duckdb/src/common/multi_file/multi_file_list.cpp b/src/duckdb/src/common/multi_file/multi_file_list.cpp index 8b48a40d8..676e7a88b 100644 --- a/src/duckdb/src/common/multi_file/multi_file_list.cpp +++ b/src/duckdb/src/common/multi_file/multi_file_list.cpp @@ -14,14 +14,6 @@ namespace duckdb { -MultiFilePushdownInfo::MultiFilePushdownInfo(LogicalGet &get) - : table_index(get.table_index), column_names(get.names), column_indexes(get.GetColumnIds()), - extra_info(get.extra_info) { - for (auto &col_id : column_indexes) { - column_ids.push_back(col_id.GetPrimaryIndex()); - } -} - MultiFilePushdownInfo::MultiFilePushdownInfo(TableIndex table_index, const vector &column_names, const vector &column_indexes, ExtraOperatorInfo &extra_info) : table_index(table_index), column_names(column_names), column_indexes(column_indexes), extra_info(extra_info) { diff --git a/src/duckdb/src/common/multi_file/multi_file_reader.cpp b/src/duckdb/src/common/multi_file/multi_file_reader.cpp index be6c42ee7..1a9ff99f2 100644 --- a/src/duckdb/src/common/multi_file/multi_file_reader.cpp +++ b/src/duckdb/src/common/multi_file/multi_file_reader.cpp @@ -133,7 +133,7 @@ OpenFileInfo MultiFileReader::ParseFileEntry(const Value &input) { // structs of its entries, which fills the options an entry did not specify with NULL continue; } - extended_info->SetUserOption(name.GetIdentifierName(), child); + extended_info->options[name.GetIdentifierName()] = child; } if (!found_path) { throw ParserException("%s reader requires a file struct to have a \"%s\" field holding the path of the file", @@ -231,18 +231,7 @@ bool MultiFileReader::ParseOption(const Identifier &key, const Value &val, Multi } options.allow_empty = BooleanValue::Get(val); } else if (key == "maximum_sample_files") { - if (val.IsNull()) { - throw BinderException("Cannot use NULL as argument to key %s", key); - } - auto sample_files = val.DefaultCastAs(LogicalType::BIGINT).GetValue(); - if (sample_files == -1) { - options.maximum_sample_files = NumericLimits::Maximum(); - } else if (sample_files > 0) { - options.maximum_sample_files = NumericCast(sample_files); - } else { - throw BinderException("\"maximum_sample_files\" parameter must be positive, or -1 to remove the limit " - "on the number of files used to determine the schema."); - } + options.SetMaximumSampleFiles(key, val); } else if (key == "hive_types_autocast" || key == "hive_type_autocast") { if (val.IsNull()) { throw InvalidInputException("Cannot use NULL as argument for %s", key); @@ -984,6 +973,33 @@ LogicalType MultiFileOptions::GetHiveLogicalType(const string &hive_partition_co return LogicalType::VARCHAR; } +void MultiFileOptions::SetMaximumSampleFiles(const Identifier &key, const Value &val) { + if (val.IsNull()) { + throw BinderException("Cannot use NULL as argument to key %s", key); + } + if (!TrySetMaximumSampleFiles(val)) { + throw BinderException("\"%s\" parameter must be positive, or -1 to remove the limit on the number of files " + "used to determine the schema.", + key); + } +} + +bool MultiFileOptions::TrySetMaximumSampleFiles(const Value &val) { + if (val.IsNull()) { + return false; + } + auto sample_files = val.DefaultCastAs(LogicalType::BIGINT).GetValue(); + if (sample_files == -1) { + maximum_sample_files = NumericLimits::Maximum(); + return true; + } + if (sample_files <= 0) { + return false; + } + maximum_sample_files = NumericCast(sample_files); + return true; +} + bool MultiFileOptions::AnySet() const { return filename || hive_partitioning || union_by_name; } diff --git a/src/duckdb/src/common/multi_file/table_function_multi_file.cpp b/src/duckdb/src/common/multi_file/table_function_multi_file.cpp index 6fe7dda13..1cdd99633 100644 --- a/src/duckdb/src/common/multi_file/table_function_multi_file.cpp +++ b/src/duckdb/src/common/multi_file/table_function_multi_file.cpp @@ -1,5 +1,7 @@ #include "duckdb/common/multi_file/table_function_multi_file.hpp" +#include "duckdb/common/bind_helpers.hpp" + #include "duckdb/execution/execution_context.hpp" #include "duckdb/function/function_set.hpp" #include "duckdb/parallel/async_result.hpp" @@ -12,7 +14,12 @@ namespace duckdb { //===--------------------------------------------------------------------===// // States //===--------------------------------------------------------------------===// -class TableFunctionMultiFileGlobalState : public GlobalTableFunctionState {}; +class TableFunctionMultiFileGlobalState : public GlobalTableFunctionState { +public: + //! The operator the files are scanned for, and how many files that scan reads + optional_ptr op; + idx_t file_count = 1; +}; class TableFunctionMultiFileLocalState : public LocalTableFunctionState { public: @@ -44,7 +51,14 @@ string TableFunctionFileReader::GetReaderType() const { return reader_type; } -void TableFunctionFileReader::BindFunction(ClientContext &context, const TableFunctionFileReaderOptions &options) { +bool TableFunctionFileReader::UseCastMap() const { + // when the function can produce columns as a different type than it bound them, the conversion is pushed into + // the function instead of being applied to its output + return function.supports_cast_map; +} + +void TableFunctionFileReader::BindFunction(ClientContext &context, const TableFunctionFileReaderOptions &options, + const MultiFileOptions &file_options) { if (!function.bind) { throw InternalException("Table function %s cannot be wrapped in a multi file function - it has no bind", function.name); @@ -57,6 +71,8 @@ void TableFunctionFileReader::BindFunction(ClientContext &context, const TableFu TableFunctionRef empty_ref; TableFunctionBindInput bind_input(inputs, parameters, input_table_types, input_table_names, function.function_info.get(), nullptr, function, empty_ref); + bind_input.multi_file_options = file_options; + bind_input.multi_file_scan = options.multi_file_scan; if (!options.expected_names.empty()) { // the schema of the scan is known upfront - bind this file against that schema bind_input.expected_names = options.expected_names; @@ -110,7 +126,14 @@ TableFunctionInitInput TableFunctionFileReader::GetInitInput() const { // the multi file reader does the projection/filter pruning itself - the wrapped function only needs to emit the // (local) columns it is asked for, in order vector projection_ids; - return TableFunctionInitInput(bind_data.get(), column_indexes, projection_ids, filters.get()); + TableFunctionInitInput input(bind_data.get(), column_indexes, projection_ids, filters.get()); + input.file_index = file_list_idx; + input.file_count = scan_file_count; + input.op = scan_op; + if (!cast_map.empty()) { + input.cast_map = cast_map; + } + return input; } optional_idx TableFunctionFileReader::MaxThreads(ClientContext &context) { @@ -122,6 +145,12 @@ optional_idx TableFunctionFileReader::MaxThreads(ClientContext &context) { return global_state->MaxThreads(); } +void TableFunctionFileReader::SetScanState(GlobalTableFunctionState &gstate) { + auto &scan_state = gstate.Cast(); + scan_op = scan_state.op; + scan_file_count = scan_state.file_count; +} + void TableFunctionFileReader::InitializeFunctionState(ClientContext &context) { lock_guard guard(lock); if (global_state || !function.init_global) { @@ -131,16 +160,18 @@ void TableFunctionFileReader::InitializeFunctionState(ClientContext &context) { global_state = function.init_global(context, init_input); } -void TableFunctionFileReader::PrepareReader(ClientContext &context, GlobalTableFunctionState &) { +void TableFunctionFileReader::PrepareReader(ClientContext &context, GlobalTableFunctionState &gstate) { + SetScanState(gstate); InitializeFunctionState(context); } -bool TableFunctionFileReader::TryInitializeScan(ClientContext &context, GlobalTableFunctionState &, +bool TableFunctionFileReader::TryInitializeScan(ClientContext &context, GlobalTableFunctionState &gstate, LocalTableFunctionState &lstate_p) { if (exhausted) { return false; } // the initial reader obtained during binding is never prepared - initialize it here instead + SetScanState(gstate); InitializeFunctionState(context); auto &lstate = lstate_p.Cast(); if (!function.init_local) { @@ -166,6 +197,16 @@ bool TableFunctionFileReader::TryInitializeScan(ClientContext &context, GlobalTa return true; } +AsyncResult TableFunctionFileReader::ScheduleIO(ClientContext &context, GlobalTableFunctionState &, + LocalTableFunctionState &lstate_p) { + if (!function.schedule_io) { + return SourceResultType::HAVE_MORE_OUTPUT; + } + auto &lstate = lstate_p.Cast(); + TableFunctionInput input(bind_data.get(), lstate.local_state.get(), global_state.get()); + return function.schedule_io(context, input); +} + AsyncResult TableFunctionFileReader::Scan(ClientContext &context, GlobalTableFunctionState &, LocalTableFunctionState &lstate_p, DataChunk &chunk) { auto &lstate = lstate_p.Cast(); @@ -223,6 +264,7 @@ FileGlobInput TableFunctionMultiFileWrapper::GetGlobInput() { void TableFunctionMultiFileWrapper::InitializeFileOptions(MultiFileOptions &file_options) { file_options.maximum_sample_files = settings.maximum_sample_files; + file_options.sampled_schema_is_union = settings.sampled_schema_is_union; } unique_ptr TableFunctionMultiFileWrapper::InitializeOptions(ClientContext &context, @@ -240,8 +282,16 @@ bool TableFunctionMultiFileWrapper::ParseNamedParameter(const Identifier &key, c } bool TableFunctionMultiFileWrapper::ParseOption(ClientContext &context, const Identifier &key, const Value &val, - MultiFileOptions &, BaseFileReaderOptions &options_p) { - return ParseNamedParameter(key, val, options_p.Cast()); + MultiFileOptions &file_options, BaseFileReaderOptions &options_p) { + if (!ParseNamedParameter(key, val, options_p.Cast())) { + return false; + } + if (!settings.sample_files_parameter.empty() && key == settings.sample_files_parameter) { + // this parameter of the wrapped function also sets how many files are sampled to determine the schema - a + // value we cannot use is left to the function to report, in its own words, when it binds + file_options.TrySetMaximumSampleFiles(val); + } + return true; } bool TableFunctionMultiFileWrapper::ParseCopyOption(ClientContext &context, const Identifier &key, @@ -254,11 +304,14 @@ bool TableFunctionMultiFileWrapper::ParseCopyOption(ClientContext &context, cons return false; } auto &type = entry->second; - if (values.size() > 1) { - throw BinderException("COPY parameter %s expects a single argument", key); - } Value val; - if (values.empty()) { + if (type.id() == LogicalTypeId::LIST || (type.id() == LogicalTypeId::ANY && values.size() != 1)) { + // COPY passes the elements of a list-valued option as separate values - an option that takes any value is + // given the list as-is, so that it can report what it expected itself + val = ConvertVectorToValue(values); + } else if (values.size() > 1) { + throw BinderException("COPY parameter %s expects a single argument", key); + } else if (values.empty()) { // a bare option is a shorthand for setting a flag - only boolean parameters can be given like that if (type.id() != LogicalTypeId::BOOLEAN) { throw BinderException("COPY parameter %s expects a single argument", key); @@ -287,6 +340,7 @@ TableFunctionMultiFileWrapper::InitializeBindData(MultiFileBindData &multi_file_ auto result = make_uniq(); // the options carry the expected schema when it is known upfront (COPY takes it from the target table) result->options = std::move(options_p->Cast()); + result->options.multi_file_scan = multi_file_data.file_list->GetExpandResult() == FileExpandResult::MULTIPLE_FILES; return std::move(result); } @@ -307,8 +361,11 @@ optional_idx TableFunctionMultiFileWrapper::MaxThreads(ClientContext &context, c void TableFunctionMultiFileWrapper::CombineSchemas(ClientContext &context, const vector> &union_data, - vector &return_types, vector &names) { + bool union_by_name, vector &return_types, + vector &names) { schema_combined = true; + // combine the types of the files by name - the function can replace or adjust the result + MultiFileReaderInterface::CombineSchemas(context, union_data, union_by_name, return_types, names); if (function.combine_schema) { vector> bind_data; bool have_all_bind_data = true; @@ -321,28 +378,22 @@ void TableFunctionMultiFileWrapper::CombineSchemas(ClientContext &context, bind_data.emplace_back(*function_data); } if (have_all_bind_data) { - TableFunctionCombineSchemaInput input(bind_data); + // when the function returns bind data, every file is read using it - otherwise the files are bound + // individually and reconciled with the schema below + TableFunctionCombineSchemaInput input(bind_data, union_by_name); combined_bind_data = function.combine_schema(context, input, return_types, names); - if (combined_bind_data) { - // the function combined the schemas itself - every file is read using the resulting bind data - combined_names = names; - combined_types = return_types; - ReleaseBindData(union_data); - return; - } - return_types.clear(); - names.clear(); } } - // fall back to combining the return types of the files - MultiFileReaderInterface::CombineSchemas(context, union_data, return_types, names); combined_names = names; combined_types = return_types; ReleaseBindData(union_data); } void TableFunctionMultiFileWrapper::FinalizeBindData(MultiFileBindData &multi_file_data) { - if (!schema_combined) { + if (!schema_combined || !combined_bind_data) { + // either the schema comes from a single file, or the schemas were combined by type. In the latter case every + // file is bound on its own and the column mapper reconciles it with the combined schema - only a schema the + // function combined itself can be used to read every file return; } auto &data = multi_file_data.bind_data->Cast(); @@ -385,8 +436,14 @@ void TableFunctionMultiFileWrapper::BindReader(ClientContext &context, vector -TableFunctionMultiFileWrapper::InitializeGlobalState(ClientContext &, MultiFileBindData &, MultiFileGlobalState &) { - return make_uniq(); +TableFunctionMultiFileWrapper::InitializeGlobalState(ClientContext &, MultiFileBindData &bind_data, + MultiFileGlobalState &global_state) { + auto result = make_uniq(); + // the wrapped function is told which file of this scan it reads, so that a function that reports per-file + // information (like the CSV rejects tables) can tell the files of a scan apart from those of another scan + result->op = global_state.op; + result->file_count = bind_data.file_list->GetTotalFileCount(); + return std::move(result); } unique_ptr TableFunctionMultiFileWrapper::InitializeLocalState(ClientContext &context, @@ -394,6 +451,18 @@ unique_ptr TableFunctionMultiFileWrapper::InitializeLoc return make_uniq(context); } +bool TableFunctionMultiFileWrapper::SupportsReadAhead(const MultiFileBindData &bind_data) const { + if (!function.supports_read_ahead || !function.schedule_io) { + return false; + } + auto &data = bind_data.bind_data->Cast(); + if (!data.options.schema_bind_data) { + // we do not have the bind of a file of this scan to ask + return false; + } + return function.supports_read_ahead(*data.options.schema_bind_data); +} + void TableFunctionMultiFileWrapper::FinishReading(ClientContext &context, GlobalTableFunctionState &, LocalTableFunctionState &lstate_p) { auto &lstate = lstate_p.Cast(); @@ -405,11 +474,11 @@ void TableFunctionMultiFileWrapper::FinishReading(ClientContext &context, Global shared_ptr TableFunctionMultiFileWrapper::CreateReader(ClientContext &context, const OpenFileInfo &file, BaseFileReaderOptions &options_p, - const MultiFileOptions &) { + const MultiFileOptions &file_options) { auto &options = options_p.Cast(); auto result = make_shared_ptr(function, file, options.named_parameters, settings.reader_type); - result->BindFunction(context, options); + result->BindFunction(context, options, file_options); return std::move(result); } @@ -420,7 +489,7 @@ shared_ptr TableFunctionMultiFileWrapper::CreateReader(ClientCon auto &data = bind_data.bind_data->Cast(); auto result = make_shared_ptr(function, file, data.options.named_parameters, settings.reader_type); - result->BindFunction(context, data.options); + result->BindFunction(context, data.options, bind_data.file_options); return std::move(result); } diff --git a/src/duckdb/src/common/multi_file/union_by_name.cpp b/src/duckdb/src/common/multi_file/union_by_name.cpp index 82ecaa1cc..5226970fb 100644 --- a/src/duckdb/src/common/multi_file/union_by_name.cpp +++ b/src/duckdb/src/common/multi_file/union_by_name.cpp @@ -54,7 +54,7 @@ vector> UnionByName::UnionCols(ClientContext &context, executor.WorkOnTasks(); // now combine the result schemas - interface.CombineSchemas(context, union_readers, union_col_types, union_col_names); + interface.CombineSchemas(context, union_readers, file_options.union_by_name, union_col_types, union_col_names); return union_readers; } diff --git a/src/duckdb/src/common/open_file_info.cpp b/src/duckdb/src/common/open_file_info.cpp index 90814fc3e..eb255c61b 100644 --- a/src/duckdb/src/common/open_file_info.cpp +++ b/src/duckdb/src/common/open_file_info.cpp @@ -1,57 +1,9 @@ #include "duckdb/common/open_file_info.hpp" #include "duckdb/common/exception.hpp" -#include "duckdb/common/string_util.hpp" namespace duckdb { -namespace { - -struct OpenFileOption { - const char *name; - LogicalTypeId type; -}; - -//! The open options the core knows about, together with the type they are read back as. Options that are not -//! listed here are stored as-is - extensions are free to define options of their own. -const OpenFileOption OPEN_FILE_OPTIONS[] = {{"file_size", LogicalTypeId::UBIGINT}, - {"last_modified", LogicalTypeId::TIMESTAMP}, - {"etag", LogicalTypeId::VARCHAR}, - {"type", LogicalTypeId::VARCHAR}, - {"force_full_download", LogicalTypeId::BOOLEAN}, - {"validate_external_file_cache", LogicalTypeId::BOOLEAN}, - {"footer_size", LogicalTypeId::UBIGINT}}; - -optional_ptr FindOpenFileOption(const string &name) { - for (auto &option : OPEN_FILE_OPTIONS) { - if (StringUtil::CIEquals(name, option.name)) { - return &option; - } - } - return nullptr; -} - -} // namespace - -void ExtendedOpenFileInfo::SetUserOption(const string &name, const Value &value) { - auto known_option = FindOpenFileOption(name); - if (!known_option) { - // not an option the core knows about - store it as-is for extensions to interpret - options[name] = value; - return; - } - LogicalType target_type(known_option->type); - string error_message; - auto casted_value = value.DefaultTryCastAs(target_type, &error_message); - if (!casted_value) { - throw InvalidInputException("Invalid value for file option \"%s\" - expected a value of type %s, but \"%s\" " - "was provided", - known_option->name, target_type.ToString(), value.ToString()); - } - // store the option under its canonical name, so a lookup of the option always finds it - options[known_option->name] = std::move(*casted_value); -} - template <> bool ExtendedOpenFileInfo::TryGetOption(const string &name, bool &result) const { auto entry = options.find(name); @@ -77,14 +29,17 @@ bool ExtendedOpenFileInfo::TryGetOption(const string &name, string &result) cons return false; } auto &value = entry->second; - // a string option can be stored as a VARCHAR or as a BLOB - both are read back with StringValue::Get, - // and casting a BLOB to VARCHAR here would escape the bytes it holds - if (value.IsNull() || value.type().InternalType() != PhysicalType::VARCHAR) { + if (value.IsNull()) { throw InvalidInputException( "Invalid value for file option \"%s\" - expected a VARCHAR, but \"%s\" was provided", name, value.ToString()); } - result = StringValue::Get(value); + // VARCHAR and BLOB are read back as-is - casting a BLOB to VARCHAR would escape the bytes it holds + if (value.type().InternalType() == PhysicalType::VARCHAR) { + result = StringValue::Get(value); + return true; + } + result = value.ToString(); return true; } @@ -106,4 +61,22 @@ bool ExtendedOpenFileInfo::TryGetOption(const string &name, idx_t &result) const return true; } +template <> +bool ExtendedOpenFileInfo::TryGetOption(const string &name, timestamp_t &result) const { + auto entry = options.find(name); + if (entry == options.end()) { + return false; + } + auto &value = entry->second; + string error_message; + auto timestamp_value = value.DefaultTryCastAs(LogicalType::TIMESTAMP, &error_message); + if (!timestamp_value || timestamp_value->IsNull()) { + throw InvalidInputException( + "Invalid value for file option \"%s\" - expected a TIMESTAMP, but \"%s\" was provided", name, + value.ToString()); + } + result = TimestampValue::Get(*timestamp_value); + return true; +} + } // namespace duckdb diff --git a/src/duckdb/src/common/opener_file_system.cpp b/src/duckdb/src/common/opener_file_system.cpp index 2b8e0e51c..5fb90fc08 100644 --- a/src/duckdb/src/common/opener_file_system.cpp +++ b/src/duckdb/src/common/opener_file_system.cpp @@ -23,6 +23,13 @@ unique_ptr OpenerFileSystem::MemoryMapFile(const OpenFileInfo return GetFileSystem().MemoryMapFile(path, flags, options, GetOpener()); } +unique_ptr OpenerFileSystem::GlobFilesExtended(const string &path, const FileGlobInput &input, + optional_ptr opener) { + VerifyNoOpener(opener); + VerifyCanAccessFile(path); + return GetFileSystem().Glob(path, input, GetOpener()); +} + void OpenerFileSystem::VerifyNoOpener(optional_ptr opener) { if (opener) { throw InternalException("OpenerFileSystem cannot take an opener - the opener is pushed automatically"); diff --git a/src/duckdb/src/common/operator/cast_operators.cpp b/src/duckdb/src/common/operator/cast_operators.cpp index 464b7d83f..0a489d448 100644 --- a/src/duckdb/src/common/operator/cast_operators.cpp +++ b/src/duckdb/src/common/operator/cast_operators.cpp @@ -2148,7 +2148,7 @@ struct HugeIntCastData { using Operation = OP; ResultType result; IntermediateType intermediate; - uint8_t digits; + idx_t digits; ResultType decimal; uint16_t decimal_total_digits; diff --git a/src/duckdb/src/common/sort/sort.cpp b/src/duckdb/src/common/sort/sort.cpp index be5b9c7e2..73d2fc983 100644 --- a/src/duckdb/src/common/sort/sort.cpp +++ b/src/duckdb/src/common/sort/sort.cpp @@ -2,7 +2,6 @@ #include "duckdb/main/client_context.hpp" #include "duckdb/main/settings.hpp" -#include "duckdb/common/type_visitor.hpp" #include "duckdb/common/sorting/sort_key.hpp" #include "duckdb/common/sorting/sorted_run.hpp" #include "duckdb/common/sorting/sorted_run_merger.hpp" @@ -23,33 +22,19 @@ Sort::Sort(ClientContext &client_context_p, const vector &orde // Convert orders to a single "create_sort_key" expression (and corresponding "decode_sort_key") FunctionBinder binder(client_context); vector> create_children; - vector> decode_children; - child_list_t decode_child_list; + child_list_t decode_columns; + vector decode_modifiers; for (idx_t col_idx = 0; col_idx < orders.size(); col_idx++) { const auto &order = orders[col_idx]; + const auto order_modifier = order.GetOrderModifier(); // Create: for each column we have two arguments: 1. the column, 2. sort specifier create_children.emplace_back(order.expression->Copy()); - create_children.emplace_back(make_uniq(Value(order.GetOrderModifier()))); - - // Avoid having unnamed structs fields (otherwise we get a parser exception while binding) - const auto col_name = StringUtil::Format("c%llu", col_idx); - auto col_type = order.expression->GetReturnType(); - decode_child_list.emplace_back(col_name, col_type); - col_type = TypeVisitor::VisitReplace(col_type, [](const LogicalType &type) { - if (!StructType::IsStruct(type)) { - return type; - } - child_list_t internal_child_list; - for (const auto &child : StructType::GetChildTypes(type)) { - internal_child_list.emplace_back(StringUtil::Format("c%llu", internal_child_list.size()), child.second); - } - return LogicalType::STRUCT(std::move(internal_child_list)); - }); + create_children.emplace_back(make_uniq(Value(order_modifier))); - // Decode: for each column we have two arguments: 1. col name + type, 2. sort specifier - decode_children.emplace_back(make_uniq(Value(col_name + " " + col_type.ToString()))); - decode_children.emplace_back(make_uniq(order.GetOrderModifier())); + // Decode: bind field types directly and use the same modifiers as the encoder + decode_columns.emplace_back(StringUtil::Format("c%llu", col_idx), order.expression->GetReturnType()); + decode_modifiers.push_back(OrderModifiers::Parse(order_modifier)); } ErrorData error; @@ -59,24 +44,10 @@ Sort::Sort(ClientContext &client_context_p, const vector &orde throw InternalException("Unable to bind create_sort_key in Sort::Sort"); } - switch (create_sort_key->GetReturnType().id()) { - case LogicalTypeId::BIGINT: - decode_children.insert(decode_children.begin(), - make_uniq(LogicalType::BIGINT, static_cast(0))); - break; - default: - D_ASSERT(create_sort_key->GetReturnType().id() == LogicalTypeId::BLOB); - decode_children.insert(decode_children.begin(), - make_uniq(LogicalType::BLOB, static_cast(0))); - } - - decode_sort_key = binder.BindScalarFunction(DecodeSortKeyFun::GetFunction(), std::move(decode_children)); - if (!decode_sort_key) { - throw InternalException("Unable to bind decode_sort_key in Sort::Sort"); - } - - // A bit hacky, but this way we make sure that the output does contain the unnamed structs again - decode_sort_key->SetReturnType(LogicalType::STRUCT(std::move(decode_child_list))); + auto sort_key_reference = + make_uniq(create_sort_key->GetReturnType(), static_cast(0)); + decode_sort_key = + DecodeSortKeyFun::Bind(std::move(sort_key_reference), std::move(decode_columns), std::move(decode_modifiers)); // For convenience, we fill the projection map if it is empty if (projection_map.empty()) { diff --git a/src/duckdb/src/common/types.cpp b/src/duckdb/src/common/types.cpp index bd465a2d2..4f28663a6 100644 --- a/src/duckdb/src/common/types.cpp +++ b/src/duckdb/src/common/types.cpp @@ -2014,6 +2014,32 @@ bool LogicalType::EqualTypeInfo(const LogicalType &rhs) const { } } +bool LogicalType::EqualsIncludingCollation(const LogicalType &rhs) const { + if (*this != rhs) { + return false; + } + vector collations; + TypeVisitor::Contains(*this, [&](const LogicalType &child) { + if (child.id() == LogicalTypeId::VARCHAR) { + collations.push_back(StringType::GetCollation(child)); + } + return false; + }); + idx_t index = 0; + auto mismatch = TypeVisitor::Contains(rhs, [&](const LogicalType &child) { + if (child.id() != LogicalTypeId::VARCHAR) { + return false; + } + if (index >= collations.size()) { + return true; + } + auto collation_mismatch = collations[index] != StringType::GetCollation(child); + index++; + return collation_mismatch; + }); + return !mismatch && index == collations.size(); +} + bool LogicalType::operator==(const LogicalType &rhs) const { if (id_ != rhs.id_) { return false; diff --git a/src/duckdb/src/common/types/conflict_manager.cpp b/src/duckdb/src/common/types/conflict_manager.cpp index c758d23dc..8c9c88bc1 100644 --- a/src/duckdb/src/common/types/conflict_manager.cpp +++ b/src/duckdb/src/common/types/conflict_manager.cpp @@ -43,7 +43,23 @@ bool ConflictManager::IsConflict(LookupResultType type) { } } -bool ConflictManager::AddHit(const idx_t index_in_chunk, const std::function &callback) { +void ConflictManager::AddRowId(const idx_t index_in_chunk, const row_t row_id) { + // Only ON CONFLICT DO NOTHING can have multiple conflict targets, + // which can cause multiple row IDs per index_in_chunk. + // We ignore later row IDs, as we don't need them. + auto &data = GetConflictData(FIRST); + if (!data.validity.RowIsValid(index_in_chunk)) { + data.Insert(index_in_chunk, row_id); + } +} + +void ConflictManager::AddSecondRowId(const idx_t index_in_chunk, const row_t row_id) { + D_ASSERT(HasConflicts()); + D_ASSERT(conflict_data[FIRST].validity.RowIsValid(index_in_chunk)); + GetConflictData(SECOND).Insert(index_in_chunk, row_id); +} + +bool ConflictManager::AddHitInternal(const idx_t index_in_chunk, const row_t row_id, const bool second) { D_ASSERT(index_in_chunk < chunk_size); if (ShouldThrow(index_in_chunk)) { return true; @@ -63,16 +79,20 @@ bool ConflictManager::AddHit(const idx_t index_in_chunk, const std::function suggested_types {"BIGINT", "INT8", @@ -82,7 +82,8 @@ static LogicalType TransformStringToUnboundType(const string &str) { // This has to be called with a level of indirection (through "parse_function") in order to avoid being included in // extensions that statically link the core DuckDB library. static LogicalType ParseLogicalTypeInternal(const string &type_str, ClientContext &context) { - auto type = TransformStringToUnboundType(type_str); + // The context grammar is compiled once, a default-constructed parser would recompile it per call + auto type = TransformStringToUnboundType(type_str, context.GetParserOptions()); if (type.IsUnbound()) { if (!context.transaction.HasActiveTransaction()) { throw InternalException( diff --git a/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp b/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp new file mode 100644 index 000000000..c4135b098 --- /dev/null +++ b/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp @@ -0,0 +1,910 @@ +#include +#include +#include +#include +#include +#include + +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" +#include "duckdb/common/types/variant/variant_binary_decoder.hpp" +#include "duckdb/common/vector/struct_vector.hpp" +#include "duckdb/common/types/variant.hpp" +#include "duckdb/function/scalar/variant_utils.hpp" +#include "duckdb/function/variant/variant_shredding.hpp" +#include "duckdb/common/operator/cast_operators.hpp" +#include "duckdb/common/assert.hpp" +#include "duckdb/common/enum_util.hpp" +#include "duckdb/common/exception.hpp" +#include "duckdb/common/helper.hpp" +#include "duckdb/common/hugeint.hpp" +#include "duckdb/common/limits.hpp" +#include "duckdb/common/numeric_utils.hpp" +#include "duckdb/common/optional_idx.hpp" +#include "duckdb/common/optional_ptr.hpp" +#include "duckdb/common/string.hpp" +#include "duckdb/common/string_map_set.hpp" +#include "duckdb/common/typedefs.hpp" +#include "duckdb/common/types.hpp" +#include "duckdb/common/types/selection_vector.hpp" +#include "duckdb/common/types/string_type.hpp" +#include "duckdb/common/types/uuid.hpp" +#include "duckdb/common/types/validity_mask.hpp" +#include "duckdb/common/types/value.hpp" +#include "duckdb/common/types/vector.hpp" +#include "duckdb/common/uhugeint.hpp" +#include "duckdb/common/unique_ptr.hpp" +#include "duckdb/common/vector.hpp" +#include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/common/vector/string_vector.hpp" +#include "duckdb/common/vector/unified_vector_format.hpp" + +namespace duckdb { + +static idx_t CalculateByteLength(idx_t value) { + if (value == 0) { + return 1; + } + auto value_data = reinterpret_cast(&value); + idx_t irrelevant_bytes = 0; + //! Check how many of the most significant bytes are 0 + for (idx_t i = sizeof(idx_t); i > 0 && value_data[i - 1] == 0; i--) { + irrelevant_bytes++; + } + return sizeof(idx_t) - irrelevant_bytes; +} + +static uint8_t EncodeMetadataHeader(idx_t byte_length) { + D_ASSERT(byte_length <= 4); + + uint8_t header_byte = 0; + //! Set 'version' to 1 + header_byte |= static_cast(1); + //! NOTE: keep 'sorted_strings' at 0, we don't always sort the key strings + //! Set 'offset_size_minus_one' to byte_length-1 + header_byte |= (static_cast(byte_length) - 1) << 6; + +#ifdef DEBUG + auto decoded_header = VariantMetadataHeader::FromHeaderByte(header_byte); + D_ASSERT(decoded_header.offset_size == byte_length); +#endif + + return header_byte; +} + +static void CreateMetadata(UnifiedVariantVectorData &variant, Vector &metadata, idx_t count) { + //! NOTE: the parquet variant is limited to a max dictionary size of NumericLimits::Maximum() + //! Whereas we can have NumericLimits::Maximum() *per* string in DuckDB + auto metadata_data = FlatVector::GetDataMutable(metadata); + for (idx_t row = 0; row < count; row++) { + uint64_t dictionary_count = 0; + if (variant.RowIsValid(row)) { + dictionary_count = variant.GetKeysCount(row); + } + idx_t dictionary_size = 0; + for (idx_t i = 0; i < dictionary_count; i++) { + auto &key = variant.GetKey(row, i); + dictionary_size += key.GetSize(); + } + if (dictionary_size >= NumericLimits::Maximum()) { + throw InvalidInputException("The total length of the dictionary exceeds a 4 byte value (uint32_t), failed " + "to export VARIANT to Parquet"); + } + + auto byte_length = CalculateByteLength(dictionary_size); + auto total_length = 1 + (byte_length * (dictionary_count + 2)) + dictionary_size; + + metadata_data[row] = StringVector::EmptyString(metadata, total_length); + auto &metadata_blob = metadata_data[row]; + auto metadata_blob_data = metadata_blob.GetDataWriteable(); + + metadata_blob_data[0] = static_cast(EncodeMetadataHeader(byte_length)); + memcpy(metadata_blob_data + 1, const_data_ptr_cast(&dictionary_count), byte_length); + + auto offset_ptr = metadata_blob_data + 1 + byte_length; + auto string_ptr = + metadata_blob_data + 1 + byte_length + (NumericCast(dictionary_count + 1) * byte_length); + idx_t total_offset = 0; + for (idx_t i = 0; i < dictionary_count; i++) { + memcpy(offset_ptr + (i * byte_length), const_data_ptr_cast(&total_offset), byte_length); + auto &key = variant.GetKey(row, i); + + memcpy(string_ptr + total_offset, key.GetData(), key.GetSize()); + total_offset += key.GetSize(); + } + memcpy(offset_ptr + (NumericCast(dictionary_count) * byte_length), const_data_ptr_cast(&total_offset), + byte_length); + D_ASSERT(offset_ptr + (NumericCast(dictionary_count + 1) * byte_length) == string_ptr); + D_ASSERT(string_ptr + total_offset == metadata_blob_data + total_length); + metadata_blob.SetSizeAndFinalize(total_length, total_length); + +#ifdef DEBUG + auto decoded_metadata = VariantMetadata(metadata_blob); + D_ASSERT(decoded_metadata.strings.size() == dictionary_count); + for (idx_t i = 0; i < dictionary_count; i++) { + D_ASSERT(decoded_metadata.strings[i] == variant.GetKey(row, i).GetString()); + } +#endif + } +} + +namespace { + +static unordered_set GetVariantType(const LogicalType &type) { + if (type.id() == LogicalTypeId::ANY) { + return {}; + } + switch (type.id()) { + case LogicalTypeId::STRUCT: + return {VariantLogicalType::OBJECT}; + case LogicalTypeId::LIST: + return {VariantLogicalType::ARRAY}; + case LogicalTypeId::BOOLEAN: + return {VariantLogicalType::BOOL_TRUE, VariantLogicalType::BOOL_FALSE}; + case LogicalTypeId::TINYINT: + return {VariantLogicalType::INT8}; + case LogicalTypeId::SMALLINT: + return {VariantLogicalType::INT16}; + case LogicalTypeId::INTEGER: + return {VariantLogicalType::INT32}; + case LogicalTypeId::BIGINT: + return {VariantLogicalType::INT64}; + case LogicalTypeId::FLOAT: + return {VariantLogicalType::FLOAT}; + case LogicalTypeId::DOUBLE: + return {VariantLogicalType::DOUBLE}; + case LogicalTypeId::DECIMAL: + return {VariantLogicalType::DECIMAL}; + case LogicalTypeId::DATE: + return {VariantLogicalType::DATE}; + case LogicalTypeId::TIME: + return {VariantLogicalType::TIME_MICROS}; + case LogicalTypeId::TIMESTAMP_TZ: + return {VariantLogicalType::TIMESTAMP_MICROS_TZ}; + case LogicalTypeId::TIMESTAMP_TZ_NS: + return {VariantLogicalType::TIMESTAMP_NANOS_TZ}; + case LogicalTypeId::TIMESTAMP: + return {VariantLogicalType::TIMESTAMP_MICROS}; + case LogicalTypeId::TIMESTAMP_NS: + return {VariantLogicalType::TIMESTAMP_NANOS}; + case LogicalTypeId::BLOB: + return {VariantLogicalType::BLOB}; + case LogicalTypeId::VARCHAR: + return {VariantLogicalType::VARCHAR}; + case LogicalTypeId::UUID: + return {VariantLogicalType::UUID}; + default: + throw BinderException("Type '%s' can't be translated to a VARIANT type", type.ToString()); + } +} + +struct ParquetVariantShreddingState : public VariantShreddingState { +public: + ParquetVariantShreddingState(const LogicalType &type, idx_t total_count) + : VariantShreddingState(type, total_count), variant_types(GetVariantType(type)) { + } + +public: + const unordered_set &GetVariantTypes() override { + return variant_types; + } + +private: + unordered_set variant_types; +}; + +struct ParquetVariantShredding : public VariantShredding { + ParquetVariantShredding() { + // for parquet untyped ("value") comes before typed ("typed_value") + untyped_value_index = 0; + typed_value_index = 1; + } + + void WriteVariantValues(UnifiedVariantVectorData &variant, Vector &result, optional_ptr sel, + optional_ptr value_index_sel, + optional_ptr result_sel, idx_t count) override; + +protected: + void WriteMissingField(Vector &vector, idx_t index) override; +}; + +} // namespace + +vector GetChildIndices(const UnifiedVariantVectorData &variant, idx_t row, const VariantNestedData &nested_data, + optional_ptr shredding_state) { + vector child_indices; + if (!shredding_state || shredding_state->type.id() != LogicalTypeId::STRUCT) { + for (idx_t i = 0; i < nested_data.child_count; i++) { + child_indices.push_back(i); + } + return child_indices; + } + auto shredded_fields = shredding_state->ObjectFields(); + + for (idx_t i = 0; i < nested_data.child_count; i++) { + auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); + auto &key = variant.GetKey(row, keys_index); + + if (shredded_fields.count(key.GetString())) { + //! This field is shredded on, omit it from the value + continue; + } + child_indices.push_back(i); + } + return child_indices; +} + +static idx_t AnalyzeValueData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_index, + vector &offsets, optional_ptr shredding_state) { + idx_t total_size = 0; + //! Every value has at least a value header + total_size++; + + idx_t offset_size = offsets.size(); + VariantLogicalType type_id = VariantLogicalType::VARIANT_NULL; + if (variant.RowIsValid(row)) { + type_id = variant.GetTypeId(row, values_index); + } + switch (type_id) { + case VariantLogicalType::OBJECT: { + auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); + + //! Calculate value and key offsets for all children + idx_t total_offset = 0; + uint32_t highest_keys_index = 0; + + auto child_indices = GetChildIndices(variant, row, nested_data, shredding_state); + if (nested_data.child_count && child_indices.empty()) { + //! All fields of the object are shredded, omit the object entirely + return 0; + } + + auto num_elements = child_indices.size(); + offsets.resize(offset_size + num_elements + 1); + + for (idx_t entry = 0; entry < child_indices.size(); entry++) { + auto i = child_indices[entry]; + auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); + auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); + offsets[offset_size + entry] = total_offset; + + total_offset += AnalyzeValueData(variant, row, values_index, offsets, nullptr); + highest_keys_index = MaxValue(highest_keys_index, keys_index); + } + offsets[offset_size + num_elements] = total_offset; + + //! Calculate the sizes for the objects value data + auto field_id_size = CalculateByteLength(highest_keys_index); + auto field_offset_size = CalculateByteLength(total_offset); + const bool is_large = num_elements > NumericLimits::Maximum(); + + //! Now add the sizes for the objects value data + if (is_large) { + total_size += sizeof(uint32_t); + } else { + total_size += sizeof(uint8_t); + } + total_size += num_elements * field_id_size; + total_size += (num_elements + 1) * field_offset_size; + total_size += total_offset; + break; + } + case VariantLogicalType::ARRAY: { + auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); + + idx_t total_offset = 0; + offsets.resize(offset_size + nested_data.child_count + 1); + for (idx_t i = 0; i < nested_data.child_count; i++) { + auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); + offsets[offset_size + i] = total_offset; + + total_offset += AnalyzeValueData(variant, row, values_index, offsets, nullptr); + } + offsets[offset_size + nested_data.child_count] = total_offset; + + auto field_offset_size = CalculateByteLength(total_offset); + auto num_elements = nested_data.child_count; + const bool is_large = num_elements > NumericLimits::Maximum(); + + if (is_large) { + total_size += sizeof(uint32_t); + } else { + total_size += sizeof(uint8_t); + } + total_size += (num_elements + 1) * field_offset_size; + total_size += total_offset; + break; + } + case VariantLogicalType::BLOB: + case VariantLogicalType::VARCHAR: { + auto string_value = VariantUtils::DecodeStringData(variant, row, values_index); + total_size += string_value.GetSize(); + if (type_id == VariantLogicalType::BLOB || string_value.GetSize() > 64) { + //! Save as regular string value + total_size += sizeof(uint32_t); + } + break; + } + case VariantLogicalType::VARIANT_NULL: + case VariantLogicalType::BOOL_TRUE: + case VariantLogicalType::BOOL_FALSE: + break; + case VariantLogicalType::INT8: + total_size += sizeof(uint8_t); + break; + case VariantLogicalType::INT16: + total_size += sizeof(uint16_t); + break; + case VariantLogicalType::INT32: + total_size += sizeof(uint32_t); + break; + case VariantLogicalType::INT64: + total_size += sizeof(uint64_t); + break; + case VariantLogicalType::FLOAT: + total_size += sizeof(float); + break; + case VariantLogicalType::DOUBLE: + total_size += sizeof(double); + break; + case VariantLogicalType::DECIMAL: { + auto decimal_data = VariantUtils::DecodeDecimalData(variant, row, values_index); + total_size += 1; + if (decimal_data.width <= 9) { + total_size += sizeof(int32_t); + } else if (decimal_data.width <= 18) { + total_size += sizeof(int64_t); + } else if (decimal_data.width <= 38) { + total_size += sizeof(uhugeint_t); + } else { + throw InvalidInputException("Can't convert VARIANT DECIMAL(%d, %d) to Parquet VARIANT", decimal_data.width, + decimal_data.scale); + } + break; + } + case VariantLogicalType::UUID: + total_size += sizeof(uhugeint_t); + break; + case VariantLogicalType::DATE: + total_size += sizeof(uint32_t); + break; + case VariantLogicalType::TIME_MICROS: + case VariantLogicalType::TIMESTAMP_MICROS: + case VariantLogicalType::TIMESTAMP_NANOS: + case VariantLogicalType::TIMESTAMP_MICROS_TZ: + total_size += sizeof(uint64_t); + break; + case VariantLogicalType::UINT8: + // store as int16_t + total_size += sizeof(int16_t); + break; + case VariantLogicalType::UINT16: + // store as int32_t + total_size += sizeof(int32_t); + break; + case VariantLogicalType::UINT32: + case VariantLogicalType::UINT64: + case VariantLogicalType::UINT128: + case VariantLogicalType::INT128: + // try to store as int64_t - fail if it doesn't fit + total_size += sizeof(int64_t); + break; + case VariantLogicalType::INTERVAL: + case VariantLogicalType::BIGNUM: + case VariantLogicalType::BITSTRING: + case VariantLogicalType::TIMESTAMP_MILIS: + case VariantLogicalType::TIMESTAMP_SEC: + case VariantLogicalType::TIME_MICROS_TZ: + case VariantLogicalType::TIME_NANOS: + default: + throw InvalidInputException("Can't convert VARIANT of type '%s' to Parquet VARIANT", + EnumUtil::ToString(type_id)); + } + + return total_size; +} + +template +void WritePrimitiveTypeHeader(data_ptr_t &value_data) { + uint8_t value_header = 0; + value_header |= static_cast(VariantBasicType::PRIMITIVE); + value_header |= static_cast(TYPE_ID) << 2; + + *value_data = value_header; + value_data++; +} + +struct VariantSimpleCopy { + template + static void CopyValue(const_data_ptr_t source, data_ptr_t target) { + memcpy(target, source, sizeof(T)); + } +}; + +template +struct VariantSimpleConversion { + template + static void CopyValue(const_data_ptr_t source, data_ptr_t target) { + auto src = Load(source); + Store(static_cast(src), target); + } +}; + +template +struct VariantTryConvert { + template + static void CopyValue(const_data_ptr_t source, data_ptr_t target) { + auto src = Load(source); + Store(Cast::Operation(src), target); + } +}; + +template +void CopySimplePrimitiveData(const UnifiedVariantVectorData &variant, data_ptr_t &value_data, idx_t row, + uint32_t values_index) { + auto byte_offset = variant.GetByteOffset(row, values_index); + auto data = const_data_ptr_cast(variant.GetData(row).GetData()); + auto ptr = data + byte_offset; + OP::template CopyValue(ptr, value_data); + value_data += sizeof(T); +} + +void CopyUUIDData(const UnifiedVariantVectorData &variant, data_ptr_t &value_data, idx_t row, uint32_t values_index) { + auto byte_offset = variant.GetByteOffset(row, values_index); + auto data = const_data_ptr_cast(variant.GetData(row).GetData()); + auto ptr = data + byte_offset; + + auto uuid = Load(ptr); + BaseUUID::ToBlob(uuid, value_data); + value_data += sizeof(uhugeint_t); +} + +static void WritePrimitiveValueData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_index, + data_ptr_t &value_data, const vector &offsets, idx_t &offset_index) { + VariantLogicalType type_id = VariantLogicalType::VARIANT_NULL; + if (variant.RowIsValid(row)) { + type_id = variant.GetTypeId(row, values_index); + } + + D_ASSERT(type_id != VariantLogicalType::OBJECT && type_id != VariantLogicalType::ARRAY); + switch (type_id) { + case VariantLogicalType::BLOB: + case VariantLogicalType::VARCHAR: { + auto string_value = VariantUtils::DecodeStringData(variant, row, values_index); + auto string_size = string_value.GetSize(); + if (type_id == VariantLogicalType::BLOB || string_size > 64) { + if (type_id == VariantLogicalType::BLOB) { + WritePrimitiveTypeHeader(value_data); + } else { + WritePrimitiveTypeHeader(value_data); + } + Store(string_size, value_data); + value_data += sizeof(uint32_t); + } else { + uint8_t value_header = 0; + value_header |= static_cast(VariantBasicType::SHORT_STRING); + value_header |= static_cast(string_size) << 2; + + *value_data = value_header; + value_data++; + } + memcpy(value_data, reinterpret_cast(string_value.GetData()), string_size); + value_data += string_size; + break; + } + case VariantLogicalType::VARIANT_NULL: + WritePrimitiveTypeHeader(value_data); + break; + case VariantLogicalType::BOOL_TRUE: + WritePrimitiveTypeHeader(value_data); + break; + case VariantLogicalType::BOOL_FALSE: + WritePrimitiveTypeHeader(value_data); + break; + case VariantLogicalType::INT8: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::INT16: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::INT32: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::INT64: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::FLOAT: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::DOUBLE: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::UUID: + WritePrimitiveTypeHeader(value_data); + CopyUUIDData(variant, value_data, row, values_index); + break; + case VariantLogicalType::DATE: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::TIME_MICROS: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::TIMESTAMP_MICROS: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::TIMESTAMP_NANOS: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::TIMESTAMP_MICROS_TZ: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData(variant, value_data, row, values_index); + break; + case VariantLogicalType::DECIMAL: { + auto decimal_data = VariantUtils::DecodeDecimalData(variant, row, values_index); + + if (decimal_data.width > 38) { + throw InvalidInputException("Can't convert VARIANT DECIMAL(%d, %d) to Parquet VARIANT", decimal_data.width, + decimal_data.scale); + } else if (decimal_data.width <= 4) { + // DuckDB uses INT16 to store small decimals, but parquet only supports DECIMAL4 at minimum, so here we + // promote to INT32. + WritePrimitiveTypeHeader(value_data); + Store(NumericCast(decimal_data.scale), value_data); + value_data++; + const int32_t promoted = Load(decimal_data.value_ptr); + Store(promoted, value_data); + value_data += sizeof(int32_t); + } else if (decimal_data.width <= 9) { + WritePrimitiveTypeHeader(value_data); + Store(NumericCast(decimal_data.scale), value_data); + value_data++; + memcpy(value_data, decimal_data.value_ptr, sizeof(int32_t)); + value_data += sizeof(int32_t); + } else if (decimal_data.width <= 18) { + WritePrimitiveTypeHeader(value_data); + Store(NumericCast(decimal_data.scale), value_data); + value_data++; + memcpy(value_data, decimal_data.value_ptr, sizeof(int64_t)); + value_data += sizeof(int64_t); + } else if (decimal_data.width <= 38) { + WritePrimitiveTypeHeader(value_data); + Store(NumericCast(decimal_data.scale), value_data); + value_data++; + memcpy(value_data, decimal_data.value_ptr, sizeof(hugeint_t)); + value_data += sizeof(hugeint_t); + } else { + throw InternalException( + "Uncovered VARIANT(DECIMAL) -> Parquet VARIANT conversion for type 'DECIMAL(%d, %d)'", + decimal_data.width, decimal_data.scale); + } + break; + } + case VariantLogicalType::UINT8: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData>(variant, value_data, row, values_index); + break; + case VariantLogicalType::UINT16: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData>(variant, value_data, row, values_index); + break; + case VariantLogicalType::UINT32: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData>(variant, value_data, row, values_index); + break; + case VariantLogicalType::UINT64: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData>(variant, value_data, row, values_index); + break; + case VariantLogicalType::UINT128: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData>(variant, value_data, row, values_index); + break; + case VariantLogicalType::INT128: + WritePrimitiveTypeHeader(value_data); + CopySimplePrimitiveData>(variant, value_data, row, values_index); + break; + case VariantLogicalType::INTERVAL: + case VariantLogicalType::BIGNUM: + case VariantLogicalType::BITSTRING: + case VariantLogicalType::TIMESTAMP_MILIS: + case VariantLogicalType::TIMESTAMP_SEC: + case VariantLogicalType::TIME_MICROS_TZ: + case VariantLogicalType::TIME_NANOS: + default: + throw InvalidInputException("Can't convert VARIANT of type '%s' to Parquet VARIANT", + EnumUtil::ToString(type_id)); + } +} + +static void WriteValueData(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_index, + data_ptr_t &value_data, const vector &offsets, idx_t &offset_index, + optional_ptr shredding_state) { + VariantLogicalType type_id = VariantLogicalType::VARIANT_NULL; + if (variant.RowIsValid(row)) { + type_id = variant.GetTypeId(row, values_index); + } + if (type_id == VariantLogicalType::OBJECT) { + auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); + + //! -- Object value header -- + + auto child_indices = GetChildIndices(variant, row, nested_data, shredding_state); + if (nested_data.child_count && child_indices.empty()) { + throw InternalException( + "The entire should be omitted, should have been handled by the Analyze step already"); + } + auto num_elements = child_indices.size(); + + //! Determine the 'field_id_size' + uint32_t highest_keys_index = 0; + for (auto &i : child_indices) { + auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); + highest_keys_index = MaxValue(highest_keys_index, keys_index); + } + auto field_id_size = CalculateByteLength(highest_keys_index); + + uint32_t last_offset = 0; + if (num_elements) { + last_offset = offsets[offset_index + num_elements]; + } + offset_index += num_elements + 1; + auto field_offset_size = CalculateByteLength(last_offset); + + const bool is_large = num_elements > NumericLimits::Maximum(); + + uint8_t value_header = 0; + value_header |= static_cast(VariantBasicType::OBJECT); + value_header |= static_cast(is_large) << 6; + value_header |= (static_cast(field_id_size) - 1) << 4; + value_header |= (static_cast(field_offset_size) - 1) << 2; + +#ifdef DEBUG + auto object_value_header = VariantValueMetadata::FromHeaderByte(value_header); + D_ASSERT(object_value_header.basic_type == VariantBasicType::OBJECT); + D_ASSERT(object_value_header.is_large == is_large); + D_ASSERT(object_value_header.field_offset_size == field_offset_size); + D_ASSERT(object_value_header.field_id_size == field_id_size); +#endif + + *value_data = value_header; + value_data++; + + //! Write the 'num_elements' + if (is_large) { + Store(static_cast(num_elements), value_data); + value_data += sizeof(uint32_t); + } else { + Store(static_cast(num_elements), value_data); + value_data += sizeof(uint8_t); + } + + //! Write the 'field_id' entries + for (auto &i : child_indices) { + auto keys_index = variant.GetKeysIndex(row, i + nested_data.children_idx); + memcpy(value_data, reinterpret_cast(&keys_index), field_id_size); + value_data += field_id_size; + } + + //! Write the 'field_offset' entries and the child 'value's + auto children_ptr = value_data + ((num_elements + 1) * field_offset_size); + idx_t total_offset = 0; + for (auto &i : child_indices) { + auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); + + memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); + value_data += field_offset_size; + auto start_ptr = children_ptr; + WriteValueData(variant, row, values_index, children_ptr, offsets, offset_index, nullptr); + total_offset += (children_ptr - start_ptr); + } + memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); + value_data += field_offset_size; + D_ASSERT(children_ptr - total_offset == value_data); + value_data = children_ptr; + } else if (type_id == VariantLogicalType::ARRAY) { + auto nested_data = VariantUtils::DecodeNestedData(variant, row, values_index); + + //! -- Array value header -- + + uint32_t last_offset = 0; + if (nested_data.child_count) { + last_offset = offsets[offset_index + nested_data.child_count]; + } + offset_index += nested_data.child_count + 1; + auto field_offset_size = CalculateByteLength(last_offset); + + auto num_elements = nested_data.child_count; + const bool is_large = num_elements > NumericLimits::Maximum(); + + uint8_t value_header = 0; + value_header |= static_cast(VariantBasicType::ARRAY); + value_header |= static_cast(is_large) << 4; + value_header |= (static_cast(field_offset_size) - 1) << 2; + +#ifdef DEBUG + auto array_value_header = VariantValueMetadata::FromHeaderByte(value_header); + D_ASSERT(array_value_header.basic_type == VariantBasicType::ARRAY); + D_ASSERT(array_value_header.is_large == is_large); + D_ASSERT(array_value_header.field_offset_size == field_offset_size); +#endif + + *value_data = value_header; + value_data++; + + //! Write the 'num_elements' + if (is_large) { + Store(static_cast(num_elements), value_data); + value_data += sizeof(uint32_t); + } else { + Store(static_cast(num_elements), value_data); + value_data += sizeof(uint8_t); + } + + //! Write the 'field_offset' entries and the child 'value's + auto children_ptr = value_data + ((num_elements + 1) * field_offset_size); + idx_t total_offset = 0; + for (idx_t i = 0; i < nested_data.child_count; i++) { + auto values_index = variant.GetValuesIndex(row, i + nested_data.children_idx); + + memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); + value_data += field_offset_size; + auto start_ptr = children_ptr; + WriteValueData(variant, row, values_index, children_ptr, offsets, offset_index, nullptr); + total_offset += (children_ptr - start_ptr); + } + memcpy(value_data, reinterpret_cast(&total_offset), field_offset_size); + value_data += field_offset_size; + D_ASSERT(children_ptr - total_offset == value_data); + value_data = children_ptr; + } else { + WritePrimitiveValueData(variant, row, values_index, value_data, offsets, offset_index); + } +} + +static void CreateValues(UnifiedVariantVectorData &variant, Vector &value, optional_ptr sel, + optional_ptr value_index_sel, + optional_ptr result_sel, + optional_ptr shredding_state, idx_t count) { + auto &validity = FlatVector::ValidityMutable(value); + auto value_data = FlatVector::GetDataMutable(value); + + for (idx_t i = 0; i < count; i++) { + idx_t value_index = 0; + if (value_index_sel) { + value_index = value_index_sel->get_index(i); + } + + idx_t row = i; + if (sel) { + row = sel->get_index(i); + } + + idx_t result_index = i; + if (result_sel) { + result_index = result_sel->get_index(i); + } + + bool is_shredded = false; + if (variant.RowIsValid(row) && shredding_state && shredding_state->ValueIsShredded(variant, row, value_index)) { + shredding_state->SetShredded(row, value_index, result_index); + is_shredded = true; + if (shredding_state->type.id() != LogicalTypeId::STRUCT) { + //! Value is shredded, directly write a NULL to the 'value' if the type is not an OBJECT + //! When the type is OBJECT, all excess fields would still need to be written to the 'value' + validity.SetInvalid(result_index); + continue; + } + } + + //! The (relative) offsets for each value, in the case of nesting + vector offsets; + //! Determine the size of this 'value' blob + idx_t blob_length = AnalyzeValueData(variant, row, value_index, offsets, shredding_state); + if (!blob_length) { + //! This is only allowed to happen for a shredded OBJECT, where there are no excess fields to write for the + //! OBJECT + (void)is_shredded; + D_ASSERT(is_shredded); + validity.SetInvalid(result_index); + continue; + } + value_data[result_index] = StringVector::EmptyString(value, blob_length); + auto &value_blob = value_data[result_index]; + auto value_blob_data = reinterpret_cast(value_blob.GetDataWriteable()); + + idx_t offset_index = 0; + WriteValueData(variant, row, value_index, value_blob_data, offsets, offset_index, shredding_state); + D_ASSERT(data_ptr_cast(value_blob.GetDataWriteable() + blob_length) == value_blob_data); + value_blob.SetSizeAndFinalize(blob_length, blob_length); + } +} + +void ParquetVariantShredding::WriteMissingField(Vector &vector, idx_t index) { + //! The field is missing, set it to null + FlatVector::SetNull(vector, index, true); +} + +void ParquetVariantShredding::WriteVariantValues(UnifiedVariantVectorData &variant, Vector &result, + optional_ptr sel, + optional_ptr value_index_sel, + optional_ptr result_sel, idx_t count) { + optional_ptr value; + optional_ptr typed_value; + + auto &result_type = result.GetType(); + D_ASSERT(result_type.id() == LogicalTypeId::STRUCT); + auto &child_types = StructType::GetChildTypes(result_type); + auto &child_vectors = StructVector::GetEntries(result); + D_ASSERT(child_types.size() == child_vectors.size()); + for (idx_t i = 0; i < child_types.size(); i++) { + auto &name = child_types[i].first; + if (name == "value") { + value = &child_vectors[i]; + } else if (name == "typed_value") { + typed_value = &child_vectors[i]; + } + } + + if (typed_value) { + ParquetVariantShreddingState shredding_state(typed_value->GetType(), count); + CreateValues(variant, *value, sel, value_index_sel, result_sel, &shredding_state, count); + + SelectionVector null_values; + if (shredding_state.count) { + WriteTypedValues(variant, *typed_value, shredding_state.shredded_sel, shredding_state.values_index_sel, + shredding_state.result_sel, shredding_state.count); + //! 'shredding_state.result_sel' will always be a subset of 'result_sel', set the rows not in the subset to + //! NULL + idx_t sel_idx = 0; + for (idx_t i = 0; i < count; i++) { + auto original_index = result_sel ? result_sel->get_index(i) : i; + if (sel_idx < shredding_state.count && shredding_state.result_sel[sel_idx] == original_index) { + sel_idx++; + continue; + } + FlatVector::SetNull(*typed_value, original_index, true); + } + } else { + //! Set all rows of the typed_value to NULL, nothing is shredded on + for (idx_t i = 0; i < count; i++) { + FlatVector::SetNull(*typed_value, result_sel ? result_sel->get_index(i) : i, true); + } + } + } else { + CreateValues(variant, *value, sel, value_index_sel, result_sel, nullptr, count); + } +} + +void ParquetVariantConversion::ToParquetVariant(const Vector &variant_vec, idx_t count, Vector &result) { + // DuckDB Variant: + // - keys = VARCHAR[] + // - children = STRUCT(keys_index UINTEGER, values_index UINTEGER)[] + // - values = STRUCT(type_id UTINYINT, byte_offset UINTEGER)[] + // - data = BLOB + + // Parquet VARIANT: + // - metadata = BLOB + // - value = BLOB (+ typed_value when 'result' declares a shredded layout) + + RecursiveUnifiedVectorFormat recursive_format; + Vector::RecursiveToUnifiedFormat(variant_vec, recursive_format); + UnifiedVariantVectorData variant(recursive_format); + + auto &result_vectors = StructVector::GetEntries(result); + auto &metadata = result_vectors[0]; + CreateMetadata(variant, metadata, count); + + ParquetVariantShredding shredding; + shredding.WriteVariantValues(variant, result, nullptr, nullptr, nullptr, count); +} + +} // namespace duckdb diff --git a/src/duckdb/extension/parquet/reader/variant/parquet_variant_iterator.cpp b/src/duckdb/src/common/types/variant/parquet_variant_iterator.cpp similarity index 97% rename from src/duckdb/extension/parquet/reader/variant/parquet_variant_iterator.cpp rename to src/duckdb/src/common/types/variant/parquet_variant_iterator.cpp index 518086c7b..0733e55b3 100644 --- a/src/duckdb/extension/parquet/reader/variant/parquet_variant_iterator.cpp +++ b/src/duckdb/src/common/types/variant/parquet_variant_iterator.cpp @@ -1,4 +1,4 @@ -#include "reader/variant/parquet_variant_iterator.hpp" +#include "duckdb/common/types/variant/parquet_variant_iterator.hpp" #include "duckdb/common/types/variant/variant_builder.hpp" #include "duckdb/common/vector/struct_vector.hpp" @@ -9,7 +9,7 @@ #include "duckdb/common/helper.hpp" #include "duckdb/common/exception.hpp" #include "duckdb/common/numeric_utils.hpp" -#include "reader/uuid_column_reader.hpp" +#include "duckdb/common/types/uuid.hpp" #include "utf8proc_wrapper.hpp" #include @@ -273,7 +273,7 @@ T CastDecimalValue(SRC value) { template T ReadBinaryUUID(const_data_ptr_t payload) { if constexpr (std::is_same::value) { - return UUIDValueConversion::ReadParquetUUID(payload); + return BaseUUID::FromBlob(payload); } else { throw InternalException("Variant UUID must be read as hugeint_t"); } @@ -705,15 +705,4 @@ void ParquetVariantConversion::ConvertBinary(Vector &metadata_and_value, Vector BuildVariant(source, count, result); } -static void VariantBytesToVariantFunction(DataChunk &input, ExpressionState &state, Vector &result) { - ParquetVariantConversion::ConvertBinary(input.data[0], result, input.size()); -} - -ScalarFunction ParquetVariantConversion::GetBytesToVariantFunction() { - ScalarFunction function("variant_bytes_to_variant", {}, LogicalType::VARIANT(), VariantBytesToVariantFunction); - function.GetSignature().AddParameter("blob", LogicalType::BLOB); - function.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); - return function; -} - } // namespace duckdb diff --git a/src/duckdb/extension/parquet/reader/variant/variant_binary_decoder.cpp b/src/duckdb/src/common/types/variant/variant_binary_decoder.cpp similarity index 98% rename from src/duckdb/extension/parquet/reader/variant/variant_binary_decoder.cpp rename to src/duckdb/src/common/types/variant/variant_binary_decoder.cpp index 868f278aa..71c127778 100644 --- a/src/duckdb/extension/parquet/reader/variant/variant_binary_decoder.cpp +++ b/src/duckdb/src/common/types/variant/variant_binary_decoder.cpp @@ -1,4 +1,4 @@ -#include "reader/variant/variant_binary_decoder.hpp" +#include "duckdb/common/types/variant/variant_binary_decoder.hpp" #include diff --git a/src/duckdb/src/common/vector/struct_vector.cpp b/src/duckdb/src/common/vector/struct_vector.cpp index 6d0619958..e258884dd 100644 --- a/src/duckdb/src/common/vector/struct_vector.cpp +++ b/src/duckdb/src/common/vector/struct_vector.cpp @@ -163,7 +163,7 @@ buffer_ptr VectorStructBuffer::SliceInternal(const LogicalType &ty buffer_ptr VectorStructBuffer::ConstantSliceInternal(const LogicalType &type, count_t count) { vector result_children; for (idx_t i = 0; i < children.size(); i++) { - result_children.emplace_back(Vector::Ref(children[i])); + result_children.emplace_back(children[i], *ConstantVector::ZeroSelectionVector(), count); } auto result = make_buffer(std::move(result_children), capacity_t(1ULL)); result->GetValidityMask().Set(0, validity.RowIsValid(0)); diff --git a/src/duckdb/src/common/virtual_file_system.cpp b/src/duckdb/src/common/virtual_file_system.cpp index 49b1c2230..c39941f6b 100644 --- a/src/duckdb/src/common/virtual_file_system.cpp +++ b/src/duckdb/src/common/virtual_file_system.cpp @@ -259,6 +259,10 @@ FileMetadata VirtualFileSystem::Stats(FileHandle &handle) { return handle.file_system.Stats(handle); } +optional VirtualFileSystem::GetStatsIfExists(const OpenFileInfo &file, optional_ptr opener) { + return FindFileSystem(file.path, opener).GetStatsIfExists(file, opener); +} + void VirtualFileSystem::Truncate(FileHandle &handle, int64_t new_size) { handle.file_system.Truncate(handle, new_size); } diff --git a/src/duckdb/src/execution/expression_executor.cpp b/src/duckdb/src/execution/expression_executor.cpp index a0b433c46..a61502e62 100644 --- a/src/duckdb/src/execution/expression_executor.cpp +++ b/src/duckdb/src/execution/expression_executor.cpp @@ -151,7 +151,7 @@ Value ExpressionExecutor::EvaluateScalar(ClientContext &context, const Expressio D_ASSERT(allow_unfoldable || result.GetVectorType() == VectorType::CONSTANT_VECTOR); auto result_value = result.GetValue(0); D_ASSERT(result_value.type().InternalType() == expr.GetReturnType().InternalType()); - return result_value; + return result_value.WithType(expr.GetReturnType()); } bool ExpressionExecutor::TryEvaluateScalar(ClientContext &context, const Expression &expr, Value &result) { diff --git a/src/duckdb/src/execution/ie_join_union.cpp b/src/duckdb/src/execution/ie_join_union.cpp new file mode 100644 index 000000000..f4652f189 --- /dev/null +++ b/src/duckdb/src/execution/ie_join_union.cpp @@ -0,0 +1,363 @@ +#include "duckdb/execution/ie_join_union.hpp" +#include "duckdb/common/bit_utils.hpp" +#include "duckdb/common/sorting/sort_key.hpp" +#include "duckdb/main/client_context.hpp" +#include "duckdb/planner/expression/bound_constant_expression.hpp" +#include "duckdb/planner/expression/bound_reference_expression.hpp" + +namespace duckdb { + +idx_t IEJoinUnion::AppendKey(ExecutionContext &context, InterruptState &interrupt, SortedTable &table, + ExpressionExecutor &executor, SortedTable &marked, int64_t increment, int64_t rid, + const ChunkRange &chunk_range) { + const auto chunk_begin = chunk_range.first; + const auto chunk_end = chunk_range.second; + + if (chunk_begin == chunk_end) { + return 0; + } + + // Reading + const auto valid = table.count - table.has_null; + auto &source = *table.sorted->payload_data; + TupleDataScanState scanner; + source.InitializeScan(scanner); + + DataChunk scanned; + source.InitializeScanChunk(scanner, scanned); + idx_t table_idx = source.Seek(scanner, chunk_begin); + + // Writing + auto &sort = *marked.sort; + auto local_sort_state = sort.GetLocalSinkState(context); + vector types; + for (const auto &expr : executor.expressions) { + types.emplace_back(expr->GetReturnType()); + } + const idx_t rid_idx = types.size(); + types.emplace_back(LogicalType::BIGINT); + + DataChunk keys; + DataChunk payload; + keys.Initialize(Allocator::DefaultAllocator(), types); + + OperatorSinkInput sink {*marked.global_sink, *local_sort_state, interrupt}; + idx_t inserted = 0; + for (auto chunk_idx = chunk_begin; chunk_idx < chunk_end; ++chunk_idx) { + source.Scan(scanner, scanned); + + // NULLs are at the end, so stop when we reach them + auto scan_count = scanned.size(); + if (table_idx + scan_count > valid) { + if (table_idx >= valid) { + scan_count = 0; + ; + } else { + scan_count = valid - table_idx; + scanned.SetChildCardinality(scan_count); + } + } + if (scan_count == 0) { + break; + } + table_idx += scan_count; + + // Compute the input columns from the payload + keys.Reset(); + keys.Split(payload, rid_idx); + executor.Execute(scanned, keys); + + // Mark the rid column + payload.data[0].Sequence(rid, increment, scan_count); + keys.Fuse(payload); + rid += increment * UnsafeNumericCast(scan_count); + + // Sort on the sort columns (which will no longer be needed) + sort.Sink(context, keys, sink); + inserted += scan_count; + } + OperatorSinkCombineInput combine {*marked.global_sink, *local_sort_state, interrupt}; + sort.Combine(context, combine); + marked.count += inserted; + + return inserted; +} + +IEJoinUnion::IEJoinUnion(SortedTable &l2, ColumnDataCollection &li, ColumnDataCollection &p, + const vector &conditions, const ChunkRange &chunks) + : n(0), i(0), li(li), p(p) { + // 7. initialize bit-array B (|B| = n), and set all bits to 0 + n_j = l2.count.load(); + bit_array.resize(ValidityMask::EntryCount(n_j), 0); + bit_mask.Initialize(bit_array.data(), n_j); + + // Bloom filter + bloom_count = (n_j + (BLOOM_CHUNK_BITS - 1)) / BLOOM_CHUNK_BITS; + bloom_array.resize(ValidityMask::EntryCount(bloom_count), 0); + bloom_filter.Initialize(bloom_array.data(), bloom_count); + + // 11. for(i←1 to n) do + const auto strict2 = IsStrictComparison(conditions[1].GetComparisonType()); + op2 = make_uniq(l2, strict2); + off2 = make_uniq(l2, strict2); + n = l2.BlockStart(chunks.second); + i = l2.BlockStart(chunks.first); + j = i; + anti_i = i; + + const auto sort_key_type = l2.GetSortKeyType(); + switch (sort_key_type) { +#define DUCKDB_SORT_KEY_CASE(SORT_KEY_TYPE) \ + case SortKeyType::SORT_KEY_TYPE: \ + next_row_func = &IEJoinUnion::NextRow; \ + break; + DUCKDB_FOR_EACH_SORT_KEY_TYPE(DUCKDB_SORT_KEY_CASE) +#undef DUCKDB_SORT_KEY_CASE + default: + throw NotImplementedException("IEJoinUnion for %s", EnumUtil::ToString(sort_key_type)); + } + + (this->*next_row_func)(); +} + +template +bool IEJoinUnion::NextRow() { + using SORT_KEY = SortKey; + using BLOCKS_ITERATOR = block_iterator_t; + + BLOCKS_ITERATOR off2_itr(*off2->state); + BLOCKS_ITERATOR op2_itr(*op2->state); + const auto strict = off2->strict; + + auto pinned_idx = off2->GetChunkIndex(); + for (; i < n; ++i) { + // 12. pos ← P[i] + auto pos = p[i]; + lrid = li[pos]; + if (lrid < 0) { + continue; + } + + // 16. B[pos] ← 1 + op2->SetIndex(i); + for (; off2->GetIndex() < n_j; ++(*off2)) { + // Prevent buildup of pinned blocks + if (off2->GetChunkIndex() != pinned_idx) { + off2->Repin(); + pinned_idx = off2->GetChunkIndex(); + } + if (!Compare(off2_itr[off2->GetIndex()], op2_itr[op2->GetIndex()], strict)) { + break; + } + const auto p2 = p[off2->GetIndex()]; + if (li[p2] < 0) { + // Only mark rhs matches. + bit_mask.SetValidUnsafe(p2); + bloom_filter.SetValidUnsafe(p2 / BLOOM_CHUNK_BITS); + } + } + + // 9. if (op1 ∈ {≤,≥} and op2 ∈ {≤,≥}) eqOff = 0 + // 10. else eqOff = 1 + // No, because there could be more than one equal value. + // Find the leftmost off1 where L1[pos] op1 L1[off1..n] + // These are the rows that satisfy the op1 condition + // and that is where we should start scanning B from + j = pos; + + return true; + } + return false; +} + +static idx_t NextValid(const ValidityMask &bits, idx_t j, const idx_t n) { + if (j >= n) { + return n; + } + + // We can do a first approximation by checking entries one at a time + // which gives 64:1. + idx_t entry_idx, idx_in_entry; + bits.GetEntryIndex(j, entry_idx, idx_in_entry); + + // Copy first entry to local and trim the bits before the start position + auto first_entry = bits.GetValidityEntryUnsafe(entry_idx++); + first_entry &= (ValidityMask::ValidityBuffer::MAX_ENTRY << idx_in_entry); + + // If the first entry has a valid bit, we can return immediately + if (first_entry) { + return j + CountZeros::Trailing(first_entry) - idx_in_entry; + } + + // The first entry did not have a valid bit + j += ValidityMask::BITS_PER_VALUE - idx_in_entry; + + // Loop over non-ragged entries + const auto entry_count_minus_one = bits.EntryCount(n) - 1; + const auto entry_idx_before = entry_idx; + + // The compiler has a hard time optimizing this loop for some reason + // Creating a static inner loop like this improves performance by almost 2x + static constexpr idx_t NEXT_VALID_UNROLL = 8; + for (; entry_idx + NEXT_VALID_UNROLL < entry_count_minus_one; entry_idx += NEXT_VALID_UNROLL) { + for (idx_t unroll_idx = 0; unroll_idx < NEXT_VALID_UNROLL; unroll_idx++) { + const auto unroll_entry_idx = entry_idx + unroll_idx; + const auto &entry = bits.GetValidityEntryUnsafe(unroll_entry_idx); + if (entry) { + return j + (unroll_entry_idx - entry_idx_before) * ValidityMask::BITS_PER_VALUE + + CountZeros::Trailing(entry); + } + } + } + + for (; entry_idx < entry_count_minus_one; ++entry_idx) { + const auto &entry = bits.GetValidityEntryUnsafe(entry_idx); + if (entry) { + return j + (entry_idx - entry_idx_before) * ValidityMask::BITS_PER_VALUE + + CountZeros::Trailing(entry); + } + } + + // Update j once after the loop so we don't have to update it in each iteration + j += (entry_idx - entry_idx_before) * ValidityMask::BITS_PER_VALUE; + + // Check the final entry + return j >= n ? n : j + CountZeros::Trailing(bits.GetValidityEntryUnsafe(entry_idx)); +} + +idx_t IEJoinUnion::JoinBlocks(unsafe_vector &lsel, unsafe_vector &rsel) { + // Release pinned blocks + op2->Repin(); + off2->Repin(); + + // 8. initialize join result as an empty list for tuple pairs + idx_t result_count = 0; + + lsel.resize(STANDARD_VECTOR_SIZE); + rsel.resize(STANDARD_VECTOR_SIZE); + + // 11. for(i←1 to n) do + while (i < n) { + // 13. for (j ← pos+eqOff to n) do + for (;;) { + // 14. if B[j] = 1 then + + // Use the Bloom filter to find candidate blocks + while (j < n_j) { + auto bloom_begin = NextValid(bloom_filter, j / BLOOM_CHUNK_BITS, bloom_count) * BLOOM_CHUNK_BITS; + auto bloom_end = MinValue(n_j, bloom_begin + BLOOM_CHUNK_BITS); + + j = MaxValue(j, bloom_begin); + j = NextValid(bit_mask, j, bloom_end); + if (j < bloom_end) { + break; + } + } + + if (j >= n_j) { + break; + } + + // Filter out tuples with the same sign (they come from the same table) + const auto rrid = li[j]; + ++j; + + D_ASSERT(lrid > 0 && rrid < 0); + // 15. add tuples w.r.t. (L1[j], L1[i]) to join result + lsel[result_count] = static_cast(+lrid - 1); + rsel[result_count] = static_cast(-rrid - 1); + ++result_count; + if (result_count == STANDARD_VECTOR_SIZE) { + // out of space! + return result_count; + } + } + + if (!FinishRow()) { + break; + } + } + + lsel.resize(result_count); + rsel.resize(result_count); + + return result_count; +} + +void IEJoinUnion::InitializeTables(ClientContext &client, const PhysicalComparisonJoin &op, + const vector &conditions, unique_ptr &l1, + unique_ptr &l2) { + // input : query Q with 2 join predicates t1.X op1 t2.X' and t1.Y op2 t2.Y', tables T, T' of sizes m and n resp. + // output: a list of tuple pairs (ti , tj) + // Note that T/T' are already sorted on X/X' and contain the payload data + // We only join the two block numbers and use the sizes of the blocks as the counts + + // 1. let L1 (resp. L2) be the array of column X (resp. Y ) + const auto first = conditions[0].GetComparisonType(); + const auto second = conditions[1].GetComparisonType(); + const auto first_order = + first == ExpressionType::COMPARE_LESSTHAN || first == ExpressionType::COMPARE_LESSTHANOREQUALTO + ? OrderType::ASCENDING + : OrderType::DESCENDING; + const auto second_order = + second == ExpressionType::COMPARE_LESSTHAN || second == ExpressionType::COMPARE_LESSTHANOREQUALTO + ? OrderType::DESCENDING + : OrderType::ASCENDING; + BoundOrderByNode order1(first_order, OrderByNullType::NULLS_LAST, + make_uniq(conditions[0].GetLHS().GetReturnType(), 0)); + BoundOrderByNode order2(second_order, OrderByNullType::NULLS_LAST, + make_uniq(conditions[1].GetLHS().GetReturnType(), 0)); + + // 2. if (op1 ∈ {>, ≥}) sort L1 in descending order + // 3. else if (op1 ∈ {<, ≤}) sort L1 in ascending order + + // For the union algorithm, we make a unified table with the keys and the rids as the payload: + // X/X', Y/Y', R/R'/Li + // The first position is the sort key. + vector types; + types.emplace_back(order2.expression->GetReturnType()); + types.emplace_back(LogicalType::BIGINT); + + // Sort on the first expression + auto ref = make_uniq(order1.expression->GetReturnType(), 0U); + vector orders; + orders.emplace_back(order1.type, order1.null_order, std::move(ref)); + // The goal is to make i (from the left table) < j (from the right table), + // if value[i] and value[j] match the condition 1. + // Add a column from_left to solve the problem when there exist multiple equal values in l1. + // If the operator is loose inequality, make t1.from_left (== true) sort BEFORE t2.from_left (== false). + // Otherwise, make t1.from_left sort (== true) sort AFTER t2.from_left (== false). + // For example, if t1.time <= t2.time + // | value | 1 | 1 | 1 | 1 | + // | --------- | ----- | ----- | ----- | ----- | + // | from_left | T(l2) | T(l2) | F(r1) | F(r2) | + // if t1.time < t2.time + // | value | 1 | 1 | 1 | 1 | + // | --------- | ----- | ----- | ----- | ----- | + // | from_left | F(r2) | F(r1) | T(l2) | T(l1) | + // Using this OrderType, if i < j then value[i] (from left table) and value[j] (from right table) match + // the condition (t1.time <= t2.time or t1.time < t2.time), then from_left will force them into the correct order. + auto from_left = make_uniq(Value::BOOLEAN(true)); + const auto strict1 = IEJoinUnion::IsStrictComparison(conditions[0].GetComparisonType()); + orders.emplace_back(!strict1 ? OrderType::DESCENDING : OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, + std::move(from_left)); + + l1 = make_uniq(client, orders, types, op); + + // 4. if (op2 ∈ {>, ≥}) sort L2 in ascending order + // 5. else if (op2 ∈ {<, ≤}) sort L2 in descending order + + // We sort on Y/Y' to obtain the sort keys and the permutation array. + // For this we just need a two-column table of Y, P + types.clear(); + types.emplace_back(LogicalType::BIGINT); + + // Sort on the first expression + orders.clear(); + ref = make_uniq(order2.expression->GetReturnType(), 0U); + orders.emplace_back(order2.type, order2.null_order, std::move(ref)); + + l2 = make_uniq(client, orders, types, op); +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/index/fixed_size_allocator.cpp b/src/duckdb/src/execution/index/fixed_size_allocator.cpp index 0dfc77d17..361506dfe 100644 --- a/src/duckdb/src/execution/index/fixed_size_allocator.cpp +++ b/src/duckdb/src/execution/index/fixed_size_allocator.cpp @@ -269,6 +269,7 @@ IndexPointer FixedSizeAllocator::VacuumPointer(const IndexPointer old_ptr) { auto old_handle = GetHandle(old_ptr); auto new_handle = GetHandle(new_ptr); + new_handle.MarkModified(); memcpy(new_handle.GetPtr(), old_handle.GetPtr(), segment_size); return new_ptr; diff --git a/src/duckdb/src/execution/mark_join_row_comparison.cpp b/src/duckdb/src/execution/mark_join_row_comparison.cpp index 8d9de1b41..d21407ad2 100644 --- a/src/duckdb/src/execution/mark_join_row_comparison.cpp +++ b/src/duckdb/src/execution/mark_join_row_comparison.cpp @@ -2,6 +2,8 @@ #include "duckdb/common/vector/constant_vector.hpp" #include "duckdb/common/vector/struct_vector.hpp" +#include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/planner/joinside.hpp" #include "duckdb/common/vector_operations/vector_operations.hpp" namespace duckdb { @@ -76,4 +78,112 @@ void MarkJoinRowComparison::CompareEquality(const Vector &left, idx_t left_row, } } +void MarkJoinRowComparison::Compare(const Vector &left, const Vector &right, ExpressionType comparison_type, + Vector &result) { + result.SetVectorType(VectorType::FLAT_VECTOR); + FlatVector::ValidityMutable(result).Reset(right.size()); + switch (comparison_type) { + case ExpressionType::COMPARE_EQUAL: + return VectorOperations::Equals(left, right, result); + case ExpressionType::COMPARE_NOTEQUAL: + return VectorOperations::NotEquals(left, right, result); + case ExpressionType::COMPARE_LESSTHAN: + return VectorOperations::LessThan(left, right, result); + case ExpressionType::COMPARE_GREATERTHAN: + return VectorOperations::GreaterThan(left, right, result); + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + return VectorOperations::LessThanEquals(left, right, result); + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + return VectorOperations::GreaterThanEquals(left, right, result); + case ExpressionType::COMPARE_DISTINCT_FROM: + return VectorOperations::DistinctFrom(left, right, result); + case ExpressionType::COMPARE_NOT_DISTINCT_FROM: + return VectorOperations::NotDistinctFrom(left, right, result); + default: + throw InternalException("Unsupported comparison type for MARK join"); + } +} + +MarkJoinRowComparison::MarkJoinRowComparison(const DataChunk &left) : comparison(LogicalType::BOOLEAN) { + left_reference.Initialize(Allocator::DefaultAllocator(), left.GetTypes()); +} + +void MarkJoinRowComparison::CompareConjunction(DataChunk &left, idx_t left_row, DataChunk &right, + const vector &conditions, Vector &result) { + D_ASSERT(left_row < left.size()); + D_ASSERT(right.size() <= STANDARD_VECTOR_SIZE); + D_ASSERT(left.ColumnCount() == conditions.size()); + D_ASSERT(right.ColumnCount() == conditions.size()); + left_reference.Reset(); + bool pair_is_false[STANDARD_VECTOR_SIZE] = {false}; + bool pair_is_unknown[STANDARD_VECTOR_SIZE] = {false}; + for (idx_t condition_idx = 0; condition_idx < conditions.size(); condition_idx++) { + const auto type = conditions[condition_idx].GetComparisonType(); + if (left.data[condition_idx].GetType().id() == LogicalTypeId::TUPLE && + (type == ExpressionType::COMPARE_EQUAL || type == ExpressionType::COMPARE_NOTEQUAL)) { + bool is_false[STANDARD_VECTOR_SIZE] = {false}; + bool is_unknown[STANDARD_VECTOR_SIZE] = {false}; + CompareEquality(left.data[condition_idx], left_row, left.size(), right.data[condition_idx], right.size(), + is_false, is_unknown); + comparison.SetVectorType(VectorType::FLAT_VECTOR); + FlatVector::ValidityMutable(comparison).Reset(right.size()); + auto writer = FlatVector::Writer(comparison, right.size()); + for (idx_t row = 0; row < right.size(); row++) { + if (is_unknown[row]) { + writer.WriteNull(); + } else { + writer.WriteValue(type == ExpressionType::COMPARE_EQUAL ? !is_false[row] : is_false[row]); + } + } + } else { + ConstantVector::Reference(left_reference.data[condition_idx], count_t(right.size()), + left.data[condition_idx], left_row, left.size()); + Compare(left_reference.data[condition_idx], right.data[condition_idx], type, comparison); + } + auto entries = comparison.Values(); + for (idx_t right_row = 0; right_row < right.size(); right_row++) { + auto entry = entries[right_row]; + if (!entry.IsValid()) { + pair_is_unknown[right_row] = true; + } else if (!entry.GetValue()) { + pair_is_false[right_row] = true; + } + } + } + result.SetVectorType(VectorType::FLAT_VECTOR); + FlatVector::ValidityMutable(result).Reset(right.size()); + auto writer = FlatVector::Writer(result, right.size()); + for (idx_t right_row = 0; right_row < right.size(); right_row++) { + if (pair_is_false[right_row]) { + writer.WriteValue(false); + } else if (pair_is_unknown[right_row]) { + writer.WriteNull(); + } else { + writer.WriteValue(true); + } + } +} + +void MarkJoinRowComparison::Perform(DataChunk &left, DataChunk &right, bool found_match[], + const vector &conditions, optional_ptr found_unknown) { + Vector comparison(LogicalType::BOOLEAN); + MarkJoinRowComparison comparer(left); + for (idx_t left_row = 0; left_row < left.size(); left_row++) { + if (found_match[left_row]) { + continue; + } + comparer.CompareConjunction(left, left_row, right, conditions, comparison); + for (auto entry : comparison.Values()) { + if (entry.IsValid()) { + if (entry.GetValue()) { + found_match[left_row] = true; + break; + } + } else if (found_unknown) { + found_unknown.get()[left_row] = true; + } + } + } +} + } // namespace duckdb diff --git a/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp b/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp index 3c614b2a4..785b3d7fc 100644 --- a/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp +++ b/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp @@ -1,5 +1,6 @@ #include "duckdb/common/operator/comparison_operators.hpp" #include "duckdb/common/vector/constant_vector.hpp" +#include "duckdb/common/vector/flat_vector.hpp" #include "duckdb/common/types/vector.hpp" #include "duckdb/common/uhugeint.hpp" #include "duckdb/common/vector_operations/vector_operations.hpp" @@ -83,16 +84,18 @@ static void MarkJoinNested(const Vector &left, const Vector &right, idx_t lcount count = VectorOperations::NotEquals(left_reference, right, nullptr, rcount, nullptr, nullptr, &null_mask); break; case ExpressionType::COMPARE_LESSTHAN: - count = VectorOperations::LessThan(left_reference, right, nullptr, rcount, nullptr, nullptr); + count = VectorOperations::LessThan(left_reference, right, nullptr, rcount, nullptr, nullptr, &null_mask); break; case ExpressionType::COMPARE_GREATERTHAN: - count = VectorOperations::GreaterThan(left_reference, right, nullptr, rcount, nullptr, nullptr); + count = VectorOperations::GreaterThan(left_reference, right, nullptr, rcount, nullptr, nullptr, &null_mask); break; case ExpressionType::COMPARE_LESSTHANOREQUALTO: - count = VectorOperations::LessThanEquals(left_reference, right, nullptr, rcount, nullptr, nullptr); + count = + VectorOperations::LessThanEquals(left_reference, right, nullptr, rcount, nullptr, nullptr, &null_mask); break; case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - count = VectorOperations::GreaterThanEquals(left_reference, right, nullptr, rcount, nullptr, nullptr); + count = VectorOperations::GreaterThanEquals(left_reference, right, nullptr, rcount, nullptr, nullptr, + &null_mask); break; case ExpressionType::COMPARE_DISTINCT_FROM: count = VectorOperations::DistinctFrom(left_reference, right, nullptr, rcount, nullptr, nullptr); @@ -189,10 +192,13 @@ void NestedLoopJoinMark::Perform(DataChunk &left, ColumnDataCollection &right, b right.InitializeScanChunk(scan_chunk); while (right.Scan(scan_state, scan_chunk)) { - for (idx_t i = 0; i < conditions.size(); i++) { - MarkJoinComparisonSwitch(left.data[i], scan_chunk.data[i], left.size(), scan_chunk.size(), found_match, - conditions[i].GetComparisonType(), found_unknown); + if (conditions.size() > 1) { + MarkJoinRowComparison::Perform(left, scan_chunk, found_match, conditions, found_unknown); + continue; } + D_ASSERT(conditions.size() == 1); + MarkJoinComparisonSwitch(left.data[0], scan_chunk.data[0], left.size(), scan_chunk.size(), found_match, + conditions[0].GetComparisonType(), found_unknown); } } diff --git a/src/duckdb/src/execution/operator/aggregate/physical_limited_distinct.cpp b/src/duckdb/src/execution/operator/aggregate/physical_limited_distinct.cpp index b5726cfdf..504ab3295 100644 --- a/src/duckdb/src/execution/operator/aggregate/physical_limited_distinct.cpp +++ b/src/duckdb/src/execution/operator/aggregate/physical_limited_distinct.cpp @@ -154,7 +154,9 @@ SinkFinalizeType PhysicalLimitedDistinct::Finalize(Pipeline &pipeline, Event &ev // Source //===--------------------------------------------------------------------===// struct LimitedDistinctGlobalSourceState : public GlobalSourceState { - LimitedDistinctGlobalSourceState(const PhysicalLimitedDistinct &op, ClientContext &context) : initialized(false) { + LimitedDistinctGlobalSourceState(const PhysicalLimitedDistinct &op, ClientContext &context) + : initialized(false), total_rows(op.sink_state->Cast().ht->Count()), + rows_scanned(0) { group_chunk.Initialize(Allocator::Get(context), op.group_types); vector payload_types; @@ -169,6 +171,8 @@ struct LimitedDistinctGlobalSourceState : public GlobalSourceState { AggregateHTScanState scan_state; bool initialized; + const idx_t total_rows; + atomic rows_scanned; DataChunk group_chunk; DataChunk payload_chunk; }; @@ -177,6 +181,19 @@ unique_ptr PhysicalLimitedDistinct::GetGlobalSourceState(Clie return make_uniq(*this, context); } +ProgressData PhysicalLimitedDistinct::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + ProgressData progress; + progress.total = double(MaxValue(state.total_rows, 1)); + progress.done = state.total_rows == 0 ? 1.0 : double(state.rows_scanned.load(std::memory_order_relaxed)); + return progress; +} + +void PhysicalLimitedDistinct::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + state.rows_scanned.store(state.total_rows, std::memory_order_relaxed); +} + unique_ptr PhysicalLimitedDistinct::GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const { return make_uniq(); @@ -217,6 +234,7 @@ SourceResultType PhysicalLimitedDistinct::GetDataInternal(ExecutionContext &cont col++; } + gstate_source.rows_scanned.fetch_add(chunk.size(), std::memory_order_relaxed); return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp b/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp index c0f339e65..d3955ce95 100644 --- a/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp +++ b/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp @@ -1,6 +1,7 @@ #include "duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp" #include "duckdb/execution/perfect_aggregate_hashtable.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/planner/expression/bound_aggregate_expression.hpp" #include "duckdb/planner/expression/bound_reference_expression.hpp" #include "duckdb/storage/buffer_manager.hpp" @@ -181,18 +182,32 @@ class PerfectHashAggregateState : public GlobalSourceState { //! The current position to scan the HT for output tuples idx_t ht_scan_position; + atomic scanned_slots {0}; }; unique_ptr PhysicalPerfectHashAggregate::GetGlobalSourceState(ClientContext &context) const { return make_uniq(); } +ProgressData PhysicalPerfectHashAggregate::GetProgress(ClientContext &context, GlobalSourceState &gstate_p) const { + auto &state = gstate_p.Cast(); + auto &gstate = sink_state->Cast(); + return ProgressData {double(state.scanned_slots.load()), double(gstate.ht->Capacity()), false}; +} + +void PhysicalPerfectHashAggregate::SourceFinished(ClientContext &context, GlobalSourceState &gstate_p) const { + auto &state = gstate_p.Cast(); + auto &gstate = sink_state->Cast(); + state.scanned_slots = gstate.ht->Capacity(); +} + SourceResultType PhysicalPerfectHashAggregate::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &state = input.global_state.Cast(); auto &gstate = sink_state->Cast(); gstate.ht->Scan(state.ht_scan_position, chunk); + state.scanned_slots = state.ht_scan_position; if (chunk.size() > 0) { return SourceResultType::HAVE_MORE_OUTPUT; diff --git a/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp b/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp index 3ef9347db..9a6619476 100644 --- a/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +++ b/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp @@ -21,6 +21,8 @@ #include "duckdb/planner/expression/bound_reference_expression.hpp" #include "duckdb/execution/operator/aggregate/ungrouped_aggregate_state.hpp" +#include "duckdb/common/atomic.hpp" + #include namespace duckdb { @@ -658,6 +660,20 @@ SinkFinalizeType PhysicalUngroupedAggregate::Finalize(Pipeline &pipeline, Event //===--------------------------------------------------------------------===// // Source //===--------------------------------------------------------------------===// +class UngroupedAggregateGlobalSourceState : public GlobalSourceState { +public: + atomic finished {false}; +}; + +unique_ptr PhysicalUngroupedAggregate::GetGlobalSourceState(ClientContext &context) const { + return make_uniq(); +} + +ProgressData PhysicalUngroupedAggregate::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + return ProgressData {state.finished ? 1.0 : 0.0, 1.0, false}; +} + void VerifyNullHandling(DataChunk &chunk, UngroupedAggregateState &state, const vector> &aggregates) { if (DBConfigOptions::global_verification_mode != DebugVerificationMode::VERIFY_FUNCTIONS) { @@ -700,6 +716,7 @@ SourceResultType PhysicalUngroupedAggregate::GetDataInternal(ExecutionContext &c // initialize the result chunk with the aggregate values gstate.state.Finalize(chunk); VerifyNullHandling(chunk, gstate.state.state, aggregates); + input.global_state.Cast().finished = true; return SourceResultType::FINISHED; } diff --git a/src/duckdb/src/execution/operator/aggregate/physical_window.cpp b/src/duckdb/src/execution/operator/aggregate/physical_window.cpp index e80bbbc71..a5ad6a8e3 100644 --- a/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +++ b/src/duckdb/src/execution/operator/aggregate/physical_window.cpp @@ -666,11 +666,13 @@ void WindowHashGroup::AllocateMasks() { // Allocate masks inside the lock partition_mask.Initialize(count); + // All masks refer to the shared sort's partition columns, including duplicate expressions. + const auto &sort_expr = gsink.op.select_list[gsink.op.order_idx]->Cast(); + const auto order_begin = gsink.op.partition_info.RequiresPartitionColumns() ? 0 : sort_expr.Partitions().size(); const auto &executors = gsink.executors; for (auto &wexec : executors) { auto &wexpr = wexec->wexpr; - const auto order_begin = gsink.op.partition_info.RequiresPartitionColumns() ? 0 : wexpr.Partitions().size(); auto &order_mask = order_masks[order_begin + wexpr.OrderBy().size()]; if (order_mask.IsMaskSet()) { continue; @@ -905,9 +907,10 @@ WindowHashGroup::ExecutorGlobalStates &WindowHashGroup::GetGlobalStates(ClientCo } // These can be large so we defer building them until we are ready. + const auto &sort_expr = gsink.op.select_list[gsink.op.order_idx]->Cast(); + const auto order_begin = gsink.op.partition_info.RequiresPartitionColumns() ? 0 : sort_expr.Partitions().size(); for (auto &wexec : executors) { auto &wexpr = wexec->wexpr; - const auto order_begin = gsink.op.partition_info.RequiresPartitionColumns() ? 0 : wexpr.Partitions().size(); auto &order_mask = order_masks[order_begin + wexpr.OrderBy().size()]; gestates.emplace_back(wexec->GetGlobalState(client, count, partition_mask, order_mask)); } diff --git a/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp b/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp index 46d7ab9be..aa0f8d6eb 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/sniffer/csv_sniffer.cpp @@ -151,7 +151,7 @@ SnifferResult CSVSniffer::AdaptiveSniff(const CSVSchema &file_schema) { // Check if we are happy with the result or if we need to do more sniffing if (!error_handler->AnyErrors() && !detection_error_handler->AnyErrors()) { // If we got no errors, we also run full if schemas do not match. - if (!set_columns.IsSet() && !file_options.AnySet()) { + if (!set_columns.IsSet()) { string error; run_full = !file_schema.SchemasMatch(error, min_sniff_res, options.file_path, true); } diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp index 099b91364..2e2e9287b 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp @@ -10,7 +10,7 @@ CSVFileScan::CSVFileScan(ClientContext &context, const OpenFileInfo &file_p, CSV const MultiFileOptions &file_options, const vector &names, const vector &types, CSVSchema &file_schema, bool per_file_single_threaded, shared_ptr buffer_manager_p, bool fixed_schema) - : BaseFileReader(file_p), buffer_manager(std::move(buffer_manager_p)), + : file(file_p), buffer_manager(std::move(buffer_manager_p)), error_handler(make_shared_ptr(options_p.ignore_errors.GetValue())), options(std::move(options_p)) { // Initialize Buffer Manager @@ -51,7 +51,7 @@ CSVFileScan::CSVFileScan(ClientContext &context, const OpenFileInfo &file_p, CSV CSVFileScan::CSVFileScan(ClientContext &context, const OpenFileInfo &file_p, const CSVReaderOptions &options_p, const MultiFileOptions &file_options) - : BaseFileReader(file_p), error_handler(make_shared_ptr(options_p.ignore_errors.GetValue())), + : file(file_p), error_handler(make_shared_ptr(options_p.ignore_errors.GetValue())), options(options_p) { buffer_manager = CSVBufferManager::Open(context, options, file); // Initialize On Disk and Size of file @@ -78,9 +78,6 @@ CSVFileScan::CSVFileScan(ClientContext &context, const OpenFileInfo &file_p, con SetStart(); } -CSVUnionData::~CSVUnionData() { -} - void CSVFileScan::SetStart() { idx_t rows_to_skip = options.GetSkipRows() + state_machine->dialect_options.header.GetValue(); @@ -159,4 +156,23 @@ void CSVFileScan::Finish() { buffer_manager.reset(); } +double CSVFileScan::GetProgressInFile(ClientContext &context) { + auto manager = buffer_manager; + if (!manager) { + // We are done with this file, so it's 100% + return 100.0; + } + double total_bytes_read; + if (manager->file_handle->compression_type == FileCompressionType::GZIP || + manager->file_handle->compression_type == FileCompressionType::ZSTD) { + // compressed file: we care about the progress made in the *underlying* file handle + // the bytes read from the uncompressed file are skewed + total_bytes_read = manager->file_handle->GetProgress(); + } else { + total_bytes_read = static_cast(bytes_read); + } + double file_progress = total_bytes_read / static_cast(file_size); + return file_progress * 100.0; +} + } // namespace duckdb diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_multi_file_info.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_multi_file_info.cpp deleted file mode 100644 index 4684e328e..000000000 --- a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_multi_file_info.cpp +++ /dev/null @@ -1,490 +0,0 @@ -#include "duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp" -#include "duckdb/execution/operator/csv_scanner/global_csv_state.hpp" -#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_buffer.hpp" -#include "duckdb/execution/operator/persistent/csv_rejects_table.hpp" -#include "duckdb/common/bind_helpers.hpp" -#include "duckdb/common/exception.hpp" -#include "duckdb/parallel/async_result.hpp" -#include "duckdb/parallel/callback_async_task.hpp" - -namespace duckdb { - -unique_ptr CSVMultiFileInfo::CreateInterface(ClientContext &context) { - return make_uniq(); -} - -unique_ptr CSVMultiFileInfo::InitializeOptions(ClientContext &context, - optional_ptr info) { - return make_uniq(); -} - -bool CSVMultiFileInfo::ParseCopyOption(ClientContext &context, const Identifier &key, const vector &values, - BaseFileReaderOptions &options_p, vector &expected_names, - vector &expected_types) { - auto &options = options_p.Cast(); - options.options.SetReadOption(key, ConvertVectorToValue(values), expected_names); - return true; -} - -bool CSVMultiFileInfo::ParseOption(ClientContext &context, const Identifier &key, const Value &val, - MultiFileOptions &file_options, BaseFileReaderOptions &options_p) { - auto &options = options_p.Cast(); - options.options.ParseOption(context, key, val); - return true; -} - -void CSVMultiFileInfo::FinalizeCopyBind(ClientContext &context, BaseFileReaderOptions &options_p, - const vector &expected_names, - const vector &expected_types) { - auto &options = options_p.Cast(); - auto &csv_options = options.options; - csv_options.name_list = expected_names; - csv_options.sql_type_list = expected_types; - csv_options.columns_set = true; - for (idx_t i = 0; i < expected_types.size(); i++) { - csv_options.sql_types_per_column[expected_names[i]] = i; - } -} - -unique_ptr CSVMultiFileInfo::InitializeBindData(MultiFileBindData &multi_file_data, - unique_ptr options_p) { - auto &options = options_p->Cast(); - auto csv_data = make_uniq(); - csv_data->options = std::move(options.options); - if (multi_file_data.file_list->GetExpandResult() == FileExpandResult::MULTIPLE_FILES) { - csv_data->options.multi_file_reader = true; - } - csv_data->options.Verify(multi_file_data.file_options); - return std::move(csv_data); -} - -//! Function to do schema discovery over one CSV file or a list/glob of CSV files -CSVSchema CSVSchemaDiscovery::SchemaDiscovery(ClientContext &context, shared_ptr &buffer_manager, - CSVReaderOptions &options, const MultiFileOptions &file_options, - vector &return_types, vector &names, - MultiFileList &multi_file_list) { - vector schemas; - const auto option_og = options; - - const auto file_paths = multi_file_list.GetAllFiles(); - - // Here what we want to do is to sniff a given number of lines, if we have many files, we might go through them - // to reach the number of lines. - const idx_t required_number_of_lines = options.sniff_size * options.sample_size_chunks; - - idx_t total_number_of_rows = 0; - idx_t current_file = 0; - options.file_path = file_paths[current_file].path; - - buffer_manager = CSVBufferManager::Open(context, options, options.file_path, false); - idx_t only_header_or_empty_files = 0; - - { - CSVSniffer sniffer(options, file_options, buffer_manager, CSVStateMachineCache::Get(context)); - auto sniffer_result = sniffer.SniffCSV(); - idx_t rows_read = sniffer.LinesSniffed() - - (options.dialect_options.skip_rows.GetValue() + options.dialect_options.header.GetValue()); - - schemas.emplace_back(sniffer_result.names, sniffer_result.return_types, file_paths[0].path, rows_read, - buffer_manager->GetBuffer(0)->actual_size == 0); - total_number_of_rows += sniffer.LinesSniffed(); - current_file++; - if (sniffer.EmptyOrOnlyHeader()) { - only_header_or_empty_files++; - } - } - - // We do a copy of the options to not pollute the options of the first file. - idx_t max_files_to_sniff = static_cast(options.files_to_sniff == -1) - ? NumericLimits::Maximum() - : static_cast(options.files_to_sniff); - idx_t files_to_sniff = file_paths.size() > max_files_to_sniff ? max_files_to_sniff : file_paths.size(); - while (total_number_of_rows < required_number_of_lines && current_file < files_to_sniff) { - auto option_copy = option_og; - option_copy.file_path = file_paths[current_file].path; - auto file_buffer_manager = CSVBufferManager::Open(context, option_copy, option_copy.file_path, false); - // TODO: We could cache the sniffer to be reused during scanning. Currently that's an exercise left to the - // reader - CSVSniffer sniffer(option_copy, file_options, file_buffer_manager, CSVStateMachineCache::Get(context)); - auto sniffer_result = sniffer.SniffCSV(); - idx_t rows_read = sniffer.LinesSniffed() - (option_copy.dialect_options.skip_rows.GetValue() + - option_copy.dialect_options.header.GetValue()); - if (file_buffer_manager->GetBuffer(0)->actual_size == 0) { - schemas.emplace_back(true); - } else { - schemas.emplace_back(sniffer_result.names, sniffer_result.return_types, option_copy.file_path, rows_read); - } - total_number_of_rows += sniffer.LinesSniffed(); - if (sniffer.EmptyOrOnlyHeader()) { - only_header_or_empty_files++; - } - current_file++; - } - - // We might now have multiple schemas, we need to go through them to define the one true schema - CSVSchema best_schema; - for (auto &schema : schemas) { - if (best_schema.Empty()) { - // A schema is bettah than no schema - best_schema = schema; - } else if (best_schema.GetRowsRead() == 0) { - // If the best-schema has no data-rows, that's easy; we just take the new schema - best_schema = schema; - } else if (schema.GetRowsRead() != 0) { - // We might have conflicting-schemas, we must merge them - best_schema.MergeSchemas(schema, options.null_padding); - } - } - - // At this point, replace a sqlnull with varchar for the type - best_schema.ReplaceNullWithVarchar(); - - if (names.empty()) { - names = StringsToIdentifiers(best_schema.GetNames()); - return_types = best_schema.GetTypes(); - } - if (names.empty() && return_types.empty()) { - throw InvalidInputException("No columns found in CSV files. Provide the columns option or ensure at least one " - "file contains a header or data row."); - } - if (only_header_or_empty_files == current_file && !options.columns_set) { - for (idx_t i = 0; i < return_types.size(); i++) { - if (!options.sql_types_per_column.empty()) { - if (options.sql_types_per_column.find(names[i]) != options.sql_types_per_column.end()) { - continue; - } - } else if (i < options.sql_type_list.size()) { - continue; - } - // we default to varchar if all files are empty or only have a header after all the sniffing - return_types[i] = LogicalType::VARCHAR; - } - } - return best_schema; -} - -void CSVMultiFileInfo::BindReader(ClientContext &context, vector &return_types, vector &names, - MultiFileBindData &bind_data) { - auto &csv_data = bind_data.bind_data->Cast(); - auto &multi_file_list = *bind_data.file_list; - auto &options = csv_data.options; - if (!bind_data.file_options.union_by_name) { - if (options.auto_detect) { - csv_data.csv_schema = - CSVSchemaDiscovery::SchemaDiscovery(context, csv_data.buffer_manager, options, bind_data.file_options, - return_types, names, multi_file_list); - } else { - // If we are not running the sniffer, the columns must be set! - if (!options.columns_set) { - throw BinderException("read_csv requires columns to be specified through the 'columns' option. Use " - "read_csv_auto or set read_csv(..., " - "AUTO_DETECT=TRUE) to automatically guess columns."); - } - names = options.name_list; - return_types = options.sql_type_list; - } - if (return_types.size() != names.size()) { - throw BinderException("read_csv: mismatch between the number of column names (%d) and column types (%d)", - names.size(), return_types.size()); - } - csv_data.options.dialect_options.num_cols = names.size(); - - bind_data.multi_file_reader->BindOptions(bind_data.file_options, multi_file_list, return_types, names, - bind_data.reader_bind); - } else { - CSVFileReaderOptions csv_options(options); - bind_data.reader_bind = bind_data.multi_file_reader->BindUnionReader( - context, return_types, names, multi_file_list, bind_data, csv_options, bind_data.file_options); - if (bind_data.union_readers.size() > 1) { - for (idx_t i = 0; i < bind_data.union_readers.size(); i++) { - auto &csv_union_data = bind_data.union_readers[i]->Cast(); - csv_data.column_info.emplace_back(csv_union_data.names, csv_union_data.types); - } - } - if (!options.sql_types_per_column.empty()) { - const auto exception = CSVError::ColumnTypesError(options.sql_types_per_column, names); - if (!exception.error_message.empty()) { - throw BinderException(exception.error_message); - } - for (idx_t i = 0; i < names.size(); i++) { - auto it = options.sql_types_per_column.find(names[i]); - if (it != options.sql_types_per_column.end()) { - return_types[i] = options.sql_type_list[it->second]; - } - } - } - bind_data.initial_reader.reset(); - } -} - -void CSVMultiFileInfo::FinalizeBindData(MultiFileBindData &multi_file_data) { - auto &csv_data = multi_file_data.bind_data->Cast(); - auto &names = multi_file_data.names; - auto &options = csv_data.options; - if (!options.force_not_null_names.empty()) { - // Let's first check all column names match - identifier_set_t column_names; - for (auto &name : names) { - column_names.insert(name); - } - for (auto &force_name : options.force_not_null_names) { - if (column_names.find(Identifier(force_name)) == column_names.end()) { - throw BinderException("\"force_not_null\" expected to find %s, but it was not found in the table", - force_name); - } - } - D_ASSERT(options.force_not_null.empty()); - for (idx_t i = 0; i < names.size(); i++) { - if (options.force_not_null_names.find(names[i].GetIdentifierName()) != options.force_not_null_names.end()) { - options.force_not_null.push_back(true); - } else { - options.force_not_null.push_back(false); - } - } - } - for (auto &type : multi_file_data.types) { - if (type.id() == LogicalTypeId::SQLNULL) { - // If after performing all the type detection of all files, - // we can't tell the type of column, we default to the highest type, a VARCHAR. - type = LogicalType::VARCHAR; - } - } - csv_data.Finalize(); -} - -optional_idx CSVMultiFileInfo::MaxThreads(const MultiFileBindData &bind_data, const MultiFileGlobalState &global_state, - FileExpandResult expand_result) { - auto &csv_data = bind_data.bind_data->Cast(); - if (!csv_data.buffer_manager) { - return optional_idx(); - } - if (expand_result == FileExpandResult::MULTIPLE_FILES) { - // always launch max threads if we are reading multiple files - return optional_idx(); - } - const idx_t bytes_per_thread = CSVIterator::BytesPerThread(csv_data.options); - const idx_t file_size = csv_data.buffer_manager->file_handle->FileSize(); - return file_size / bytes_per_thread + 1; -} - -bool CSVMultiFileInfo::SupportsReadAhead(const MultiFileBindData &bind_data) const { - auto &csv_data = bind_data.bind_data->Cast(); - return csv_data.buffer_manager && csv_data.buffer_manager->file_handle && - csv_data.buffer_manager->file_handle->HasKnownBufferRanges(); -} - -unique_ptr CSVMultiFileInfo::InitializeGlobalState(ClientContext &context, - MultiFileBindData &bind_data, - MultiFileGlobalState &global_state) { - auto &csv_data = bind_data.bind_data->Cast(); - - // Create the temporary rejects table - if (csv_data.options.store_rejects.GetValue()) { - CSVRejectsTable::GetOrCreate(context, csv_data.options.rejects_scan_name.GetValue(), - csv_data.options.rejects_table_name.GetValue()) - ->InitializeTable(context, csv_data); - } - return make_uniq(context, csv_data.options, bind_data.file_list->GetTotalFileCount(), bind_data); -} - -unique_ptr CSVMultiFileInfo::InitializeLocalState(ClientContext &, - GlobalTableFunctionState &) { - return make_uniq(); -} - -shared_ptr CSVMultiFileInfo::CreateReader(ClientContext &context, GlobalTableFunctionState &gstate_p, - BaseUnionData &union_data_p, - const MultiFileBindData &bind_data) { - auto &union_data = union_data_p.Cast(); - auto &gstate = gstate_p.Cast(); - auto &csv_data = bind_data.bind_data->Cast(); - // union readers - use cached options - auto &csv_names = union_data.names; - auto &csv_types = union_data.types; - auto options = union_data.options; - options.auto_detect = false; - D_ASSERT(csv_data.csv_schema.Empty()); - return make_shared_ptr(context, union_data.GetFileName(), std::move(options), bind_data.file_options, - StringsToIdentifiers(csv_names), csv_types, csv_data.csv_schema, - gstate.SingleThreadedRead(), nullptr, false); -} - -shared_ptr CSVMultiFileInfo::CreateReader(ClientContext &context, GlobalTableFunctionState &gstate_p, - const OpenFileInfo &file, idx_t file_idx, - const MultiFileBindData &bind_data) { - auto &gstate = gstate_p.Cast(); - auto &csv_data = bind_data.bind_data->Cast(); - - auto options = csv_data.options; - if (bind_data.file_list->GetExpandResult() == FileExpandResult::SINGLE_FILE) { - options.auto_detect = false; - } - - shared_ptr buffer_manager; - if (file_idx == 0) { - buffer_manager = csv_data.buffer_manager; - if (buffer_manager && buffer_manager->GetFilePath() != file.path) { - buffer_manager.reset(); - } - } - return make_shared_ptr(context, file, std::move(options), bind_data.file_options, bind_data.names, - bind_data.types, csv_data.csv_schema, gstate.SingleThreadedRead(), - std::move(buffer_manager), false); -} - -shared_ptr CSVMultiFileInfo::CreateReader(ClientContext &context, const OpenFileInfo &file, - BaseFileReaderOptions &options_p, - const MultiFileOptions &file_options) { - auto &csv_options = options_p.Cast(); - return make_shared_ptr(context, file, csv_options.options, file_options); -} - -shared_ptr CSVFileScan::GetUnionData(idx_t file_idx) { - auto data = make_shared_ptr(file); - data->names = GetNames(); - data->types = GetTypes(); - if (file_idx == 0) { - data->options = options; - data->reader = shared_from_this(); - } else { - data->options = std::move(options); - } - data->options.auto_detect = false; - return data; -} - -void CSVFileScan::PrepareReader(ClientContext &context, GlobalTableFunctionState &) { - InitializeFileNamesTypes(); - SetStart(); -} - -bool CSVFileScan::TryInitializeScan(ClientContext &context, GlobalTableFunctionState &gstate_p, - LocalTableFunctionState &lstate_p) { - auto &gstate = gstate_p.Cast(); - auto &lstate = lstate_p.Cast(); - auto csv_reader_ptr = shared_ptr_cast(shared_from_this()); - gstate.FinishScan(std::move(lstate.csv_reader)); - lstate.claim_state = CSVLocalState::ClaimState::IDLE; - return gstate.Next(csv_reader_ptr, lstate); -} - -// A task that loads the buffer on the async pool, sized for the read-ahead I/O budget -static unique_ptr BufferLoadTask(const shared_ptr &manager, const idx_t buffer_idx) { - const idx_t io_size = - manager->HasKnownBufferRanges() ? manager->KnownBufferSize(buffer_idx) : manager->GetBufferSize(); - return make_uniq([manager, buffer_idx] { manager->GetBuffer(buffer_idx); }, io_size); -} - -// Adds a load task when the buffer is not in memory -static void TryPushBufferLoadTask(const shared_ptr &manager, const idx_t buffer_idx, - vector> &io_tasks) { - shared_ptr buffer_handle; - if (manager->GetBufferResidency(buffer_idx, buffer_handle) == CSVBufferResidency::NEEDS_LOAD) { - io_tasks.push_back(BufferLoadTask(manager, buffer_idx)); - } -} - -// I/O tasks for the buffers of the claim's decode start that are not in memory -static vector> CollectClaimIOTasks(CSVLocalState &lstate) { - auto &manager = lstate.file_scan->buffer_manager; - const idx_t start_buffer_idx = lstate.iterator.GetBufferIdx(); - vector> io_tasks; - if (manager->HasKnownBufferRanges() && start_buffer_idx >= manager->KnownBufferCount()) { - // the claim starts past the last buffer (e.g. skipping the header consumed the whole file) - return io_tasks; - } - TryPushBufferLoadTask(manager, start_buffer_idx, io_tasks); - if (lstate.iterator.IsBoundarySet() && - (!manager->HasKnownBufferRanges() || - lstate.iterator.GetEndPos() >= manager->KnownBufferSize(start_buffer_idx))) { - // a boundary reaching the end of its buffer also touches the next one, for straddling values - // and first-line detection - TryPushBufferLoadTask(manager, start_buffer_idx + 1, io_tasks); - } - return io_tasks; -} - -AsyncResult CSVFileScan::ScheduleIO(ClientContext &context, GlobalTableFunctionState &gstate, - LocalTableFunctionState &lstate_p) { - auto &lstate = lstate_p.Cast(); - D_ASSERT(lstate.claim_state == CSVLocalState::ClaimState::PENDING); - return AsyncResult::FromTasks(CollectClaimIOTasks(lstate), TaskSchedulerType::ASYNC); -} - -AsyncResult CSVFileScan::Scan(ClientContext &context, GlobalTableFunctionState &global_state, - LocalTableFunctionState &local_state, DataChunk &chunk) { -#ifdef DUCKDB_DEBUG_ASYNC_SINK_SOURCE - { - AsyncResult test_result; - if (AsyncResult::TryGenerateTestResult(test_result)) { - return test_result; - } - } -#endif - auto &lstate = local_state.Cast(); - if (lstate.claim_state == CSVLocalState::ClaimState::PENDING) { - lstate.Materialize(); - } - auto &csv_reader = *lstate.csv_reader; - if (!csv_reader.IsSuspended() && csv_reader.FinishedIterator()) { - return AsyncResult(SourceResultType::FINISHED); - } - csv_reader.Flush(chunk); - if (csv_reader.IsSuspended()) { - // buffer is not in memory, we need to load it to the async pool - vector> io_tasks; - io_tasks.push_back(BufferLoadTask(csv_reader.buffer_manager, csv_reader.PendingBufferIdx())); - return AsyncResult(std::move(io_tasks), TaskSchedulerType::ASYNC); - } - return AsyncResult::FromChunk(chunk); -} - -void CSVFileScan::FinishFile(ClientContext &context, GlobalTableFunctionState &global_state) { - auto &gstate = global_state.Cast(); - gstate.FinishLaunchingTasks(*this); -} - -void CSVMultiFileInfo::FinishReading(ClientContext &context, GlobalTableFunctionState &global_state, - LocalTableFunctionState &local_state) { - auto &gstate = global_state.Cast(); - auto &lstate = local_state.Cast(); - gstate.FinishScan(std::move(lstate.csv_reader)); -} - -unique_ptr CSVMultiFileInfo::GetCardinality(const MultiFileBindData &bind_data, idx_t file_count) { - auto &csv_data = bind_data.bind_data->Cast(); - // determined through the scientific method as the average amount of rows in a CSV file - idx_t per_file_cardinality = 42; - if (csv_data.buffer_manager && csv_data.buffer_manager->file_handle) { - auto estimated_row_width = (bind_data.types.size() * 5); - per_file_cardinality = csv_data.buffer_manager->file_handle->FileSize() / estimated_row_width; - } - return make_uniq(file_count * per_file_cardinality); -} - -double CSVFileScan::GetProgressInFile(ClientContext &context) { - auto manager = buffer_manager; - if (!manager) { - // We are done with this file, so it's 100% - return 100.0; - } - double total_bytes_read; - if (manager->file_handle->compression_type == FileCompressionType::GZIP || - manager->file_handle->compression_type == FileCompressionType::ZSTD) { - // compressed file: we care about the progress made in the *underlying* file handle - // the bytes read from the uncompressed file are skewed - total_bytes_read = manager->file_handle->GetProgress(); - } else { - total_bytes_read = static_cast(bytes_read); - } - double file_progress = total_bytes_read / static_cast(file_size); - return file_progress * 100.0; -} - -FileGlobInput CSVMultiFileInfo::GetGlobInput() { - return FileGlobInput(FileGlobOptions::FALLBACK_GLOB, "csv"); -} - -} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_schema_discovery.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_schema_discovery.cpp new file mode 100644 index 000000000..b370d62a9 --- /dev/null +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_schema_discovery.cpp @@ -0,0 +1,115 @@ +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" + +#include "duckdb/execution/operator/csv_scanner/csv_buffer.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" + +namespace duckdb { + +//! Function to do schema discovery over one CSV file or a list/glob of CSV files +CSVSchema CSVSchemaDiscovery::SchemaDiscovery(ClientContext &context, shared_ptr &buffer_manager, + CSVReaderOptions &options, const MultiFileOptions &file_options, + vector &return_types, vector &names, + MultiFileList &multi_file_list, bool replace_null_with_varchar) { + vector schemas; + const auto option_og = options; + + const auto file_paths = multi_file_list.GetAllFiles(); + + // Here what we want to do is to sniff a given number of lines, if we have many files, we might go through them + // to reach the number of lines. + const idx_t required_number_of_lines = options.sniff_size * options.sample_size_chunks; + + idx_t total_number_of_rows = 0; + idx_t current_file = 0; + options.file_path = file_paths[current_file].path; + + buffer_manager = CSVBufferManager::Open(context, options, options.file_path, false); + idx_t only_header_or_empty_files = 0; + + { + CSVSniffer sniffer(options, file_options, buffer_manager, CSVStateMachineCache::Get(context)); + auto sniffer_result = sniffer.SniffCSV(); + idx_t rows_read = sniffer.LinesSniffed() - + (options.dialect_options.skip_rows.GetValue() + options.dialect_options.header.GetValue()); + + schemas.emplace_back(sniffer_result.names, sniffer_result.return_types, file_paths[0].path, rows_read, + buffer_manager->GetBuffer(0)->actual_size == 0); + total_number_of_rows += sniffer.LinesSniffed(); + current_file++; + if (sniffer.EmptyOrOnlyHeader()) { + only_header_or_empty_files++; + } + } + + // We do a copy of the options to not pollute the options of the first file. + idx_t max_files_to_sniff = static_cast(options.files_to_sniff == -1) + ? NumericLimits::Maximum() + : static_cast(options.files_to_sniff); + idx_t files_to_sniff = file_paths.size() > max_files_to_sniff ? max_files_to_sniff : file_paths.size(); + while (total_number_of_rows < required_number_of_lines && current_file < files_to_sniff) { + auto option_copy = option_og; + option_copy.file_path = file_paths[current_file].path; + auto file_buffer_manager = CSVBufferManager::Open(context, option_copy, option_copy.file_path, false); + // TODO: We could cache the sniffer to be reused during scanning. Currently that's an exercise left to the + // reader + CSVSniffer sniffer(option_copy, file_options, file_buffer_manager, CSVStateMachineCache::Get(context)); + auto sniffer_result = sniffer.SniffCSV(); + idx_t rows_read = sniffer.LinesSniffed() - (option_copy.dialect_options.skip_rows.GetValue() + + option_copy.dialect_options.header.GetValue()); + if (file_buffer_manager->GetBuffer(0)->actual_size == 0) { + schemas.emplace_back(true); + } else { + schemas.emplace_back(sniffer_result.names, sniffer_result.return_types, option_copy.file_path, rows_read); + } + total_number_of_rows += sniffer.LinesSniffed(); + if (sniffer.EmptyOrOnlyHeader()) { + only_header_or_empty_files++; + } + current_file++; + } + + // We might now have multiple schemas, we need to go through them to define the one true schema + CSVSchema best_schema; + for (auto &schema : schemas) { + if (best_schema.Empty()) { + // A schema is bettah than no schema + best_schema = schema; + } else if (best_schema.GetRowsRead() == 0) { + // If the best-schema has no data-rows, that's easy; we just take the new schema + best_schema = schema; + } else if (schema.GetRowsRead() != 0) { + // We might have conflicting-schemas, we must merge them + best_schema.MergeSchemas(schema, options.null_padding); + } + } + + // At this point, replace a sqlnull with varchar for the type + if (replace_null_with_varchar) { + best_schema.ReplaceNullWithVarchar(); + } + + if (names.empty()) { + names = StringsToIdentifiers(best_schema.GetNames()); + return_types = best_schema.GetTypes(); + } + if (names.empty() && return_types.empty()) { + throw InvalidInputException("No columns found in CSV files. Provide the columns option or ensure at least one " + "file contains a header or data row."); + } + if (replace_null_with_varchar && only_header_or_empty_files == current_file && !options.columns_set) { + for (idx_t i = 0; i < return_types.size(); i++) { + if (!options.sql_types_per_column.empty()) { + if (options.sql_types_per_column.find(names[i]) != options.sql_types_per_column.end()) { + continue; + } + } else if (i < options.sql_type_list.size()) { + continue; + } + // we default to varchar if all files are empty or only have a header after all the sniffing + return_types[i] = LogicalType::VARCHAR; + } + } + return best_schema; +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp index a1525659f..e037aa74a 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/global_csv_state.cpp @@ -7,13 +7,17 @@ #include "duckdb/execution/operator/persistent/csv_rejects_table.hpp" #include "duckdb/main/appender.hpp" #include "duckdb/main/client_data.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" +#include "duckdb/parallel/callback_async_task.hpp" namespace duckdb { -CSVGlobalState::CSVGlobalState(ClientContext &context_p, const CSVReaderOptions &options, idx_t total_file_count, - const MultiFileBindData &bind_data) - : context(context_p), bind_data(bind_data), sniffer_mismatch_error(options.sniffer_user_mismatch_error) { +CSVGlobalState::CSVGlobalState(ClientContext &context_p, ReadCSVData &csv_data_p, + const vector &column_names_p, idx_t total_file_count_p, + optional_ptr scan_op_p) + : context(context_p), csv_data(csv_data_p), scan_op(scan_op_p), total_file_count(total_file_count_p), + column_names(column_names_p), sniffer_mismatch_error(csv_data_p.options.sniffer_user_mismatch_error) { + auto &options = csv_data.options; // There are situations where we only support single threaded scanning auto system_threads = context.db->NumberOfThreads(); bool many_csv_files = total_file_count > 1 && total_file_count > system_threads * 2; @@ -22,6 +26,42 @@ CSVGlobalState::CSVGlobalState(ClientContext &context_p, const CSVReaderOptions initialized = false; } +// A task that loads the buffer on the async pool, sized for the read-ahead I/O budget +static unique_ptr BufferLoadTask(const shared_ptr &manager, const idx_t buffer_idx) { + const idx_t io_size = + manager->HasKnownBufferRanges() ? manager->KnownBufferSize(buffer_idx) : manager->GetBufferSize(); + return make_uniq([manager, buffer_idx] { manager->GetBuffer(buffer_idx); }, io_size); +} + +// Adds a load task when the buffer is not in memory +static void TryPushBufferLoadTask(const shared_ptr &manager, const idx_t buffer_idx, + vector> &io_tasks) { + shared_ptr buffer_handle; + if (manager->GetBufferResidency(buffer_idx, buffer_handle) == CSVBufferResidency::NEEDS_LOAD) { + io_tasks.push_back(BufferLoadTask(manager, buffer_idx)); + } +} + +//! I/O tasks for the buffers of the claim's decode start that are not in memory +vector> CSVCollectClaimIOTasks(CSVLocalState &lstate) { + auto &manager = lstate.file_scan->buffer_manager; + const idx_t start_buffer_idx = lstate.iterator.GetBufferIdx(); + vector> io_tasks; + if (manager->HasKnownBufferRanges() && start_buffer_idx >= manager->KnownBufferCount()) { + // the claim starts past the last buffer (e.g. skipping the header consumed the whole file) + return io_tasks; + } + TryPushBufferLoadTask(manager, start_buffer_idx, io_tasks); + if (lstate.iterator.IsBoundarySet() && + (!manager->HasKnownBufferRanges() || + lstate.iterator.GetEndPos() >= manager->KnownBufferSize(start_buffer_idx))) { + // a boundary reaching the end of its buffer also touches the next one, for straddling values + // and first-line detection + TryPushBufferLoadTask(manager, start_buffer_idx + 1, io_tasks); + } + return io_tasks; +} + void CSVGlobalState::FinishTask(CSVFileScan &scan) { auto started_tasks = scan.started_tasks.load(); auto finished_tasks = ++scan.finished_tasks; @@ -106,7 +146,6 @@ void CSVGlobalState::FinishFile(CSVFileScan &scan) { current_buffer_in_use.reset(); } scan.Finish(); - auto &csv_data = bind_data.bind_data->Cast(); const bool ignore_or_store_errors = csv_data.options.ignore_errors.GetValue() || csv_data.options.store_rejects.GetValue(); if (!single_threaded && !ignore_or_store_errors) { @@ -182,7 +221,6 @@ void FillScanErrorTable(InternalAppender &scan_appender, idx_t scan_idx, idx_t f } void CSVGlobalState::FillRejectsTable(CSVFileScan &scan) { - auto &csv_data = bind_data.bind_data->Cast(); auto &options = csv_data.options; if (!options.store_rejects.GetValue()) { @@ -198,15 +236,13 @@ void CSVGlobalState::FillRejectsTable(CSVFileScan &scan) { InternalAppender scans_appender(context, scans_table); idx_t scan_idx = context.transaction.GetActiveQuery(); - // get the file indexes for the rejects table - // we store these so that they are deterministic (i.e. file index 0 always gets the lowest rejects index) - // otherwise parallelism can result in out-of-order file indexes - auto file_idx = scan.GetFileIndex(); - for (idx_t i = rejects_file_indexes.size(); i <= file_idx; i++) { - rejects_file_indexes.push_back(rejects->GetCurrentFileIndex(scan_idx)); - } - const idx_t rejects_file_idx = rejects_file_indexes[file_idx]; - scan.error_handler->FillRejectsTable(errors_appender, rejects_file_idx, scan_idx, scan, *rejects, bind_data, limit); + // the files of a scan report under a block of indexes, so that the index of a file within its scan identifies + // it - that keeps the indexes deterministic when files are read in parallel, and keeps the files of one scan + // apart from those of another scan in the same query + const idx_t rejects_file_idx = + rejects->GetFileIndexBase(scan_idx, scan_op.get(), total_file_count) + scan.GetFileIndex(); + scan.error_handler->FillRejectsTable(errors_appender, rejects_file_idx, scan_idx, scan, *rejects, column_names, + limit); if (rejects->count != 0) { rejects->count = 0; FillScanErrorTable(scans_appender, scan_idx, rejects_file_idx, scan); diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/read_single_csv_file.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/read_single_csv_file.cpp new file mode 100644 index 000000000..bf6f30e33 --- /dev/null +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/read_single_csv_file.cpp @@ -0,0 +1,500 @@ +#include "duckdb/common/multi_file/multi_file_list.hpp" +#include "duckdb/common/multi_file/table_function_multi_file.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_error.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" +#include "duckdb/execution/operator/csv_scanner/global_csv_state.hpp" +#include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" +#include "duckdb/execution/operator/persistent/csv_rejects_table.hpp" +#include "duckdb/function/table/read_csv.hpp" + +namespace duckdb { + +//! Bind data of read_single_csv_file - the regular CSV read data plus the single file that is read +struct ReadSingleCSVFileData : public ReadCSVData { + OpenFileInfo file; + //! The names/types this file is read with + vector csv_names; + vector csv_types; +}; + +struct ReadSingleCSVFileGlobalState : public GlobalTableFunctionState { +public: + ReadSingleCSVFileGlobalState(ClientContext &context, ReadSingleCSVFileData &csv_data, + const TableFunctionInitInput &input) + : state(context, csv_data, csv_data.csv_names, input.file_count, input.op) { + } + +public: + idx_t MaxThreads() const override { + return max_threads; + } + +public: + //! The file that is read - declared before the state below, which holds buffers of this file and must therefore + //! be destroyed first + shared_ptr file_scan; + CSVGlobalState state; + //! Handing out the next part of the file is done single-threadedly + mutable mutex lock; + //! Whether we are done handing out parts of the file + bool finished_launching = false; + idx_t max_threads = 1; +}; + +struct ReadSingleCSVFileLocalState : public LocalTableFunctionState { + CSVLocalState state; + //! Whether our caller claims the batches we read - see table_function_claim_batch_t + bool claimed_externally = false; +}; + +//! The columns "force_not_null" was given, looked up the way column names are compared +static identifier_set_t GetForceNotNullNames(const CSVReaderOptions &options) { + identifier_set_t result; + for (auto &force_name : options.force_not_null_names) { + result.insert(Identifier(force_name)); + } + return result; +} + +//! "force_not_null" names columns of the scan, so it is verified against the schema of the scan rather than +//! against the columns of any single file of it +static void VerifyForceNotNull(const CSVReaderOptions &options, const vector &schema) { + if (options.force_not_null_names.empty()) { + return; + } + identifier_set_t column_names; + for (auto &name : schema) { + column_names.insert(name); + } + for (auto &force_name : GetForceNotNullNames(options)) { + if (column_names.find(force_name) == column_names.end()) { + throw BinderException("\"force_not_null\" expected to find %s, but it was not found in the table", + force_name.GetIdentifierName()); + } + } +} + +//! The equivalent of MultiFileReaderInterface::FinalizeBindData - mark the columns of this file that +//! "force_not_null" names. A file of a multi-file scan only has some of the columns of the scan +static void ApplyForceNotNull(CSVReaderOptions &options, const vector &names) { + if (options.force_not_null_names.empty()) { + return; + } + const auto force_not_null = GetForceNotNullNames(options); + options.force_not_null.clear(); + for (auto &name : names) { + options.force_not_null.push_back(force_not_null.find(name) != force_not_null.end()); + } +} + +//! Sniff this file - the dialect that is detected is stored in the options of the bind data. When a schema is given +//! the sniffed schema is reconciled with it, and files whose schema does not match it are reported +static void SniffCSVFile(ClientContext &context, ReadSingleCSVFileData &result, const CSVSchema &file_schema, + const MultiFileOptions &file_options, vector &return_types, + vector &names) { + auto &options = result.options; + result.buffer_manager = CSVBufferManager::Open(context, options, options.file_path, false); + auto &state_machine_cache = CSVStateMachineCache::Get(context); + if (file_schema.Empty()) { + // the columns of this file are fixed - only its dialect is sniffed + CSVSniffer sniffer(options, file_options, result.buffer_manager, state_machine_cache); + sniffer.SniffCSV(); + return; + } + if (result.buffer_manager->file_handle->FileSize() == 0) { + // an empty file has no dialect for us to reconcile with the schema of the scan + return; + } + CSVSniffer sniffer(options, file_options, result.buffer_manager, state_machine_cache, false); + auto sniff_result = sniffer.AdaptiveSniff(file_schema); + names = std::move(sniff_result.names); + return_types = std::move(sniff_result.return_types); +} + +static unique_ptr ReadSingleCSVFileBind(ClientContext &context, TableFunctionBindInput &input, + vector &return_types, vector &names) { + auto result = make_uniq(); + auto &options = result->options; + for (auto &kv : input.named_parameters) { + options.ParseOption(context, kv.first, kv.second); + } + if (input.inputs[0].IsNull()) { + throw BinderException("read_single_csv_file requires a non-NULL file name"); + } + result->file = OpenFileInfo(StringValue::Get(input.inputs[0])); + + // the options of the scan this file is part of steer the sniffer - the file list is this single file + MultiFileOptions file_options; + if (input.multi_file_options) { + file_options = *input.multi_file_options; + } + SimpleMultiFileList file_list(vector {result->file}); + + //! Whether the options that name columns are verified against the columns of this file, which is the schema of + //! the scan only when this file is the whole scan + bool verify_against_file = false; + optional_ptr schema_source; + if (input.HasExpectedSchema()) { + if (input.expected_bind_data) { + // the schema of the scan was determined on (other) files of this scan - start from the options it was + // determined with, so that this file is read with the same dialect + schema_source = input.expected_bind_data->Cast(); + options = schema_source->options; + options.force_not_null.clear(); + names = *input.expected_names; + return_types = *input.expected_types; + } else { + // the columns are known but the dialect of this file is not - this is the case for COPY, which takes + // its columns from the target table + options.name_list = *input.expected_names; + options.sql_type_list = *input.expected_types; + options.columns_set = true; + options.sql_types_per_column.clear(); + for (idx_t i = 0; i < options.name_list.size(); i++) { + options.sql_types_per_column[options.name_list[i]] = i; + } + names = options.name_list; + return_types = options.sql_type_list; + } + } + options.file_path = result->file.path; + // when several files are read, options like "names" describe the scan and not this file - the sniffer is then + // lenient about a file whose columns do not line up with them exactly + options.multi_file_reader = input.multi_file_scan; + options.Verify(file_options); + + // when the schema of the scan is known upfront the options are verified against it before this file is + // sniffed, so that an option that does not match it is reported before any error in the file itself + if (input.HasExpectedSchema()) { + VerifyForceNotNull(options, *input.expected_names); + } else if (!input.multi_file_scan) { + // this file is the whole scan, so its own columns are the schema the options are verified against + verify_against_file = true; + } + if (schema_source) { + // the schema of this file must be reconcilable with the schema of the scan + result->csv_schema = schema_source->csv_schema; + if (options.auto_detect) { + SniffCSVFile(context, *result, result->csv_schema, file_options, return_types, names); + } + } else if (input.HasExpectedSchema()) { + if (options.auto_detect) { + SniffCSVFile(context, *result, CSVSchema(), file_options, return_types, names); + } + } else if (options.auto_detect || file_options.union_by_name) { + // a column without any value is kept as SQLNULL here, so the other files can still determine its type + result->csv_schema = CSVSchemaDiscovery::SchemaDiscovery(context, result->buffer_manager, options, file_options, + return_types, names, file_list, false); + } else { + if (!options.columns_set) { + throw BinderException("read_csv requires columns to be specified through the 'columns' option. Use " + "read_csv_auto or set read_csv(..., AUTO_DETECT=TRUE) to automatically guess " + "columns."); + } + names = options.name_list; + return_types = options.sql_type_list; + } + if (return_types.size() != names.size()) { + throw BinderException("read_csv: mismatch between the number of column names (%d) and column types (%d)", + names.size(), return_types.size()); + } + options.dialect_options.num_cols = names.size(); + + if (verify_against_file) { + VerifyForceNotNull(options, names); + } + ApplyForceNotNull(options, names); + if (!file_options.union_by_name) { + for (auto &type : return_types) { + if (type.id() == LogicalTypeId::SQLNULL) { + // if we cannot tell the type of a column we default to the highest type, a VARCHAR + type = LogicalType::VARCHAR; + } + } + } + result->Finalize(); + result->csv_names = names; + result->csv_types = return_types; + return std::move(result); +} + +//! Combine the schemas of several CSV files the way the multi-file sniffer does - the resulting CSV schema is +//! handed to the bind of every file, whose dialect is then sniffed and reconciled with it +static unique_ptr ReadSingleCSVFileCombineSchema(ClientContext &context, + TableFunctionCombineSchemaInput &input, + vector &return_types, + vector &names) { + if (input.union_by_name) { + // the columns of the files were unified by name - the options that name columns apply to the result of that + auto &options = input.bind_data[0].get().Cast().options; + VerifyForceNotNull(options, names); + if (!options.sql_types_per_column.empty()) { + const auto exception = CSVError::ColumnTypesError(options.sql_types_per_column, names); + if (!exception.error_message.empty()) { + throw BinderException(exception.error_message); + } + for (idx_t i = 0; i < names.size(); i++) { + auto entry = options.sql_types_per_column.find(names[i]); + if (entry != options.sql_types_per_column.end()) { + return_types[i] = options.sql_type_list[entry->second]; + } + } + } + for (auto &type : return_types) { + if (type.id() == LogicalTypeId::SQLNULL) { + // if we cannot tell the type of a column we default to the highest type, a VARCHAR + type = LogicalType::VARCHAR; + } + } + // the files have different columns - every file is read the way it was bound + return nullptr; + } + optional_ptr first_file; + CSVSchema best_schema; + for (auto &bind_data : input.bind_data) { + auto &csv_data = bind_data.get().Cast(); + if (csv_data.csv_schema.Empty()) { + // the schema of this file was not sniffed - fall back to combining the types + return nullptr; + } + auto schema = csv_data.csv_schema; + if (first_file && schema.IsEmptyFile()) { + // a file without any data contributes no columns to the schema of the scan + schema = CSVSchema(true); + } + if (!first_file) { + first_file = csv_data; + } + if (best_schema.Empty() || best_schema.GetRowsRead() == 0) { + // a schema is better than no schema, and any schema beats one without data rows + best_schema = schema; + } else if (schema.GetRowsRead() != 0) { + best_schema.MergeSchemas(schema, first_file->options.null_padding); + } + } + if (!first_file) { + return nullptr; + } + if (best_schema.Empty()) { + throw InvalidInputException("No columns found in CSV files. Provide the columns option or ensure at least one " + "file contains a header or data row."); + } + best_schema.ReplaceNullWithVarchar(); + names = StringsToIdentifiers(best_schema.GetNames()); + return_types = best_schema.GetTypes(); + VerifyForceNotNull(first_file->options, names); + + auto result = make_uniq(); + // the options that were sniffed on the first file are the starting point for every file of the scan. The + // columns are not set on them - they are carried by the CSV schema, which each file is reconciled with + result->options = first_file->options; + result->options.dialect_options.num_cols = names.size(); + // the buffer manager of the first file is kept, like the multi-file sniffer does - it tells the scan whether + // the files can be read ahead, and the first file does not need to be opened again + result->buffer_manager = first_file->buffer_manager; + result->csv_schema = best_schema; + result->csv_names = names; + result->csv_types = return_types; + result->Finalize(); + return std::move(result); +} + +static unique_ptr ReadSingleCSVFileInitGlobal(ClientContext &context, + TableFunctionInitInput &input) { + auto &csv_data = input.bind_data->CastNoConst(); + + // create the temporary rejects table + if (csv_data.options.store_rejects.GetValue()) { + CSVRejectsTable::GetOrCreate(context, csv_data.options.rejects_scan_name.GetValue(), + csv_data.options.rejects_table_name.GetValue()) + ->InitializeTable(context, csv_data); + } + + auto result = make_uniq(context, csv_data, input); + + // this file was sniffed during binding, so its dialect and columns are known + auto options = csv_data.options; + options.auto_detect = false; + MultiFileOptions file_options; + CSVSchema no_schema; + result->file_scan = make_shared_ptr( + context, csv_data.file, std::move(options), file_options, csv_data.csv_names, csv_data.csv_types, no_schema, + result->state.SingleThreadedRead(), csv_data.buffer_manager, false); + + // perform projection pushdown - the scanner emits the columns in the order they are requested + auto &file_scan = *result->file_scan; + for (auto &column_index : input.column_indexes) { + const auto col_id = column_index.GetPrimaryIndex(); + if (IsVirtualColumn(col_id)) { + continue; + } + file_scan.column_ids.push_back(MultiFileLocalColumnId(col_id)); + } + // the index of this file in the scan it is part of - it identifies the file in the rejects tables + file_scan.file_list_idx = input.file_index.IsValid() ? input.file_index.GetIndex() : 0; + if (input.cast_map) { + // our caller needs some columns as a different type than this file has them - the scanner converts to those + // types while parsing, so that "ignore_errors" applies to the conversions that fail + for (auto &entry : *input.cast_map) { + file_scan.cast_map[entry.first] = entry.second; + } + } + file_scan.InitializeFileNamesTypes(); + file_scan.SetStart(); + + if (!result->state.SingleThreadedRead()) { + const idx_t bytes_per_thread = CSVIterator::BytesPerThread(csv_data.options); + result->max_threads = file_scan.file_size / bytes_per_thread + 1; + } + return std::move(result); +} + +static unique_ptr ReadSingleCSVFileInitLocal(ExecutionContext &context, + TableFunctionInitInput &input, + GlobalTableFunctionState *global_state) { + return make_uniq(); +} + +//! Assign the next part of the file to this thread +static bool ClaimNextPart(ReadSingleCSVFileGlobalState &gstate, ReadSingleCSVFileLocalState &lstate) { + lock_guard guard(gstate.lock); + gstate.state.FinishScan(std::move(lstate.state.csv_reader)); + lstate.state.claim_state = CSVLocalState::ClaimState::IDLE; + if (gstate.finished_launching) { + return false; + } + if (gstate.state.Next(gstate.file_scan, lstate.state)) { + return true; + } + // we have handed out the entire file - this is also where the errors of the file are reported + gstate.finished_launching = true; + gstate.state.FinishLaunchingTasks(*gstate.file_scan); + return false; +} + +static bool ReadSingleCSVFileClaimBatch(ClientContext &context, TableFunctionInput &input) { + auto &gstate = input.global_state->Cast(); + auto &lstate = input.local_state->Cast(); + // our caller hands out the parts of the file, so we must not claim the next one ourselves + lstate.claimed_externally = true; + return ClaimNextPart(gstate, lstate); +} + +//! The CSV scanner can be read ahead when the buffers of the file can be addressed individually +static bool ReadSingleCSVFileSupportsReadAhead(const FunctionData &bind_data) { + auto &csv_data = bind_data.Cast(); + return csv_data.buffer_manager && csv_data.buffer_manager->file_handle && + csv_data.buffer_manager->file_handle->HasKnownBufferRanges(); +} + +//! Load the buffers of the claimed part of the file that are not in memory yet +static AsyncResult ReadSingleCSVFileScheduleIO(ClientContext &context, TableFunctionInput &input) { + auto &lstate = input.local_state->Cast(); + if (lstate.state.claim_state != CSVLocalState::ClaimState::PENDING) { + return SourceResultType::HAVE_MORE_OUTPUT; + } + return AsyncResult::FromTasks(CSVCollectClaimIOTasks(lstate.state), TaskSchedulerType::ASYNC); +} + +//! Release the part of the file this thread was reading +static void ReadSingleCSVFileFinishBatch(ClientContext &context, TableFunctionInput &input) { + auto &gstate = input.global_state->Cast(); + auto &lstate = input.local_state->Cast(); + lock_guard guard(gstate.lock); + gstate.state.FinishScan(std::move(lstate.state.csv_reader)); +} + +static void ReadSingleCSVFileFunction(ClientContext &context, TableFunctionInput &input, DataChunk &output) { + auto &gstate = input.global_state->Cast(); + auto &lstate = input.local_state->Cast(); + + while (true) { + if (lstate.state.claim_state == CSVLocalState::ClaimState::IDLE) { + if (lstate.claimed_externally) { + // the next part of the file is claimed by our caller + return; + } + if (!ClaimNextPart(gstate, lstate)) { + // there is nothing left for us to read in this file + return; + } + } + if (lstate.state.claim_state == CSVLocalState::ClaimState::PENDING) { + lstate.state.Materialize(); + } + auto &csv_reader = *lstate.state.csv_reader; + if (csv_reader.IsSuspended() || !csv_reader.FinishedIterator()) { + csv_reader.Flush(output); + if (csv_reader.IsSuspended()) { + // the scanner needs a buffer that is not in memory - load it and resume + csv_reader.buffer_manager->GetBuffer(csv_reader.PendingBufferIdx()); + continue; + } + if (output.size() != 0) { + return; + } + } + // this part of the file is done - grab the next one + lock_guard guard(gstate.lock); + gstate.state.FinishScan(std::move(lstate.state.csv_reader)); + lstate.state.claim_state = CSVLocalState::ClaimState::IDLE; + } +} + +static double ReadSingleCSVFileProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + if (!global_state) { + return 0; + } + auto &gstate = global_state->Cast(); + // the buffers of the file are released when the last part of it is handed out - hold the lock so we do not read + // them while that happens + lock_guard guard(gstate.lock); + if (!gstate.file_scan) { + return 0; + } + return gstate.file_scan->GetProgressInFile(context); +} + +static unique_ptr ReadSingleCSVFileCardinality(ClientContext &context, const FunctionData *bind_data) { + auto &csv_data = bind_data->Cast(); + // determined through the scientific method as the average amount of rows in a CSV file + idx_t per_file_cardinality = 42; + if (csv_data.buffer_manager && csv_data.buffer_manager->file_handle) { + auto estimated_row_width = csv_data.csv_types.size() * 5; + per_file_cardinality = csv_data.buffer_manager->file_handle->FileSize() / estimated_row_width; + } + return make_uniq(per_file_cardinality); +} + +TableFunction ReadCSVTableFunction::GetSingleFileFunction() { + TableFunction read_csv("read_single_csv_file", {LogicalType::VARCHAR}, ReadSingleCSVFileFunction, + ReadSingleCSVFileBind, ReadSingleCSVFileInitGlobal, ReadSingleCSVFileInitLocal); + read_csv.combine_schema = ReadSingleCSVFileCombineSchema; + read_csv.claim_batch = ReadSingleCSVFileClaimBatch; + read_csv.finish_batch = ReadSingleCSVFileFinishBatch; + read_csv.supports_read_ahead = ReadSingleCSVFileSupportsReadAhead; + read_csv.schedule_io = ReadSingleCSVFileScheduleIO; + read_csv.table_scan_progress = ReadSingleCSVFileProgress; + read_csv.cardinality = ReadSingleCSVFileCardinality; + read_csv.projection_pushdown = true; + // the scanner converts to the types the caller asks for while parsing, rather than casting its output + read_csv.supports_cast_map = true; + ReadCSVAddNamedParameters(read_csv); + return read_csv; +} + +TableFunction ReadCSVTableFunction::GetMultiFileFunction(Identifier name) { + // the multi-file CSV reader is the single-file CSV reader wrapped into a multi-file function + TableFunctionMultiFileSettings settings; + settings.glob_input = FileGlobInput(FileGlobOptions::FALLBACK_GLOB, "csv"); + settings.reader_type = "CSV"; + // like read_csv, the schema is determined by combining the schemas of up to "files_to_sniff" files + settings.maximum_sample_files = 10; + settings.sample_files_parameter = "files_to_sniff"; + // the schemas of the sampled files are reconciled with one another - every file must have every column + settings.sampled_schema_is_union = false; + return TableFunctionMultiFileWrapper::CreateFunction(GetSingleFileFunction(), std::move(name), std::move(settings)); +} + +} // namespace duckdb diff --git a/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp b/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp index 429621a83..cdfbc1de6 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp @@ -186,7 +186,7 @@ string CSVErrorTypeToEnum(CSVErrorType type) { void CSVErrorHandler::FillRejectsTable(InternalAppender &errors_appender, const idx_t file_idx, const idx_t scan_idx, const CSVFileScan &file, CSVRejectsTable &rejects, - const MultiFileBindData &bind_data, const idx_t limit) { + const vector &column_names, const idx_t limit) { lock_guard parallel_lock(main_mutex); // We first insert the file into the file scans table for (auto &error : file.error_handler->errors) { @@ -232,15 +232,15 @@ void CSVErrorHandler::FillRejectsTable(InternalAppender &errors_appender, const errors_appender.Append(Value()); break; case CSVErrorType::TOO_FEW_COLUMNS: - if (col_idx + 1 < bind_data.names.size()) { - errors_appender.Append(string_t(bind_data.names[col_idx + 1].GetIdentifierName())); + if (col_idx + 1 < column_names.size()) { + errors_appender.Append(string_t(column_names[col_idx + 1].GetIdentifierName())); } else { errors_appender.Append(Value()); } break; default: - if (col_idx < bind_data.names.size()) { - errors_appender.Append(string_t(bind_data.names[col_idx].GetIdentifierName())); + if (col_idx < column_names.size()) { + errors_appender.Append(string_t(column_names[col_idx].GetIdentifierName())); } else { errors_appender.Append(Value()); } diff --git a/src/duckdb/src/execution/operator/helper/launch_external_resource.cpp b/src/duckdb/src/execution/operator/helper/launch_external_resource.cpp index b483d26f0..a31a6338b 100644 --- a/src/duckdb/src/execution/operator/helper/launch_external_resource.cpp +++ b/src/duckdb/src/execution/operator/helper/launch_external_resource.cpp @@ -1,10 +1,12 @@ #include "duckdb/execution/operator/helper/launch_external_resource.hpp" #include "duckdb/common/exception.hpp" +#include "duckdb/common/string_util.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/main/connection.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/external_resources_manager.hpp" +#include "duckdb/main/attached_database.hpp" #include "duckdb/parser/parsed_data/attach_info.hpp" namespace duckdb { @@ -30,7 +32,7 @@ LaunchedResource ProvisionExternalResource(ClientContext &client, const string & Connection con(DatabaseInstance::GetDatabase(client)); // resource_name is forwarded only for observability (it labels the recipe-call log entries). auto name_arg = resource_name.empty() ? string() : ", resource_name := " + Value(resource_name).ToSQLString(); - // A handle triggers the adopt path (skip create, resolve the given handle). + // A handle skips create and resolves the given one instead (REGISTER). auto handle_arg = adopt_handle.IsNull() ? string() : ", handle := " + adopt_handle.ToSQLString(); auto sql = "SELECT uri, attached_db_type, result, deleter_function, deleter_payload " "FROM create_external_resource(" + @@ -53,7 +55,7 @@ LaunchedResource ProvisionExternalResource(ClientContext &client, const string & if (uri_val.IsNull()) { // A resource without an endpoint is legal (it just cannot be attached), but one provisioned // solely in order to attach to it is useless now, so reap it rather than strand it. Only ever - // reap what we created: an adopted handle names a resource the caller merely borrows, and + // reap what we created: a registered handle names a resource the caller merely borrows, and // destroying it would tear down something someone else owns. Best-effort, so a teardown failure // is logged rather than masking the error below. if (adopt_handle.IsNull()) { @@ -70,10 +72,25 @@ LaunchedResource ProvisionExternalResource(ClientContext &client, const string & return out; } +//! The statement's options are already in place, so a key the resource also supplies would silently +//! overrule what the user wrote. The resource dictates how it is reached, so refuse instead. Compared +//! by setting, not by key: READWRITE and READ_ONLY are one option under two names. +static void RejectOptionCollision(const AttachInfo &info, const string &key) { + auto setting = AttachOptions::OptionSetting(key); + for (auto &entry : info.options) { + if (AttachOptions::OptionSetting(entry.first) == setting) { + throw InvalidInputException("EXTERNAL RESOURCE: the resource supplies \"%s\", so it cannot also be given " + "as an option on the statement", + key); + } + } +} + void ApplyLaunchedResource(const LaunchedResource &launched, AttachInfo &info) { info.path = launched.uri; // A NULL/empty db type falls back to the extension prefix extracted from the uri. if (!launched.attached_db_type.empty()) { + RejectOptionCollision(info, "type"); info.options["type"] = Value(launched.attached_db_type); } // The remaining connect options (e.g. token) flow through as attach options. @@ -84,6 +101,14 @@ void ApplyLaunchedResource(const LaunchedResource &launched, AttachInfo &info) { if (key == "uri" || key == "attached_db_type") { continue; } + RejectOptionCollision(info, key); + // No option takes NULL: consumers cast and unwrap without checking, so it reads as a value + // (read_only would come out true). A recipe meaning "no value" omits the key. + if (kv[1].IsNull()) { + throw InvalidInputException("EXTERNAL RESOURCE: NULL is not supported as a valid option for \"%s\"; " + "omit the key rather than returning NULL", + key); + } info.options[key] = kv[1]; } } diff --git a/src/duckdb/src/execution/operator/helper/physical_batch_collector.cpp b/src/duckdb/src/execution/operator/helper/physical_batch_collector.cpp index e79a4d044..18fb87d8a 100644 --- a/src/duckdb/src/execution/operator/helper/physical_batch_collector.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_batch_collector.cpp @@ -1,8 +1,8 @@ #include "duckdb/execution/operator/helper/physical_batch_collector.hpp" #include "duckdb/common/types/batched_data_collection.hpp" +#include "duckdb/main/query_result.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/materialized_query_result.hpp" namespace duckdb { @@ -33,8 +33,8 @@ SinkFinalizeType PhysicalBatchCollector::Finalize(Pipeline &pipeline, Event &eve auto &gstate = input.global_state.Cast(); auto collection = gstate.data.FetchCollection(); D_ASSERT(collection); - auto result = make_uniq(statement_type, properties, names, std::move(collection), - context.GetClientProperties()); + auto result = + make_uniq(statement_type, properties, names, std::move(collection), context.GetClientProperties()); gstate.result = std::move(result); return SinkFinalizeType::READY; } diff --git a/src/duckdb/src/execution/operator/helper/physical_connect.cpp b/src/duckdb/src/execution/operator/helper/physical_connect.cpp index 7a55de083..5084f30c2 100644 --- a/src/duckdb/src/execution/operator/helper/physical_connect.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_connect.cpp @@ -2,10 +2,13 @@ #include "duckdb/catalog/catalog.hpp" #include "duckdb/common/exception.hpp" #include "duckdb/common/types/uuid.hpp" +#include "duckdb/execution/operator/helper/launch_external_resource.hpp" #include "duckdb/main/attached_database.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/main/config.hpp" +#include "duckdb/main/database.hpp" #include "duckdb/main/database_manager.hpp" +#include "duckdb/main/external_resources_manager.hpp" #include "duckdb/main/database_path_and_type.hpp" #include "duckdb/parser/parsed_data/attach_info.hpp" #include "duckdb/storage/storage_extension.hpp" @@ -19,21 +22,95 @@ SourceResultType PhysicalConnect::GetDataInternal(ExecutionContext &context, Dat if (info->target_is_local) { throw NotImplementedException("CONNECT LOCAL is not yet implemented"); } - if (info->name.empty()) { - throw NotImplementedException("CONNECT with no target is not yet implemented"); - } auto &client = context.client; + auto &db_manager = DatabaseManager::Get(client); // At most one active connection; only DISCONNECT clears it (even if the target was detached // elsewhere, so the user explicitly acknowledges the broken connection). - if (client.IsConnected()) { - auto current = client.TryGetConnectedCatalog(); - throw InvalidInputException("Already connected to \"%s\"; DISCONNECT first before issuing another CONNECT", - current ? current->GetName().GetIdentifierName() : ""); + auto ensure_not_connected = [&]() { + if (client.IsConnected()) { + auto current = client.TryGetConnectedCatalog(); + throw InvalidInputException("Already connected to \"%s\"; DISCONNECT first before issuing another CONNECT", + current ? current->GetName().GetIdentifierName() : ""); + } + }; + + // `CONNECT TO [NEW TEMPORARY] EXTERNAL RESOURCE`: get the endpoint, then ephemeral-attach it + // under a hidden alias and connect to it. The deleter is bound so the DISCONNECT reap tears it down. + if (info->external_resource) { + ensure_not_connected(); + auto &external_resource = *info->external_resource; + // A string type PROVISIONS a resource this connection OWNS (deleter bound, DISCONNECT reaps it); + // a bare identifier REFERENCES a registered resource it only BORROWS (no deleter). + LaunchedResource launched; + string resource_type, borrowed_resource_name; + bool owns_resource = false; + if (!external_resource.reference_name.empty()) { + auto instance = ExternalResourcesManager::Get(client).Lookup(external_resource.reference_name); + if (!instance) { + throw InvalidInputException("no external resource named \"%s\" is registered", + external_resource.reference_name); + } + launched = ProvisionExternalResource(client, instance->type, {}, instance->name, instance->handle); + // Record the borrow so DESTROY refuses while this connection is still using the resource. + borrowed_resource_name = instance->name; + } else { + resource_type = external_resource.provider; + // CONNECT has no alias to borrow a label from, so the resource stays unnamed in the logs. + launched = ProvisionExternalResource(client, external_resource.provider, external_resource.params); + owns_resource = true; + } + AttachInfo attach_info; + attach_info.name = Identifier("__connect_" + UUID::ToString(UUID::GenerateRandomUUID())); + // Applying the resource, parsing its options and the attach can all throw, and by now the + // resource exists with nothing owning it. One guard covers the lot; a narrower one strands it. + auto reap_if_owned = [&]() { + if (owns_resource) { + ResourceDeleter(DatabaseInstance::GetDatabase(client), launched.deleter_function, + launched.deleter_payload, resource_type, string()) + .TryDelete(); + } + }; + shared_ptr target; + try { + ApplyLaunchedResource(launched, attach_info); + + auto &config = DBConfig::GetConfig(client); + AttachOptions options(attach_info.options, config.options.access_mode); + options.visibility = AttachVisibility::HIDDEN; + options.ephemeral = true; + if (owns_resource) { + options.deleter_function = launched.deleter_function; + options.deleter_payload = launched.deleter_payload; + options.deleter_resource_type = resource_type; + } + options.borrowed_resource_name = borrowed_resource_name; + if (options.db_type.empty()) { + DBPathAndType::ExtractExtensionPrefix(attach_info.path, options.db_type); + } + target = db_manager.AttachDatabase(client, attach_info, options); + } catch (...) { + // Compensating teardown (best-effort): only for a resource we just PROVISIONED; a borrowed + // (referenced) resource is never torn down here. + reap_if_owned(); + throw; + } + if (!target->GetCatalog().Supports(RemoteCapability::CONNECT)) { + // The detach also runs the extracted deleter, destroying the provisioned resource. + db_manager.DetachDatabase(client, attach_info.name, OnEntryNotFound::RETURN_NULL); + throw InvalidInputException("CONNECT TO EXTERNAL RESOURCE: the provisioned resource does not " + "support CONNECT"); + } + client.ConnectToCatalog(target); + return SourceResultType::FINISHED; } - auto &db_manager = DatabaseManager::Get(client); + if (info->name.empty()) { + throw NotImplementedException("CONNECT with no target is not yet implemented"); + } + + ensure_not_connected(); if (info->name_is_string_literal) { // `CONNECT ''`: attach the connection string under an internal, hidden, ephemeral alias and // bind to it in one shot. The name is a random UUID (like __pivot_enum_): unique, ASCII diff --git a/src/duckdb/src/execution/operator/helper/physical_external_resource.cpp b/src/duckdb/src/execution/operator/helper/physical_external_resource.cpp index 17c1ce16b..49f87548f 100644 --- a/src/duckdb/src/execution/operator/helper/physical_external_resource.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_external_resource.cpp @@ -3,11 +3,12 @@ #include "duckdb/execution/operator/helper/launch_external_resource.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/main/database.hpp" +#include "duckdb/main/database_manager.hpp" #include "duckdb/main/external_resources_manager.hpp" namespace duckdb { -//! Provision (CREATE) or adopt (REGISTER) a resource and register it in the manager under its name. +//! Provision it (CREATE) or take over an existing handle (REGISTER), then record it under its name. static void RegisterExternalResource(ClientContext &client, const BoundExternalResource &data) { auto &manager = ExternalResourcesManager::Get(client); // Reject a duplicate name before provisioning, so a name clash does not spin up (and tear down) a @@ -46,10 +47,14 @@ static void DestroyExternalResource(ClientContext &client, const BoundExternalRe if (!instance) { throw InvalidInputException("external resource \"%s\" is not registered", data.name); } - ResourceDeleter(DatabaseInstance::GetDatabase(client), instance->deleter_function, instance->deleter_payload, - instance->type, instance->name) - .Delete(); + // Never blocked by a borrower: DESTROY is what stops the meter, so it cannot depend on a DETACH + // that may itself be refused. A stranded resource costs money; a dangling attachment costs nothing. + auto &db = DatabaseInstance::GetDatabase(client); + ResourceDeleter(db, instance->deleter_function, instance->deleter_payload, instance->type, instance->name).Delete(); manager.Remove(data.name); + // Then clean up after it: the borrowing attachments now point at nothing, so detach them best-effort. + // Runs only after a successful teardown, so the scan never sits in front of the remote call. + DatabaseManager::Get(client).DetachResourceBorrowers(client, instance->name); } SourceResultType PhysicalExternalResource::GetDataInternal(ExecutionContext &context, DataChunk &chunk, diff --git a/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp b/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp index 270287907..4a96ee71b 100644 --- a/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp @@ -104,7 +104,8 @@ SinkResultType PhysicalLimitPercent::Sink(ExecutionContext &context, DataChunk & //===--------------------------------------------------------------------===// class LimitPercentOperatorState : public GlobalSourceState { public: - explicit LimitPercentOperatorState(const PhysicalLimitPercent &op) : current_offset(0) { + explicit LimitPercentOperatorState(const PhysicalLimitPercent &op) + : current_offset(0), progress(0), limit_validated(false) { D_ASSERT(op.sink_state); auto &gstate = op.sink_state->Cast(); gstate.data.InitializeScan(scan_state); @@ -113,12 +114,28 @@ class LimitPercentOperatorState : public GlobalSourceState { ColumnDataScanState scan_state; optional_idx limit; idx_t current_offset; + atomic progress; + atomic limit_validated; }; unique_ptr PhysicalLimitPercent::GetGlobalSourceState(ClientContext &context) const { return make_uniq(*this); } +ProgressData PhysicalLimitPercent::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + ProgressData progress; + progress.done = gstate.Cast().progress.load(std::memory_order_relaxed); + progress.total = 1.0; + return progress; +} + +void PhysicalLimitPercent::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + if (state.limit_validated.load(std::memory_order_relaxed)) { + state.progress.store(1.0, std::memory_order_relaxed); + } +} + SourceResultType PhysicalLimitPercent::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &gstate = sink_state->Cast(); @@ -133,6 +150,7 @@ SourceResultType PhysicalLimitPercent::GetDataInternal(ExecutionContext &context // no limit value and we have not set limit_percent // we are running LIMIT % with a subquery over an empty table D_ASSERT(gstate.data.Count() == 0); + state.limit_validated.store(true, std::memory_order_relaxed); return SourceResultType::FINISHED; } idx_t count = gstate.data.Count(); @@ -148,6 +166,7 @@ SourceResultType PhysicalLimitPercent::GetDataInternal(ExecutionContext &context } else { limit = idx_t(limit_percentage); } + state.limit_validated.store(true, std::memory_order_relaxed); if (limit == 0) { return SourceResultType::FINISHED; } @@ -161,6 +180,9 @@ SourceResultType PhysicalLimitPercent::GetDataInternal(ExecutionContext &context } PhysicalLimit::HandleOffset(chunk, current_offset, 0, limit.GetIndex()); + const auto total = MinValue(limit.GetIndex(), gstate.data.Count()); + D_ASSERT(total > 0); + state.progress.store(double(MinValue(current_offset, total)) / double(total), std::memory_order_relaxed); return SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp b/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp index 2b2edad5c..de46fdf48 100644 --- a/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp @@ -1,5 +1,6 @@ #include "duckdb/execution/operator/helper/physical_reservoir_sample.hpp" #include "duckdb/execution/reservoir_sample.hpp" +#include "duckdb/common/atomic.hpp" namespace duckdb { @@ -78,19 +79,48 @@ SinkFinalizeType PhysicalReservoirSample::Finalize(Pipeline &pipeline, Event &ev //===--------------------------------------------------------------------===// // Source //===--------------------------------------------------------------------===// +class SampleGlobalSourceState : public GlobalSourceState { +public: + atomic total_rows {0}; + atomic rows_scanned {0}; + atomic progress {0.0}; +}; + +unique_ptr PhysicalReservoirSample::GetGlobalSourceState(ClientContext &context) const { + return make_uniq(); +} + +ProgressData PhysicalReservoirSample::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + return ProgressData {gstate.Cast().progress.load(), 1.0, false}; +} + +void PhysicalReservoirSample::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { + gstate.Cast().progress = 1.0; +} + SourceResultType PhysicalReservoirSample::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &sink = this->sink_state->Cast(); + auto &state = input.global_state.Cast(); lock_guard glock(sink.lock); if (!sink.sample) { + state.progress = 1.0; return SourceResultType::FINISHED; } auto sample_chunk = sink.sample->GetChunk(); if (!sample_chunk) { + state.progress = 1.0; return SourceResultType::FINISHED; } + if (state.total_rows == 0) { + auto remaining = options->is_percentage ? sink.sample->Cast().GetActiveSampleCount() + : sink.sample->Cast().GetActiveSampleCount(); + state.total_rows = sample_chunk->size() + remaining; + } chunk.Move(*sample_chunk); + state.rows_scanned += chunk.size(); + state.progress = double(state.rows_scanned.load()) / double(state.total_rows.load()); return SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp b/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp index f742c8e00..5a25fe3f6 100644 --- a/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_result_collector.cpp @@ -25,8 +25,9 @@ unique_ptr PhysicalResultCollector::GetResultCollector(ClientC auto &physical_plan = *data.physical_plan; auto &root = physical_plan.Root(); - const auto lifetime = data.output_type == QueryResultOutputType::ALLOW_STREAMING ? ResultLifetime::UNDECIDED - : ResultLifetime::RETAINED; + // The plan always leaves the retention open; the consumer's first call settles it, and the + // submission pre-decides it for a query that must not park + const auto lifetime = ResultLifetime::UNDECIDED; if (!PhysicalPlanGenerator::PreserveInsertionOrder(context, root)) { return make_uniq(physical_plan, data, lifetime, ResultOrdering::UNORDERED); } diff --git a/src/duckdb/src/execution/operator/helper/physical_result_sink.cpp b/src/duckdb/src/execution/operator/helper/physical_result_sink.cpp index fcbdad23e..39b8066ce 100644 --- a/src/duckdb/src/execution/operator/helper/physical_result_sink.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_result_sink.cpp @@ -8,8 +8,8 @@ #include "duckdb/main/buffered_data/batched_buffered_data.hpp" #include "duckdb/main/buffered_data/simple_buffered_data.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/materialized_query_result.hpp" -#include "duckdb/main/stream_query_result.hpp" +#include "duckdb/main/query_result.hpp" +#include "duckdb/main/result_unit.hpp" namespace duckdb { @@ -38,7 +38,7 @@ class ResultSinkGlobalState : public GlobalSinkState { class ResultSinkLocalState : public LocalSinkState { public: //! Set when a park deposited the chunk, so the re-delivery is not appended again. Parks deposit - //! so that a parked producer always implies a poppable chunk + //! so that a parked producer always implies a poppable unit bool chunk_deposited = false; //! The batch this producer is currently sinking idx_t current_batch = 0; @@ -49,15 +49,17 @@ class ResultSinkLocalState : public LocalSinkState { unique_ptr batch_data; }; +void PhysicalResultSink::SetResultBuffer(shared_ptr buffer) { + D_ASSERT(!result_buffer); + result_buffer = std::move(buffer); +} + unique_ptr PhysicalResultSink::GetGlobalSinkState(ClientContext &context) const { auto state = make_uniq(); state->context = context.shared_from_this(); if (lifetime != ResultLifetime::RETAINED) { - if (BatchOrdered()) { - state->buffered_data = make_shared_ptr(context, lifetime); - } else { - state->buffered_data = make_shared_ptr(context, lifetime); - } + D_ASSERT(result_buffer); + state->buffered_data = result_buffer; } return std::move(state); } @@ -111,6 +113,11 @@ SinkResultType PhysicalResultSink::SinkRetained(ExecutionContext &context, Resul return SinkResultType::NEED_MORE_INPUT; } +static unique_ptr FinishChunkUnit(DataChunk &chunk) { + // Built outside the buffer's lock, so parallel producers copy concurrently + return make_uniq(BufferedData::CopyForBuffering(chunk)); +} + SinkResultType PhysicalResultSink::SinkDraining(ResultSinkGlobalState &gstate, ResultSinkLocalState &lstate, DataChunk &chunk, OperatorSinkInput &input) const { if (lstate.chunk_deposited) { @@ -123,14 +130,14 @@ SinkResultType PhysicalResultSink::SinkDraining(ResultSinkGlobalState &gstate, R lstate.current_batch = batch; auto &buffered_data = gstate.buffered_data->Cast(); buffered_data.UpdateMinBatchIndex(min_batch_index); - if (buffered_data.AppendOrBlock(chunk, batch, input.interrupt_state)) { + if (buffered_data.AppendOrBlock(FinishChunkUnit(chunk), batch, input.interrupt_state)) { lstate.chunk_deposited = true; return SinkResultType::BLOCKED; } return SinkResultType::NEED_MORE_INPUT; } auto &buffered_data = gstate.buffered_data->Cast(); - if (buffered_data.AppendOrBlock(chunk, input.interrupt_state)) { + if (buffered_data.AppendOrBlock(FinishChunkUnit(chunk), input.interrupt_state)) { lstate.chunk_deposited = true; return SinkResultType::BLOCKED; } @@ -213,19 +220,9 @@ SinkNextBatchType PhysicalResultSink::UpdateMinBatchIndex(ExecutionContext &cont unique_ptr PhysicalResultSink::GetResult(GlobalSinkState &state) const { auto &gstate = state.Cast(); - if (CurrentLifetime(gstate) == ResultLifetime::RETAINED) { - return GetMaterializedResult(gstate); - } - return GetStreamResult(gstate); -} - -unique_ptr PhysicalResultSink::GetStreamResult(ResultSinkGlobalState &gstate) const { - auto cc = gstate.context.lock(); - if (!cc) { - throw ConnectionException("Connection has already been closed"); - } - return make_uniq(statement_type, properties, types, names, cc->GetClientProperties(), - gstate.buffered_data); + // A draining sink hands its chunks to the consumer through the buffer, never through a result + D_ASSERT(CurrentLifetime(gstate) == ResultLifetime::RETAINED); + return GetMaterializedResult(gstate); } unique_ptr PhysicalResultSink::GetMaterializedResult(ResultSinkGlobalState &gstate) const { @@ -247,16 +244,7 @@ unique_ptr PhysicalResultSink::GetMaterializedResult(ResultSinkGlob if (!collection) { collection = CreateCollection(*cc); } - return make_uniq(statement_type, properties, names, std::move(collection), - cc->GetClientProperties()); -} - -bool PhysicalResultSink::HasBlockedResultProducer(GlobalSinkState &state) const { - auto &gstate = state.Cast(); - if (!gstate.buffered_data) { - return false; - } - return gstate.buffered_data->HasParkedProducer(); + return make_uniq(statement_type, properties, names, std::move(collection), cc->GetClientProperties()); } OperatorPartitionInfo PhysicalResultSink::RequiredPartitionInfo() const { diff --git a/src/duckdb/src/execution/operator/join/outer_join_marker.cpp b/src/duckdb/src/execution/operator/join/outer_join_marker.cpp index 87997a861..4ee8e8721 100644 --- a/src/duckdb/src/execution/operator/join/outer_join_marker.cpp +++ b/src/duckdb/src/execution/operator/join/outer_join_marker.cpp @@ -4,6 +4,14 @@ namespace duckdb { +ProgressData OuterJoinGlobalScanState::GetProgress() const { + const auto total = data->Count(); + if (total == 0) { + return ProgressData {1.0, 1.0, false}; + } + return ProgressData {double(rows_scanned.load()), double(total), false}; +} + void OuterJoinLocalScanState::Reset() { scan_chunk.Reset(); local_scan = ColumnDataLocalScanState(); @@ -77,6 +85,7 @@ idx_t OuterJoinMarker::MaxThreads() const { void OuterJoinMarker::InitializeScan(ColumnDataCollection &data, OuterJoinGlobalScanState &gstate) { gstate.data = &data; + gstate.rows_scanned = 0; data.InitializeScan(gstate.global_scan); } @@ -107,6 +116,9 @@ void OuterJoinMarker::Scan(OuterJoinGlobalScanState &gstate, OuterJoinLocalScanS result.data[col_idx].Slice(lstate.scan_chunk.data[col_idx - left_column_count], lstate.match_sel, result_count); } + } + gstate.rows_scanned += lstate.scan_chunk.size(); + if (result_count > 0) { return; } } diff --git a/src/duckdb/src/execution/operator/join/physical_blockwise_nl_join.cpp b/src/duckdb/src/execution/operator/join/physical_blockwise_nl_join.cpp index 9c4993c74..6089d6a62 100644 --- a/src/duckdb/src/execution/operator/join/physical_blockwise_nl_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_blockwise_nl_join.cpp @@ -253,6 +253,10 @@ class BlockwiseNLJoinLocalScanState : public LocalSourceState { OuterJoinLocalScanState scan_state; }; +ProgressData PhysicalBlockwiseNLJoin::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + return gstate.Cast().scan_state.GetProgress(); +} + unique_ptr PhysicalBlockwiseNLJoin::GetGlobalSourceState(ClientContext &context) const { return make_uniq(*this); } diff --git a/src/duckdb/src/execution/operator/join/physical_hash_join.cpp b/src/duckdb/src/execution/operator/join/physical_hash_join.cpp index 6b89415e7..9d4d5fb22 100644 --- a/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_hash_join.cpp @@ -2672,7 +2672,7 @@ ProgressData PhysicalHashJoin::GetProgress(ClientContext &context, GlobalSourceS res.total = static_cast(gstate.full_outer_chunk_count); return res; } - res.done = 0.0; + res.done = gstate.global_stage == HashJoinSourceStage::DONE ? 1.0 : 0.0; res.total = 1.0; return res; } diff --git a/src/duckdb/src/execution/operator/join/physical_iejoin.cpp b/src/duckdb/src/execution/operator/join/physical_iejoin.cpp index 4aedf9e2a..cd8b66a6a 100644 --- a/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +++ b/src/duckdb/src/execution/operator/join/physical_iejoin.cpp @@ -1,3 +1,4 @@ +#include "duckdb/execution/ie_join_union.hpp" #include "duckdb/execution/operator/join/physical_iejoin.hpp" #include "duckdb/common/atomic.hpp" @@ -361,479 +362,6 @@ class IEJoinGlobalSourceState : public GlobalSourceState { bool TryNextTask(Task &task); }; -template -class IEJoinCursor { -public: - explicit IEJoinCursor(ColumnDataCollection &collection) : collection(collection) { - collection.InitializeScan(state); - collection.InitializeScanChunk(state, chunk); - } - - //! The row count of the paged collection - idx_t size() const { // NOLINT - return collection.Count(); - } - - //! Read a typed cell - const T &operator[](idx_t row_idx) { - auto index = Seek(row_idx); - const auto &source = chunk.data[0]; - const auto data_ptr = reinterpret_cast(FlatVector::GetData(source)); - return data_ptr[index]; - } - -private: - //! Is the scan in range? - inline bool RowIsVisible(idx_t row_idx) const { - return (row_idx < state.next_row_index && state.current_row_index <= row_idx); - } - //! The offset of the row in the given state - inline sel_t RowOffset(idx_t row_idx) const { - D_ASSERT(RowIsVisible(row_idx)); - return UnsafeNumericCast(row_idx - state.current_row_index); - } - //! Scan the next chunk - inline bool Scan() { - return collection.Scan(state, chunk); - } - //! Seek to the given row - inline idx_t Seek(idx_t row_idx) { - if (!RowIsVisible(row_idx)) { - collection.Seek(row_idx, state, chunk); - } - return RowOffset(row_idx); - } - - //! The pageable data - const ColumnDataCollection &collection; - //! The state used for reading the collection - ColumnDataScanState state; - //! The data chunk read into - DataChunk chunk; -}; - -struct IEJoinUnion { - using SortedTable = PhysicalRangeJoin::GlobalSortedTable; - using ChunkRange = std::pair; - - // Comparison utilities - static bool IsStrictComparison(ExpressionType comparison) { - switch (comparison) { - case ExpressionType::COMPARE_LESSTHAN: - case ExpressionType::COMPARE_GREATERTHAN: - return true; - case ExpressionType::COMPARE_LESSTHANOREQUALTO: - case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - return false; - default: - throw InternalException("Unimplemented comparison type for IEJoin!"); - } - } - - template - static inline bool Compare(const T &lhs, const T &rhs, const bool strict) { - const bool less_than = lhs < rhs; - if (!less_than && !strict) { - return !(rhs < lhs); - } - return less_than; - } - - static idx_t AppendKey(ExecutionContext &context, InterruptState &interrupt, SortedTable &table, - ExpressionExecutor &executor, SortedTable &marked, int64_t increment, int64_t rid, - const ChunkRange &range); - - static unique_ptr ExtractColumn(SortedTable &table, idx_t col_idx, - BufferManager &buffer_manager) { - auto &collection = *table.sorted->payload_data; - vector scan_ids(1, col_idx); - TupleDataScanState scan_state; - collection.InitializeScan(scan_state, scan_ids); - - DataChunk payload; - collection.InitializeScanChunk(scan_state, payload); - - auto result = make_uniq(buffer_manager, payload.GetTypes()); - ColumnDataAppendState append_state; - result->InitializeAppend(append_state); - while (collection.Scan(scan_state, payload)) { - result->Append(append_state, payload); - } - - return result; - } - - class UnionIterator { - public: - UnionIterator(SortedTable &table, bool strict) : state(table.CreateIteratorState()), strict(strict) { - } - - inline idx_t GetIndex() const { - return index; - } - - inline void SetIndex(idx_t i) { - index = i; - } - - inline idx_t GetChunkIndex() const { - idx_t chunk_idx; - idx_t tuple_idx; - state->RandomAccess(chunk_idx, tuple_idx, index); - return chunk_idx; - } - - inline void SetChunkIndex(idx_t chunk_idx) { - index = state->GetDivisor() * chunk_idx; - } - - UnionIterator &operator++() { - ++index; - return *this; - } - - void Repin() { - state->SetKeepPinned(true); - state->SetPinPayload(true); - } - - unique_ptr state; - idx_t index = 0; - const bool strict; - }; - - IEJoinUnion(IEJoinGlobalSourceState &gsource, const ChunkRange &chunks); - - idx_t SearchL1(idx_t pos); - - //! Start the current row. - //! Returns false if there are no more rows to process - template - bool NextRow(); - - //! NextRow pointer to member for the sort key type. - using next_row_t = bool (duckdb::IEJoinUnion::*)(); - next_row_t next_row_func; - - //! Finish this row and move to the next one. - //! Returns false if there are no more rows to process - bool FinishRow() { - ++i; - return (this->*next_row_func)(); - } - - //! Constructor arguments - IEJoinGlobalSourceState &gsource; - - //! Inverted loop - idx_t JoinBlocks(unsafe_vector &lsel, unsafe_vector &rsel); - - //! B - vector bit_array; - ValidityMask bit_mask; - //! Bloom Filter - static constexpr idx_t BLOOM_CHUNK_BITS = 1024; - idx_t bloom_count; - vector bloom_array; - ValidityMask bloom_filter; - - //! Iteration state - idx_t n; - idx_t i; - idx_t n_j; - idx_t j; - unique_ptr op2; - unique_ptr off2; - int64_t lrid = std::numeric_limits::max(); - - //! ANTI JOIN bookmark - idx_t anti_i; - - //! Li - IEJoinCursor li; - //! P - IEJoinCursor p; -}; - -idx_t IEJoinUnion::AppendKey(ExecutionContext &context, InterruptState &interrupt, SortedTable &table, - ExpressionExecutor &executor, SortedTable &marked, int64_t increment, int64_t rid, - const ChunkRange &chunk_range) { - const auto chunk_begin = chunk_range.first; - const auto chunk_end = chunk_range.second; - - if (chunk_begin == chunk_end) { - return 0; - } - - // Reading - const auto valid = table.count - table.has_null; - auto &source = *table.sorted->payload_data; - TupleDataScanState scanner; - source.InitializeScan(scanner); - - DataChunk scanned; - source.InitializeScanChunk(scanner, scanned); - idx_t table_idx = source.Seek(scanner, chunk_begin); - - // Writing - auto &sort = *marked.sort; - auto local_sort_state = sort.GetLocalSinkState(context); - vector types; - for (const auto &expr : executor.expressions) { - types.emplace_back(expr->GetReturnType()); - } - const idx_t rid_idx = types.size(); - types.emplace_back(LogicalType::BIGINT); - - DataChunk keys; - DataChunk payload; - keys.Initialize(Allocator::DefaultAllocator(), types); - - OperatorSinkInput sink {*marked.global_sink, *local_sort_state, interrupt}; - idx_t inserted = 0; - for (auto chunk_idx = chunk_begin; chunk_idx < chunk_end; ++chunk_idx) { - source.Scan(scanner, scanned); - - // NULLs are at the end, so stop when we reach them - auto scan_count = scanned.size(); - if (table_idx + scan_count > valid) { - if (table_idx >= valid) { - scan_count = 0; - ; - } else { - scan_count = valid - table_idx; - scanned.SetChildCardinality(scan_count); - } - } - if (scan_count == 0) { - break; - } - table_idx += scan_count; - - // Compute the input columns from the payload - keys.Reset(); - keys.Split(payload, rid_idx); - executor.Execute(scanned, keys); - - // Mark the rid column - payload.data[0].Sequence(rid, increment, scan_count); - keys.Fuse(payload); - rid += increment * UnsafeNumericCast(scan_count); - - // Sort on the sort columns (which will no longer be needed) - sort.Sink(context, keys, sink); - inserted += scan_count; - } - OperatorSinkCombineInput combine {*marked.global_sink, *local_sort_state, interrupt}; - sort.Combine(context, combine); - marked.count += inserted; - - return inserted; -} - -IEJoinUnion::IEJoinUnion(IEJoinGlobalSourceState &gsource, const ChunkRange &chunks) - : gsource(gsource), n(0), i(0), li(*gsource.li), p(*gsource.p) { - auto &op = gsource.op; - - // 7. initialize bit-array B (|B| = n), and set all bits to 0 - auto &l2 = *gsource.l2; - n_j = l2.count.load(); - bit_array.resize(ValidityMask::EntryCount(n_j), 0); - bit_mask.Initialize(bit_array.data(), n_j); - - // Bloom filter - bloom_count = (n_j + (BLOOM_CHUNK_BITS - 1)) / BLOOM_CHUNK_BITS; - bloom_array.resize(ValidityMask::EntryCount(bloom_count), 0); - bloom_filter.Initialize(bloom_array.data(), bloom_count); - - // 11. for(i←1 to n) do - const auto strict2 = IsStrictComparison(op.conditions[1].GetComparisonType()); - op2 = make_uniq(l2, strict2); - off2 = make_uniq(l2, strict2); - n = l2.BlockStart(chunks.second); - i = l2.BlockStart(chunks.first); - j = i; - anti_i = i; - - const auto sort_key_type = l2.GetSortKeyType(); - switch (sort_key_type) { -#define DUCKDB_SORT_KEY_CASE(SORT_KEY_TYPE) \ - case SortKeyType::SORT_KEY_TYPE: \ - next_row_func = &IEJoinUnion::NextRow; \ - break; - DUCKDB_FOR_EACH_SORT_KEY_TYPE(DUCKDB_SORT_KEY_CASE) -#undef DUCKDB_SORT_KEY_CASE - default: - throw NotImplementedException("IEJoinUnion for %s", EnumUtil::ToString(sort_key_type)); - } - - (this->*next_row_func)(); -} - -template -bool IEJoinUnion::NextRow() { - using SORT_KEY = SortKey; - using BLOCKS_ITERATOR = block_iterator_t; - - BLOCKS_ITERATOR off2_itr(*off2->state); - BLOCKS_ITERATOR op2_itr(*op2->state); - const auto strict = off2->strict; - - auto pinned_idx = off2->GetChunkIndex(); - for (; i < n; ++i) { - // 12. pos ← P[i] - auto pos = p[i]; - lrid = li[pos]; - if (lrid < 0) { - continue; - } - - // 16. B[pos] ← 1 - op2->SetIndex(i); - for (; off2->GetIndex() < n_j; ++(*off2)) { - // Prevent buildup of pinned blocks - if (off2->GetChunkIndex() != pinned_idx) { - off2->Repin(); - pinned_idx = off2->GetChunkIndex(); - } - if (!Compare(off2_itr[off2->GetIndex()], op2_itr[op2->GetIndex()], strict)) { - break; - } - const auto p2 = p[off2->GetIndex()]; - if (li[p2] < 0) { - // Only mark rhs matches. - bit_mask.SetValidUnsafe(p2); - bloom_filter.SetValidUnsafe(p2 / BLOOM_CHUNK_BITS); - } - } - - // 9. if (op1 ∈ {≤,≥} and op2 ∈ {≤,≥}) eqOff = 0 - // 10. else eqOff = 1 - // No, because there could be more than one equal value. - // Find the leftmost off1 where L1[pos] op1 L1[off1..n] - // These are the rows that satisfy the op1 condition - // and that is where we should start scanning B from - j = pos; - - return true; - } - return false; -} - -static idx_t NextValid(const ValidityMask &bits, idx_t j, const idx_t n) { - if (j >= n) { - return n; - } - - // We can do a first approximation by checking entries one at a time - // which gives 64:1. - idx_t entry_idx, idx_in_entry; - bits.GetEntryIndex(j, entry_idx, idx_in_entry); - - // Copy first entry to local and trim the bits before the start position - auto first_entry = bits.GetValidityEntryUnsafe(entry_idx++); - first_entry &= (ValidityMask::ValidityBuffer::MAX_ENTRY << idx_in_entry); - - // If the first entry has a valid bit, we can return immediately - if (first_entry) { - return j + CountZeros::Trailing(first_entry) - idx_in_entry; - } - - // The first entry did not have a valid bit - j += ValidityMask::BITS_PER_VALUE - idx_in_entry; - - // Loop over non-ragged entries - const auto entry_count_minus_one = bits.EntryCount(n) - 1; - const auto entry_idx_before = entry_idx; - - // The compiler has a hard time optimizing this loop for some reason - // Creating a static inner loop like this improves performance by almost 2x - static constexpr idx_t NEXT_VALID_UNROLL = 8; - for (; entry_idx + NEXT_VALID_UNROLL < entry_count_minus_one; entry_idx += NEXT_VALID_UNROLL) { - for (idx_t unroll_idx = 0; unroll_idx < NEXT_VALID_UNROLL; unroll_idx++) { - const auto unroll_entry_idx = entry_idx + unroll_idx; - const auto &entry = bits.GetValidityEntryUnsafe(unroll_entry_idx); - if (entry) { - return j + (unroll_entry_idx - entry_idx_before) * ValidityMask::BITS_PER_VALUE + - CountZeros::Trailing(entry); - } - } - } - - for (; entry_idx < entry_count_minus_one; ++entry_idx) { - const auto &entry = bits.GetValidityEntryUnsafe(entry_idx); - if (entry) { - return j + (entry_idx - entry_idx_before) * ValidityMask::BITS_PER_VALUE + - CountZeros::Trailing(entry); - } - } - - // Update j once after the loop so we don't have to update it in each iteration - j += (entry_idx - entry_idx_before) * ValidityMask::BITS_PER_VALUE; - - // Check the final entry - return j >= n ? n : j + CountZeros::Trailing(bits.GetValidityEntryUnsafe(entry_idx)); -} - -idx_t IEJoinUnion::JoinBlocks(unsafe_vector &lsel, unsafe_vector &rsel) { - // Release pinned blocks - op2->Repin(); - off2->Repin(); - - // 8. initialize join result as an empty list for tuple pairs - idx_t result_count = 0; - - lsel.resize(STANDARD_VECTOR_SIZE); - rsel.resize(STANDARD_VECTOR_SIZE); - - // 11. for(i←1 to n) do - while (i < n) { - // 13. for (j ← pos+eqOff to n) do - for (;;) { - // 14. if B[j] = 1 then - - // Use the Bloom filter to find candidate blocks - while (j < n_j) { - auto bloom_begin = NextValid(bloom_filter, j / BLOOM_CHUNK_BITS, bloom_count) * BLOOM_CHUNK_BITS; - auto bloom_end = MinValue(n_j, bloom_begin + BLOOM_CHUNK_BITS); - - j = MaxValue(j, bloom_begin); - j = NextValid(bit_mask, j, bloom_end); - if (j < bloom_end) { - break; - } - } - - if (j >= n_j) { - break; - } - - // Filter out tuples with the same sign (they come from the same table) - const auto rrid = li[j]; - ++j; - - D_ASSERT(lrid > 0 && rrid < 0); - // 15. add tuples w.r.t. (L1[j], L1[i]) to join result - lsel[result_count] = static_cast(+lrid - 1); - rsel[result_count] = static_cast(-rrid - 1); - ++result_count; - if (result_count == STANDARD_VECTOR_SIZE) { - // out of space! - return result_count; - } - } - - if (!FinishRow()) { - break; - } - } - - lsel.resize(result_count); - rsel.resize(result_count); - - return result_count; -} - IEJoinGlobalSourceState::IEJoinGlobalSourceState(const PhysicalIEJoin &op, ClientContext &client, IEJoinGlobalState &gsink) : op(op), gsink(gsink), stage(IEJoinSourceStage::INIT), started(0), finished(0), stopped(false) { @@ -850,65 +378,7 @@ IEJoinGlobalSourceState::IEJoinGlobalSourceState(const PhysicalIEJoin &op, Clien right_outers = right_blocks; } - // input : query Q with 2 join predicates t1.X op1 t2.X' and t1.Y op2 t2.Y', tables T, T' of sizes m and n resp. - // output: a list of tuple pairs (ti , tj) - // Note that T/T' are already sorted on X/X' and contain the payload data - // We only join the two block numbers and use the sizes of the blocks as the counts - - // 1. let L1 (resp. L2) be the array of column X (resp. Y ) - const auto &order1 = op.lhs_orders[0]; - const auto &order2 = op.lhs_orders[1]; - - // 2. if (op1 ∈ {>, ≥}) sort L1 in descending order - // 3. else if (op1 ∈ {<, ≤}) sort L1 in ascending order - - // For the union algorithm, we make a unified table with the keys and the rids as the payload: - // X/X', Y/Y', R/R'/Li - // The first position is the sort key. - vector types; - types.emplace_back(order2.expression->GetReturnType()); - types.emplace_back(LogicalType::BIGINT); - - // Sort on the first expression - auto ref = make_uniq(order1.expression->GetReturnType(), 0U); - vector orders; - orders.emplace_back(order1.type, order1.null_order, std::move(ref)); - // The goal is to make i (from the left table) < j (from the right table), - // if value[i] and value[j] match the condition 1. - // Add a column from_left to solve the problem when there exist multiple equal values in l1. - // If the operator is loose inequality, make t1.from_left (== true) sort BEFORE t2.from_left (== false). - // Otherwise, make t1.from_left sort (== true) sort AFTER t2.from_left (== false). - // For example, if t1.time <= t2.time - // | value | 1 | 1 | 1 | 1 | - // | --------- | ----- | ----- | ----- | ----- | - // | from_left | T(l2) | T(l2) | F(r1) | F(r2) | - // if t1.time < t2.time - // | value | 1 | 1 | 1 | 1 | - // | --------- | ----- | ----- | ----- | ----- | - // | from_left | F(r2) | F(r1) | T(l2) | T(l1) | - // Using this OrderType, if i < j then value[i] (from left table) and value[j] (from right table) match - // the condition (t1.time <= t2.time or t1.time < t2.time), then from_left will force them into the correct order. - auto from_left = make_uniq(Value::BOOLEAN(true)); - const auto strict1 = IEJoinUnion::IsStrictComparison(op.conditions[0].GetComparisonType()); - orders.emplace_back(!strict1 ? OrderType::DESCENDING : OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, - std::move(from_left)); - - l1 = make_uniq(client, orders, types, op); - - // 4. if (op2 ∈ {>, ≥}) sort L2 in ascending order - // 5. else if (op2 ∈ {<, ≤}) sort L2 in descending order - - // We sort on Y/Y' to obtain the sort keys and the permutation array. - // For this we just need a two-column table of Y, P - types.clear(); - types.emplace_back(LogicalType::BIGINT); - - // Sort on the first expression - orders.clear(); - ref = make_uniq(order2.expression->GetReturnType(), 0U); - orders.emplace_back(order2.type, order2.null_order, std::move(ref)); - - l2 = make_uniq(client, orders, types, op); + IEJoinUnion::InitializeTables(client, op, op.conditions, l1, l2); // The number of blocks in L2 is not quite the sum of the blocks in the two tables... const auto join_count = left_table.count.load() + right_table.count.load(); @@ -1149,7 +619,7 @@ bool IEJoinLocalSourceState::TryAssignTask() { right_block_index = 0; right_base = 0; - joiner = make_uniq(gsource, task->range); + joiner = make_uniq(*gsource.l2, *gsource.li, *gsource.p, gsource.op.conditions, task->range); break; case IEJoinSourceStage::OUTER: if (task->thread_idx < gsource.left_outers) { diff --git a/src/duckdb/src/execution/operator/join/physical_nested_loop_join.cpp b/src/duckdb/src/execution/operator/join/physical_nested_loop_join.cpp index 5b6faefe7..749e8c856 100644 --- a/src/duckdb/src/execution/operator/join/physical_nested_loop_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_nested_loop_join.cpp @@ -2,9 +2,12 @@ #include "duckdb/parallel/thread_context.hpp" #include "duckdb/execution/expression_executor.hpp" #include "duckdb/execution/nested_loop_join.hpp" +#include "duckdb/execution/mark_join_row_comparison.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/execution/operator/join/outer_join_marker.hpp" +#include "duckdb/common/types/vector_cache.hpp" #include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/common/vector/constant_vector.hpp" namespace duckdb { @@ -16,8 +19,16 @@ PhysicalNestedLoopJoin::PhysicalNestedLoopJoin(PhysicalPlan &physical_plan, Logi : PhysicalComparisonJoin(physical_plan, op, PhysicalOperatorType::NESTED_LOOP_JOIN, std::move(conds), join_type, estimated_cardinality) { filter_pushdown = std::move(pushdown_info_p); + track_unknown = + join_type == JoinType::MARK && + (predicate || conditions.size() > 1 || + (conditions.size() == 1 && (conditions[0].GetLHS().GetReturnType().id() == LogicalTypeId::TUPLE || + conditions[0].GetComparisonType() == ExpressionType::COMPARE_DISTINCT_FROM))); children.push_back(left); children.push_back(right); + if (join_type == JoinType::MARK) { + mark_projection_map = FillProjectionMap(left, op.left_projection_map); + } } PhysicalNestedLoopJoin::PhysicalNestedLoopJoin(PhysicalPlan &physical_plan, LogicalComparisonJoin &op, @@ -337,10 +348,20 @@ class PhysicalNestedLoopJoinState : public CachingOperatorState { right_condition.Initialize(allocator, condition_types); right_payload.Initialize(allocator, op.children[1].get().GetTypes()); left_outer.Initialize(STANDARD_VECTOR_SIZE); + if (op.join_type == JoinType::MARK) { + auto payload_types = op.GetTypes(); + payload_types.pop_back(); + mark_payload.InitializeEmpty(payload_types); + } if (op.predicate) { pred_executor.AddExpression(*op.predicate); pred_matches.Initialize(); + auto predicate_types = op.children[0].get().GetTypes(); + for (auto &type : op.children[1].get().GetTypes()) { + predicate_types.push_back(type); + } + pred_input.Initialize(allocator, predicate_types); } ResetState(); } @@ -364,6 +385,8 @@ class PhysicalNestedLoopJoinState : public CachingOperatorState { //! Predicate ExpressionExecutor pred_executor; SelectionVector pred_matches; + DataChunk pred_input; + DataChunk mark_payload; private: void ResetState() { @@ -375,6 +398,8 @@ class PhysicalNestedLoopJoinState : public CachingOperatorState { payload_scan_state = ColumnDataScanState(); right_condition.Reset(); right_payload.Reset(); + pred_input.Reset(); + mark_payload.Reset(); left_tuple = 0; right_tuple = 0; left_outer.Reset(); @@ -402,11 +427,16 @@ OperatorResultType PhysicalNestedLoopJoin::ExecuteInternal(ExecutionContext &con DataChunk &chunk, GlobalOperatorState &gstate_p, OperatorState &state_p) const { auto &gstate = sink_state->Cast(); + auto &state = state_p.Cast(); + if (join_type == JoinType::MARK) { + state.mark_payload.ReferenceColumns(input, mark_projection_map); + } if (gstate.right_payload_data.Count() == 0) { // empty RHS if (!EmptyResultIfRHSIsEmpty()) { - ConstructEmptyJoinResult(join_type, gstate.has_null, input, chunk); + auto &payload = join_type == JoinType::MARK ? state.mark_payload : input; + ConstructEmptyJoinResult(join_type, gstate.has_null, payload, chunk); return OperatorResultType::NEED_MORE_INPUT; } else { return OperatorResultType::FINISHED; @@ -430,6 +460,61 @@ OperatorResultType PhysicalNestedLoopJoin::ExecuteInternal(ExecutionContext &con } } +static void ResolveSimpleJoinPredicate(const vector &conditions, JoinType join_type, DataChunk &input, + PhysicalNestedLoopJoinState &state, NestedLoopJoinGlobalState &gstate, + bool found_match[], bool found_unknown[]) { + gstate.right_condition_data.InitializeScan(state.condition_scan_state); + gstate.right_payload_data.InitializeScan(state.payload_scan_state); + Vector comparison(LogicalType::BOOLEAN); + MarkJoinRowComparison comparer(state.left_condition); + VectorCache predicate_cache(state.pred_executor.GetAllocator(), LogicalType::BOOLEAN); + Vector predicate_result(predicate_cache); + while (gstate.right_condition_data.Scan(state.condition_scan_state, state.right_condition)) { + if (!gstate.right_payload_data.Scan(state.payload_scan_state, state.right_payload) || + state.right_condition.size() != state.right_payload.size()) { + throw InternalException("Nested loop join: payload and conditions are unaligned!?"); + } + for (idx_t left_row = 0; left_row < input.size(); left_row++) { + if (found_match[left_row]) { + continue; + } + comparer.CompareConjunction(state.left_condition, left_row, state.right_condition, conditions, comparison); + auto comparisons = comparison.Values(); + idx_t candidate_count = 0; + for (idx_t right_row = 0; right_row < state.right_condition.size(); right_row++) { + auto entry = comparisons[right_row]; + if (entry.IsValid() ? entry.GetValue() : join_type == JoinType::MARK) { + state.pred_matches.set_index(candidate_count++, right_row); + } + } + if (candidate_count == 0) { + continue; + } + state.pred_input.Reset(); + state.pred_input.SetChildCardinality(candidate_count); + state.pred_input.Slice(state.right_payload, state.pred_matches, candidate_count, input.ColumnCount()); + for (idx_t column_idx = 0; column_idx < input.ColumnCount(); column_idx++) { + ConstantVector::Reference(state.pred_input.data[column_idx], count_t(candidate_count), + input.data[column_idx], left_row, input.size()); + } + predicate_result.ResetFromCache(predicate_cache); + state.pred_executor.ExecuteExpression(state.pred_input, predicate_result); + auto predicates = predicate_result.Values(); + for (idx_t candidate = 0; candidate < candidate_count; candidate++) { + auto predicate = predicates[candidate]; + if (predicate.IsValid() && !predicate.GetValue()) { + continue; + } + if (predicate.IsValid() && comparisons[state.pred_matches.get_index(candidate)].IsValid()) { + found_match[left_row] = true; + break; + } + found_unknown[left_row] = true; + } + } + } +} + void PhysicalNestedLoopJoin::ResolveSimpleJoin(ExecutionContext &context, DataChunk &input, DataChunk &chunk, OperatorState &state_p) const { auto &state = state_p.Cast(); @@ -441,14 +526,18 @@ void PhysicalNestedLoopJoin::ResolveSimpleJoin(ExecutionContext &context, DataCh bool found_match[STANDARD_VECTOR_SIZE] = {false}; bool found_unknown[STANDARD_VECTOR_SIZE] = {false}; - const bool track_unknown = join_type == JoinType::MARK && conditions.size() == 1 && - conditions[0].GetLHS().GetReturnType().id() == LogicalTypeId::TUPLE; - NestedLoopJoinMark::Perform(state.left_condition, gstate.right_condition_data, found_match, conditions, - track_unknown ? optional_ptr(found_unknown) : nullptr); + + if (predicate) { + ResolveSimpleJoinPredicate(conditions, join_type, input, state, gstate, found_match, found_unknown); + } else { + NestedLoopJoinMark::Perform(state.left_condition, gstate.right_condition_data, found_match, conditions, + track_unknown ? optional_ptr(found_unknown) : nullptr); + } switch (join_type) { case JoinType::MARK: // now construct the mark join result from the found matches - PhysicalJoin::ConstructMarkJoinResult(state.left_condition, input, chunk, found_match, gstate.has_null, + PhysicalJoin::ConstructMarkJoinResult(state.left_condition, state.mark_payload, chunk, found_match, + gstate.has_null, track_unknown ? optional_ptr(found_unknown) : nullptr); break; case JoinType::SEMI: @@ -611,6 +700,10 @@ class NestedLoopJoinLocalScanState : public LocalSourceState { } }; +ProgressData PhysicalNestedLoopJoin::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + return gstate.Cast().scan_state.GetProgress(); +} + unique_ptr PhysicalNestedLoopJoin::GetGlobalSourceState(ClientContext &context) const { return make_uniq(*this, context); } diff --git a/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp b/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp index 26c6ca177..98a218f60 100644 --- a/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp @@ -2,6 +2,7 @@ #include +#include "duckdb/common/atomic.hpp" #include "duckdb/common/row_operations/row_operations.hpp" #include "duckdb/common/sorting/sort_key.hpp" #include "duckdb/common/types/row/block_iterator.hpp" @@ -798,6 +799,7 @@ class PiecewiseJoinGlobalScanState : public GlobalSourceState { } TupleDataCollection &payload; + atomic rows_scanned {0}; public: idx_t MaxThreads() override { @@ -827,6 +829,15 @@ unique_ptr PhysicalPiecewiseMergeJoin::GetGlobalSourceState(C return make_uniq(*gsink.table->sorted->payload_data); } +ProgressData PhysicalPiecewiseMergeJoin::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + const auto total = state.payload.Count(); + if (total == 0) { + return ProgressData {1.0, 1.0, false}; + } + return ProgressData {double(state.rows_scanned.load()), double(total), false}; +} + unique_ptr PhysicalPiecewiseMergeJoin::GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const { return make_uniq(gstate.Cast()); @@ -879,6 +890,9 @@ SourceResultType PhysicalPiecewiseMergeJoin::GetDataInternal(ExecutionContext &c for (idx_t col_idx = 0; col_idx < right_column_count; ++col_idx) { result.data[left_column_count + col_idx].Slice(rhs_chunk.data[col_idx], rsel, result_count); } + } + gsource.rows_scanned += count; + if (result_count > 0) { break; } } diff --git a/src/duckdb/src/execution/operator/join/physical_positional_join.cpp b/src/duckdb/src/execution/operator/join/physical_positional_join.cpp index 035858e18..c839b52cc 100644 --- a/src/duckdb/src/execution/operator/join/physical_positional_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_positional_join.cpp @@ -21,7 +21,7 @@ class PositionalJoinGlobalState : public GlobalSinkState { public: explicit PositionalJoinGlobalState(ClientContext &context, const PhysicalPositionalJoin &op) : rhs(context, op.children[1].get().GetTypes()), initialized(false), source_count(0), source_offset(0), - exhausted(false) { + exhausted(false), rows_scanned(0) { rhs.InitializeAppend(append_state); } @@ -35,6 +35,7 @@ class PositionalJoinGlobalState : public GlobalSinkState { idx_t source_count; idx_t source_offset; bool exhausted; + atomic rows_scanned; void InitializeScan(); idx_t Refill(); @@ -137,6 +138,8 @@ void PositionalJoinGlobalState::Execute(DataChunk &input, DataChunk &output) { CopyData(output, count, col_offset); output.SetChildCardinality(count); + const auto scanned = rows_scanned.load(std::memory_order_relaxed); + rows_scanned.store(scanned + MinValue(count, rhs.Count() - scanned), std::memory_order_relaxed); } OperatorResultType PhysicalPositionalJoin::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, @@ -172,6 +175,8 @@ void PositionalJoinGlobalState::GetData(DataChunk &output) { // RHS still has data, so copy it CopyData(output, count, col_offset); output.SetChildCardinality(count); + const auto scanned = rows_scanned.load(std::memory_order_relaxed); + rows_scanned.store(scanned + MinValue(count, rhs.Count() - scanned), std::memory_order_relaxed); } SourceResultType PhysicalPositionalJoin::GetDataInternal(ExecutionContext &context, DataChunk &result, @@ -182,6 +187,19 @@ SourceResultType PhysicalPositionalJoin::GetDataInternal(ExecutionContext &conte return result.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } +ProgressData PhysicalPositionalJoin::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &sink = sink_state->Cast(); + ProgressData progress; + progress.total = double(MaxValue(sink.rhs.Count(), 1)); + progress.done = sink.rhs.Count() == 0 ? 1.0 : double(sink.rows_scanned.load(std::memory_order_relaxed)); + return progress; +} + +void PhysicalPositionalJoin::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { + auto &sink = sink_state->Cast(); + sink.rows_scanned.store(sink.rhs.Count(), std::memory_order_relaxed); +} + //===--------------------------------------------------------------------===// // Pipeline Construction //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/execution/operator/join/physical_range_join.cpp b/src/duckdb/src/execution/operator/join/physical_range_join.cpp index 48fc406ec..26426f4ed 100644 --- a/src/duckdb/src/execution/operator/join/physical_range_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_range_join.cpp @@ -80,7 +80,7 @@ void PhysicalRangeJoin::LocalSortedTable::Sink(ExecutionContext &context, DataCh PhysicalRangeJoin::GlobalSortedTable::GlobalSortedTable(ClientContext &client, const vector &order_bys, const vector &payload_types, - const PhysicalRangeJoin &op) + const PhysicalComparisonJoin &op) : op(op), has_null(0), count(0), tasks_completed(0) { // Set up the sort. We will materialize keys ourselves, so just set up references. vector orders; diff --git a/src/duckdb/src/execution/operator/order/physical_top_n.cpp b/src/duckdb/src/execution/operator/order/physical_top_n.cpp index 4e59e3fcd..1395be181 100644 --- a/src/duckdb/src/execution/operator/order/physical_top_n.cpp +++ b/src/duckdb/src/execution/operator/order/physical_top_n.cpp @@ -1,4 +1,5 @@ #include "duckdb/execution/operator/order/physical_top_n.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/common/assert.hpp" #include "duckdb/common/mutex.hpp" @@ -562,6 +563,7 @@ class TopNGlobalSourceState : public GlobalSourceState { public: explicit TopNGlobalSourceState(TopNGlobalSinkState &sink_p) : sink(sink_p), batch_index(0) { sink.heap.InitializeScan(state, true); + total_rows = state.scan_order.size() - MinValue(sink.heap.offset, state.scan_order.size()); } idx_t MaxThreads() override { @@ -575,12 +577,22 @@ class TopNGlobalSourceState : public GlobalSourceState { TopNGlobalSinkState &sink; TopNScanState state; idx_t batch_index; + idx_t total_rows; + atomic rows_scanned {0}; }; unique_ptr PhysicalTopN::GetGlobalSourceState(ClientContext &context) const { return make_uniq(this->sink_state->Cast()); } +ProgressData PhysicalTopN::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + if (state.total_rows == 0) { + return ProgressData {1.0, 1.0, false}; + } + return ProgressData {double(state.rows_scanned.load()), double(state.total_rows), false}; +} + unique_ptr PhysicalTopN::GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const { return make_uniq(); @@ -605,6 +617,7 @@ SourceResultType PhysicalTopN::GetDataInternal(ExecutionContext &context, DataCh } sink.heap.Scan(gstate.state, chunk, lstate.pos); + gstate.rows_scanned += chunk.size(); return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/persistent/csv_rejects_table.cpp b/src/duckdb/src/execution/operator/persistent/csv_rejects_table.cpp index bf80823fb..212fea934 100644 --- a/src/duckdb/src/execution/operator/persistent/csv_rejects_table.cpp +++ b/src/duckdb/src/execution/operator/persistent/csv_rejects_table.cpp @@ -23,14 +23,6 @@ TableCatalogEntry &CSVRejectsTable::GetScansTable(ClientContext &context) { return table_entry; } -idx_t CSVRejectsTable::GetCurrentFileIndex(idx_t query_id) { - if (current_query_id != query_id) { - current_query_id = query_id; - current_file_idx = 0; - } - return current_file_idx++; -} - shared_ptr CSVRejectsTable::GetOrCreate(ClientContext &context, const string &rejects_scan, const string &rejects_error) { // Check that these names can't be the same @@ -65,7 +57,31 @@ shared_ptr CSVRejectsTable::GetOrCreate(ClientContext &context, return cache.GetOrCreate(key, rejects_scan, rejects_error); } +idx_t CSVRejectsTable::GetFileIndexBase(idx_t query_id, const void *scan_key, idx_t file_count) { + const lock_guard lock(file_index_lock); + if (file_index_query_id != query_id) { + // the file indexes are unique within a query + file_index_query_id = query_id; + next_file_index = 0; + scan_file_index_base.clear(); + } + if (!scan_key) { + // we cannot tell which scan this file belongs to - give it an index of its own + return next_file_index++; + } + auto entry = scan_file_index_base.find(scan_key); + if (entry != scan_file_index_base.end()) { + return entry->second; + } + const idx_t base = next_file_index; + next_file_index += MaxValue(file_count, 1); + scan_file_index_base.emplace(scan_key, base); + return base; +} + void CSVRejectsTable::InitializeTable(ClientContext &context, const ReadCSVData &data) { + // every file of a scan initializes the table it reports its rejects to, and files are opened in parallel + const lock_guard lock(write_lock); // (Re)Create the temporary rejects table auto &catalog = Catalog::GetCatalog(context, Identifier::TempCatalog()); diff --git a/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp b/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp index ae291b6e9..9e1d3b223 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp @@ -72,7 +72,8 @@ SourceResultType PhysicalCopyDatabase::GetDataInternal(ExecutionContext &context if (!create_info || create_info->type != CatalogType::INDEX_ENTRY) { continue; } - catalog.CreateIndex(context.client, create_info->Cast()); + auto index_entry = catalog.CreateIndex(context.client, create_info->Cast()); + D_ASSERT(index_entry); auto &create_index_info = create_info->Cast(); auto &table_entry = catalog.GetEntry( @@ -84,7 +85,7 @@ SourceResultType PhysicalCopyDatabase::GetDataInternal(ExecutionContext &context storage_info.options.emplace("v1_0_0_storage", false); auto unbound_index = make_uniq(create_index_info.Copy(), std::move(storage_info), data_table.GetTableIOManager(), catalog.GetAttached()); - data_table.AddIndex(std::move(unbound_index)); + data_table.AddIndex(std::move(unbound_index), index_entry->oid); // We add unbound indexes, so we immediately bind them. // Otherwise, WAL serialization fails due to unbound indexes. diff --git a/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp b/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp index ee3345fda..f967e6b8c 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp @@ -2,13 +2,17 @@ #include "duckdb/common/file_opener.hpp" #include "duckdb/common/file_system.hpp" -#include "duckdb/common/hive_partitioning.hpp" +#include "duckdb/common/path.hpp" #include "duckdb/common/optional.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/common/sorting/sort_strategy.hpp" #include "duckdb/common/types/column/column_data_collection_segment.hpp" #include "duckdb/common/value_operations/value_operations.hpp" +#include "duckdb/execution/expression_executor.hpp" +#include "duckdb/function/function_binder.hpp" +#include "duckdb/function/scalar/string_functions.hpp" #include "duckdb/function/window/window_collection.hpp" +#include "duckdb/planner/expression/bound_constant_expression.hpp" #include "duckdb/planner/expression/bound_reference_expression.hpp" #include "duckdb/planner/operator/logical_copy_to_file.hpp" #include "duckdb/parallel/base_pipeline_event.hpp" @@ -109,6 +113,8 @@ struct PendingFileState { struct PartitionDirectory { string path; vector directories; + //! The directory relative to the COPY target, with "/" separators + string relative_path; }; enum class CopyDirectoryState : uint8_t { PENDING, COMPLETE, FAILED }; @@ -672,6 +678,9 @@ class PartitionWriteManager { ReservationLock LockForReservation() DUCKDB_EXCLUDES(lock); PartitionFileStateReservation ReserveFileState(ReservationLock &reservation_lock, const vector &values, FileCreationReason reason) DUCKDB_NO_THREAD_SAFETY_ANALYSIS; + //! Claims the directory of a partition, throws if it equals, contains or is inside another partition's directory + void ClaimDirectory(ReservationLock &reservation_lock, const vector &values, + const string &directory) DUCKDB_NO_THREAD_SAFETY_ANALYSIS; FileStateHandle TryTakeInactiveFileState(const vector &values) DUCKDB_EXCLUDES(lock); vector TakeOpenFileStates() DUCKDB_EXCLUDES(lock); @@ -686,6 +695,9 @@ class PartitionWriteManager { ActiveWrites active_writes DUCKDB_GUARDED_BY(lock); vector_of_value_map_t previous_partitions DUCKDB_GUARDED_BY(lock); idx_t global_offset DUCKDB_GUARDED_BY(lock) = 0; + //! The claimed directory of each partition, and the partition owning each directory + vector_of_value_map_t partition_directories DUCKDB_GUARDED_BY(lock); + map> directory_partitions DUCKDB_GUARDED_BY(lock); friend class PartitionWriteLease; }; @@ -824,7 +836,7 @@ struct PartitionedCopyBatchState { const vector &Values() const { D_ASSERT(values); - return *values; + return values.value(); } idx_t AddCollectionSlot(PartitionedCopyCollectionSchema schema, idx_t row_count) { @@ -1378,6 +1390,11 @@ class PartitionedCopy { vector write_types; vector raw_columns; + //! Expression describing the directories of a partition's files relative to the COPY target: + //! PARTITION_PATH, or the hive layout by default. useful if partitions are registered in + //! locations that do not follow hive partition naming structures + unique_ptr partition_path; + //! Partition/sort strategy with PhysicalOperator-like interface const unique_ptr sort_strategy; @@ -1458,6 +1475,65 @@ class DelayedPartitionFlushGuard { //===--------------------------------------------------------------------===// // Utility Helpers //===--------------------------------------------------------------------===// +static bool UsePerPartitionFileOffsets(const PhysicalCopyToFile &op) { + // every partition has a directory of its own, unless all files are written to the COPY target + return op.hive_file_pattern || op.partition_path_expression; +} + +//! The hive layout, e.g. year=2024/month=1, as an expression over the partition values +static unique_ptr CreateHivePartitionPath(ClientContext &context, const PhysicalCopyToFile &op) { + if (op.partition_columns.empty()) { + return nullptr; + } + auto component_function = HivePartitionComponentFun::GetFunction(); + + FunctionBinder function_binder(context); + vector> components; + for (idx_t i = 0; i < op.partition_columns.size(); i++) { + auto col_idx = op.partition_columns[i]; + vector> children; + children.push_back(make_uniq(Value(op.names[col_idx].GetIdentifierName()))); + children.push_back(make_uniq(op.expected_types[col_idx], i)); + components.push_back(function_binder.BindScalarFunction(component_function, std::move(children))); + } + return function_binder.BindScalarFunction(PathJoinFun::GetFunction(), std::move(components)); +} + +//! e.g. "year=2024, month=NULL" +static string PartitionValuesToString(const PhysicalCopyToFile &op, const vector &values) { + string result; + for (idx_t i = 0; i < values.size(); i++) { + result += i > 0 ? ", " : ""; + result += op.names[op.partition_columns[i]].GetIdentifierName() + "=" + values[i].ToString(); + } + return result; +} + +static string EvaluatePartitionPath(ClientContext &context, const PhysicalCopyToFile &op, + const Expression &partition_path, const vector &values) { + D_ASSERT(values.size() == op.partition_columns.size()); + vector types; + for (auto &col_idx : op.partition_columns) { + types.push_back(op.expected_types[col_idx]); + } + DataChunk partition_values; + partition_values.Initialize(Allocator::Get(context), types, 1); + for (idx_t i = 0; i < values.size(); i++) { + partition_values.data[i].Append(values[i]); + } + partition_values.CheckCardinality(1); + + ExpressionExecutor executor(context, partition_path); + Vector result(LogicalType::VARCHAR, 1); + executor.ExecuteExpression(partition_values, result); + auto path = result.GetValue(0); + if (path.IsNull()) { + throw InvalidInputException("PARTITION_PATH evaluated to NULL for partition %s", + PartitionValuesToString(op, values)); + } + return StringValue::Get(path); +} + void CheckDirectory(FileSystem &fs, const string &file_path, CopyOverwriteMode overwrite_mode) { if (overwrite_mode == CopyOverwriteMode::COPY_OVERWRITE_OR_IGNORE || overwrite_mode == CopyOverwriteMode::COPY_APPEND) { @@ -1795,6 +1871,42 @@ PartitionWriteManager::ReservationLock PartitionWriteManager::LockForReservation return ReservationLock(lock); } +void PartitionWriteManager::ClaimDirectory(ReservationLock &reservation_lock, const vector &values, + const string &directory) DUCKDB_NO_THREAD_SAFETY_ANALYSIS { + D_ASSERT(reservation_lock.guard.owns_lock()); + D_ASSERT(!directory.empty()); + auto claimed = partition_directories.find(values); + if (claimed != partition_directories.end() && claimed->second == directory) { + return; + } + auto throw_overlap = [&](const string &other_directory, const vector &other_values) { + if (other_directory == directory) { + throw InvalidInputException("PARTITION_PATH puts partitions (%s) and (%s) in the same directory \"%s\"", + PartitionValuesToString(op, other_values), PartitionValuesToString(op, values), + directory); + } + throw InvalidInputException( + "PARTITION_PATH puts partitions (%s) and (%s) in overlapping directories \"%s\" and \"%s\"", + PartitionValuesToString(op, other_values), PartitionValuesToString(op, values), other_directory, directory); + }; + // the same directory, or a directory containing it + string ancestor; + for (auto &component : StringUtil::Split(directory, '/')) { + ancestor += ancestor.empty() ? component : "/" + component; + auto owner = directory_partitions.find(ancestor); + if (owner != directory_partitions.end()) { + throw_overlap(owner->first, owner->second); + } + } + // a directory inside it - those all start with the directory and a separator, so they are adjacent in the map + auto descendant = directory_partitions.lower_bound(directory + "/"); + if (descendant != directory_partitions.end() && StringUtil::StartsWith(descendant->first, directory + "/")) { + throw_overlap(descendant->first, descendant->second); + } + directory_partitions.emplace(directory, values); + partition_directories[values] = directory; +} + PartitionFileStateReservation PartitionWriteManager::ReserveFileState(ReservationLock &reservation_lock, const vector &values, FileCreationReason reason) DUCKDB_NO_THREAD_SAFETY_ANALYSIS { @@ -1809,7 +1921,7 @@ PartitionWriteManager::ReserveFileState(ReservationLock &reservation_lock, const } } - if (op.hive_file_pattern) { + if (UsePerPartitionFileOffsets(op)) { if (reason == FileCreationReason::SORTED_RUN_BOUNDARY || reason == FileCreationReason::ROTATION) { ++previous_partitions[values]; } @@ -1842,7 +1954,7 @@ FileStateHandle PartitionWriteManager::TakeInactiveFileStateLocked(ActiveWriteIt D_ASSERT(entry->second->active_writes == 0); auto file_state = std::move(entry->second->file_state); - if (op.hive_file_pattern) { + if (UsePerPartitionFileOffsets(op)) { ++previous_partitions[entry->first]; } active_writes.erase(entry); @@ -2557,6 +2669,11 @@ PartitionedCopy::PartitionedCopy(const PhysicalCopyToFile &op_p, ClientContext & write_types.push_back(op.expected_types[col_idx]); } } + if (op.partition_path_expression) { + partition_path = op.partition_path_expression->Copy(); + } else if (op.hive_file_pattern) { + partition_path = CreateHivePartitionPath(context, op); + } } unique_ptr PartitionedCopy::ConstructSortStrategy() const { @@ -2989,18 +3106,24 @@ unique_ptr PartitionedCopy::ProjectToWriteColumns(unique_p // Partition File Request Builder //===--------------------------------------------------------------------===// optional PartitionFileRequestBuilder::Build() { + auto &op = partitioned_copy.op; + auto &context = partitioned_copy.context; + // built before locking and reserving, as evaluating the partition path can throw + auto directory = BuildDirectory(op.GetTrimmedPath(context, op.file_path)); + auto reservation_lock = partitioned_copy.partition_writes.LockForReservation(); annotated_lock_guard global_guard(partitioned_copy.copy_gstate.lock); if (file_state) { return nullopt; } + if (op.partition_path_expression) { + // claimed before reserving, which can take evicted file states that must not get lost when this throws + partitioned_copy.partition_writes.ClaimDirectory(reservation_lock, values, directory.relative_path); + } reservation = partitioned_copy.partition_writes.ReserveFileState(reservation_lock, values, reason); - auto &op = partitioned_copy.op; - auto &context = partitioned_copy.context; auto &fs = FileSystem::GetFileSystem(context); - auto directory = BuildDirectory(op.GetTrimmedPath(context, op.file_path)); auto full_path = op.filename_pattern.CreateFilename(fs, directory.path, op.file_extension, reservation.offset); auto pending_file_state_open = partitioned_copy.copy_gstate.CreatePartitionFileStateOpenLocked(file_state, std::move(full_path), values); @@ -3015,25 +3138,43 @@ vector PartitionFileRequestBuilder::TakeFilesToFinalize() { } PartitionDirectory PartitionFileRequestBuilder::BuildDirectory(string path) const { - auto &fs = FileSystem::GetFileSystem(partitioned_copy.context); PartitionDirectory result; result.path = std::move(path); - if (partitioned_copy.op.hive_file_pattern) { - for (idx_t i = 0; i < partitioned_copy.op.partition_columns.size(); i++) { - const auto &partition_col_name = partitioned_copy.op.names[partitioned_copy.op.partition_columns[i]]; - const auto &partition_value = values[i]; - string p_dir; - p_dir += HivePartitioning::Escape(partition_col_name.GetIdentifierName()); - p_dir += "="; - if (partition_value.IsNull()) { - p_dir += HivePartitioning::DEFAULT_PARTITION_NAME; - } else { - p_dir += HivePartitioning::EscapeValue(partition_value.ToString()); - } - result.path = fs.JoinPath(result.path, p_dir); - result.directories.push_back(result.path); + if (!partitioned_copy.partition_path) { + return result; + } + auto &context = partitioned_copy.context; + auto &fs = FileSystem::GetFileSystem(context); + auto partition_path = EvaluatePartitionPath(context, partitioned_copy.op, *partitioned_copy.partition_path, values); + // This is a relative path fragment, not a file to resolve through the VFS. Resolving it + // would require the local filesystem even when the COPY target is remote. + auto parsed_path = Path::FromString(partition_path); + if (parsed_path.IsAbsolute() || FileSystem::IsRemoteFile(partition_path)) { + throw InvalidInputException("PARTITION_PATH must be relative to the COPY target, but got \"%s\"", + partition_path); + } + auto separator = fs.PathSeparator(result.path); + if (!FileSystem::IsRemoteFile(result.path)) { + partition_path = fs.ConvertSeparators(partition_path); + } + vector components; + for (auto &component : StringUtil::Split(partition_path, separator)) { + if (component.empty() || component == ".") { + continue; } + if (component == "..") { + throw InvalidInputException("PARTITION_PATH cannot contain \"..\", but got \"%s\"", partition_path); + } + components.push_back(component); + result.path = fs.JoinPath(result.path, component); + result.directories.push_back(result.path); + } + if (components.empty()) { + // every partition needs a directory of its own + throw InvalidInputException("PARTITION_PATH evaluated to an empty path for partition %s", + PartitionValuesToString(partitioned_copy.op, values)); } + result.relative_path = StringUtil::Join(components, "/"); return result; } diff --git a/src/duckdb/src/execution/operator/persistent/physical_insert.cpp b/src/duckdb/src/execution/operator/persistent/physical_insert.cpp index a9d417bb3..c8c9c1635 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_insert.cpp @@ -802,6 +802,7 @@ SinkFinalizeType PhysicalInsert::Finalize(Pipeline &pipeline, Event &event, Clie current_rows += data_table.GetOptimisticCollection(context, collection_index).collection->GetTotalRows(); if (current_rows >= row_group_size) { mergers.push_back(std::move(current_merger)); + current_merger.reset(); current_rows = 0; } } @@ -821,31 +822,44 @@ SinkFinalizeType PhysicalInsert::Finalize(Pipeline &pipeline, Event &event, Clie //===--------------------------------------------------------------------===// class InsertSourceState : public GlobalSourceState { public: - explicit InsertSourceState(const PhysicalInsert &op) { + explicit InsertSourceState(const PhysicalInsert &op) : total_rows(1), rows_scanned(0) { if (op.return_chunk) { D_ASSERT(op.sink_state); auto &g = op.sink_state->Cast(); g.return_collection.InitializeScan(scan_state); + total_rows = g.return_collection.Count(); } } ColumnDataScanState scan_state; + idx_t total_rows; + atomic rows_scanned; }; unique_ptr PhysicalInsert::GetGlobalSourceState(ClientContext &context) const { return make_uniq(*this); } +ProgressData PhysicalInsert::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + ProgressData progress; + progress.total = double(MaxValue(state.total_rows, 1)); + progress.done = state.total_rows == 0 ? 1.0 : double(state.rows_scanned.load(std::memory_order_relaxed)); + return progress; +} + SourceResultType PhysicalInsert::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &state = input.global_state.Cast(); auto &insert_gstate = sink_state->Cast(); if (!return_chunk) { chunk.data[0].Append(Value::BIGINT(NumericCast(insert_gstate.insert_count))); + state.rows_scanned.store(1, std::memory_order_relaxed); return SourceResultType::FINISHED; } insert_gstate.return_collection.Scan(state.scan_state, chunk); + state.rows_scanned.fetch_add(chunk.size(), std::memory_order_relaxed); return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp b/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp index 94cfebe0a..3db3e3591 100644 --- a/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp +++ b/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp @@ -308,7 +308,7 @@ string PhysicalTableScan::GetFilterInfo(const TableFilterSet &filter_set) const for (auto &f : filter_set) { auto filter_idx = f.GetIndex(); auto &filter = f.Filter().Cast(); - if (filter_idx < names.size()) { + if (filter_idx < column_ids.size()) { if (!first_item) { filters_info += "\n"; } diff --git a/src/duckdb/src/execution/operator/schema/physical_attach.cpp b/src/duckdb/src/execution/operator/schema/physical_attach.cpp index 3925a74ab..2bfccae25 100644 --- a/src/duckdb/src/execution/operator/schema/physical_attach.cpp +++ b/src/duckdb/src/execution/operator/schema/physical_attach.cpp @@ -1,8 +1,12 @@ #include "duckdb/execution/operator/schema/physical_attach.hpp" #include "duckdb/catalog/catalog.hpp" +#include "duckdb/common/types/value.hpp" +#include "duckdb/execution/operator/helper/launch_external_resource.hpp" #include "duckdb/main/attached_database.hpp" +#include "duckdb/main/database.hpp" #include "duckdb/main/database_manager.hpp" +#include "duckdb/main/external_resources_manager.hpp" #include "duckdb/main/extension_helper.hpp" #include "duckdb/parser/parsed_data/attach_info.hpp" #include "duckdb/storage/storage_extension.hpp" @@ -15,27 +19,85 @@ namespace duckdb { //===--------------------------------------------------------------------===// SourceResultType PhysicalAttach::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { - // parse the options auto &config = DBConfig::GetConfig(context.client); - // construct the options - AttachOptions options(info->options, config.options.access_mode); - - // get the name and path of the database - auto &name = info->name; - auto &path = info->path; - // preserve the verbatim path before extension-prefix stripping - options.original_path = path; - if (options.db_type.empty()) { - DBPathAndType::ExtractExtensionPrefix(path, options.db_type); - } - if (name.empty()) { - auto &fs = FileSystem::GetFileSystem(context.client); - name = Identifier(AttachedDatabase::ExtractDatabaseName(path, fs)); + + // Attach mutates the info (name resolution, path prefix stripping) and the external-resource path + // writes the provisioned endpoint into it, so work on a copy and leave the plan-owned info pristine. + auto attach_info = info->Copy(); + + // `NEW TEMPORARY` provisions a resource this attachment OWNS: a deleter is bound and DETACH reaps it. + // A bare identifier BORROWS a registered one -- no deleter, and DETACH leaves it for DESTROY. + LaunchedResource launched; + string resource_type, resource_name, borrowed_resource_name; + bool owns_resource = false; + if (attach_info->external_resource) { + auto &external_resource = *attach_info->external_resource; + if (!external_resource.reference_name.empty()) { + auto instance = ExternalResourcesManager::Get(context.client).Lookup(external_resource.reference_name); + if (!instance) { + throw InvalidInputException("no external resource named \"%s\" is registered", + external_resource.reference_name); + } + // Resolve the current endpoint from the registered handle (status); bind no deleter. Record the + // borrow so DESTROY refuses while this attachment is still pointing at the resource. + launched = ProvisionExternalResource(context.client, instance->type, {}, instance->name, instance->handle); + borrowed_resource_name = instance->name; + } else { + resource_type = external_resource.provider; + // The scoped resource is anonymous; label its log entries with the database it backs. + resource_name = attach_info->name.GetIdentifierName(); + launched = ProvisionExternalResource(context.client, external_resource.provider, external_resource.params, + resource_name); + owns_resource = true; + } } - // check ATTACH IF NOT EXISTS - auto &db_manager = DatabaseManager::Get(context.client); - db_manager.AttachDatabase(context.client, *info, options); + // Applying the resource, parsing its options, deriving the name and the attach can all throw, and by + // now the resource exists with nothing owning it. One guard covers the lot; a narrower one strands it. + auto reap_if_owned = [&]() { + if (owns_resource) { + ResourceDeleter(DatabaseInstance::GetDatabase(context.client), launched.deleter_function, + launched.deleter_payload, resource_type, resource_name) + .TryDelete(); + } + }; + try { + if (attach_info->external_resource) { + ApplyLaunchedResource(launched, *attach_info); + } + + // construct the options + AttachOptions options(attach_info->options, config.options.access_mode); + if (owns_resource) { + options.deleter_function = launched.deleter_function; + options.deleter_payload = launched.deleter_payload; + options.deleter_resource_type = resource_type; + options.deleter_resource_name = resource_name; + } + options.borrowed_resource_name = borrowed_resource_name; + + // get the name and path of the database + auto &name = attach_info->name; + auto &path = attach_info->path; + // preserve the verbatim path before extension-prefix stripping + options.original_path = path; + if (options.db_type.empty()) { + DBPathAndType::ExtractExtensionPrefix(path, options.db_type); + } + if (name.empty()) { + auto &fs = FileSystem::GetFileSystem(context.client); + name = Identifier(AttachedDatabase::ExtractDatabaseName(path, fs)); + } + + // check ATTACH IF NOT EXISTS + auto &db_manager = DatabaseManager::Get(context.client); + db_manager.AttachDatabase(context.client, *attach_info, options); + } catch (...) { + // Compensating teardown (best-effort): a resource we just PROVISIONED has nothing owning it yet. + // A borrowed (referenced) resource is never torn down here. + reap_if_owned(); + throw; + } return SourceResultType::FINISHED; } diff --git a/src/duckdb/src/execution/operator/schema/physical_create_index.cpp b/src/duckdb/src/execution/operator/schema/physical_create_index.cpp index 7ee10a131..eae7df398 100644 --- a/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +++ b/src/duckdb/src/execution/operator/schema/physical_create_index.cpp @@ -161,30 +161,29 @@ SinkFinalizeType PhysicalCreateIndex::Finalize(Pipeline &pipeline, Event &event, D_ASSERT(index_entry); auto &index = index_entry->Cast(); index.initial_index_size = bound_index->GetInMemorySize(); + storage.AddIndex(std::move(bound_index), index.oid); + return SinkFinalizeType::READY; + } - } else { - // Ensure that there are no other indexes with that name on this table. - const auto &indexes = storage.GetDataTableInfo()->GetIndexes(); - if (indexes.Contains(info->GetIndexName())) { - throw CatalogException("an index with that name already exists for this table: %s", - SQLIdentifier(info->GetIndexName())); - } + // Ensure that there are no other indexes with that name on this table. + const auto &indexes = storage.GetDataTableInfo()->GetIndexes(); + if (indexes.Contains(info->GetIndexName())) { + throw CatalogException("an index with that name already exists for this table: %s", + SQLIdentifier(info->GetIndexName())); + } - // PRIMARY KEY columns cannot be NULL. - if (info->constraint_type == IndexConstraintType::PRIMARY) { - auto &local_storage = LocalStorage::Get(context, storage.db); - for (const auto &column_id : storage_ids) { - BoundNotNullConstraint not_null {PhysicalIndex(column_id)}; - local_storage.VerifyNewConstraint(storage, not_null); - } + // PRIMARY KEY columns cannot be NULL. + if (info->constraint_type == IndexConstraintType::PRIMARY) { + auto &local_storage = LocalStorage::Get(context, storage.db); + for (const auto &column_id : storage_ids) { + BoundNotNullConstraint not_null {PhysicalIndex(column_id)}; + local_storage.VerifyNewConstraint(storage, not_null); } - - auto &catalog = Catalog::GetCatalog(context, info->GetQualifiedName().Catalog()); - catalog.Alter(context, *alter_table_info); } - // Add the index to the storage. - storage.AddIndex(std::move(bound_index)); + auto &catalog = Catalog::GetCatalog(context, info->GetQualifiedName().Catalog()); + catalog.Alter(context, *alter_table_info); + storage.AddConstraintIndex(std::move(bound_index)); return SinkFinalizeType::READY; } diff --git a/src/duckdb/src/execution/operator/set/physical_cte.cpp b/src/duckdb/src/execution/operator/set/physical_cte.cpp index 8173b1362..229b6058d 100644 --- a/src/duckdb/src/execution/operator/set/physical_cte.cpp +++ b/src/duckdb/src/execution/operator/set/physical_cte.cpp @@ -607,9 +607,9 @@ ProgressData PhysicalCTE::GetSinkProgress(ClientContext &context, GlobalSinkStat return ProgressData {0, 1, true}; } auto count = double(state.ordered_data ? state.ordered_data->Count() : state.working_table_ref->Count()); - ProgressData progress; - progress.done = count; - progress.total = count + source_progress.total; + auto progress = source_progress; + progress.done += count; + progress.total += count; return progress; } diff --git a/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp b/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp index 7005c4e41..07ee46352 100644 --- a/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +++ b/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp @@ -56,7 +56,7 @@ PerfectAggregateHashTable::PerfectAggregateHashTable(ClientContext &context, All RowOperations::InitializeStates(*layout_ptr, addresses, *FlatVector::IncrementalSelectionVector(), init_count); } -PerfectAggregateHashTable::~PerfectAggregateHashTable() { +PerfectAggregateHashTable::~PerfectAggregateHashTable() { // NOLINT(bugprone-exception-escape) Destroy(); } diff --git a/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp b/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp index 15201e54e..ce5746864 100644 --- a/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp +++ b/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp @@ -84,6 +84,7 @@ PhysicalOperator &PhysicalPlanGenerator::CreatePlan(LogicalCopyToFile &op) { cast_copy.write_empty_file = op.write_empty_file; cast_copy.hive_file_pattern = op.hive_file_pattern; cast_copy.order_columns = std::move(op.order_columns); + cast_copy.partition_path_expression = std::move(op.partition_path_expression); cast_copy.children.push_back(plan); return copy; diff --git a/src/duckdb/src/execution/sample/reservoir_sample.cpp b/src/duckdb/src/execution/sample/reservoir_sample.cpp index a3fd1f013..b47fbd8b4 100644 --- a/src/duckdb/src/execution/sample/reservoir_sample.cpp +++ b/src/duckdb/src/execution/sample/reservoir_sample.cpp @@ -899,6 +899,15 @@ unique_ptr ReservoirSamplePercentage::GetChunk() { return nullptr; } +idx_t ReservoirSamplePercentage::GetActiveSampleCount() const { + D_ASSERT(is_finalized); + idx_t count = 0; + for (auto &sample : finished_samples) { + count += sample->GetActiveSampleCount(); + } + return count; +} + unique_ptr ReservoirSamplePercentage::Copy() const { throw InternalException("Cannot call Copy on ReservoirSample Percentage"); } diff --git a/src/duckdb/src/function/aggregate/distributive/count.cpp b/src/duckdb/src/function/aggregate/distributive/count.cpp index 2e52552ae..69360d5aa 100644 --- a/src/duckdb/src/function/aggregate/distributive/count.cpp +++ b/src/duckdb/src/function/aggregate/distributive/count.cpp @@ -149,10 +149,10 @@ struct CountFunction : public BaseCountFunction { static void CountClusteredRuns(const ClusteredAggr &cs, const ValidityMask &validity, INDEXER indexer) { const bool all_valid = !validity.CanHaveNull(); idx_t pos = 0; - for (idx_t r = 0; r < cs.n_group_runs; r++) { - auto &state = *reinterpret_cast(cs.group_runs[r].state); - const auto *run_sel = cs.group_runs[r].sel; - const auto run_count = cs.group_runs[r].count; + for (auto &run : cs.runs()) { + auto &state = *reinterpret_cast(run.state); + const auto *run_sel = run.sel; + const auto run_count = run.count; if (all_valid) { state += UnsafeNumericCast(run_count); } else { @@ -200,13 +200,13 @@ struct CountFunction : public BaseCountFunction { if (ConstantVector::IsNull(inputs[0])) { return; } - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); - state += UnsafeNumericCast(clustered.group_runs[r].count); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); + state += UnsafeNumericCast(run.count); } return; } - auto *cluster_iter = clustered.ClusterIter(inputs[0], count); + auto *cluster_iter = clustered.ClusterIter(inputs[0]); if (cluster_iter) { CountClusteredDict(inputs[0], clustered, count, cluster_iter); return; @@ -221,7 +221,7 @@ struct CountFunction : public BaseCountFunction { // pre-composes the dict sel once for the whole chunk. if (aggr_input_data.clustered) { auto &cs = *aggr_input_data.clustered; - auto *cluster_iter = cs.ClusterIter(inputs[0], count); + auto *cluster_iter = cs.ClusterIter(inputs[0]); if (cluster_iter) { CountClusteredDict(inputs[0], cs, count, cluster_iter); return; diff --git a/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp b/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp index 46d7d11e2..f4181593b 100644 --- a/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp +++ b/src/duckdb/src/function/aggregate/distributive/first_last_any.cpp @@ -86,24 +86,25 @@ struct FirstStringStateBase { bool value_is_valid; //! Whether the state has been set (i.e. we have seen a row) bool is_set; - //! The size of the arena allocation for a non-inlined string value - not part of the exported state - uint32_t alloc_size; + //! The size of the arena allocation for a non-inlined string value - not part of the exported state. + //! Must be wide enough for NextPowerOfTwo(MAX_STRING_SIZE), which does not fit in a uint32_t. + idx_t alloc_size; void Assign(string_t input, AggregateInputData &input_data) { if (input.IsInlined()) { value = input; alloc_size = 0; } else { - auto len = UnsafeNumericCast(input.GetSize()); + auto len = input.GetSize(); char *ptr; if (alloc_size >= len) { ptr = value.GetDataWriteable(); } else { - alloc_size = UnsafeNumericCast(NextPowerOfTwo(len)); + alloc_size = NextPowerOfTwo(len); ptr = char_ptr_cast(input_data.allocator.Allocate(alloc_size)); } memcpy(ptr, input.GetData(), len); - value = string_t(ptr, len); + value = string_t(ptr, UnsafeNumericCast(len)); } } }; @@ -384,10 +385,10 @@ void FirstFunctionClusterUpdate(Vector inputs[], AggregateInputData &aggregate_i inputs[0].ToUnifiedFormat(idata); auto input_data = UnifiedVectorFormat::GetData(idata); AggregateUnaryInput unary_input(aggregate_input_data, idata.validity); - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast *>(clustered.group_runs[r].state); - const auto *run_sel = clustered.group_runs[r].sel; - const auto run_count = clustered.group_runs[r].count; + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast *>(run.state); + const auto *run_sel = run.sel; + const auto run_count = run.count; FirstFunction::template ClusteredOp, FirstFunction>( state, input_data, unary_input, run_sel, *idata.sel, idata.validity, 0, run_count); } diff --git a/src/duckdb/src/function/aggregate/distributive/minmax.cpp b/src/duckdb/src/function/aggregate/distributive/minmax.cpp index 8d24996a9..ae8c2664b 100644 --- a/src/duckdb/src/function/aggregate/distributive/minmax.cpp +++ b/src/duckdb/src/function/aggregate/distributive/minmax.cpp @@ -156,23 +156,24 @@ using MaxOperation = NumericMinMaxBase; struct BaseMinMaxStringState { string_t value; bool is_set; - uint32_t alloc_size; + //! Must be wide enough for NextPowerOfTwo(MAX_STRING_SIZE), which does not fit in a uint32_t + idx_t alloc_size; void Assign(string_t input, AggregateInputData &input_data) { if (input.IsInlined()) { value = input; alloc_size = 0; } else { - auto len = UnsafeNumericCast(input.GetSize()); + auto len = input.GetSize(); char *ptr; if (alloc_size >= len) { ptr = value.GetDataWriteable(); } else { - alloc_size = UnsafeNumericCast(NextPowerOfTwo(len)); + alloc_size = NextPowerOfTwo(len); ptr = char_ptr_cast(input_data.allocator.Allocate(alloc_size)); } memcpy(ptr, input.GetData(), len); - value = string_t(ptr, len); + value = string_t(ptr, UnsafeNumericCast(len)); } } }; diff --git a/src/duckdb/src/function/aggregate_function.cpp b/src/duckdb/src/function/aggregate_function.cpp index 24fd34ee2..a24b2fe41 100644 --- a/src/duckdb/src/function/aggregate_function.cpp +++ b/src/duckdb/src/function/aggregate_function.cpp @@ -114,9 +114,7 @@ BoundAggregateFunction::BoundAggregateFunction(const AggregateFunction &function BoundAggregateFunction::BoundAggregateFunction(shared_ptr function_p) : definition(std::move(function_p)) { auto &function = *definition; - name = function.name; - schema_name = function.GetSchemaName(); - catalog_name = function.GetCatalogName(); + qualified_name = function.GetQualifiedName(); extra_info = function.extra_info; return_type = function.GetReturnType(); properties = function.GetProperties(); @@ -147,13 +145,12 @@ void BoundAggregateFunction::ReplaceImplementation(const BoundAggregateFunction } void BoundAggregateFunction::ReplaceImplementation(const AggregateFunction &function) { - this->name = function.name; + SetName(function.GetName()); // The replacement is a specialized implementation of the function we were bound from, and is usually built by // a factory rather than handed out by a catalog entry. Only take its qualification when it has one, so that // specializing an implementation does not drop the catalog and schema name of the definition. if (!function.GetCatalogName().empty() || !function.GetSchemaName().empty()) { - this->schema_name = function.GetSchemaName(); - this->catalog_name = function.GetCatalogName(); + qualified_name = function.GetQualifiedName(); } this->return_type = function.GetReturnType(); this->properties = function.GetProperties(); diff --git a/src/duckdb/src/function/cast/cast_statistics.cpp b/src/duckdb/src/function/cast/cast_statistics.cpp index ed8ad55e9..b382f1633 100644 --- a/src/duckdb/src/function/cast/cast_statistics.cpp +++ b/src/duckdb/src/function/cast/cast_statistics.cpp @@ -165,12 +165,18 @@ static unique_ptr StatisticsPropagateVariant(const BaseStatistic } // extract the typed stats auto &typed_stats = VariantStats::GetTypedStats(shredded_stats); + unique_ptr result; if (structured_type == target) { // type matches - return stats directly - return typed_stats.ToUnique(); + result = typed_stats.ToUnique(); + } else { + // typed stats don't match - try to cast + result = CastStatistics::TryPropagate(typed_stats, structured_type, target); } - // typed stats don't match - try to cast - return CastStatistics::TryPropagate(typed_stats, structured_type, target); + if (result && input.CanHaveNull()) { + result->SetHasNull(); + } + return result; } static unique_ptr StatisticsPropagateArrayToList(const BaseStatistics &input, const LogicalType &source, diff --git a/src/duckdb/src/function/cast/enum_casts.cpp b/src/duckdb/src/function/cast/enum_casts.cpp index 25a682d2f..18bdfc523 100644 --- a/src/duckdb/src/function/cast/enum_casts.cpp +++ b/src/duckdb/src/function/cast/enum_casts.cpp @@ -103,13 +103,14 @@ static bool EnumToAnyCast(Vector &source, Vector &result, idx_t count, CastParam // cast to varchar CastParameters to_varchar_params(parameters, cast_data.to_varchar_cast.GetCastData(), lstate.to_varchar_local); - cast_data.to_varchar_cast.Cast(source, varchar_cast, count, to_varchar_params); + if (!cast_data.to_varchar_cast.Cast(source, varchar_cast, count, to_varchar_params)) { + return false; + } // cast from varchar to the target CastParameters from_varchar_params(parameters, cast_data.from_varchar_cast.GetCastData(), lstate.from_varchar_local); - cast_data.from_varchar_cast.Cast(varchar_cast, result, count, from_varchar_params); - return true; + return cast_data.from_varchar_cast.Cast(varchar_cast, result, count, from_varchar_params); } BoundCastInfo DefaultCasts::EnumCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target) { diff --git a/src/duckdb/src/function/cast/variant/from_variant.cpp b/src/duckdb/src/function/cast/variant/from_variant.cpp index 5358b92ba..c6f366b1b 100644 --- a/src/duckdb/src/function/cast/variant/from_variant.cpp +++ b/src/duckdb/src/function/cast/variant/from_variant.cpp @@ -12,6 +12,7 @@ #include "duckdb/common/serializer/varint.hpp" #include "yyjson.hpp" +#include "duckdb/common/algorithm.hpp" #include "duckdb/common/enum_util.hpp" #include "duckdb/common/exception/conversion_exception.hpp" @@ -434,6 +435,7 @@ static bool ConvertVariantToStruct(FromVariantConversionData &conversion_data, V auto row_index = row.IsValid() ? row.GetIndex() : nested_index.GetIndex(); auto object_keys = VariantUtils::GetObjectKeys(conversion_data.variant, row_index, child_data[nested_index.GetIndex()]); + std::sort(object_keys.begin(), object_keys.end()); conversion_data.error = StringUtil::Format("VARIANT(OBJECT(%s)) is missing key '%s'", StringUtil::Join(object_keys, ","), component.key); return false; @@ -517,9 +519,16 @@ static bool CastVariantToJSON(FromVariantConversionData &conversion_data, Vector ConvertedJSONHolder holder(Allocator::DefaultAllocator()); + auto &variant = conversion_data.variant; auto result_data = FlatVector::Writer(result, count, offset); for (idx_t i = 0; i < count; i++) { const auto row_index = row.IsValid() ? row.GetIndex() : i; + if (!variant.RowIsValid(row_index)) { + // a SQL NULL row stays a SQL NULL - rendering it as the JSON token `null` would make it + // indistinguishable from a JSON null actually stored in the variant + result_data.WriteNull(); + continue; + } const auto json_val = VariantCasts::ConvertVariantToJSON(holder.GetDocument(), conversion_data.variant, row_index, sel[i]); if (!json_val) { @@ -784,9 +793,10 @@ static bool TryFromShreddedCast(Vector &variant_vec, Vector &result) { if (ShreddedVector::IsFullyShredded(variant_vec) && shredded_vec.GetType().id() == LogicalTypeId::STRUCT) { // it is! check if the type of the typed_value entry matches auto &shredded_entries = StructVector::GetEntries(shredded_vec); - if (shredded_entries[1].GetType() == result.GetType()) { + auto &typed_value = shredded_entries[VariantStats::TYPED_VALUE_INDEX]; + if (typed_value.GetType() == result.GetType()) { // the typed_value matches - directly reference it - result.Reference(shredded_entries[1]); + result.Reference(typed_value); return true; } } diff --git a/src/duckdb/src/function/function.cpp b/src/duckdb/src/function/function.cpp index 6e84d4228..8cdb4addb 100644 --- a/src/duckdb/src/function/function.cpp +++ b/src/duckdb/src/function/function.cpp @@ -210,7 +210,8 @@ hash_t BoundSimpleFunction::Hash() const { } string BoundSimpleFunction::ToString() const { - return Function::CallToString(catalog_name, schema_name, name, arguments, LogicalTypeId::INVALID, return_type); + return Function::CallToString(GetCatalogName(), GetSchemaName(), GetName(), arguments, LogicalTypeId::INVALID, + return_type); } bool FunctionParameter::operator==(const FunctionParameter &other) const { diff --git a/src/duckdb/src/function/function_binder.cpp b/src/duckdb/src/function/function_binder.cpp index aa18d03d2..d61de650f 100644 --- a/src/duckdb/src/function/function_binder.cpp +++ b/src/duckdb/src/function/function_binder.cpp @@ -1306,6 +1306,8 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, vec } ResolveTemplateTypes(bound_function, children); + auto logical_arguments = CaptureLogicalArguments(bound_function, children); + auto argument_types = bound_function.GetArguments(); unique_ptr bind_info; @@ -1317,6 +1319,13 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, vec } CheckTemplateTypesResolved(bound_function); + for (idx_t i = 0; i < argument_types.size() && i < bound_function.GetArguments().size(); i++) { + if (!argument_types[i].IsComplete() && bound_function.GetArguments()[i].IsComplete()) { + logical_arguments[i] = bound_function.GetArguments()[i]; + } + } + bound_function.SetLogicalArguments(std::move(logical_arguments)); + bound_function.SetLogicalReturnType(bound_function.GetReturnType()); // check if we need to add casts to the children CastToFunctionArguments(bound_function, children); diff --git a/src/duckdb/src/function/function_list.cpp b/src/duckdb/src/function/function_list.cpp index b477a26be..57660084c 100644 --- a/src/duckdb/src/function/function_list.cpp +++ b/src/duckdb/src/function/function_list.cpp @@ -114,6 +114,7 @@ static const StaticFunctionDefinition function[] = { DUCKDB_SCALAR_FUNCTION(InternalCompressStringUintegerFun), DUCKDB_SCALAR_FUNCTION(InternalCompressStringUsmallintFun), DUCKDB_SCALAR_FUNCTION(InternalCompressStringUtinyintFun), + DUCKDB_SCALAR_FUNCTION(InternalCompressedMaterializationCastFun), DUCKDB_SCALAR_FUNCTION(InternalDecompressGeometryPointFun), DUCKDB_SCALAR_FUNCTION_SET(InternalDecompressIntegralBigintFun), DUCKDB_SCALAR_FUNCTION_SET(InternalDecompressIntegralHugeintFun), @@ -173,6 +174,7 @@ static const StaticFunctionDefinition function[] = { DUCKDB_AGGREGATE_FUNCTION_SET(FirstFun), DUCKDB_WINDOW_FUNCTION(FirstValueFun), DUCKDB_SCALAR_FUNCTION(GetVariableFun), + DUCKDB_SCALAR_FUNCTION(HivePartitionComponentFun), DUCKDB_SCALAR_FUNCTION(IlikeEscapeFun), DUCKDB_SCALAR_FUNCTION(InvokeFun), DUCKDB_WINDOW_FUNCTION(LagFun), diff --git a/src/duckdb/src/function/scalar/comparison/between.cpp b/src/duckdb/src/function/scalar/comparison/between.cpp index e8aa8b0cf..f1fc5b657 100644 --- a/src/duckdb/src/function/scalar/comparison/between.cpp +++ b/src/duckdb/src/function/scalar/comparison/between.cpp @@ -12,8 +12,7 @@ namespace duckdb { struct BetweenFunctionData : public FunctionData { BetweenFunctionData(bool lower_inclusive, bool upper_inclusive) - : FunctionData(InternalKind::BOUND_BETWEEN), lower_inclusive(lower_inclusive), - upper_inclusive(upper_inclusive) { + : lower_inclusive(lower_inclusive), upper_inclusive(upper_inclusive) { } bool lower_inclusive; @@ -244,8 +243,7 @@ bool BoundBetweenExpression::UpperInclusive(const BoundFunctionExpression &betwe } bool BoundBetweenExpression::HasValidBindData(const BoundFunctionExpression &between_expr) { - return between_expr.BindInfo() && - between_expr.BindInfo()->GetInternalKind() == FunctionData::InternalKind::BOUND_BETWEEN; + return between_expr.BindInfo() != nullptr; } const Expression &BoundBetweenExpression::Input(const BoundFunctionExpression &between_expr) { diff --git a/src/duckdb/src/function/scalar/compressed_materialization/compress_geometry.cpp b/src/duckdb/src/function/scalar/compressed_materialization/compress_geometry.cpp index accdfa082..ca258058e 100644 --- a/src/duckdb/src/function/scalar/compressed_materialization/compress_geometry.cpp +++ b/src/duckdb/src/function/scalar/compressed_materialization/compress_geometry.cpp @@ -133,4 +133,14 @@ ScalarFunction InternalDecompressGeometryPointFun::GetFunction() { return CMGeometryPointDecompressFun::GetFunction(); } +CMExpressionType CMUtils::GetGeometryType(const BoundScalarFunction &function) { + if (function.GetDeserializeCallback() == CMGeometryPointCompressDeserialize) { + return CMExpressionType::COMPRESS; + } + if (function.GetDeserializeCallback() == CMGeometryPointDecompressDeserialize) { + return CMExpressionType::DECOMPRESS; + } + return CMExpressionType::NONE; +} + } // namespace duckdb diff --git a/src/duckdb/src/function/scalar/compressed_materialization/compress_integral.cpp b/src/duckdb/src/function/scalar/compressed_materialization/compress_integral.cpp index 8083edeb8..05806a431 100644 --- a/src/duckdb/src/function/scalar/compressed_materialization/compress_integral.cpp +++ b/src/duckdb/src/function/scalar/compressed_materialization/compress_integral.cpp @@ -297,4 +297,14 @@ ScalarFunctionSet InternalDecompressIntegralUhugeintFun::GetFunctions() { return GetIntegralDecompressFunctionSet(LogicalType(LogicalTypeId::UHUGEINT)); } +CMExpressionType CMUtils::GetIntegralType(const BoundScalarFunction &function) { + if (function.GetDeserializeCallback() == CMIntegralDeserialize) { + return CMExpressionType::COMPRESS; + } + if (function.GetDeserializeCallback() == CMIntegralDeserialize) { + return CMExpressionType::DECOMPRESS; + } + return CMExpressionType::NONE; +} + } // namespace duckdb diff --git a/src/duckdb/src/function/scalar/compressed_materialization/compress_string.cpp b/src/duckdb/src/function/scalar/compressed_materialization/compress_string.cpp index b2e66cf77..e428d5f7b 100644 --- a/src/duckdb/src/function/scalar/compressed_materialization/compress_string.cpp +++ b/src/duckdb/src/function/scalar/compressed_materialization/compress_string.cpp @@ -298,4 +298,14 @@ ScalarFunctionSet InternalDecompressStringFun::GetFunctions() { return GetStringDecompressFunctionSet(); } +CMExpressionType CMUtils::GetStringType(const BoundScalarFunction &function) { + if (function.GetDeserializeCallback() == CMStringCompressDeserialize) { + return CMExpressionType::COMPRESS; + } + if (function.GetDeserializeCallback() == CMStringDecompressDeserialize) { + return CMExpressionType::DECOMPRESS; + } + return CMExpressionType::NONE; +} + } // namespace duckdb diff --git a/src/duckdb/src/function/scalar/compressed_materialization_utils.cpp b/src/duckdb/src/function/scalar/compressed_materialization_utils.cpp index c8aa67eb1..2320279d7 100644 --- a/src/duckdb/src/function/scalar/compressed_materialization_utils.cpp +++ b/src/duckdb/src/function/scalar/compressed_materialization_utils.cpp @@ -1,7 +1,47 @@ #include "duckdb/function/scalar/compressed_materialization_utils.hpp" +#include "duckdb/function/scalar/compressed_materialization_functions.hpp" +#include "duckdb/function/scalar/operator_functions.hpp" +#include "duckdb/planner/expression/bound_cast_expression.hpp" +#include "duckdb/planner/expression/bound_function_expression.hpp" namespace duckdb { +ScalarFunction InternalCompressedMaterializationCastFun::GetFunction() { + auto function = CastFun::GetFunction(); + function.SetQualifiedName(QualifiedName("system", "main", Name)); + function.SetBindCallback(CMUtils::Bind); + return function; +} + +void CMUtils::MarkCast(BoundFunctionExpression &expression) { + D_ASSERT(BoundCastExpression::IsCast(expression)); + D_ASSERT(BoundCastExpression::IsDefaultCast(expression)); + auto definition = make_shared_ptr(InternalCompressedMaterializationCastFun::GetFunction()); + auto &function = expression.FunctionMutable(); + function.SetName(definition->GetName()); + function.SetBindCallback(CMUtils::Bind); + function.SetDefinition(std::move(definition)); +} + +CMExpressionType CMUtils::GetExpressionType(const BoundFunctionExpression &expression) { + auto &function = expression.Function(); + if (function.GetBindCallback() != Bind) { + return CMExpressionType::NONE; + } + if (function.GetName() == InternalCompressedMaterializationCastFun::Name && + function.GetDeserializeCallback() == CastFun::GetFunction().GetDeserializeCallback()) { + return CMExpressionType::CAST; + } + auto type = GetIntegralType(function); + if (type == CMExpressionType::NONE) { + type = GetStringType(function); + } + if (type == CMExpressionType::NONE) { + type = GetGeometryType(function); + } + return type; +} + const vector CMUtils::IntegralTypes() { return {LogicalType::UTINYINT, LogicalType::USMALLINT, LogicalType::UINTEGER, LogicalType::UBIGINT}; } diff --git a/src/duckdb/src/function/scalar/create_sort_key.cpp b/src/duckdb/src/function/scalar/create_sort_key.cpp index d97a81ba2..d875797ea 100644 --- a/src/duckdb/src/function/scalar/create_sort_key.cpp +++ b/src/duckdb/src/function/scalar/create_sort_key.cpp @@ -17,6 +17,7 @@ #include "duckdb/planner/expression/bound_function_expression.hpp" #include "duckdb/planner/expression_binder.hpp" #include "duckdb/parser/parser.hpp" +#include "duckdb/main/client_context.hpp" namespace duckdb { @@ -37,6 +38,30 @@ struct SortKeyBindData : public FunctionData { } }; +static void AccumulateSortKeyWidth(const LogicalType &type, bool &all_constant, idx_t &constant_size) { + const auto physical_type = type.InternalType(); + if (!TypeIsConstantSize(physical_type)) { + all_constant = false; + return; + } + // we always add one byte for the validity + constant_size += GetTypeIdSize(physical_type) + 1; +} + +static void VerifyDecodeSortKeyType(const LogicalType &sort_key_type, bool all_constant, idx_t constant_size) { + if (sort_key_type == LogicalType::BIGINT) { + if (!all_constant || constant_size > sizeof(int64_t)) { + throw BinderException("sort_key has type BIGINT but arguments require BLOB"); + } + } else if (sort_key_type == LogicalType::BLOB) { + if (all_constant && constant_size <= sizeof(int64_t)) { + throw BinderException("sort_key has type BLOB but arguments require BIGINT"); + } + } else { + throw BinderException("sort_key must be either BIGINT or BLOB, got %s instead", sort_key_type.ToString()); + } +} + unique_ptr CreateSortKeyBind(BindScalarFunctionInput &input) { auto &arguments = input.GetArguments(); auto &function = input.GetBoundFunction(); @@ -55,13 +80,7 @@ unique_ptr CreateSortKeyBind(BindScalarFunctionInput &input) { bool all_constant = true; idx_t constant_size = 0; for (idx_t i = 0; i < arguments.size(); i += 2) { - auto physical_type = arguments[i]->GetReturnType().InternalType(); - if (!TypeIsConstantSize(physical_type)) { - all_constant = false; - } else { - // we always add one byte for the validity - constant_size += GetTypeIdSize(physical_type) + 1; - } + AccumulateSortKeyWidth(arguments[i]->GetReturnType(), all_constant, constant_size); } if (all_constant) { if (constant_size <= sizeof(int64_t)) { @@ -1028,22 +1047,20 @@ unique_ptr DecodeSortKeyBind(BindScalarFunctionInput &input) { for (idx_t i = 1; i < arguments.size(); i += 2) { // Parse column definition Value col = input.GetConstant(i); - const auto col_list = Parser::ParseColumnList(col.ToString()); + const auto col_list = Parser::ParseColumnList(col.ToString(), context.GetParserOptions()); if (col_list.LogicalColumnCount() != 1) { throw BinderException("decode_sort_key col must contain exactly one column"); } const auto &col_def = col_list.GetColumn(PhysicalIndex(0)); const auto &col_name = col_def.GetName(); - const auto &col_type = TransformStringToLogicalType(col_def.GetType().ToString(), context); + auto col_type = col_def.GetType(); + if (col_type.IsUnbound()) { + // Resolve the parsed type against the catalog. + col_type = TransformStringToLogicalType(col_type.ToString(), context); + } // Keep track of this to validate the arguments - const auto physical_type = col_type.InternalType(); - if (!TypeIsConstantSize(physical_type)) { - all_constant = false; - } else { - // we always add one byte for the validity - constant_size += GetTypeIdSize(physical_type) + 1; - } + AccumulateSortKeyWidth(col_type, all_constant, constant_size); // Add name/type to create a struct children.emplace_back(col_name, col_type); @@ -1054,19 +1071,7 @@ unique_ptr DecodeSortKeyBind(BindScalarFunctionInput &input) { result->modifiers.push_back(OrderModifiers::Parse(sort_specifier_str)); } - const auto &sort_key_arg = *arguments[0]; - if (sort_key_arg.GetReturnType() == LogicalType::BIGINT) { - if (!all_constant || constant_size > sizeof(int64_t)) { - throw BinderException("sort_key has type BIGINT but arguments require BLOB"); - } - } else if (sort_key_arg.GetReturnType() == LogicalType::BLOB) { - if (all_constant && constant_size <= sizeof(int64_t)) { - throw BinderException("sort_key has type BLOB but arguments require BIGINT"); - } - } else { - throw BinderException("sort_key must be either BIGINT or BLOB, got %s instead", - sort_key_arg.GetReturnType().ToString()); - } + VerifyDecodeSortKeyType(arguments[0]->GetReturnType(), all_constant, constant_size); function.SetReturnType(LogicalType::STRUCT(std::move(children))); return std::move(result); @@ -1484,11 +1489,33 @@ static void DecodeSortKeyFunction(DataChunk &args, ExpressionState &state, Vecto ScalarFunction CreateSortKeyFun::GetFunction() { ScalarFunction sort_key_function("create_sort_key", {LogicalType::ANY}, LogicalType::BLOB, CreateSortKeyFunction, CreateSortKeyBind); + sort_key_function.GetSignature().GetParameter(0).SetName("key1"); sort_key_function.SetVarArgs(LogicalType::ANY); sort_key_function.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return sort_key_function; } +unique_ptr DecodeSortKeyFun::Bind(unique_ptr sort_key, child_list_t columns, + vector modifiers) { + D_ASSERT(columns.size() == modifiers.size()); + bool all_constant = true; + idx_t constant_size = 0; + for (auto &column : columns) { + AccumulateSortKeyWidth(column.second, all_constant, constant_size); + } + VerifyDecodeSortKeyType(sort_key->GetReturnType(), all_constant, constant_size); + + auto bind_data = make_uniq(); + bind_data->modifiers = std::move(modifiers); + bind_data->all_constant = all_constant; + ScalarFunction definition("decode_sort_key", {sort_key->GetReturnType()}, LogicalType::STRUCT(std::move(columns)), + DecodeSortKeyFunction); + BoundScalarFunction function(definition); + vector> children; + children.push_back(std::move(sort_key)); + return make_uniq(std::move(function), std::move(children), std::move(bind_data)); +} + ScalarFunction DecodeSortKeyFun::GetFunction() { ScalarFunction sort_key_function( "decode_sort_key", diff --git a/src/duckdb/src/function/scalar/generic/invoke.cpp b/src/duckdb/src/function/scalar/generic/invoke.cpp index 86b873036..2c13ca3d4 100644 --- a/src/duckdb/src/function/scalar/generic/invoke.cpp +++ b/src/duckdb/src/function/scalar/generic/invoke.cpp @@ -9,6 +9,15 @@ namespace duckdb { namespace { +static void PropagateLambdaProperties(BoundScalarFunction &function, const Expression &lambda_expr) { + if (lambda_expr.IsVolatile()) { + function.SetVolatile(); + } + if (lambda_expr.CanThrow()) { + function.SetFallible(); + } +} + struct LambdaInvokeData final : public LambdaFunctionData { unique_ptr lambda_expr; @@ -33,9 +42,13 @@ struct LambdaInvokeData final : public LambdaFunctionData { } //! Deserializes a lambda function's bind data - static unique_ptr Deserialize(Deserializer &deserializer, BoundScalarFunction &) { + static unique_ptr Deserialize(Deserializer &deserializer, BoundScalarFunction &function) { auto lambda_expr = deserializer.ReadPropertyWithExplicitDefault>( 101, "lambda_expr", unique_ptr()); + if (lambda_expr) { + auto &bound_lambda_expr = lambda_expr->Cast(); + PropagateLambdaProperties(function, *bound_lambda_expr.LambdaExpr()); + } return make_uniq(std::move(lambda_expr)); } @@ -117,6 +130,7 @@ unique_ptr LambdaInvokeBind(BindScalarFunctionInput &input) { } bound_function.SetReturnType(bound_lambda_expr.LambdaExpr()->GetReturnType()); + PropagateLambdaProperties(bound_function, *bound_lambda_expr.LambdaExpr()); return make_uniq(bound_lambda_expr.Copy()); } diff --git a/src/duckdb/src/function/scalar/list/list_extract.cpp b/src/duckdb/src/function/scalar/list/list_extract.cpp index 42be1683b..5c7910077 100644 --- a/src/duckdb/src/function/scalar/list/list_extract.cpp +++ b/src/duckdb/src/function/scalar/list/list_extract.cpp @@ -176,6 +176,9 @@ ScalarFunctionSet ListExtractFun::GetFunctions() { ScalarFunction sfun({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR, ListExtractFunction, StringExtractBind); + sfun.GetSignature().GetParameter(0).SetName("string"); + sfun.GetSignature().GetParameter(1).SetName("index"); + lfun.SetFallible(); list_extract_set.AddFunction(lfun); list_extract_set.AddFunction(sfun); diff --git a/src/duckdb/src/function/scalar/operator/arithmetic.cpp b/src/duckdb/src/function/scalar/operator/arithmetic.cpp index 86be9a6d2..823622c94 100644 --- a/src/duckdb/src/function/scalar/operator/arithmetic.cpp +++ b/src/duckdb/src/function/scalar/operator/arithmetic.cpp @@ -1165,7 +1165,7 @@ namespace { [[noreturn]] void ThrowDivisionByZero(const Expression &expr) { throw InvalidInputException("Division by zero in expression %s. Use TRY(...) to return NULL for this expression, " - "or SET null_on_division_by_zero=true to return NULL for all divisions by zero.", + "or SET error_on_division_by_zero=false to return NULL for all divisions by zero.", expr.ToString()); } @@ -1285,7 +1285,7 @@ template unique_ptr BindDivisionByZero(BindScalarFunctionInput &input) { auto &context = input.GetClientContext(); auto &bound_function = input.GetBoundFunction(); - auto null_on_zero = Settings::Get(context); + auto null_on_zero = !Settings::Get(context); bound_function.SetFunctionCallback( GetBinaryFunctionZeroCheck(bound_function.GetReturnType().InternalType(), null_on_zero)); return nullptr; @@ -1294,7 +1294,7 @@ unique_ptr BindDivisionByZero(BindScalarFunctionInput &input) { unique_ptr BindIntervalDivide(BindScalarFunctionInput &input) { auto &context = input.GetClientContext(); auto &bound_function = input.GetBoundFunction(); - if (Settings::Get(context)) { + if (!Settings::Get(context)) { bound_function.SetFunctionCallback(BinaryScalarFunctionZeroCheck>); } else { @@ -1312,7 +1312,7 @@ unique_ptr BindBinaryFloatingPoint(BindScalarFunctionInput &input) if (Settings::Get(context)) { bound_function.SetFunctionCallback(GetScalarBinaryFunction(bound_function.GetReturnType().InternalType())); } else { - auto null_on_zero = Settings::Get(context); + auto null_on_zero = !Settings::Get(context); bound_function.SetFunctionCallback( GetBinaryFunctionZeroCheck(bound_function.GetReturnType().InternalType(), null_on_zero)); } @@ -1356,7 +1356,7 @@ struct DividePropagateStatistics { }; // When propagation fails the divisor range may contain zero, and division by zero either raises or (with -// null_on_division_by_zero) produces NULLs that the inputs do not have: return no statistics instead of the +// error_on_division_by_zero=false) produces NULLs that the inputs do not have: return no statistics instead of the // validity-only statistics that PropagateNumericStats falls back to. unique_ptr PropagateIntegerDivideStats(ClientContext &context, FunctionStatisticsInput &input) { auto stats = PropagateNumericStats(context, input); @@ -1415,7 +1415,7 @@ static unique_ptr BindDecimalModulo(BindScalarFunctionInput &input bound_function.SetReturnType(LogicalType::DOUBLE); } auto &result_type = bound_function.GetReturnType(); - auto null_on_zero = Settings::Get(input.GetClientContext()); + auto null_on_zero = !Settings::Get(input.GetClientContext()); bound_function.SetFunctionCallback(GetBinaryFunctionZeroCheck(result_type.InternalType(), null_on_zero)); return std::move(bind_data); } diff --git a/src/duckdb/src/function/scalar/operator/cast.cpp b/src/duckdb/src/function/scalar/operator/cast.cpp index 0c4350c30..256fc399d 100644 --- a/src/duckdb/src/function/scalar/operator/cast.cpp +++ b/src/duckdb/src/function/scalar/operator/cast.cpp @@ -53,9 +53,8 @@ static bool BoundCastCanThrow(const BoundCastInfo &bound_cast, const LogicalType struct CastFunctionData : public FunctionData { CastFunctionData(LogicalType source_type_p, LogicalType target_type_p, BoundCastInfo bound_cast_p, bool try_cast_p, bool is_default_cast_p) - : FunctionData(InternalKind::BOUND_CAST), source_type(std::move(source_type_p)), - target_type(std::move(target_type_p)), bound_cast(std::move(bound_cast_p)), try_cast(try_cast_p), - is_default_cast(is_default_cast_p) { + : source_type(std::move(source_type_p)), target_type(std::move(target_type_p)), + bound_cast(std::move(bound_cast_p)), try_cast(try_cast_p), is_default_cast(is_default_cast_p) { } LogicalType source_type; @@ -180,12 +179,13 @@ static unique_ptr CreateCastExpression(unique_ptr child, vector> children; children.push_back(std::move(child)); + auto can_throw = BoundCastCanThrow(bound_cast, source_type, target_type, try_cast); auto function_data = make_uniq(source_type, target_type, std::move(bound_cast), try_cast, is_default_cast); auto scalar_function = CastFun::GetFunction(); scalar_function.SetReturnType(target_type); - if (BoundCastCanThrow(bound_cast, source_type, target_type, try_cast)) { + if (can_throw) { scalar_function.SetErrorMode(FunctionErrors::CAN_THROW_RUNTIME_ERROR); } SetCastNullHandling(scalar_function, target_type); @@ -235,8 +235,7 @@ bool BoundCastExpression::IsTryCast(const BoundFunctionExpression &cast_expr) { } bool BoundCastExpression::HasValidBindData(const BoundFunctionExpression &cast_expr) { - if (cast_expr.GetChildren().size() != 1 || !cast_expr.GetChildren()[0] || !cast_expr.BindInfo() || - cast_expr.BindInfo()->GetInternalKind() != FunctionData::InternalKind::BOUND_CAST) { + if (cast_expr.GetChildren().size() != 1 || !cast_expr.GetChildren()[0] || !cast_expr.BindInfo()) { return false; } auto &data = cast_expr.BindInfo()->Cast(); diff --git a/src/duckdb/src/function/scalar/operator/multiply.cpp b/src/duckdb/src/function/scalar/operator/multiply.cpp index ce6c8d6c2..c728cdd58 100644 --- a/src/duckdb/src/function/scalar/operator/multiply.cpp +++ b/src/duckdb/src/function/scalar/operator/multiply.cpp @@ -1,6 +1,7 @@ #include "duckdb/common/operator/multiply.hpp" #include "duckdb/common/limits.hpp" +#include "duckdb/common/operator/add.hpp" #include "duckdb/common/operator/cast_operators.hpp" #include "duckdb/common/types/hugeint.hpp" #include "duckdb/common/types/uhugeint.hpp" @@ -91,12 +92,17 @@ bool TryMultiplyOperator::Operation(interval_t left, double right, interval_t &r * of cascade and the seconds factor operation itself. */ if (std::fabs(sec_remainder) >= Interval::SECS_PER_DAY) { - result.days += LossyNumericCast(sec_remainder / Interval::SECS_PER_DAY); - sec_remainder -= LossyNumericCast(sec_remainder / Interval::SECS_PER_DAY) * Interval::SECS_PER_DAY; + const auto extra_days = LossyNumericCast(sec_remainder / Interval::SECS_PER_DAY); + if (!TryAddOperator::Operation(result.days, extra_days, result.days)) { + return false; + } + sec_remainder -= extra_days * Interval::SECS_PER_DAY; } /* cascade units down */ - result.days += day_remainder; + if (!TryAddOperator::Operation(result.days, day_remainder, result.days)) { + return false; + } if (!TryCast::Operation(left.micros, d)) { return false; } diff --git a/src/duckdb/src/function/scalar/string/caseconvert.cpp b/src/duckdb/src/function/scalar/string/caseconvert.cpp index 3bc2b336f..d02addb86 100644 --- a/src/duckdb/src/function/scalar/string/caseconvert.cpp +++ b/src/duckdb/src/function/scalar/string/caseconvert.cpp @@ -144,16 +144,13 @@ static unique_ptr CaseConvertPropagateStats(ClientContext &conte if (!StringStats::HasMinMax(child_stats[0])) { return result.ToUnique(); } - // When min == max, all values share the stored string (exact) or the stored prefix (truncated). - // Case conversion is codepoint-local, so the converted string/prefix bounds the result. + // All values share the common prefix of min and max; case conversion preserves this property. auto min = StringStats::Min(child_stats[0]); auto max = StringStats::Max(child_stats[0]); - if (min != max) { - return result.ToUnique(); - } - const bool is_exact = StringStats::GetMinType(child_stats[0]) == StringStatsType::EXACT_STATS && + const bool is_exact = min == max && StringStats::GetMinType(child_stats[0]) == StringStatsType::EXACT_STATS && StringStats::GetMaxType(child_stats[0]) == StringStatsType::EXACT_STATS; if (!is_exact) { + min.resize(StringUtil::GetCommonPrefixSize(min, max)); // truncated stats can end in the middle of a character - only complete ones can be converted size_t invalid_pos = 0; if (Utf8Proc::Analyze(min.c_str(), min.size(), nullptr, &invalid_pos) == UnicodeType::INVALID) { diff --git a/src/duckdb/src/function/scalar/string/hive_partition_component.cpp b/src/duckdb/src/function/scalar/string/hive_partition_component.cpp new file mode 100644 index 000000000..4c3aac3b5 --- /dev/null +++ b/src/duckdb/src/function/scalar/string/hive_partition_component.cpp @@ -0,0 +1,33 @@ +#include "duckdb/function/scalar/string_functions.hpp" + +#include "duckdb/common/hive_partitioning.hpp" +#include "duckdb/common/vector/vector_writer.hpp" + +namespace duckdb { + +namespace { + +void HivePartitionComponentFunction(DataChunk &args, ExpressionState &state, Vector &result) { + // type-erased, as the partition value can have any type + auto writer = FlatVector::Writer(result, args.size()); + for (idx_t row = 0; row < args.size(); row++) { + auto value = args.data[1].GetValue(row); + // the name and the value are escaped the same way url_encode does + auto component = HivePartitioning::Escape(args.data[0].GetValue(row).ToString()) + "="; + component += + value.IsNull() ? HivePartitioning::DEFAULT_PARTITION_NAME : HivePartitioning::EscapeValue(value.ToString()); + writer.WriteValue(string_t(component.c_str(), UnsafeNumericCast(component.size()))); + } +} + +} // namespace + +ScalarFunction HivePartitionComponentFun::GetFunction() { + ScalarFunction component(HivePartitionComponentFun::Name, {}, LogicalType::VARCHAR, HivePartitionComponentFunction); + component.GetSignature().AddParameter("name", LogicalType::VARCHAR).AddParameter("value", LogicalType::ANY); + // a NULL partition value has a directory of its own + component.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); + return component; +} + +} // namespace duckdb diff --git a/src/duckdb/src/function/scalar/struct/remap_struct.cpp b/src/duckdb/src/function/scalar/struct/remap_struct.cpp index 8a5e61b1e..f9eb938ca 100644 --- a/src/duckdb/src/function/scalar/struct/remap_struct.cpp +++ b/src/duckdb/src/function/scalar/struct/remap_struct.cpp @@ -335,6 +335,11 @@ struct RemapEntry { RemapEntry remap; remap.index = entry->second.index; remap.target_type = target_entry->second.type; + if (source_type.id() == LogicalTypeId::SQLNULL && struct_val.IsNull()) { + // NULL can be cast directly to a nested type without remapping its children. + result.emplace(remap_target, std::move(remap)); + return; + } if (source_is_nested || target_is_nested || !struct_val.IsNull()) { if (source_type.id() != target_type.id()) { throw BinderException("Can't change source type (%s) to target type (%s), type conversion not allowed", diff --git a/src/duckdb/src/function/scalar/system/aggregate_export.cpp b/src/duckdb/src/function/scalar/system/aggregate_export.cpp index bee19d25e..b6737d24e 100644 --- a/src/duckdb/src/function/scalar/system/aggregate_export.cpp +++ b/src/duckdb/src/function/scalar/system/aggregate_export.cpp @@ -355,6 +355,10 @@ unique_ptr BindAggregateStateInternal(ClientContext &co ParseOrderBys(order_entry->second, column_count, orders); // the leading buffered columns are the inner aggregate's bound arguments (post constant-erasure) const idx_t argument_count = inner->aggr.GetArguments().size(); + if (argument_count > column_count) { + throw BinderException("to_aggregate_state: argument count %llu exceeds the number of state columns (%llu)", + (uint64_t)argument_count, (uint64_t)column_count); + } auto reconstructed = FunctionBinder::BindSortedAggregateState(context, inner->aggr, std::move(inner->bind_data), buffer_struct, orders, argument_count); diff --git a/src/duckdb/src/function/scalar/variant/variant_extract.cpp b/src/duckdb/src/function/scalar/variant/variant_extract.cpp index ee3974668..bd3807cfd 100644 --- a/src/duckdb/src/function/scalar/variant/variant_extract.cpp +++ b/src/duckdb/src/function/scalar/variant/variant_extract.cpp @@ -50,7 +50,12 @@ static unique_ptr VariantExtractPropagateStats(ClientContext &co return nullptr; } - return VariantStats::WrapExtractedFieldAsVariant(variant_stats, *found_stats); + auto result = VariantStats::WrapExtractedFieldAsVariant(variant_stats, *found_stats); + if (info.component.lookup_mode == VariantChildLookupMode::BY_INDEX) { + // Element statistics do not account for NULLs from out-of-bounds array indexes. + result->SetHasNull(); + } + return result; } static unique_ptr VariantExtractBind(BindScalarFunctionInput &input) { @@ -113,7 +118,15 @@ static bool TryShreddedExtractRecursive(const Vector &input, const vector> children_p) + : expression(expression_p), children(std::move(children_p)) { +} + +FunctionUnbindInput::~FunctionUnbindInput() { +} + void ThrowNonFallibleFunctionError(const Identifier &name, std::exception &ex) { ErrorData error(ex); if (!Exception::IsExecutionError(error.Type())) { @@ -19,7 +28,7 @@ bool ScalarFunctionCallbacks::operator==(const ScalarFunctionCallbacks &rhs) con return bind == rhs.bind && init_local_state == rhs.init_local_state && statistics == rhs.statistics && bind_lambda == rhs.bind_lambda && bind_expression == rhs.bind_expression && get_modified_databases == rhs.get_modified_databases && serialize == rhs.serialize && - deserialize == rhs.deserialize && filter_prune == rhs.filter_prune; + deserialize == rhs.deserialize && filter_prune == rhs.filter_prune && unbind == rhs.unbind; } bool ScalarFunctionCallbacks::operator!=(const ScalarFunctionCallbacks &rhs) const { @@ -34,7 +43,7 @@ ScalarFunctionInfo::~ScalarFunctionInfo() { ScalarFunction::ScalarFunction(Identifier name, FunctionSignature sig, scalar_function_t function) : SimpleFunction(std::move(name), std::move(sig)) { - callbacks.function = std::move(function); + SetFunctionCallback(std::move(function)); } ScalarFunction::ScalarFunction(Identifier name, vector arguments, LogicalType return_type, @@ -46,7 +55,7 @@ ScalarFunction::ScalarFunction(Identifier name, vector arguments, L properties.stability = side_effects; properties.null_handling = null_handling; - callbacks.function = std::move(function); + SetFunctionCallback(std::move(function)); callbacks.bind = bind; callbacks.init_local_state = init_local_state; callbacks.statistics = statistics; @@ -71,7 +80,7 @@ ScalarFunction::ScalarFunction(Identifier name, std::initializer_list function_p) : definition(std::move(function_p)) { auto &function = *definition; - name = function.name; - schema_name = function.GetSchemaName(); - catalog_name = function.GetCatalogName(); + qualified_name = function.GetQualifiedName(); extra_info = function.extra_info; return_type = function.GetReturnType(); callbacks = function.GetCallbacks(); @@ -145,7 +152,7 @@ BoundScalarFunction::BoundScalarFunction(shared_ptr functi } bool BoundScalarFunction::operator==(const BoundScalarFunction &rhs) const { - return callbacks == rhs.callbacks && properties == rhs.properties && name == rhs.name && + return callbacks == rhs.callbacks && properties == rhs.properties && GetName() == rhs.GetName() && return_type == rhs.return_type && arguments == rhs.arguments; } bool BoundScalarFunction::operator!=(const BoundScalarFunction &rhs) const { diff --git a/src/duckdb/src/function/table/arrow.cpp b/src/duckdb/src/function/table/arrow.cpp index bc09f3565..326752051 100644 --- a/src/duckdb/src/function/table/arrow.cpp +++ b/src/duckdb/src/function/table/arrow.cpp @@ -59,28 +59,14 @@ unique_ptr ArrowTableFunction::ArrowScanBindDumb(ClientContext &co unique_ptr ArrowTableFunction::ArrowScanBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { - if (input.inputs[0].IsNull() || input.inputs[1].IsNull() || input.inputs[2].IsNull()) { - throw BinderException("arrow_scan: pointers cannot be null"); + if (!input.ref.bind_info) { + throw BinderException("arrow_scan requires an ArrowScanFactory bind input"); } - auto &ref = input.ref; - - shared_ptr dependency; - if (ref.external_dependency) { - // This was created during the replacement scan for Python (see python_replacement_scan.cpp) - // this object is the owning reference to 'stream_factory_ptr' and has to be kept alive. - dependency = ref.external_dependency->GetDependency("replacement_cache"); - D_ASSERT(dependency); - } - - auto stream_factory_ptr = input.inputs[0].GetPointer(); - auto stream_factory_produce = (stream_factory_produce_t)input.inputs[1].GetPointer(); // NOLINT - auto stream_factory_get_schema = (stream_factory_get_schema_t)input.inputs[2].GetPointer(); // NOLINT - - auto res = make_uniq(stream_factory_produce, stream_factory_ptr, std::move(dependency)); - - auto &data = *res; - stream_factory_get_schema(reinterpret_cast(stream_factory_ptr), data.schema_root.arrow_schema); - PopulateArrowTableSchema(context, res->arrow_table, data.schema_root.arrow_schema); + DynamicCastCheck(input.ref.bind_info.get()); + auto factory = shared_ptr_cast(input.ref.bind_info); + auto res = make_uniq(std::move(factory)); + res->factory->GetSchema(res->schema_root.arrow_schema); + PopulateArrowTableSchema(context, res->arrow_table, res->schema_root.arrow_schema); names = StringsToIdentifiers(res->arrow_table.GetNames()); return_types = res->arrow_table.GetTypes(); res->all_types = return_types; @@ -107,7 +93,7 @@ unique_ptr ProduceArrowScan(const ArrowScanFunctionData } } parameters.filters = filters; - return function.scanner_producer(function.stream_factory_ptr, parameters); + return function.factory->ProduceStream(parameters); } idx_t ArrowTableFunction::ArrowScanMaxThreads(ClientContext &context, const FunctionData *bind_data_p) { @@ -335,8 +321,7 @@ bool ArrowTableFunction::ArrowPushdownType(const FunctionData &bind_data, idx_t } void ArrowTableFunction::RegisterFunction(BuiltinFunctions &set) { - TableFunction arrow("arrow_scan", {LogicalType::POINTER, LogicalType::POINTER, LogicalType::POINTER}, - ArrowScanFunction, ArrowScanBind, ArrowScanInitGlobal, ArrowScanInitLocal); + TableFunction arrow("arrow_scan", {}, ArrowScanFunction, ArrowScanBind, ArrowScanInitGlobal, ArrowScanInitLocal); arrow.cardinality = ArrowScanCardinality; arrow.get_partition_data = ArrowGetPartitionData; arrow.projection_pushdown = true; @@ -346,8 +331,8 @@ void ArrowTableFunction::RegisterFunction(BuiltinFunctions &set) { arrow.parallelism = TableFunctionParallelism::SEQUENTIAL; set.AddFunction(arrow); - TableFunction arrow_dumb("arrow_scan_dumb", {LogicalType::POINTER, LogicalType::POINTER, LogicalType::POINTER}, - ArrowScanFunction, ArrowScanBindDumb, ArrowScanInitGlobal, ArrowScanInitLocal); + TableFunction arrow_dumb("arrow_scan_dumb", {}, ArrowScanFunction, ArrowScanBindDumb, ArrowScanInitGlobal, + ArrowScanInitLocal); arrow_dumb.cardinality = ArrowScanCardinality; arrow_dumb.get_partition_data = ArrowGetPartitionData; arrow_dumb.projection_pushdown = false; diff --git a/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp b/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp index fbdfad1a7..fb4e986d2 100644 --- a/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +++ b/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp @@ -338,6 +338,13 @@ LogicalType ArrowType::GetDuckType(bool use_dictionary) const { if (!use_dictionary) { return type; } + if (HasExtension()) { + // A registered extension type's type info describes the extension's STORAGE tree, which need not + // mirror the logical type's children — reconstructing through it would produce a hybrid type. + // The logical type is authoritative here; any dictionaries inside the storage are handled by the + // storage-side conversion, not by the output type. + return type; + } // Dictionaries can exist in arbitrarily nested schemas // have to reconstruct the type auto id = type.id(); @@ -417,7 +424,11 @@ unique_ptr ArrowType::GetTypeFromSchema(ClientContext &context, Arrow if (config.HasArrowExtension(extension_info)) { auto extension = config.GetArrowExtension(extension_info); arrow_type = extension.GetType(context, schema, schema_metadata); - arrow_type->extension_data = extension.GetTypeExtension(); + if (!arrow_type->extension_data) { + // GetType may have attached per-column extension data (e.g. to record the incoming + // schema's field order); fall back to the registered instance otherwise + arrow_type->extension_data = extension.GetTypeExtension(); + } } } diff --git a/src/duckdb/src/function/table/arrow_conversion.cpp b/src/duckdb/src/function/table/arrow_conversion.cpp index 79c72cf5b..b8de02f1f 100644 --- a/src/duckdb/src/function/table/arrow_conversion.cpp +++ b/src/duckdb/src/function/table/arrow_conversion.cpp @@ -842,7 +842,15 @@ void ArrowToDuckDBConversion::ColumnArrowToDuckDB(Vector &vector, ArrowArray &ar if (!ignore_extensions && arrow_type.HasExtension()) { if (arrow_type.extension_data->arrow_to_duckdb) { // Convert the storage and then call the cast function - Vector input_data(arrow_type.extension_data->GetInternalType()); + // `size` is the child's own count, which for a nested child is not bounded by + // STANDARD_VECTOR_SIZE -- size the storage vector for it (as ArrowAppendData::AppendChild does). + Vector input_data(arrow_type.extension_data->GetInternalType(), + MaxValue(size, STANDARD_VECTOR_SIZE)); + // Every caller has already established this column's top-level validity on `vector` — transfer + // it onto the storage vector, since the cast function is responsible for carrying it through to + // its result (a conversion that rebuilds the result does not preserve the pre-set validity, and + // a spec-clean writer need not mirror a parent NULL in the storage children's own validity). + FlatVector::CopyValidity(input_data, vector, size); ColumnArrowToDuckDB(input_data, array, chunk_offset, array_state, size, arrow_type, nested_offset, parent_mask, parent_offset, /*ignore_extensions*/ true); arrow_type.extension_data->arrow_to_duckdb(array_state.context, input_data, vector, size); diff --git a/src/duckdb/src/function/table/copy_csv.cpp b/src/duckdb/src/function/table/copy_csv.cpp index 4fd142f81..cfc056e19 100644 --- a/src/duckdb/src/function/table/copy_csv.cpp +++ b/src/duckdb/src/function/table/copy_csv.cpp @@ -10,11 +10,12 @@ #include "duckdb/common/types/column/column_data_collection.hpp" #include "duckdb/common/types/string_type.hpp" #include "duckdb/common/vector_operations/vector_operations.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" #include "duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp" #include "duckdb/function/copy_function.hpp" #include "duckdb/function/scalar/string_functions.hpp" #include "duckdb/function/function_binder.hpp" +#include "duckdb/common/multi_file/table_function_multi_file.hpp" #include "duckdb/function/table/read_csv.hpp" #include "duckdb/parser/parsed_data/copy_info.hpp" #include "duckdb/planner/binder.hpp" @@ -461,7 +462,7 @@ void CSVCopyFunction::RegisterFunction(BuiltinFunctions &set) { info.flush_batch = WriteCSVFlushBatch; info.file_size_bytes = WriteCSVFileSizeBytes; - info.copy_from_bind = MultiFileFunction::MultiFileBindCopy; + info.copy_from_bind = TableFunctionMultiFileWrapper::MultiFileBindCopy; info.copy_from_function = ReadCSVTableFunction::GetFunction(); info.extension = "csv"; diff --git a/src/duckdb/src/function/table/direct_file_reader.cpp b/src/duckdb/src/function/table/direct_file_reader.cpp index 88ac996de..657d377a5 100644 --- a/src/duckdb/src/function/table/direct_file_reader.cpp +++ b/src/duckdb/src/function/table/direct_file_reader.cpp @@ -61,21 +61,28 @@ AsyncResult DirectFileReader::Scan(ClientContext &context, GlobalTableFunctionSt auto &fs = FileSystem::GetFileSystem(context); const idx_t out_idx = 0; - // We utilize projection pushdown here to only read the file content if the 'data' column is requested unique_ptr file_handle = nullptr; + optional file_metadata; + const bool is_remote = FileSystem::IsRemoteFile(file.path); - // Given the columns requested, do we even need to open the file? - if (state.requires_file_open) { + // Remote metadata is obtained from the opened handle so it can use the remote file cache and validators. + if (state.requires_file_open || (state.requires_file_metadata && is_remote)) { auto flags = FileFlags::FILE_FLAGS_READ; - if (FileSystem::IsRemoteFile(file.path)) { + if (is_remote) { flags |= FileFlags::FILE_FLAGS_DIRECT_IO; } flags.SetCachingMode(CachingMode::CACHE_REMOTE_ONLY); file_handle = fs.OpenFile(file, flags); + } else if (state.requires_file_metadata) { + file_metadata = fs.GetStatsIfExists(file); + if (!file_metadata) { + done = true; + return SourceResultType::FINISHED; + } } else { // At least verify that the file exist // The globbing behavior in remote filesystems can lead to files being listed that do not actually exist - if (FileSystem::IsRemoteFile(file.path) && !fs.FileExists(file.path)) { + if (is_remote && !fs.FileExists(file.path)) { done = true; return SourceResultType::FINISHED; } @@ -97,6 +104,8 @@ AsyncResult DirectFileReader::Scan(ClientContext &context, GlobalTableFunctionSt case ReadFileBindData::FILE_CONTENT_COLUMN: { const auto file_size = file_handle->GetFileSize(); AssertMaxFileSize(file.path, file_size); + // Zero-sized files could be a special file, so read until EOF. + const bool read_until_eof = file_handle->IsPipe() || file_size == 0; // Initialize write stream if not yet done if (!state.stream) { @@ -106,16 +115,18 @@ AsyncResult DirectFileReader::Scan(ClientContext &context, GlobalTableFunctionSt // Read in batches of 128mb constexpr idx_t MAX_READ_SIZE = 128LL * 1024 * 1024; - auto remaining_bytes = file_handle->IsPipe() ? MAX_READ_SIZE : file_size; + constexpr idx_t UNKNOWN_FILE_READ_SIZE = 64LL * 1024; + const auto read_size = read_until_eof ? UNKNOWN_FILE_READ_SIZE : MAX_READ_SIZE; + auto remaining_bytes = read_until_eof ? read_size : file_size; while (remaining_bytes > 0) { - const auto bytes_to_read = MinValue(remaining_bytes, MAX_READ_SIZE); + const auto bytes_to_read = MinValue(remaining_bytes, read_size); state.stream->GrowCapacity(bytes_to_read); idx_t actually_read = NumericCast(file_handle->Read( context, state.stream->GetData() + state.stream->GetPosition(), bytes_to_read)); state.stream->SetPosition(state.stream->GetPosition() + actually_read); AssertMaxFileSize(file.path, state.stream->GetPosition()); - if (file_handle->IsPipe()) { + if (read_until_eof) { if (actually_read == 0) { remaining_bytes = 0; } @@ -141,15 +152,19 @@ AsyncResult DirectFileReader::Scan(ClientContext &context, GlobalTableFunctionSt } break; case ReadFileBindData::FILE_SIZE_COLUMN: { auto &file_size_vector = output.data[col_idx]; - FlatVector::GetDataMutable(file_size_vector)[out_idx] = - NumericCast(file_handle->GetFileSize()); + D_ASSERT(file_metadata.has_value() || file_handle); + auto file_size = + file_metadata ? file_metadata->file_size : NumericCast(file_handle->GetFileSize()); + FlatVector::GetDataMutable(file_size_vector)[out_idx] = file_size; } break; case ReadFileBindData::FILE_LAST_MODIFIED_COLUMN: { auto &last_modified_vector = output.data[col_idx]; // This can sometimes fail (e.g. httpfs file system cant always parse the last modified time // correctly) try { - const auto timestamp_seconds = fs.GetLastModifiedTime(*file_handle); + D_ASSERT(file_metadata.has_value() || file_handle); + const auto timestamp_seconds = + file_metadata ? file_metadata->last_modification_time : fs.GetLastModifiedTime(*file_handle); FlatVector::GetDataMutable(last_modified_vector)[out_idx] = timestamp_tz_t(timestamp_seconds); } catch (std::exception &ex) { diff --git a/src/duckdb/src/function/table/range.cpp b/src/duckdb/src/function/table/range.cpp index d777c40a2..40a7d1e91 100644 --- a/src/duckdb/src/function/table/range.cpp +++ b/src/duckdb/src/function/table/range.cpp @@ -42,7 +42,7 @@ struct RangeFunctionBindData : public TableFunctionData { GetParameters(values, inputs.size(), start, end, increment); if (generate_series) { // generate_series has inclusive bounds on the RHS - end += 1; + end += increment < 0 ? -1 : 1; } cardinality = Hugeint::Cast((end - start) / increment); diff --git a/src/duckdb/src/function/table/read_csv.cpp b/src/duckdb/src/function/table/read_csv.cpp index 0b02df23c..18d2860b4 100644 --- a/src/duckdb/src/function/table/read_csv.cpp +++ b/src/duckdb/src/function/table/read_csv.cpp @@ -1,3 +1,4 @@ +#include "duckdb/common/multi_file/table_function_multi_file.hpp" #include "duckdb/function/table/read_csv.hpp" #include "duckdb/catalog/catalog.hpp" #include "duckdb/function/table/read_duckdb.hpp" @@ -31,7 +32,7 @@ #include #include "duckdb/execution/operator/csv_scanner/csv_schema.hpp" #include "duckdb/common/multi_file/multi_file_function.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" namespace duckdb { @@ -59,6 +60,12 @@ void ReadCSVData::FinalizeRead(ClientContext &context) { void ReadCSVTableFunction::ReadCSVAddNamedParameters(TableFunction &table_function) { table_function.named_parameters["sep"] = LogicalType::VARCHAR; table_function.named_parameters["delim"] = LogicalType::VARCHAR; + // aliases that the CSV options accept - COPY has always taken these, so the table function takes them too + table_function.named_parameters["separator"] = LogicalType::VARCHAR; + table_function.named_parameters["delimiter"] = LogicalType::VARCHAR; + table_function.named_parameters["null"] = LogicalType::ANY; + table_function.named_parameters["date_format"] = LogicalType::VARCHAR; + table_function.named_parameters["timestamp_format"] = LogicalType::VARCHAR; table_function.named_parameters["quote"] = LogicalType::VARCHAR; table_function.named_parameters["new_line"] = LogicalType::VARCHAR; table_function.named_parameters["escape"] = LogicalType::VARCHAR; @@ -168,13 +175,30 @@ static bool PushdownProjectionExpression(ClientContext &context, const TableFunc return true; } +//! The same, for the multi-file wrapper around read_single_csv_file - every file is bound against the schema of the +//! scan, so the pushed-down type has to be applied there too. That way the CSV reader converts to it itself, and +//! "ignore_errors" applies to the conversions that fail +static bool PushdownProjectionExpressionMultiFile(ClientContext &context, + const TableFunctionProjectionExpressionInput &input) { + if (!PushdownProjectionExpression(context, input)) { + return false; + } + auto &bind_data = input.get.bind_data->Cast(); + auto &data = bind_data.bind_data->Cast(); + const idx_t idx = input.get.GetColumnIds()[input.column_index].GetPrimaryIndex(); + if (idx < data.options.expected_types.size()) { + data.options.expected_types[idx] = input.expr.Cast().GetReturnType(); + } + return true; +} + TableFunction ReadCSVTableFunction::GetFunction() { - MultiFileFunction read_csv("read_csv"); + // the multi-file CSV reader is the single-file CSV reader wrapped into a multi-file function + auto read_csv = ReadCSVTableFunction::GetMultiFileFunction("read_csv"); read_csv.serialize = CSVReaderSerialize; read_csv.deserialize = CSVReaderDeserialize; - read_csv.projection_expression_pushdown = PushdownProjectionExpression; - ReadCSVAddNamedParameters(read_csv); - return static_cast(read_csv); + read_csv.projection_expression_pushdown = PushdownProjectionExpressionMultiFile; + return read_csv; } TableFunction ReadCSVTableFunction::GetAutoFunction() { @@ -186,6 +210,10 @@ TableFunction ReadCSVTableFunction::GetAutoFunction() { void ReadCSVTableFunction::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(MultiFileReader::CreateFunctionSet(ReadCSVTableFunction::GetFunction())); set.AddFunction(MultiFileReader::CreateFunctionSet(ReadCSVTableFunction::GetAutoFunction())); + // the single-file CSV reader that read_csv is built on + TableFunctionSet single_file_set("read_single_csv_file"); + single_file_set.AddFunction(ReadCSVTableFunction::GetSingleFileFunction()); + set.AddFunction(std::move(single_file_set)); } unique_ptr ReadCSVReplacement(ClientContext &context, ReplacementScanInput &input, diff --git a/src/duckdb/src/function/table/read_file.cpp b/src/duckdb/src/function/table/read_file.cpp index d04d8423c..f5b423354 100644 --- a/src/duckdb/src/function/table/read_file.cpp +++ b/src/duckdb/src/function/table/read_file.cpp @@ -110,10 +110,11 @@ DirectMultiFileInfo::InitializeGlobalState(ClientContext &context, MultiFile } for (const auto &column_id : column_ids) { - // For everything except the 'file' name column, we need to open the file - if (column_id != ReadFileBindData::FILE_NAME_COLUMN && column_id != COLUMN_IDENTIFIER_ROW_ID) { + if (column_id == ReadFileBindData::FILE_CONTENT_COLUMN) { result->requires_file_open = true; - break; + } else if (column_id == ReadFileBindData::FILE_SIZE_COLUMN || + column_id == ReadFileBindData::FILE_LAST_MODIFIED_COLUMN) { + result->requires_file_metadata = true; } } diff --git a/src/duckdb/src/function/table/repeat.cpp b/src/duckdb/src/function/table/repeat.cpp index d6afd5342..e049f5b63 100644 --- a/src/duckdb/src/function/table/repeat.cpp +++ b/src/duckdb/src/function/table/repeat.cpp @@ -1,5 +1,6 @@ #include "duckdb/function/table/range.hpp" #include "duckdb/common/algorithm.hpp" +#include "duckdb/common/atomic.hpp" namespace duckdb { @@ -14,7 +15,7 @@ struct RepeatFunctionData : public TableFunctionData { struct RepeatOperatorData : public GlobalTableFunctionState { RepeatOperatorData() : current_count(0) { } - idx_t current_count; + atomic current_count; }; static unique_ptr RepeatBind(ClientContext &context, TableFunctionBindInput &input, @@ -47,6 +48,17 @@ static void RepeatFunction(ClientContext &context, TableFunctionInput &data_p, D state.current_count += remaining; } +static double RepeatProgress(ClientContext &, const FunctionData *bind_data_p, + const GlobalTableFunctionState *state_p) { + if (!state_p) { + return -1; + } + auto &bind_data = bind_data_p->Cast(); + auto &state = state_p->Cast(); + return bind_data.target_count == 0 ? 100 + : 100.0 * double(state.current_count.load()) / double(bind_data.target_count); +} + static unique_ptr RepeatCardinality(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = bind_data_p->Cast(); return make_uniq(bind_data.target_count, bind_data.target_count); @@ -55,6 +67,7 @@ static unique_ptr RepeatCardinality(ClientContext &context, cons void RepeatTableFunction::RegisterFunction(BuiltinFunctions &set) { TableFunction repeat("repeat", {LogicalType::ANY, LogicalType::BIGINT}, RepeatFunction, RepeatBind, RepeatInit); repeat.cardinality = RepeatCardinality; + repeat.table_scan_progress = RepeatProgress; set.AddFunction(repeat); } diff --git a/src/duckdb/src/function/table/repeat_row.cpp b/src/duckdb/src/function/table/repeat_row.cpp index 9dd93a11e..fe1f16fad 100644 --- a/src/duckdb/src/function/table/repeat_row.cpp +++ b/src/duckdb/src/function/table/repeat_row.cpp @@ -1,5 +1,6 @@ #include "duckdb/function/table/range.hpp" #include "duckdb/common/algorithm.hpp" +#include "duckdb/common/atomic.hpp" namespace duckdb { @@ -15,7 +16,7 @@ struct RepeatRowFunctionData : public TableFunctionData { struct RepeatRowOperatorData : public GlobalTableFunctionState { RepeatRowOperatorData() : current_count(0) { } - idx_t current_count; + atomic current_count; }; static unique_ptr RepeatRowBind(ClientContext &context, TableFunctionBindInput &input, @@ -32,7 +33,14 @@ static unique_ptr RepeatRowBind(ClientContext &context, TableFunct if (inputs.empty()) { throw BinderException("repeat_rows requires at least one column to be specified"); } - return make_uniq(inputs, NumericCast(entry->second.GetValue())); + if (entry->second.IsNull()) { + throw BinderException("num_rows should be an integer value >= 0"); + } + auto repeat_rows = entry->second.GetValue(); + if (repeat_rows < 0) { + throw BinderException("num_rows cannot be less than zero"); + } + return make_uniq(inputs, NumericCast(repeat_rows)); } static unique_ptr RepeatRowInit(ClientContext &context, TableFunctionInitInput &input) { @@ -51,6 +59,17 @@ static void RepeatRowFunction(ClientContext &context, TableFunctionInput &data_p state.current_count += remaining; } +static double RepeatRowProgress(ClientContext &, const FunctionData *bind_data_p, + const GlobalTableFunctionState *state_p) { + if (!state_p) { + return -1; + } + auto &bind_data = bind_data_p->Cast(); + auto &state = state_p->Cast(); + return bind_data.target_count == 0 ? 100 + : 100.0 * double(state.current_count.load()) / double(bind_data.target_count); +} + static unique_ptr RepeatRowCardinality(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = bind_data_p->Cast(); return make_uniq(bind_data.target_count, bind_data.target_count); @@ -61,6 +80,7 @@ void RepeatRowTableFunction::RegisterFunction(BuiltinFunctions &set) { repeat_row.SetVarArgs(LogicalType::ANY); repeat_row.named_parameters["num_rows"] = LogicalType::BIGINT; repeat_row.cardinality = RepeatRowCardinality; + repeat_row.table_scan_progress = RepeatRowProgress; set.AddFunction(repeat_row); } diff --git a/src/duckdb/src/function/table/sniff_csv.cpp b/src/duckdb/src/function/table/sniff_csv.cpp index 6933ebeca..ff564a1dc 100644 --- a/src/duckdb/src/function/table/sniff_csv.cpp +++ b/src/duckdb/src/function/table/sniff_csv.cpp @@ -7,7 +7,7 @@ #include "duckdb/main/client_context.hpp" #include "duckdb/function/table/range.hpp" #include "duckdb/execution/operator/csv_scanner/csv_file_handle.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" #include "duckdb/function/table/read_csv.hpp" namespace duckdb { diff --git a/src/duckdb/src/function/table/system/duckdb_functions.cpp b/src/duckdb/src/function/table/system/duckdb_functions.cpp index daca6a14f..70908c2be 100644 --- a/src/duckdb/src/function/table/system/duckdb_functions.cpp +++ b/src/duckdb/src/function/table/system/duckdb_functions.cpp @@ -571,19 +571,20 @@ static vector ToValueVector(vector &string_vector) { template static Value GetParameterNames(CatalogEntry &entry, idx_t function_idx, FunctionDescription &function_description, Value ¶meter_types) { - vector parameter_names; - if (!function_description.parameter_names.empty()) { - for (idx_t param_idx = 0; param_idx < ListValue::GetChildren(parameter_types).size(); param_idx++) { + // default param names from function signature (if it exists), + // otherwise fall back to function.json entry + auto &function = entry.Cast(); + vector parameter_names = OP::GetParameters(function, function_idx); + idx_t parameter_count = ListValue::GetChildren(parameter_types).size(); + if (parameter_names.size() != parameter_count) { + parameter_names.clear(); + for (idx_t param_idx = 0; param_idx < parameter_count; param_idx++) { if (param_idx < function_description.parameter_names.size()) { parameter_names.emplace_back(function_description.parameter_names[param_idx]); } else { parameter_names.emplace_back("col" + to_string(param_idx)); } } - } else { - // fallback - auto &function = entry.Cast(); - parameter_names = OP::GetParameters(function, function_idx); } return Value::LIST(LogicalType::VARCHAR, parameter_names); } diff --git a/src/duckdb/src/function/table/system/duckdb_keywords.cpp b/src/duckdb/src/function/table/system/duckdb_keywords.cpp index 56ea13ca8..ea5d55244 100644 --- a/src/duckdb/src/function/table/system/duckdb_keywords.cpp +++ b/src/duckdb/src/function/table/system/duckdb_keywords.cpp @@ -1,6 +1,5 @@ #include "duckdb/function/table/system_functions.hpp" -#include "duckdb/common/exception.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/parser/parser.hpp" @@ -50,24 +49,7 @@ void DuckDBKeywordsFunction(ClientContext &context, TableFunctionInput &data_p, auto &entry = data.entries[data.offset++]; keyword_name.Append(Value(entry.name)); - string category_name; - switch (entry.category) { - case KeywordCategory::KEYWORD_RESERVED: - category_name = "reserved"; - break; - case KeywordCategory::KEYWORD_UNRESERVED: - category_name = "unreserved"; - break; - case KeywordCategory::KEYWORD_TYPE_FUNC: - category_name = "type_function"; - break; - case KeywordCategory::KEYWORD_COL_NAME: - category_name = "column_name"; - break; - default: - throw InternalException("Unrecognized keyword category"); - } - keyword_category.Append(Value(std::move(category_name))); + keyword_category.Append(Value(entry.category)); count++; } diff --git a/src/duckdb/src/function/table/system/external_resources.cpp b/src/duckdb/src/function/table/system/external_resources.cpp index 3926864db..908b6e38f 100644 --- a/src/duckdb/src/function/table/system/external_resources.cpp +++ b/src/duckdb/src/function/table/system/external_resources.cpp @@ -6,7 +6,6 @@ #include "duckdb/common/set.hpp" #include "duckdb/common/types/value.hpp" #include "duckdb/main/connection.hpp" -#include "duckdb/main/materialized_query_result.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/external_resource_type_registry.hpp" #include "duckdb/main/external_resources_manager.hpp" @@ -101,7 +100,7 @@ static void DiscoverExternalResources(ClientContext &context, const ExternalReso // con.Query reports query errors in-band, but with statement verification active (a global debug setting // the internal connection inherits) a bind-time failure of the callback is thrown instead. Handle both so // the wrapped message is identical in every mode. - unique_ptr res; + unique_ptr res; try { res = con.Query(sql); } catch (const std::exception &ex) { diff --git a/src/duckdb/src/function/table/table_scan.cpp b/src/duckdb/src/function/table/table_scan.cpp index 5796b39c4..840a00e97 100644 --- a/src/duckdb/src/function/table/table_scan.cpp +++ b/src/duckdb/src/function/table/table_scan.cpp @@ -576,10 +576,10 @@ class DuckTableScanState : public TableScanGlobalState { auto &l_state = input.local_state->Cast(); // with read-ahead the assignment being decoded lives in the claimed job's scan state auto &scan_state = l_state.job ? *l_state.job->scan_state : l_state.scan_state; - if (scan_state.table_state.row_group) { + if (scan_state.table_state.GetRowGroup()) { return OperatorPartitionData(scan_state.table_state.batch_index); } - if (scan_state.local_state.row_group) { + if (scan_state.local_state.GetRowGroup()) { return OperatorPartitionData(scan_state.table_state.batch_index + scan_state.local_state.batch_index); } return OperatorPartitionData(0); @@ -959,6 +959,11 @@ unique_ptr TableScanInitGlobal(ClientContext &context, return DuckTableScanInitGlobal(context, input, storage, bind_data); } + // The index scan does not apply the sample. + if (input.sample_options) { + return DuckTableScanInitGlobal(context, input, storage, bind_data); + } + auto &filter_set = *input.filters; // FIXME: We currently only support scanning one ART with one filter. diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 13136230a..fda09db01 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "0-alpha41839" +#define DUCKDB_PATCH_VERSION "0-alpha42986" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 0 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 2 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v2.0.0-alpha41839" +#define DUCKDB_VERSION "v2.0.0-alpha42986" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "38c5eebcb0" +#define DUCKDB_SOURCE_ID "d4e72566aa" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/function/table_function.cpp b/src/duckdb/src/function/table_function.cpp index 84654a49b..b4955fe82 100644 --- a/src/duckdb/src/function/table_function.cpp +++ b/src/duckdb/src/function/table_function.cpp @@ -23,11 +23,12 @@ TableFunction::TableFunction(Identifier name, const vector &argumen in_out_function(nullptr), in_out_function_final(nullptr), statistics(nullptr), statistics_extended(nullptr), dependency(nullptr), cardinality(nullptr), get_metrics(nullptr), pushdown_complex_filter(nullptr), pushdown_expression(nullptr), combine_schema(nullptr), claim_batch(nullptr), finish_batch(nullptr), - to_string(nullptr), table_scan_progress(nullptr), get_partition_data(nullptr), get_bind_info(nullptr), - projection_expression_pushdown(nullptr), get_multi_file_reader(nullptr), supports_pushdown_type(nullptr), - supports_pushdown_extract(nullptr), is_repeatable(nullptr), get_partition_info(nullptr), - get_partition_stats(nullptr), get_virtual_columns(nullptr), get_row_id_columns(nullptr), set_scan_order(nullptr), - serialize(nullptr), deserialize(nullptr), projection_pushdown(false), filter_pushdown(false), filter_prune(false), + supports_read_ahead(nullptr), schedule_io(nullptr), to_string(nullptr), table_scan_progress(nullptr), + get_partition_data(nullptr), get_bind_info(nullptr), projection_expression_pushdown(nullptr), + get_multi_file_reader(nullptr), supports_pushdown_type(nullptr), supports_pushdown_extract(nullptr), + is_repeatable(nullptr), get_partition_info(nullptr), get_partition_stats(nullptr), get_virtual_columns(nullptr), + get_row_id_columns(nullptr), set_scan_order(nullptr), serialize(nullptr), deserialize(nullptr), + projection_pushdown(false), supports_cast_map(false), filter_pushdown(false), filter_prune(false), sampling_pushdown(false), late_materialization(false), return_type(TableFunctionReturnType::TABLE_RETURNING_FUNCTION) { } @@ -40,11 +41,12 @@ TableFunction::TableFunction(Identifier name, const vector &argumen in_out_function(nullptr), in_out_function_final(nullptr), statistics(nullptr), statistics_extended(nullptr), dependency(nullptr), cardinality(nullptr), get_metrics(nullptr), pushdown_complex_filter(nullptr), pushdown_expression(nullptr), combine_schema(nullptr), claim_batch(nullptr), finish_batch(nullptr), - to_string(nullptr), table_scan_progress(nullptr), get_partition_data(nullptr), get_bind_info(nullptr), - projection_expression_pushdown(nullptr), get_multi_file_reader(nullptr), supports_pushdown_type(nullptr), - supports_pushdown_extract(nullptr), is_repeatable(nullptr), get_partition_info(nullptr), - get_partition_stats(nullptr), get_virtual_columns(nullptr), get_row_id_columns(nullptr), set_scan_order(nullptr), - serialize(nullptr), deserialize(nullptr), projection_pushdown(false), filter_pushdown(false), filter_prune(false), + supports_read_ahead(nullptr), schedule_io(nullptr), to_string(nullptr), table_scan_progress(nullptr), + get_partition_data(nullptr), get_bind_info(nullptr), projection_expression_pushdown(nullptr), + get_multi_file_reader(nullptr), supports_pushdown_type(nullptr), supports_pushdown_extract(nullptr), + is_repeatable(nullptr), get_partition_info(nullptr), get_partition_stats(nullptr), get_virtual_columns(nullptr), + get_row_id_columns(nullptr), set_scan_order(nullptr), serialize(nullptr), deserialize(nullptr), + projection_pushdown(false), supports_cast_map(false), filter_pushdown(false), filter_prune(false), sampling_pushdown(false), late_materialization(false), return_type(TableFunctionReturnType::TABLE_RETURNING_FUNCTION) { } diff --git a/src/duckdb/src/function/window/window_value_function.cpp b/src/duckdb/src/function/window/window_value_function.cpp index 6d1d6b694..29cfebb66 100644 --- a/src/duckdb/src/function/window/window_value_function.cpp +++ b/src/duckdb/src/function/window/window_value_function.cpp @@ -149,8 +149,15 @@ class WindowValueStreamingState : public WindowExecutorStreamingState { WindowValueStreamingState(ClientContext &client, DataChunk &input, const BoundWindowExpression &wexpr) : wexpr(wexpr), vec(GetFirstValue(client, input, wexpr), count_t(STANDARD_VECTOR_SIZE)), - sel(STANDARD_VECTOR_SIZE), eval(client), arg(wexpr.GetChildren()[0]->GetReturnType()) { + sel(STANDARD_VECTOR_SIZE), eval(client) { eval.AddExpression(*wexpr.GetChildren()[0]); + arg_chunk.Initialize(client, {wexpr.GetChildren()[0]->GetReturnType()}); + } + + Vector &EvalArg(DataChunk &input) { + arg_chunk.Reset(); + eval.Execute(input, arg_chunk); + return arg_chunk.data[0]; } const BoundWindowExpression &wexpr; @@ -160,8 +167,8 @@ class WindowValueStreamingState : public WindowExecutorStreamingState { SelectionVector sel; //! An executor for computing the argument ExpressionExecutor eval; - //! A reusable argument vector - Vector arg; + //! A reusable argument chunk + DataChunk arg_chunk; }; //===--------------------------------------------------------------------===// @@ -179,6 +186,9 @@ struct WindowValueExecutor { static unique_ptr GetLocal(ExecutionContext &context, const GlobalSinkState &gstate); //! Streaming APIs + static bool ArgumentIsStreamable(const BoundWindowExpression &wexpr) { + return !wexpr.IsVolatile(); + } static unique_ptr GetStreamingState(ClientContext &client, DataChunk &input, const BoundWindowExpression &wexpr) { return make_uniq(client, input, wexpr); @@ -528,6 +538,9 @@ struct WindowLeadLagExecutor : public WindowValueExecutor { if (!WindowLeadLagStreamingState::ComputeOffset(client, wexpr, offset)) { return false; } + if (offset < 0 && !ArgumentIsStreamable(wexpr)) { + return false; + } return UnsafeNumericCast(std::abs(offset)) < max_delta; } @@ -783,6 +796,9 @@ struct WindowFirstValueExecutor : public WindowValueExecutor { //! Streaming APIs static bool CanStream(ClientContext &client, const BoundWindowExpression &wexpr, idx_t max_delta) { + if (!ArgumentIsStreamable(wexpr)) { + return false; + } if (wexpr.IgnoreNulls()) { // We can stream first values ignoring NULLs if they are "running totals" return wexpr.WindowStart() == WindowBoundary::UNBOUNDED_PRECEDING && @@ -809,9 +825,7 @@ void WindowFirstValueExecutor::StreamData(ExecutionContext &context, DataChunk & // then look for a non-NULL value and update it if (wexpr.IgnoreNulls() && ConstantVector::IsNull(sstate.vec)) { // Find the first non-NULL value - auto &executor = sstate.eval; - auto &arg = sstate.arg; - executor.ExecuteExpression(input, arg); + auto &arg = sstate.EvalArg(input); UnifiedVectorFormat unified; arg.ToUnifiedFormat(unified); const auto &validity = unified.validity; @@ -914,6 +928,9 @@ struct WindowLastValueExecutor : public WindowValueExecutor { //! Streaming APIs static bool CanStream(ClientContext &client, const BoundWindowExpression &wexpr, idx_t max_delta) { + if (!ArgumentIsStreamable(wexpr)) { + return false; + } // We can stream last values if they are "running totals" return wexpr.WindowStart() == WindowBoundary::UNBOUNDED_PRECEDING && wexpr.WindowEnd() == WindowBoundary::CURRENT_ROW_ROWS; @@ -931,8 +948,7 @@ void WindowLastValueExecutor::StreamData(ExecutionContext &context, DataChunk &i auto &executor = sstate.eval; if (wexpr.IgnoreNulls()) { auto &prev = sstate.vec; - auto &arg = sstate.arg; - executor.ExecuteExpression(input, arg); + auto &arg = sstate.EvalArg(input); UnifiedVectorFormat unified; arg.ToUnifiedFormat(unified); const auto &validity = unified.validity; @@ -943,7 +959,7 @@ void WindowLastValueExecutor::StreamData(ExecutionContext &context, DataChunk &i Vector copy(wexpr.GetChildren()[0]->GetReturnType()); VectorOperations::Copy(arg, copy, count, 0, 0); // Overwrite the previous non-NULL value if the first one is NULL - if (!validity.RowIsValidUnsafe(0)) { + if (!validity.RowIsValidUnsafe(unified.sel->get_index(0))) { VectorOperations::Copy(prev, copy, 1, 0, 0); } // Select appropriate the non-NULL values to copy over @@ -1078,6 +1094,9 @@ struct WindowNthValueExecutor : public WindowValueExecutor { //! Streaming APIs static bool CanStream(ClientContext &client, const BoundWindowExpression &wexpr, idx_t max_delta) { + if (!ArgumentIsStreamable(wexpr)) { + return false; + } // We can only stream Nth Value if N is positive constant. idx_t nth_index; if (!WindowNthValueStreamingState::ComputeNthIndex(client, wexpr, nth_index)) { @@ -1112,7 +1131,7 @@ void WindowNthValueStreamingState::StreamData(ExecutionContext &context, DataChu return; } - eval.ExecuteExpression(input, arg); + auto &arg = EvalArg(input); UnifiedVectorFormat unified; arg.ToUnifiedFormat(unified); diff --git a/src/duckdb/src/function/window_function.cpp b/src/duckdb/src/function/window_function.cpp index f0e638c1e..4a205038f 100644 --- a/src/duckdb/src/function/window_function.cpp +++ b/src/duckdb/src/function/window_function.cpp @@ -26,9 +26,7 @@ BoundWindowFunction::BoundWindowFunction(const WindowFunction &base) BoundWindowFunction::BoundWindowFunction(shared_ptr base_p) : window_enum(base_p->window_enum), definition(std::move(base_p)) { auto &base = *definition; - name = base.name; - schema_name = base.GetSchemaName(); - catalog_name = base.GetCatalogName(); + qualified_name = base.GetQualifiedName(); extra_info = base.extra_info; return_type = base.GetReturnType(); callbacks = base.GetCallbacks(); @@ -40,6 +38,8 @@ BoundWindowFunction::BoundWindowFunction(shared_ptr base_p for (auto ¶m : base.GetSignature().GetParameters()) { arguments.push_back(param.GetType()); } + logical_arguments = arguments; + logical_return_type = return_type; } bool BoundWindowFunction::operator==(const BoundWindowFunction &rhs) const { diff --git a/src/duckdb/src/include/duckdb.hpp b/src/duckdb/src/include/duckdb.hpp index 168dfd00c..ce47149a0 100644 --- a/src/duckdb/src/include/duckdb.hpp +++ b/src/duckdb/src/include/duckdb.hpp @@ -11,4 +11,5 @@ #include "duckdb/main/connection.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/query_result.hpp" +#include "duckdb/main/query_result_stream.hpp" #include "duckdb/main/appender.hpp" diff --git a/src/duckdb/src/include/duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp b/src/duckdb/src/include/duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp index 3c8465184..dac3e9ddf 100644 --- a/src/duckdb/src/include/duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp +++ b/src/duckdb/src/include/duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp @@ -26,5 +26,7 @@ class AggregateFunctionCatalogEntry : public FunctionEntry { //! The aggregate functions AggregateFunctionSet functions; + +private: }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp b/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp index 3063335b6..d023fa5bd 100644 --- a/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +++ b/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp @@ -16,12 +16,10 @@ class TableCatalogEntry; //! Wrapper class to allow copying a DuckIndexEntry (for altering the DuckIndexEntry metadata such as comments) struct IndexDataTableInfo { - IndexDataTableInfo(shared_ptr info_p, const Identifier &index_name_p); + explicit IndexDataTableInfo(shared_ptr info_p); //! Pointer to the DataTableInfo shared_ptr info; - //! The index to be removed on destruction - Identifier index_name; }; //! A duck index entry diff --git a/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp b/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp index a2e275700..fad041ded 100644 --- a/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +++ b/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp @@ -29,5 +29,9 @@ class TableFunctionCatalogEntry : public FunctionEntry { public: unique_ptr AlterEntry(CatalogTransaction transaction, AlterInfo &info) override; + +private: + friend class ExtensionLoader; + void FinalizeFunction(TableFunction &function) const; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/catalog/dependency.hpp b/src/duckdb/src/include/duckdb/catalog/dependency.hpp index 1d35dd681..0f85c5165 100644 --- a/src/duckdb/src/include/duckdb/catalog/dependency.hpp +++ b/src/duckdb/src/include/duckdb/catalog/dependency.hpp @@ -65,7 +65,7 @@ struct DependencySubjectFlags : public DependencyFlags { static constexpr uint8_t OWNERSHIP = 0; public: - DependencySubjectFlags &Apply(DependencySubjectFlags other) { + DependencySubjectFlags &Apply(const DependencySubjectFlags &other) { Merge(other.Value()); return *this; } @@ -104,7 +104,7 @@ struct DependencyDependentFlags : public DependencyFlags { } public: - DependencyDependentFlags &Apply(DependencyDependentFlags other) { + DependencyDependentFlags &Apply(const DependencyDependentFlags &other) { Merge(other.Value()); return *this; } diff --git a/src/duckdb/src/include/duckdb/common/arrow/arrow_query_result.hpp b/src/duckdb/src/include/duckdb/common/arrow/arrow_query_result.hpp index d7232fd31..afad6f40e 100644 --- a/src/duckdb/src/include/duckdb/common/arrow/arrow_query_result.hpp +++ b/src/duckdb/src/include/duckdb/common/arrow/arrow_query_result.hpp @@ -34,6 +34,7 @@ class ArrowQueryResult : public QueryResult { public: //! Converts the QueryResult to a string DUCKDB_API string ToString() override; + DUCKDB_API string ToBox(BoxRendererContext &context, const BoxRendererConfig &config) override; public: vector> ConsumeArrays(); diff --git a/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp b/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp index 67e8cf12d..03a1aba32 100644 --- a/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp +++ b/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp @@ -9,18 +9,26 @@ #pragma once #include "duckdb/main/query_result.hpp" +#include "duckdb/main/query_result_stream.hpp" #include "duckdb/common/arrow/arrow_wrapper.hpp" #include "duckdb/main/chunk_scan_state.hpp" #include "duckdb/function/table/arrow/arrow_duck_schema.hpp" namespace duckdb { +//! Exports a query result as an Arrow C stream. A result that can be drained is streamed one batch at a time; +//! a result that cannot (a statement that completes before its result is returned, a detached result, or a handle +//! whose retention is already retained) is completed on the first pull and read from its collection. class ResultArrowArrayStreamWrapper { public: explicit ResultArrowArrayStreamWrapper(unique_ptr result, idx_t batch_size); public: ArrowArrayStream stream; + ClientProperties client_properties; + //! The handle, when the result is read from its retained collection unique_ptr result; + //! The engine stream, when the result is drained + unique_ptr stream_result; ErrorData last_error; idx_t batch_size; vector column_types; diff --git a/src/duckdb/src/include/duckdb/common/clustered_aggregate.hpp b/src/duckdb/src/include/duckdb/common/clustered_aggregate.hpp index bf0d9d206..fc5c5ef74 100644 --- a/src/duckdb/src/include/duckdb/common/clustered_aggregate.hpp +++ b/src/duckdb/src/include/duckdb/common/clustered_aggregate.hpp @@ -50,17 +50,33 @@ struct ClusteredAggr { idx_t count; //! number of tuples in this group }; - idx_t n_group_runs = 0; - GroupRun group_runs[MAX_RUNS]; + ClusteredAggr() : group_runs(&single_run) { + } - const ClusteredAggrState *state = nullptr; + struct RunRange { + const GroupRun *begin_ptr; + const GroupRun *end_ptr; + const GroupRun *begin() const { + return begin_ptr; + } + const GroupRun *end() const { + return end_ptr; + } + idx_t size() const { + return static_cast(end_ptr - begin_ptr); + } + const GroupRun &operator[](idx_t i) const { + return begin_ptr[i]; + } + }; + RunRange runs() const { + return RunRange {group_runs, group_runs + n_group_runs}; + } - //! Build a clustered permutation of 0..count-1 from raw integer group ids. - //! On success fills group_runs[].sel/gid/count. - bool TryClustered(const uint64_t *group_ids, sel_t count, sel_t *arena, uint64_t *slots); + const ClusteredAggrState *state = nullptr; //! Initialize a single run covering 0..count-1 for one aggregate state. - void SetSingleRun(data_ptr_t state, idx_t count); + void SetSingleRun(data_ptr_t state_ptr, idx_t count); //! Advance all run state pointers by payload_size. void AdvanceStates(idx_t payload_size); @@ -73,10 +89,19 @@ struct ClusteredAggr { } //! Returns a composed dict sel for simple dictionary input, or nullptr. - const sel_t *ClusterIter(const Vector &input, idx_t count) const; + const sel_t *ClusterIter(const Vector &input) const; private: - mutable sel_t composed_sel_data[STANDARD_VECTOR_SIZE]; + friend struct ClusteredAggrState; + + //! Build a clustered permutation of 0..count-1 from group ids into runs. + //! On success fills runs[].sel/gid/count. + bool TryClustered(const uint64_t *group_ids, sel_t count, sel_t *arena, uint64_t *slots, GroupRun *runs); + + idx_t n_group_runs = 0; + GroupRun single_run; + GroupRun *group_runs; + mutable const sel_t *cached_dict_sel = nullptr; }; @@ -84,6 +109,8 @@ struct ClusteredAggr { struct ClusteredAggrState { unsafe_unique_array arena; unsafe_unique_array slots; + unsafe_unique_array group_runs; + mutable unsafe_unique_array composed_sel_data; bool all_clustered = false; idx_t n_clustered = 0; idx_t skipped_opportunities = 0; diff --git a/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp b/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp index 786d4cba4..ad184ac33 100644 --- a/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp +++ b/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp @@ -35,6 +35,7 @@ struct StreamWrapper { DUCKDB_API virtual void Initialize(QueryContext context, CompressedFile &file, bool write) = 0; DUCKDB_API virtual bool Read(StreamData &stream_data) = 0; + DUCKDB_API virtual void FinalizeRead(StreamData &stream_data); DUCKDB_API virtual void Write(CompressedFile &file, StreamData &stream_data, data_ptr_t buffer, int64_t nr_bytes) = 0; DUCKDB_API virtual void Close() = 0; diff --git a/src/duckdb/src/include/duckdb/common/enable_shared_from_this_ipp.hpp b/src/duckdb/src/include/duckdb/common/enable_shared_from_this_ipp.hpp index 5c707082e..855bed430 100644 --- a/src/duckdb/src/include/duckdb/common/enable_shared_from_this_ipp.hpp +++ b/src/duckdb/src/include/duckdb/common/enable_shared_from_this_ipp.hpp @@ -15,7 +15,7 @@ class enable_shared_from_this { // NOLINT: invalid case style mutable weak_ptr __weak_this_; // NOLINT: __weak_this_ is reserved protected: - constexpr enable_shared_from_this() noexcept { + constexpr enable_shared_from_this() noexcept { // NOLINT(bugprone-crtp-constructor-accessibility) } enable_shared_from_this(enable_shared_from_this const &) noexcept { // NOLINT: not marked as explicit } diff --git a/src/duckdb/src/include/duckdb/common/enum_util.hpp b/src/duckdb/src/include/duckdb/common/enum_util.hpp index c8fbe0800..1983731f4 100644 --- a/src/duckdb/src/include/duckdb/common/enum_util.hpp +++ b/src/duckdb/src/include/duckdb/common/enum_util.hpp @@ -120,6 +120,8 @@ enum class CacheValidationMode : uint8_t; enum class CachingMode : uint8_t; +enum class CanUnloadResult : uint8_t; + enum class CatalogLookupBehavior : uint8_t; enum class CatalogType : uint8_t; @@ -174,6 +176,8 @@ enum class DebugInitialize : uint8_t; enum class DebugOrderVerification : uint8_t; +enum class DebugProgressVerification : uint8_t; + enum class DebugStatementVerification : uint8_t; enum class DebugVectorVerification : uint8_t; @@ -248,6 +252,8 @@ enum class FileLockType : uint8_t; enum class FileNameSegmentType : uint8_t; +enum class FileSyncMode : uint8_t; + enum class FileWriteMode : uint8_t; enum class FilterPropagateResult : uint8_t; @@ -376,6 +382,8 @@ enum class OperatorFinalResultType : uint8_t; enum class OperatorFinalizeResultType : uint8_t; +enum class OperatorMatcherMode : uint8_t; + enum class OperatorResultType : uint8_t; enum class OptimizerType : uint32_t; @@ -394,8 +402,6 @@ enum class OrdinalityType : uint8_t; enum class OutputStream : uint8_t; -enum class PEGKeywordCategory : uint8_t; - enum class ParseInfoType : uint8_t; enum class ParseResultType : uint8_t; @@ -408,8 +414,6 @@ enum class PartitionedTupleDataType : uint8_t; enum class PatternMatchType : uint8_t; -enum class PendingExecutionResult : uint8_t; - enum class PhysicalOperatorType : uint8_t; enum class PhysicalTableScanExecutionStrategy : uint8_t; @@ -440,6 +444,8 @@ enum class ProfilingCoverage : uint8_t; enum class ProfilingParameterNames : uint8_t; +enum class ProgressInvariant : uint8_t; + enum class PushdownExtractSupport : uint8_t; enum class QualifiedNameToStringMode : uint8_t; @@ -450,7 +456,7 @@ enum class QueryNodeType : uint8_t; enum class QueryResultMemoryType : uint8_t; -enum class QueryResultOutputType : uint8_t; +enum class QueryResultState : uint8_t; enum class QueryResultType : uint8_t; @@ -474,6 +480,8 @@ enum class RenderMode : uint8_t; enum class RequestType : uint8_t; +enum class ResultEagerness : uint8_t; + enum class ResultLifetime : uint8_t; enum class ResultModifierType : uint8_t; @@ -558,8 +566,6 @@ enum class StorageVersion : uint64_t; enum class StrTimeSpecifier : uint8_t; -enum class StreamExecutionResult : uint8_t; - enum class SubqueryType : uint8_t; enum class SuggestionState : uint8_t; @@ -779,6 +785,9 @@ const char* EnumUtil::ToChars(CacheValidationMode value); template<> const char* EnumUtil::ToChars(CachingMode value); +template<> +const char* EnumUtil::ToChars(CanUnloadResult value); + template<> const char* EnumUtil::ToChars(CatalogLookupBehavior value); @@ -860,6 +869,9 @@ const char* EnumUtil::ToChars(DebugInitialize value); template<> const char* EnumUtil::ToChars(DebugOrderVerification value); +template<> +const char* EnumUtil::ToChars(DebugProgressVerification value); + template<> const char* EnumUtil::ToChars(DebugStatementVerification value); @@ -971,6 +983,9 @@ const char* EnumUtil::ToChars(FileLockType value); template<> const char* EnumUtil::ToChars(FileNameSegmentType value); +template<> +const char* EnumUtil::ToChars(FileSyncMode value); + template<> const char* EnumUtil::ToChars(FileWriteMode value); @@ -1163,6 +1178,9 @@ const char* EnumUtil::ToChars(OperatorFinalResultType v template<> const char* EnumUtil::ToChars(OperatorFinalizeResultType value); +template<> +const char* EnumUtil::ToChars(OperatorMatcherMode value); + template<> const char* EnumUtil::ToChars(OperatorResultType value); @@ -1190,9 +1208,6 @@ const char* EnumUtil::ToChars(OrdinalityType value); template<> const char* EnumUtil::ToChars(OutputStream value); -template<> -const char* EnumUtil::ToChars(PEGKeywordCategory value); - template<> const char* EnumUtil::ToChars(ParseInfoType value); @@ -1211,9 +1226,6 @@ const char* EnumUtil::ToChars(PartitionedTupleDataType template<> const char* EnumUtil::ToChars(PatternMatchType value); -template<> -const char* EnumUtil::ToChars(PendingExecutionResult value); - template<> const char* EnumUtil::ToChars(PhysicalOperatorType value); @@ -1259,6 +1271,9 @@ const char* EnumUtil::ToChars(ProfilingCoverage value); template<> const char* EnumUtil::ToChars(ProfilingParameterNames value); +template<> +const char* EnumUtil::ToChars(ProgressInvariant value); + template<> const char* EnumUtil::ToChars(PushdownExtractSupport value); @@ -1275,7 +1290,7 @@ template<> const char* EnumUtil::ToChars(QueryResultMemoryType value); template<> -const char* EnumUtil::ToChars(QueryResultOutputType value); +const char* EnumUtil::ToChars(QueryResultState value); template<> const char* EnumUtil::ToChars(QueryResultType value); @@ -1310,6 +1325,9 @@ const char* EnumUtil::ToChars(RenderMode value); template<> const char* EnumUtil::ToChars(RequestType value); +template<> +const char* EnumUtil::ToChars(ResultEagerness value); + template<> const char* EnumUtil::ToChars(ResultLifetime value); @@ -1436,9 +1454,6 @@ const char* EnumUtil::ToChars(StorageVersion value); template<> const char* EnumUtil::ToChars(StrTimeSpecifier value); -template<> -const char* EnumUtil::ToChars(StreamExecutionResult value); - template<> const char* EnumUtil::ToChars(SubqueryType value); @@ -1701,6 +1716,9 @@ CacheValidationMode EnumUtil::FromString(const char *value) template<> CachingMode EnumUtil::FromString(const char *value); +template<> +CanUnloadResult EnumUtil::FromString(const char *value); + template<> CatalogLookupBehavior EnumUtil::FromString(const char *value); @@ -1782,6 +1800,9 @@ DebugInitialize EnumUtil::FromString(const char *value); template<> DebugOrderVerification EnumUtil::FromString(const char *value); +template<> +DebugProgressVerification EnumUtil::FromString(const char *value); + template<> DebugStatementVerification EnumUtil::FromString(const char *value); @@ -1893,6 +1914,9 @@ FileLockType EnumUtil::FromString(const char *value); template<> FileNameSegmentType EnumUtil::FromString(const char *value); +template<> +FileSyncMode EnumUtil::FromString(const char *value); + template<> FileWriteMode EnumUtil::FromString(const char *value); @@ -2085,6 +2109,9 @@ OperatorFinalResultType EnumUtil::FromString(const char template<> OperatorFinalizeResultType EnumUtil::FromString(const char *value); +template<> +OperatorMatcherMode EnumUtil::FromString(const char *value); + template<> OperatorResultType EnumUtil::FromString(const char *value); @@ -2112,9 +2139,6 @@ OrdinalityType EnumUtil::FromString(const char *value); template<> OutputStream EnumUtil::FromString(const char *value); -template<> -PEGKeywordCategory EnumUtil::FromString(const char *value); - template<> ParseInfoType EnumUtil::FromString(const char *value); @@ -2133,9 +2157,6 @@ PartitionedTupleDataType EnumUtil::FromString(const ch template<> PatternMatchType EnumUtil::FromString(const char *value); -template<> -PendingExecutionResult EnumUtil::FromString(const char *value); - template<> PhysicalOperatorType EnumUtil::FromString(const char *value); @@ -2181,6 +2202,9 @@ ProfilingCoverage EnumUtil::FromString(const char *value); template<> ProfilingParameterNames EnumUtil::FromString(const char *value); +template<> +ProgressInvariant EnumUtil::FromString(const char *value); + template<> PushdownExtractSupport EnumUtil::FromString(const char *value); @@ -2197,7 +2221,7 @@ template<> QueryResultMemoryType EnumUtil::FromString(const char *value); template<> -QueryResultOutputType EnumUtil::FromString(const char *value); +QueryResultState EnumUtil::FromString(const char *value); template<> QueryResultType EnumUtil::FromString(const char *value); @@ -2232,6 +2256,9 @@ RenderMode EnumUtil::FromString(const char *value); template<> RequestType EnumUtil::FromString(const char *value); +template<> +ResultEagerness EnumUtil::FromString(const char *value); + template<> ResultLifetime EnumUtil::FromString(const char *value); @@ -2358,9 +2385,6 @@ StorageVersion EnumUtil::FromString(const char *value); template<> StrTimeSpecifier EnumUtil::FromString(const char *value); -template<> -StreamExecutionResult EnumUtil::FromString(const char *value); - template<> SubqueryType EnumUtil::FromString(const char *value); diff --git a/src/duckdb/src/include/duckdb/common/enums/debug_progress_verification.hpp b/src/duckdb/src/include/duckdb/common/enums/debug_progress_verification.hpp new file mode 100644 index 000000000..d891e4bb1 --- /dev/null +++ b/src/duckdb/src/include/duckdb/common/enums/debug_progress_verification.hpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/debug_progress_verification.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/constants.hpp" +#include "duckdb/common/windows_undefs.hpp" + +namespace duckdb { + +//! How operator progress reporting is verified (debug setting) +enum class DebugProgressVerification : uint8_t { + //! No verification (default) + NONE = 0, + //! Violations are written to the log (log type "ProgressVerification") + LOG = 1, + //! Violations that are not ignored fail the query + ERROR = 2 +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/enums/pending_execution_result.hpp b/src/duckdb/src/include/duckdb/common/enums/file_sync_mode.hpp similarity index 59% rename from src/duckdb/src/include/duckdb/common/enums/pending_execution_result.hpp rename to src/duckdb/src/include/duckdb/common/enums/file_sync_mode.hpp index 406ffbe9e..300e38db3 100644 --- a/src/duckdb/src/include/duckdb/common/enums/pending_execution_result.hpp +++ b/src/duckdb/src/include/duckdb/common/enums/file_sync_mode.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/pending_execution_result.hpp +// duckdb/common/enums/file_sync_mode.hpp // // //===----------------------------------------------------------------------===// @@ -12,13 +12,6 @@ namespace duckdb { -enum class PendingExecutionResult : uint8_t { - RESULT_READY, - RESULT_NOT_READY, - EXECUTION_ERROR, - BLOCKED, - NO_TASKS_AVAILABLE, - EXECUTION_FINISHED -}; +enum class FileSyncMode : uint8_t { STANDARD, NONE, FULL }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/enums/stream_execution_result.hpp b/src/duckdb/src/include/duckdb/common/enums/query_result_memory_type.hpp similarity index 57% rename from src/duckdb/src/include/duckdb/common/enums/stream_execution_result.hpp rename to src/duckdb/src/include/duckdb/common/enums/query_result_memory_type.hpp index 19ba824dd..3ed1f97c3 100644 --- a/src/duckdb/src/include/duckdb/common/enums/stream_execution_result.hpp +++ b/src/duckdb/src/include/duckdb/common/enums/query_result_memory_type.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/stream_execution_result.hpp +// duckdb/common/enums/query_result_memory_type.hpp // // //===----------------------------------------------------------------------===// @@ -12,14 +12,7 @@ namespace duckdb { -enum class StreamExecutionResult : uint8_t { - CHUNK_READY, - CHUNK_NOT_READY, - EXECUTION_ERROR, - EXECUTION_CANCELLED, - BLOCKED, - NO_TASKS_AVAILABLE, - EXECUTION_FINISHED -}; +//! Where a retained result keeps its rows +enum class QueryResultMemoryType : uint8_t { IN_MEMORY, BUFFER_MANAGED }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/enums/query_result_state.hpp b/src/duckdb/src/include/duckdb/common/enums/query_result_state.hpp new file mode 100644 index 000000000..a91680914 --- /dev/null +++ b/src/duckdb/src/include/duckdb/common/enums/query_result_state.hpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/query_result_state.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/constants.hpp" + +namespace duckdb { + +//! Where a submitted query stands. READY means the engine is waiting on the consumer: producers are +//! parked for a retention decision, or parked for buffer space with a chunk to pop +enum class QueryResultState : uint8_t { READY, NOT_READY, BLOCKED, NO_TASKS_AVAILABLE, FINISHED, EXECUTION_ERROR }; + +//! Whether execution reached a terminal state +constexpr bool IsTerminal(QueryResultState state) { + return state == QueryResultState::FINISHED || state == QueryResultState::EXECUTION_ERROR; +} + +//! Whether the result is ready to be observed by a consumer. Execution is in ready state or in a final state. +constexpr bool IsObservable(QueryResultState state) { + return IsTerminal(state) || state == QueryResultState::READY; +} + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/enums/result_eagerness.hpp b/src/duckdb/src/include/duckdb/common/enums/result_eagerness.hpp new file mode 100644 index 000000000..491bbba77 --- /dev/null +++ b/src/duckdb/src/include/duckdb/common/enums/result_eagerness.hpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/result_eagerness.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/constants.hpp" + +namespace duckdb { + +//! When the retention of a result is settled. FORCED settles it on retained at submission, so +//! producers never wait for a consumer and no stream can be opened on the handle. AUTO leaves the +//! decision to the statement and the consumer +enum class ResultEagerness : uint8_t { FORCED, AUTO }; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp b/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp index a780ca990..2a8686741 100644 --- a/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +++ b/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp @@ -9,10 +9,10 @@ #pragma once #include "duckdb/common/constants.hpp" +#include "duckdb/common/enums/result_eagerness.hpp" #include "duckdb/common/identifier.hpp" #include "duckdb/common/optional_idx.hpp" #include "duckdb/common/unordered_set.hpp" -#include "duckdb/common/query_parameters.hpp" #include "duckdb/common/enums/database_modification_type.hpp" namespace duckdb { @@ -54,7 +54,8 @@ enum class StatementType : uint8_t { MERGE_INTO_STATEMENT, CONNECT_STATEMENT, DISCONNECT_STATEMENT, - EXTERNAL_RESOURCE_STATEMENT + EXTERNAL_RESOURCE_STATEMENT, + ENUM_SIZE // This has to stay the last entry of the type! }; DUCKDB_API string StatementTypeToString(StatementType type); @@ -73,9 +74,8 @@ class ClientContext; //! A struct containing various properties of a SQL statement struct StatementProperties { StatementProperties() - : requires_valid_transaction(true), output_type(QueryResultOutputType::FORCE_MATERIALIZED), - bound_all_parameters(true), return_type(StatementReturnType::QUERY_RESULT), parameter_count(0), - always_require_rebind(false) { + : requires_valid_transaction(true), result_eagerness(ResultEagerness::FORCED), bound_all_parameters(true), + return_type(StatementReturnType::QUERY_RESULT), parameter_count(0), always_require_rebind(false) { } struct CatalogIdentity { @@ -103,8 +103,9 @@ struct StatementProperties { //! Whether or not the statement requires a valid transaction. Almost all statements require this, with the //! exception of ROLLBACK bool requires_valid_transaction; - //! Whether or not the result can be streamed to the client - QueryResultOutputType output_type; + //! FORCED for a statement whose side effects cannot wait for a consumer: it runs to completion + //! before the call that returns its result does, and its result is never streamed + ResultEagerness result_eagerness; //! Whether or not all parameters have successfully had their types determined bool bound_all_parameters; //! What type of data the statement returns diff --git a/src/duckdb/src/include/duckdb/common/extra_operator_info.hpp b/src/duckdb/src/include/duckdb/common/extra_operator_info.hpp index 14055d9fc..cb0688c0b 100644 --- a/src/duckdb/src/include/duckdb/common/extra_operator_info.hpp +++ b/src/duckdb/src/include/duckdb/common/extra_operator_info.hpp @@ -13,6 +13,8 @@ #include #include "duckdb/common/operator/comparison_operators.hpp" #include "duckdb/common/optional_idx.hpp" +#include "duckdb/common/optional.hpp" +#include "duckdb/planner/expression.hpp" #include "duckdb/parser/parsed_data/sample_options.hpp" namespace duckdb { @@ -21,28 +23,8 @@ class ExtraOperatorInfo { public: ExtraOperatorInfo() : file_filters(""), sample_options(nullptr) { } - ExtraOperatorInfo(ExtraOperatorInfo &&extra_info) noexcept - : file_filters(std::move(extra_info.file_filters)), sample_options(std::move(extra_info.sample_options)) { - if (extra_info.total_files.IsValid()) { - total_files = extra_info.total_files.GetIndex(); - } - if (extra_info.filtered_files.IsValid()) { - filtered_files = extra_info.filtered_files.GetIndex(); - } - } - ExtraOperatorInfo &operator=(ExtraOperatorInfo &&extra_info) noexcept { - if (this != &extra_info) { - file_filters = extra_info.file_filters; - if (extra_info.total_files.IsValid()) { - total_files = extra_info.total_files.GetIndex(); - } - if (extra_info.filtered_files.IsValid()) { - filtered_files = extra_info.filtered_files.GetIndex(); - } - sample_options = std::move(extra_info.sample_options); - } - return *this; - } + ExtraOperatorInfo(ExtraOperatorInfo &&extra_info) noexcept = default; + ExtraOperatorInfo &operator=(ExtraOperatorInfo &&extra_info) noexcept = default; bool operator==(const ExtraOperatorInfo &other) const { return file_filters == other.file_filters && total_files == other.total_files && @@ -51,6 +33,8 @@ class ExtraOperatorInfo { //! Filters that have been pushed down into the main file list string file_filters; + //! Consumed file predicates with bindings in the unprojected source column space. + optional>> file_filter_expressions; //! Total size of file list optional_idx total_files; //! Size of file list after applying filters diff --git a/src/duckdb/src/include/duckdb/common/file_system.hpp b/src/duckdb/src/include/duckdb/common/file_system.hpp index e356342bc..7261cc5d3 100644 --- a/src/duckdb/src/include/duckdb/common/file_system.hpp +++ b/src/duckdb/src/include/duckdb/common/file_system.hpp @@ -236,6 +236,9 @@ class FileSystem { DUCKDB_API virtual FileType GetFileType(FileHandle &handle); //! Returns the file stats of the attached handle. DUCKDB_API virtual FileMetadata Stats(FileHandle &handle); + //! Returns the stats of a file, or nullopt if the file does not exist. + DUCKDB_API virtual optional GetStatsIfExists(const OpenFileInfo &file, + optional_ptr opener = nullptr); //! Truncate a file to a maximum size of new_size, new_size should be smaller than or equal to the current size of //! the file DUCKDB_API virtual void Truncate(FileHandle &handle, int64_t new_size); diff --git a/src/duckdb/src/include/duckdb/common/local_file_system.hpp b/src/duckdb/src/include/duckdb/common/local_file_system.hpp index 69107e428..d4f76a057 100644 --- a/src/duckdb/src/include/duckdb/common/local_file_system.hpp +++ b/src/duckdb/src/include/duckdb/common/local_file_system.hpp @@ -49,6 +49,8 @@ class LocalFileSystem : public FileSystem { FileType GetFileType(FileHandle &handle) override; //! Returns the file stats of the attached handle. FileMetadata Stats(FileHandle &handle) override; + optional GetStatsIfExists(const OpenFileInfo &file, + optional_ptr opener = nullptr) override; //! Truncate a file to a maximum size of new_size, new_size should be smaller than or equal to the current size of //! the file void Truncate(FileHandle &handle, int64_t new_size) override; diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp index 8d3d2e57d..adca4434d 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp @@ -46,7 +46,7 @@ struct MultiFileReaderInterface { //! Combine the schemas of a set of files that were bound individually into a single schema //! The default implementation combines the return types of the files by name virtual void CombineSchemas(ClientContext &context, const vector> &union_data, - vector &return_types, vector &names); + bool union_by_name, vector &return_types, vector &names); virtual void FinalizeBindData(MultiFileBindData &multi_file_data); virtual void GetBindInfo(const TableFunctionData &bind_data, BindInfo &info); virtual optional_idx MaxThreads(const MultiFileBindData &bind_data_p, const MultiFileGlobalState &global_state, @@ -408,6 +408,15 @@ class MultiFileFunction : public TableFunction { return OpenMarkedFile(context, bind_data, global_state, current_reader_data, current_file_index, parallel_lock); } + //! Record an error of an async file open. Read-ahead is optional, and a scan drains the opens it scheduled + //! before it goes away - without a read-ahead to report to, the error only marks the scan as failed + static void PushAsyncOpenError(MultiFileGlobalState &gstate, ErrorData error) { + if (gstate.read_ahead) { + gstate.read_ahead->PushError(std::move(error)); + } + gstate.error_opening_file = true; + } + //! Open a file on the read-ahead async pool. Runs off the operator thread; records errors instead of throwing. static void OpenMarkedFileAsync(ClientContext &context, const MultiFileBindData &bind_data, MultiFileGlobalState &gstate, MultiFileReaderData &reader_data, idx_t file_index) { @@ -419,14 +428,12 @@ class MultiFileFunction : public TableFunction { if (!parallel_lock.owns_lock()) { parallel_lock.lock(); } - gstate.read_ahead->PushError(ErrorData(ex)); - gstate.error_opening_file = true; + PushAsyncOpenError(gstate, ErrorData(ex)); } catch (...) { // LCOV_EXCL_START if (!parallel_lock.owns_lock()) { parallel_lock.lock(); } - gstate.read_ahead->PushError(ErrorData("Unknown exception while opening a file")); - gstate.error_opening_file = true; + PushAsyncOpenError(gstate, ErrorData("Unknown exception while opening a file")); } // LCOV_EXCL_STOP } @@ -736,7 +743,9 @@ class MultiFileFunction : public TableFunction { result->job->scan_state = bind_data.interface->InitializeLocalState(context.client, *gstate.global_state); if (!ClaimNextJob(context.client, bind_data, gstate, *result->job)) { - return nullptr; + // keep the local state so the scan can still emit FinalizeScan output + result->job.reset(); + return std::move(result); } result->job_state = MultiFileJobState::SCHEDULE; return std::move(result); @@ -869,6 +878,12 @@ class MultiFileFunction : public TableFunction { auto &bind_data = input.bind_data->CastNoConst(); auto &data = input.local_state->Cast(); auto &gstate = input.global_state->Cast(); + if (data.finalize_batch_index.IsValid()) { + if (input.partition_info.RequiresPartitionColumns()) { + throw InternalException("Cannot get partition columns for FinalizeScan output"); + } + return OperatorPartitionData(data.finalize_batch_index.GetIndex()); + } auto &job = *data.job; OperatorPartitionData partition_data(job.batch_index); bind_data.multi_file_reader->GetPartitionData(context, bind_data.reader_bind, *job.reader_data, @@ -953,7 +968,7 @@ class MultiFileFunction : public TableFunction { MultiFileLocalState &lstate, MultiFileGlobalState &gstate, MultiFileBindData &bind_data) { if (lstate.job_state == MultiFileJobState::NONE) { - if (!ClaimNextJob(context, bind_data, gstate, *lstate.job)) { + if (!lstate.job || !ClaimNextJob(context, bind_data, gstate, *lstate.job)) { return ScanReadAheadAcquire::EXHAUSTED; } lstate.job_state = MultiFileJobState::SCHEDULE; @@ -1002,13 +1017,6 @@ class MultiFileFunction : public TableFunction { static void MultiFileScan(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { if (!data_p.local_state) { - auto &gstate = data_p.global_state->Cast(); - auto &bind_data = data_p.bind_data->CastNoConst(); - if (gstate.global_state && bind_data.interface && - bind_data.interface->FinalizeScan(context, *gstate.global_state, output)) { - data_p.async_result = SourceResultType::HAVE_MORE_OUTPUT; - return; - } data_p.async_result = SourceResultType::FINISHED; return; } @@ -1026,6 +1034,11 @@ class MultiFileFunction : public TableFunction { return; case ScanReadAheadAcquire::EXHAUSTED: if (bind_data.interface->FinalizeScan(context, *gstate.global_state, output)) { + // finalized output has no job, give it its own batch index for GetPartitionData + if (!data.finalize_batch_index.IsValid()) { + lock_guard guard(gstate.lock); + data.finalize_batch_index = gstate.batch_index++; + } data_p.async_result = SourceResultType::HAVE_MORE_OUTPUT; return; } @@ -1148,6 +1161,9 @@ class MultiFileFunction : public TableFunction { if (reader_data.file_state == MultiFileFileState::OPEN) { // file is currently open - get the progress within the file progress_in_file = reader_data.reader->GetProgressInFile(context); + } else if (reader_data.file_state == MultiFileFileState::SKIPPED) { + // file was skipped (e.g. pruned by a filter) - there is nothing left to read + progress_in_file = 100.0; } else if (reader_data.file_state == MultiFileFileState::CLOSED) { // file has been closed - check if the reader is still in use auto reader = reader_data.closed_reader.lock(); @@ -1209,7 +1225,7 @@ class MultiFileFunction : public TableFunction { vector> &filters) { auto &data = bind_data_p->Cast(); - MultiFilePushdownInfo info(get); + MultiFilePushdownInfo info(get.table_index, data.names, get.GetColumnIds(), get.extra_info); auto new_list = data.multi_file_reader->ComplexFilterPushdown(context, *data.file_list, data.file_options, info, filters); diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_list.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_list.hpp index ebb13701d..7f986880e 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_list.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_list.hpp @@ -73,7 +73,6 @@ class MultiFileListIterationHelper { }; struct MultiFilePushdownInfo { - explicit MultiFilePushdownInfo(LogicalGet &get); MultiFilePushdownInfo(TableIndex table_index, const vector &column_names, const vector &column_indexes, ExtraOperatorInfo &extra_info); diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_options.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_options.hpp index 40a6bbe1c..280d40bc5 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_options.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_options.hpp @@ -28,6 +28,10 @@ struct MultiFileOptions { //! The maximum number of files that are opened to determine the schema - the schemas of the sampled files are //! combined into one. NumericLimits::Maximum() samples every file idx_t maximum_sample_files = 1; + //! Whether the schemas of the sampled files are combined into a union of their columns - files are then allowed + //! to be missing columns of the combined schema, the way they are with union_by_name. This is how the schemas of + //! sampled files are combined unless the reader combines them itself + bool sampled_schema_is_union = true; MultiFileColumnMappingMode mapping = MultiFileColumnMappingMode::BY_NAME; case_insensitive_map_t hive_types_schema; @@ -48,10 +52,14 @@ struct MultiFileOptions { DUCKDB_API LogicalType GetHiveLogicalType(const string &hive_partition_column) const; DUCKDB_API Value GetHivePartitionValue(const string &base, const string &entry, ClientContext &context) const; DUCKDB_API bool AnySet() const; + //! Set "maximum_sample_files" from an option value - a positive count, or -1 for all files + DUCKDB_API void SetMaximumSampleFiles(const Identifier &key, const Value &val); + //! Set "maximum_sample_files" from an option value, returning false if it is not a valid count + DUCKDB_API bool TrySetMaximumSampleFiles(const Value &val); //! Whether the global schema is a union of the schemas of several files - individual files are then allowed to //! be missing columns that are present in the global schema bool SchemaIsUnion() const { - return union_by_name || maximum_sample_files > 1; + return union_by_name || (maximum_sample_files > 1 && sampled_schema_is_union); } }; diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp index 9d2783eb9..7fad141be 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp @@ -258,6 +258,8 @@ struct MultiFileLocalState : public LocalTableFunctionState { ExpressionExecutor executor; //! Number of rows scanned by this thread (for profiling) idx_t rows_scanned = 0; + //! FinalizeScan may have no job, here's a special batch index for it + optional_idx finalize_batch_index; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/multi_file/table_function_multi_file.hpp b/src/duckdb/src/include/duckdb/common/multi_file/table_function_multi_file.hpp index 64ff7760d..1b0fa88d9 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/table_function_multi_file.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/table_function_multi_file.hpp @@ -23,6 +23,8 @@ class TableFunctionFileReaderOptions : public BaseFileReaderOptions { vector expected_types; //! The bind data that determined the schema above, if it came from binding a file of this same scan shared_ptr schema_bind_data; + //! Whether the scan reads several files + bool multi_file_scan = false; }; //! Bind data of a multi-file function that wraps a single-file table function @@ -46,6 +48,11 @@ struct TableFunctionMultiFileSettings { string reader_type; //! How many files are sampled by default to determine the schema idx_t maximum_sample_files = 1; + //! The named parameter of the wrapped function that sets how many files are sampled (if it has one) + Identifier sample_files_parameter; + //! Whether the schemas of the sampled files are combined into a union of their columns - files are then allowed + //! to be missing columns of the combined schema + bool sampled_schema_is_union = true; }; //! The function info of a multi-file wrapper - holds the single-file function that is wrapped @@ -82,12 +89,15 @@ class TableFunctionFileReader : public BaseFileReader { public: string GetReaderType() const override; + bool UseCastMap() const override; shared_ptr GetUnionData(idx_t file_idx) override; unique_ptr GetStatistics(ClientContext &context, const Identifier &name) override; void AddVirtualColumn(column_t virtual_column_id) override; void PrepareReader(ClientContext &context, GlobalTableFunctionState &gstate) override; bool TryInitializeScan(ClientContext &context, GlobalTableFunctionState &gstate, LocalTableFunctionState &lstate) override; + AsyncResult ScheduleIO(ClientContext &context, GlobalTableFunctionState &gstate, + LocalTableFunctionState &lstate) override; AsyncResult Scan(ClientContext &context, GlobalTableFunctionState &gstate, LocalTableFunctionState &lstate, DataChunk &chunk) override; double GetProgressInFile(ClientContext &context) override; @@ -97,7 +107,8 @@ class TableFunctionFileReader : public BaseFileReader { void FinishBatch(ClientContext &context, LocalTableFunctionState &local_state); //! Bind the wrapped table function over this file - this sets up the columns of the reader. //! When the schema of the scan is known upfront, the file is bound against that schema - void BindFunction(ClientContext &context, const TableFunctionFileReaderOptions &options); + void BindFunction(ClientContext &context, const TableFunctionFileReaderOptions &options, + const MultiFileOptions &file_options); //! The cardinality of this file (if the wrapped function can provide one) optional_idx GetCardinality() const { return cardinality; @@ -115,8 +126,13 @@ class TableFunctionFileReader : public BaseFileReader { vector types; //! The cardinality estimate of the wrapped function for this file (if it has one) optional_idx cardinality; + //! The operator this file is scanned for, and the number of files that scan reads + optional_ptr scan_op; + idx_t scan_file_count = 1; private: + //! Take the operator and file count of the scan this file is read for from its state + void SetScanState(GlobalTableFunctionState &gstate); TableFunctionInitInput GetInitInput() const; //! Initialize the global state of the wrapped function (if it has not been initialized yet) void InitializeFunctionState(ClientContext &context); @@ -179,7 +195,7 @@ class TableFunctionMultiFileWrapper : public MultiFileReaderInterface { const MultiFileGlobalState &global_state, FileExpandResult expand_result) override; void BindReader(ClientContext &context, vector &return_types, vector &names, MultiFileBindData &bind_data) override; - void CombineSchemas(ClientContext &context, const vector> &union_data, + void CombineSchemas(ClientContext &context, const vector> &union_data, bool union_by_name, vector &return_types, vector &names) override; void FinalizeBindData(MultiFileBindData &multi_file_data) override; unique_ptr InitializeGlobalState(ClientContext &context, MultiFileBindData &bind_data, @@ -188,6 +204,7 @@ class TableFunctionMultiFileWrapper : public MultiFileReaderInterface { GlobalTableFunctionState &global_state) override; void FinishReading(ClientContext &context, GlobalTableFunctionState &global_state, LocalTableFunctionState &local_state) override; + bool SupportsReadAhead(const MultiFileBindData &bind_data) const override; shared_ptr CreateReader(ClientContext &context, GlobalTableFunctionState &gstate, BaseUnionData &union_data, const MultiFileBindData &bind_data) override; shared_ptr CreateReader(ClientContext &context, GlobalTableFunctionState &gstate, diff --git a/src/duckdb/src/include/duckdb/common/open_file_info.hpp b/src/duckdb/src/include/duckdb/common/open_file_info.hpp index 6a8a3f256..4db343dbf 100644 --- a/src/duckdb/src/include/duckdb/common/open_file_info.hpp +++ b/src/duckdb/src/include/duckdb/common/open_file_info.hpp @@ -18,10 +18,6 @@ struct ExtendedOpenFileInfo { unordered_map options; public: - //! Set an option to a value that originates from the user, casting it to the type the option is read back - //! as and storing it under its canonical name. Throws when the value cannot be converted to that type. - //! Options the core does not know about are stored as-is, for extensions to interpret - DUCKDB_API void SetUserOption(const string &name, const Value &value); //! Read an option as a T - returns false when the option is not set, throws when it is set to a value //! that cannot be read as a T. Only the types specialized below are supported template @@ -31,12 +27,15 @@ struct ExtendedOpenFileInfo { //! A boolean option - anything that casts to BOOLEAN is accepted template <> DUCKDB_API bool ExtendedOpenFileInfo::TryGetOption(const string &name, bool &result) const; -//! A string option - VARCHAR and BLOB are both stored as a string and both are accepted +//! A string option - VARCHAR and BLOB are read back as-is, other values as their text representation template <> DUCKDB_API bool ExtendedOpenFileInfo::TryGetOption(const string &name, string &result) const; //! An unsigned integer option - anything that casts to UBIGINT is accepted template <> DUCKDB_API bool ExtendedOpenFileInfo::TryGetOption(const string &name, idx_t &result) const; +//! A timestamp option - anything that casts to TIMESTAMP is accepted +template <> +DUCKDB_API bool ExtendedOpenFileInfo::TryGetOption(const string &name, timestamp_t &result) const; struct OpenFileInfo { OpenFileInfo() = default; diff --git a/src/duckdb/src/include/duckdb/common/opener_file_system.hpp b/src/duckdb/src/include/duckdb/common/opener_file_system.hpp index 576e610c9..309d3a06d 100644 --- a/src/duckdb/src/include/duckdb/common/opener_file_system.hpp +++ b/src/duckdb/src/include/duckdb/common/opener_file_system.hpp @@ -145,6 +145,9 @@ class OpenerFileSystem : public FileSystem { void MoveFile(const string &source, const string &target) { MoveFile(source, target, nullptr); } + optional GetStatsIfExists(const OpenFileInfo &file) { + return GetStatsIfExists(file, nullptr); + } bool FileExists(const string &filename) { return FileExists(filename, nullptr); } @@ -175,6 +178,12 @@ class OpenerFileSystem : public FileSystem { return GetFileSystem().FileExists(filename, GetOpener()); } + optional GetStatsIfExists(const OpenFileInfo &file, optional_ptr opener) override { + VerifyNoOpener(opener); + VerifyCanAccessFile(file.path); + return GetFileSystem().GetStatsIfExists(file, GetOpener()); + } + bool IsPipe(const string &filename, optional_ptr opener) override { VerifyNoOpener(opener); return GetFileSystem().IsPipe(filename, GetOpener()); @@ -276,11 +285,7 @@ class OpenerFileSystem : public FileSystem { } unique_ptr GlobFilesExtended(const string &path, const FileGlobInput &input, - optional_ptr opener) override { - VerifyNoOpener(opener); - VerifyCanAccessFile(path); - return GetFileSystem().Glob(path, input, GetOpener()); - } + optional_ptr opener) override; bool SupportsGlobExtended() const override { return true; diff --git a/src/duckdb/src/include/duckdb/common/operator/aggregate_operators.hpp b/src/duckdb/src/include/duckdb/common/operator/aggregate_operators.hpp index e0da13d4f..05a403c9d 100644 --- a/src/duckdb/src/include/duckdb/common/operator/aggregate_operators.hpp +++ b/src/duckdb/src/include/duckdb/common/operator/aggregate_operators.hpp @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include #include "duckdb/common/operator/comparison_operators.hpp" @@ -29,6 +30,48 @@ struct Max { } }; +template +inline T MinFloatingPoint(T left, T right) { + if (std::isnan(left)) { + return right; + } + if (std::isnan(right)) { + return left; + } + return right > left ? left : right; +} + +template +inline T MaxFloatingPoint(T left, T right) { + if (std::isnan(right)) { + return right; + } + if (std::isnan(left)) { + return left; + } + return left > right ? left : right; +} + +template <> +inline float Min::Operation(float left, float right) { + return MinFloatingPoint(left, right); +} + +template <> +inline double Min::Operation(double left, double right) { + return MinFloatingPoint(left, right); +} + +template <> +inline float Max::Operation(float left, float right) { + return MaxFloatingPoint(left, right); +} + +template <> +inline double Max::Operation(double left, double right) { + return MaxFloatingPoint(left, right); +} + struct LogicalAnd { template static inline T Operation(T left, T right) { diff --git a/src/duckdb/src/include/duckdb/common/query_parameters.hpp b/src/duckdb/src/include/duckdb/common/query_parameters.hpp deleted file mode 100644 index 19d0d9d8d..000000000 --- a/src/duckdb/src/include/duckdb/common/query_parameters.hpp +++ /dev/null @@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/query_parameters.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/common.hpp" - -namespace duckdb { - -enum class QueryResultOutputType : uint8_t { FORCE_MATERIALIZED, ALLOW_STREAMING }; - -enum class QueryResultMemoryType : uint8_t { IN_MEMORY, BUFFER_MANAGED }; - -struct QueryParameters { - QueryParameters() { - } - QueryParameters(bool allow_streaming) // NOLINT: allow implicit conversion - : output_type(allow_streaming ? QueryResultOutputType::ALLOW_STREAMING - : QueryResultOutputType::FORCE_MATERIALIZED) { - } - QueryParameters(QueryResultOutputType output_type) // NOLINT: allow implicit conversion - : output_type(output_type) { - } - QueryResultOutputType output_type = QueryResultOutputType::FORCE_MATERIALIZED; - QueryResultMemoryType memory_type = QueryResultMemoryType::IN_MEMORY; -}; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/shared_ptr_ipp.hpp b/src/duckdb/src/include/duckdb/common/shared_ptr_ipp.hpp index e60681c03..b313c233a 100644 --- a/src/duckdb/src/include/duckdb/common/shared_ptr_ipp.hpp +++ b/src/duckdb/src/include/duckdb/common/shared_ptr_ipp.hpp @@ -55,7 +55,7 @@ class shared_ptr { // NOLINT: invalid case style } // From raw pointer of type T with custom DELETER template - shared_ptr(T *ptr, DELETER deleter) : internal(ptr, deleter) { + shared_ptr(T *ptr, DELETER deleter) : internal(ptr, std::move(deleter)) { __enable_weak_this(internal.get(), internal.get()); } // Aliasing constructor: shares ownership information with ref but contains ptr instead @@ -92,7 +92,7 @@ class shared_ptr { // NOLINT: invalid case style } // Construct from std::shared_ptr - explicit shared_ptr(std::shared_ptr other) : internal(other) { + explicit shared_ptr(std::shared_ptr other) : internal(std::move(other)) { // FIXME: should we __enable_weak_this here? // *our* enable_shared_from_this hasn't initialized yet, so I think so? __enable_weak_this(internal.get(), internal.get()); @@ -100,7 +100,7 @@ class shared_ptr { // NOLINT: invalid case style // Construct from weak_ptr template - explicit shared_ptr(weak_ptr other) : internal(other.internal) { + explicit shared_ptr(const weak_ptr &other) : internal(other.internal) { } // Construct from unique_ptr, takes over ownership of the unique_ptr diff --git a/src/duckdb/src/include/duckdb/common/string_util.hpp b/src/duckdb/src/include/duckdb/common/string_util.hpp index 9411a9178..bee930182 100644 --- a/src/duckdb/src/include/duckdb/common/string_util.hpp +++ b/src/duckdb/src/include/duckdb/common/string_util.hpp @@ -243,7 +243,7 @@ class StringUtil { //! Format a string using printf semantics template - static string Format(const string fmt_str, ARGS... params) { + static string Format(const string &fmt_str, const ARGS &...params) { return Exception::ConstructMessage(fmt_str, params...); } diff --git a/src/duckdb/src/include/duckdb/common/types.hpp b/src/duckdb/src/include/duckdb/common/types.hpp index a1f029e13..904206641 100644 --- a/src/duckdb/src/include/duckdb/common/types.hpp +++ b/src/duckdb/src/include/duckdb/common/types.hpp @@ -324,6 +324,8 @@ struct LogicalType { } DUCKDB_API bool operator==(const LogicalType &rhs) const; + //! Logical type equality including collations in this type and its children. + DUCKDB_API bool EqualsIncludingCollation(const LogicalType &rhs) const; inline bool operator!=(const LogicalType &rhs) const { return !(*this == rhs); } diff --git a/src/duckdb/src/include/duckdb/common/types/batched_data_collection.hpp b/src/duckdb/src/include/duckdb/common/types/batched_data_collection.hpp index d52852c89..1c65414a3 100644 --- a/src/duckdb/src/include/duckdb/common/types/batched_data_collection.hpp +++ b/src/duckdb/src/include/duckdb/common/types/batched_data_collection.hpp @@ -10,7 +10,7 @@ #include "duckdb/common/map.hpp" #include "duckdb/common/types/column/column_data_collection.hpp" -#include "duckdb/common/query_parameters.hpp" +#include "duckdb/common/enums/query_result_memory_type.hpp" namespace duckdb { diff --git a/src/duckdb/src/include/duckdb/common/types/conflict_manager.hpp b/src/duckdb/src/include/duckdb/common/types/conflict_manager.hpp index 440e1ad70..aa7a21be1 100644 --- a/src/duckdb/src/include/duckdb/common/types/conflict_manager.hpp +++ b/src/duckdb/src/include/duckdb/common/types/conflict_manager.hpp @@ -69,15 +69,18 @@ class ConflictManager { } //! Adds an index and its respective delete_index. - void AddIndex(const shared_ptr &index, const Identifier &index_name, - shared_ptr delete_index) { + void AddIndex(const shared_ptr &index, shared_ptr delete_index) { matching_indexes.push_back(index); matching_delete_indexes.push_back(std::move(delete_index)); - index_names.insert(index_name); } //! Returns true, if the index is in this conflict manager. - bool IndexMatches(const Identifier &index_name) const { - return index_names.find(index_name) != index_names.end(); + bool IndexMatches(const shared_ptr &index) const { + for (const auto &matching_index : matching_indexes) { + if (matching_index == index) { + return true; + } + } + return false; } //! Returns a reference to the matching indexes. const vector> &MatchingIndexes() const { @@ -139,11 +142,7 @@ class ConflictManager { vector> matching_indexes; //! Delete indexes matching the conflict target. vector> matching_delete_indexes; - //! All matching indexes by their name (unique identifier). - identifier_set_t index_names; - //! Registers all conflicting rows in a data chunk. - unordered_set conflict_rows; //! True, if we can skip recording any further conflicts. bool finished = false; @@ -201,7 +200,7 @@ class ConflictManager { //! Returns true, if we register a conflict for the lookup type. bool IsConflict(LookupResultType type); //! Adds a hit to the conflicts. - bool AddHit(const idx_t index_in_chunk, const std::function &callback); + bool AddHitInternal(const idx_t index_in_chunk, const row_t row_id, const bool second); //! Determine visible row ID for each index with two possible row IDs. void Finalize(const std::function &callback); //! Returns true, if the conflict manager should throw an exception, else false. @@ -224,23 +223,10 @@ class ConflictManager { } //! Adds a row ID to the primary conflict data. - void AddRowId(const idx_t index_in_chunk, const row_t row_id) { - // Only ON CONFLICT DO NOTHING can have multiple conflict targets, - // which can cause multiple row IDs per index_in_chunk. - // We let them overwrite each other, as we don't need the row IDs later. - auto elem = conflict_rows.find(index_in_chunk); - if (elem == conflict_rows.end()) { - // We have not yet seen this conflict: insert. - conflict_rows.insert(index_in_chunk); - GetConflictData(FIRST).Insert(index_in_chunk, row_id); - } - } + void AddRowId(const idx_t index_in_chunk, const row_t row_id); //! Adds a row ID to the secondary conflict data. - void AddSecondRowId(const idx_t index_in_chunk, const row_t row_id) { - D_ASSERT(conflict_rows.find(index_in_chunk) != conflict_rows.end()); - GetConflictData(SECOND).Insert(index_in_chunk, row_id); - } + void AddSecondRowId(const idx_t index_in_chunk, const row_t row_id); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/common/types/value.hpp b/src/duckdb/src/include/duckdb/common/types/value.hpp index e76e74c3b..b5a4d8c96 100644 --- a/src/duckdb/src/include/duckdb/common/types/value.hpp +++ b/src/duckdb/src/include/duckdb/common/types/value.hpp @@ -66,7 +66,7 @@ class Value { //! Create a VARCHAR value DUCKDB_API Value(String val); // NOLINT: Allow implicit conversion from `string` //! Create a VARCHAR value - DUCKDB_API Value(std::string_view val); + DUCKDB_API Value(std::string_view val); // NOLINT: Allow implicit conversion from `std::string_view` //! Copy constructor DUCKDB_API Value(const Value &other); //! Move constructor @@ -203,7 +203,9 @@ class Value { return Value::BLOB(const_data_ptr_cast(data.c_str()), data.size()); } static Value BLOB_RAW(std::string_view data) { - return Value::BLOB(const_data_ptr_cast(data.data()), data.size()); + return Value::BLOB( + const_data_ptr_cast(data.data()), // NOLINT(bugprone-suspicious-stringview-data-usage): length is passed + data.size()); } //! Creates a blob by casting a specified string to a blob (i.e. interpreting \x characters) DUCKDB_API static Value BLOB(const string &data); diff --git a/src/duckdb/extension/parquet/include/reader/variant/parquet_variant_iterator.hpp b/src/duckdb/src/include/duckdb/common/types/variant/parquet_variant_iterator.hpp similarity index 79% rename from src/duckdb/extension/parquet/include/reader/variant/parquet_variant_iterator.hpp rename to src/duckdb/src/include/duckdb/common/types/variant/parquet_variant_iterator.hpp index c4097f625..dcdbf6495 100644 --- a/src/duckdb/extension/parquet/include/reader/variant/parquet_variant_iterator.hpp +++ b/src/duckdb/src/include/duckdb/common/types/variant/parquet_variant_iterator.hpp @@ -1,7 +1,7 @@ //===----------------------------------------------------------------------===// // DuckDB // -// reader/variant/parquet_variant_iterator.hpp +// duckdb/common/types/variant/parquet_variant_iterator.hpp // // //===----------------------------------------------------------------------===// @@ -16,7 +16,7 @@ #include "duckdb/common/unique_ptr.hpp" #include "duckdb/common/helper.hpp" #include "duckdb/function/scalar_function.hpp" -#include "reader/variant/variant_binary_decoder.hpp" +#include "duckdb/common/types/variant/variant_binary_decoder.hpp" namespace duckdb { @@ -52,7 +52,7 @@ struct ShreddedGroupView { vector> fields; //! Build the view recursively from a group Vector - void Build(Vector &group); + DUCKDB_API void Build(Vector &group); }; class ParquetVariantIterator; @@ -111,14 +111,14 @@ class ParquetVariantNode { return kind == Kind::MISSING; } - VariantLogicalType GetTypeId() const; + DUCKDB_API VariantLogicalType GetTypeId() const; //! Returns the fixed-width primitive payload (loaded / re-encoded as T) template T GetData() const; - string_t GetString() const; - VariantDecimalProperties GetDecimalProperties() const; - ParquetObjectIterator GetObjectChildren(VariantIterationOrder order) const; - ParquetArrayIterator GetArrayChildren() const; + DUCKDB_API string_t GetString() const; + DUCKDB_API VariantDecimalProperties GetDecimalProperties() const; + DUCKDB_API ParquetObjectIterator GetObjectChildren(VariantIterationOrder order) const; + DUCKDB_API ParquetArrayIterator GetArrayChildren() const; private: explicit ParquetVariantNode(Kind kind) : kind(kind) { @@ -149,11 +149,11 @@ struct ParquetObjectEntry { class ParquetObjectIterator { public: //! Shredded object (typed fields + optional binary overlay) - ParquetObjectIterator(const ParquetVariantIterator &state, const ShreddedGroupView &view, idx_t index, - const_data_ptr_t overlay, const_data_ptr_t overlay_end); + DUCKDB_API ParquetObjectIterator(const ParquetVariantIterator &state, const ShreddedGroupView &view, idx_t index, + const_data_ptr_t overlay, const_data_ptr_t overlay_end); //! Binary object - ParquetObjectIterator(const ParquetVariantIterator &state, const VariantMetadata &metadata, const_data_ptr_t data, - const_data_ptr_t end); + DUCKDB_API ParquetObjectIterator(const ParquetVariantIterator &state, const VariantMetadata &metadata, + const_data_ptr_t data, const_data_ptr_t end); public: const ParquetObjectEntry *begin() const { // NOLINT: match stl API @@ -174,16 +174,16 @@ class ParquetObjectIterator { class ParquetArrayIterator { public: //! Shredded array - ParquetArrayIterator(const ParquetVariantIterator &state, const ShreddedGroupView &view, idx_t index); + DUCKDB_API ParquetArrayIterator(const ParquetVariantIterator &state, const ShreddedGroupView &view, idx_t index); //! Binary array - ParquetArrayIterator(const ParquetVariantIterator &state, const VariantMetadata &metadata, const_data_ptr_t data, - const_data_ptr_t end); + DUCKDB_API ParquetArrayIterator(const ParquetVariantIterator &state, const VariantMetadata &metadata, + const_data_ptr_t data, const_data_ptr_t end); public: idx_t size() const { return length; } - ParquetVariantNode operator[](idx_t i) const; + DUCKDB_API ParquetVariantNode operator[](idx_t i) const; private: reference state; @@ -207,30 +207,30 @@ class ParquetArrayIterator { //! are fetched by value (no materialization). class ParquetVariantIterator { public: - ParquetVariantIterator(Vector &metadata, Vector &group); + DUCKDB_API ParquetVariantIterator(Vector &metadata, Vector &group); //! Binary-only: each row is a full Spark variant-encoded value (the metadata blob immediately followed //! by the value blob). There is no shredded group - the value is read right after the metadata. - explicit ParquetVariantIterator(Vector &metadata); + DUCKDB_API explicit ParquetVariantIterator(Vector &metadata); public: //! Reset the per-row state (lazily-decoded metadata) for a new row - void BeginRow(idx_t row); + DUCKDB_API void BeginRow(idx_t row); //! Resolve the root value of 'row' (a missing root is promoted to a SQL NULL) - ParquetVariantNode Root(idx_t row) const; + DUCKDB_API ParquetVariantNode Root(idx_t row) const; //! Resolve the root of a binary-only row: the value blob starts right after the metadata - ParquetVariantNode BinaryRoot() const; + DUCKDB_API ParquetVariantNode BinaryRoot() const; //! Resolve the value of the group 'view' at logical position 'index' - ParquetVariantNode ResolveGroup(const ShreddedGroupView &view, idx_t index) const; + DUCKDB_API ParquetVariantNode ResolveGroup(const ShreddedGroupView &view, idx_t index) const; //! The (lazily-decoded) Variant metadata of the current row - const VariantMetadata &GetMetadata() const; + DUCKDB_API const VariantMetadata &GetMetadata() const; //! The recursive view of the Parquet group tree (used by the shredded-conversion path) const ShreddedGroupView &GetRootView() const { return root_view; } //! Emit the binary value in ['data', 'end') of the current row into the builder (BeginRow must precede) - void EmitBinary(const_data_ptr_t data, const_data_ptr_t end, VariantBuilder &builder) const; + DUCKDB_API void EmitBinary(const_data_ptr_t data, const_data_ptr_t end, VariantBuilder &builder) const; private: ShreddedGroupView root_view; @@ -248,10 +248,12 @@ class ParquetVariantConversion { public: //! Convert binary Variant values (each row being the metadata blob followed by the value blob) into the //! canonical VARIANT 'result' in a single pass - static void ConvertBinary(Vector &metadata_and_value, Vector &result, idx_t count); - //! 'variant_bytes_to_variant': decode a binary Variant value (metadata followed by value) into a VARIANT. - //! The inverse of 'variant_to_parquet_variant'. - static ScalarFunction GetBytesToVariantFunction(); + DUCKDB_API static void ConvertBinary(Vector &metadata_and_value, Vector &result, idx_t count); + + //! Convert VARIANT values into the Parquet Variant layout declared by 'result's type — + //! struct. This is 'variant_to_parquet_variant's + //! conversion, and also the storage of the arrow.parquet.variant canonical extension type. + DUCKDB_API static void ToParquetVariant(const Vector &variant, idx_t count, Vector &result); }; } // namespace duckdb diff --git a/src/duckdb/extension/parquet/include/reader/variant/variant_binary_decoder.hpp b/src/duckdb/src/include/duckdb/common/types/variant/variant_binary_decoder.hpp similarity index 92% rename from src/duckdb/extension/parquet/include/reader/variant/variant_binary_decoder.hpp rename to src/duckdb/src/include/duckdb/common/types/variant/variant_binary_decoder.hpp index d9bfacdd7..a4a9459ee 100644 --- a/src/duckdb/extension/parquet/include/reader/variant/variant_binary_decoder.hpp +++ b/src/duckdb/src/include/duckdb/common/types/variant/variant_binary_decoder.hpp @@ -16,7 +16,7 @@ namespace duckdb { struct VariantMetadataHeader { public: - static VariantMetadataHeader FromHeaderByte(uint8_t byte); + DUCKDB_API static VariantMetadataHeader FromHeaderByte(uint8_t byte); public: //! The version of the protocol used (only '1' supported for now) @@ -29,7 +29,7 @@ struct VariantMetadataHeader { struct VariantMetadata { public: - explicit VariantMetadata(const string_t &metadata); + DUCKDB_API explicit VariantMetadata(const string_t &metadata); public: const string_t &metadata; @@ -80,7 +80,7 @@ struct VariantValueMetadata { } public: - static VariantValueMetadata FromHeaderByte(uint8_t byte); + DUCKDB_API static VariantValueMetadata FromHeaderByte(uint8_t byte); static VariantBasicType VariantBasicTypeFromByte(uint8_t byte) { if (byte >= static_cast(VariantBasicType::INVALID)) { throw NotImplementedException("Variant BasicType (%d) is not supported", byte); diff --git a/src/duckdb/src/include/duckdb/common/types/variant/variant_builder.hpp b/src/duckdb/src/include/duckdb/common/types/variant/variant_builder.hpp index 3ca61f325..08ede9dc5 100644 --- a/src/duckdb/src/include/duckdb/common/types/variant/variant_builder.hpp +++ b/src/duckdb/src/include/duckdb/common/types/variant/variant_builder.hpp @@ -101,6 +101,8 @@ struct VariantBuilder { //! maps a key string to its (unsorted) dictionary index, owned by the result's keys vector OrderedOwningStringMap &dictionary; + static constexpr idx_t INIT_NESTING_DEPTH = 8; + //! the offsets at which the current row's entries begin idx_t row_values = 0; idx_t row_children = 0; @@ -126,14 +128,18 @@ struct VariantBuilder { //! Emit a VARIANT_NULL value void EmitNull() { type_ids.push_back(static_cast(VariantLogicalType::VARIANT_NULL)); - byte_offsets.push_back(NumericCast(blob.size())); + //! 'blob' may already exceed uint32_t mid-row; this offset is only read once the row is known to fit + //! (checked in BuildVariant once the row is fully emitted), so a narrowing wrap here is harmless. + byte_offsets.push_back(static_cast(blob.size())); } //! Emit an OBJECT value with 'n' children (assumed to be in lexicographic key order). 'key_fn(i)' //! returns the (string_t) key of child i; 'emit_fn(i)' must emit exactly one value for child i. template void EmitObject(idx_t n, KEY_FN &&key_fn, EMIT_FN &&emit_fn) { - auto byte_offset = NumericCast(blob.size()); + //! 'blob' may already exceed uint32_t mid-row; this offset is only read once the row is known to fit + //! (checked in BuildVariant once the row is fully emitted), so a narrowing wrap here is harmless. + auto byte_offset = static_cast(blob.size()); type_ids.push_back(static_cast(VariantLogicalType::OBJECT)); byte_offsets.push_back(byte_offset); VariantBuilderAppendVarint(blob, NumericCast(n)); @@ -155,7 +161,9 @@ struct VariantBuilder { //! Emit an ARRAY value with 'n' elements. 'emit_fn(i)' must emit exactly one value for element i. template void EmitArray(idx_t n, EMIT_FN &&emit_fn) { - auto byte_offset = NumericCast(blob.size()); + //! 'blob' may already exceed uint32_t mid-row; this offset is only read once the row is known to fit + //! (checked in BuildVariant once the row is fully emitted), so a narrowing wrap here is harmless. + auto byte_offset = static_cast(blob.size()); type_ids.push_back(static_cast(VariantLogicalType::ARRAY)); byte_offsets.push_back(byte_offset); VariantBuilderAppendVarint(blob, NumericCast(n)); @@ -341,7 +349,9 @@ struct VariantBuilder { //! 'it.GetDecimalProperties()' followed by 'it.GetData()' at the physical type implied by the width. template void EmitPrimitiveNode(const NODE &it, VariantLogicalType type_id) { - auto byte_offset = NumericCast(blob.size()); + //! 'blob' may already exceed uint32_t mid-row; this offset is only read once the row is known to fit + //! (checked in BuildVariant once the row is fully emitted), so a narrowing wrap here is harmless. + auto byte_offset = static_cast(blob.size()); type_ids.push_back(static_cast(type_id)); byte_offsets.push_back(byte_offset); switch (type_id) { @@ -455,6 +465,32 @@ struct VariantBuilder { throw InternalException("EmitPrimitiveNode: unhandled VariantLogicalType (%d)", static_cast(type_id)); } } + + optional_idx BeginContainer(VariantLogicalType type_id, idx_t n) { + auto byte_offset = NumericCast(blob.size()); + type_ids.push_back(static_cast(type_id)); + byte_offsets.push_back(byte_offset); + VariantBuilderAppendVarint(blob, NumericCast(n)); + if (!n) { + return optional_idx(); + } + VariantBuilderAppendVarint(blob, LocalChild()); + auto block = child_value_ids.size(); + child_value_ids.resize(block + n); + child_key_ids.resize(block + n); + return optional_idx(block); + } + + void AssignObjectChild(idx_t block, idx_t i, string_t key) { + child_value_ids[block + i] = LocalValue(); + child_key_ids[block + i] = LocalKey(); + key_slots.push_back(VariantBuilderGetOrCreateIndex(dictionary, key)); + } + + void AssignArrayChild(idx_t block, idx_t i) { + child_value_ids[block + i] = LocalValue(); + child_key_ids[block + i] = VARIANT_INVALID_KEY; + } }; //===--------------------------------------------------------------------===// @@ -474,29 +510,90 @@ auto CollectObjectChildren(const NODE &it) { //! Traverse a VariantNode-like cursor 'it' (any type exposing the node concept) into the builder. template -void EmitIterator(const NODE &it, VariantBuilder &builder) { - if (it.IsNull() || it.IsMissing()) { - builder.EmitNull(); - return; - } +void EmitIterator(const NODE &root, VariantBuilder &builder) { + using EntryT = typename decltype(CollectObjectChildren(root))::value_type; + using ArrayIterT = decltype(std::declval().GetArrayChildren()); + + struct Frame { + bool is_object = false; + idx_t index = 0; + idx_t block = 0; + vector object_children; + optional array_children; + }; + + vector stack; + stack.reserve(VariantBuilder::INIT_NESTING_DEPTH); + + auto ProcessNode = [&](const NODE &node) { + if (node.IsNull() || node.IsMissing()) { + builder.EmitNull(); + return; + } + auto type_id = node.GetTypeId(); + switch (type_id) { + case VariantLogicalType::OBJECT: { + auto children = CollectObjectChildren(node); + auto n = children.size(); + if (stack.size() >= stack.capacity()) { + stack.reserve(NextPowerOfTwo(stack.size() + 1)); + } + auto block = builder.BeginContainer(VariantLogicalType::OBJECT, n); + if (block.IsValid()) { + Frame frame; + frame.is_object = true; + frame.block = block.GetIndex(); + frame.object_children = std::move(children); + stack.push_back(std::move(frame)); + } + break; + } + case VariantLogicalType::ARRAY: { + auto array_iter = node.GetArrayChildren(); + auto n = array_iter.size(); + if (stack.size() >= stack.capacity()) { + stack.reserve(NextPowerOfTwo(stack.size() + 1)); + } + auto block = builder.BeginContainer(VariantLogicalType::ARRAY, n); + if (block.IsValid()) { + Frame frame; + frame.is_object = false; + frame.block = block.GetIndex(); + frame.array_children.emplace(std::move(array_iter)); + stack.push_back(std::move(frame)); + } + break; + } + default: + builder.EmitPrimitiveNode(node, type_id); + break; + } + }; - auto type_id = it.GetTypeId(); - switch (type_id) { - case VariantLogicalType::OBJECT: { - auto children = CollectObjectChildren(it); - builder.EmitObject( - children.size(), [&](idx_t i) { return children[i].key; }, - [&](idx_t i) { EmitIterator(children[i].value, builder); }); - break; - } - case VariantLogicalType::ARRAY: { - auto array = it.GetArrayChildren(); - builder.EmitArray(array.size(), [&](idx_t i) { EmitIterator(array[i], builder); }); - break; - } - default: - builder.EmitPrimitiveNode(it, type_id); - break; + ProcessNode(root); + + while (!stack.empty()) { + auto &frame = stack.back(); + + const idx_t count = frame.is_object ? frame.object_children.size() : frame.array_children->size(); + + if (frame.index >= count) { + stack.pop_back(); + continue; + } + + const bool is_object = frame.is_object; + const idx_t block = frame.block; + const idx_t i = frame.index++; + + if (is_object) { + auto &entry = frame.object_children[i]; + builder.AssignObjectChild(block, i, entry.key); + ProcessNode(entry.value); + } else { + builder.AssignArrayChild(block, i); + ProcessNode((*frame.array_children)[i]); + } } } @@ -531,6 +628,12 @@ void BuildVariant(SOURCE &source, idx_t count, Vector &result) { for (idx_t row = 0; row < count; row++) { builder.BeginRow(); bool is_null = source.Emit(row, builder); + size_t temp = builder.blob.size(); + if (temp > NumericLimits::Maximum()) { + throw InvalidInputException( + "Cannot convert value to VARIANT: encoded row size exceeds the maximum supported %u bytes", + NumericLimits::Maximum()); + } blob_writer.WriteValue(string_t(builder.blob.data(), NumericCast(builder.blob.size()))); if (is_null) { //! SPEC: If a Variant is missing in a context where a value is required, readers must return a Variant null diff --git a/src/duckdb/src/include/duckdb/common/types/variant_visitor.hpp b/src/duckdb/src/include/duckdb/common/types/variant_visitor.hpp index f8cd314d5..7787fc0a1 100644 --- a/src/duckdb/src/include/duckdb/common/types/variant_visitor.hpp +++ b/src/duckdb/src/include/duckdb/common/types/variant_visitor.hpp @@ -1,5 +1,6 @@ #pragma once +#include "duckdb/common/algorithm.hpp" #include "duckdb/common/types/variant.hpp" #include "duckdb/common/types/variant_iterator.hpp" #include "duckdb/function/scalar/variant_utils.hpp" @@ -34,7 +35,7 @@ class VariantVisitor { template static ReturnType Visit(const UnifiedVariantVectorData &variant, idx_t row, uint32_t values_idx, Args &&...args) { if (!variant.RowIsValid(row)) { - VisitMetadata(VariantLogicalType::VARIANT_NULL, std::forward(args)...); + VisitMetadata(VariantLogicalType::VARIANT_NULL, args...); return Visitor::VisitNull(std::forward(args)...); } @@ -43,7 +44,7 @@ class VariantVisitor { auto blob_data = const_data_ptr_cast(variant.GetData(row).GetData()); auto ptr = const_data_ptr_cast(blob_data + byte_offset); - VisitMetadata(type_id, std::forward(args)...); + VisitMetadata(type_id, args...); switch (type_id) { case VariantLogicalType::VARIANT_NULL: @@ -120,12 +121,12 @@ class VariantVisitor { template static ReturnType Visit(const VariantNode &node, Args &&...args) { if (node.IsNull() || node.IsMissing()) { - VisitMetadata(VariantLogicalType::VARIANT_NULL, std::forward(args)...); + VisitMetadata(VariantLogicalType::VARIANT_NULL, args...); return Visitor::VisitNull(std::forward(args)...); } auto type_id = node.GetTypeId(); - VisitMetadata(type_id, std::forward(args)...); + VisitMetadata(type_id, args...); switch (type_id) { case VariantLogicalType::VARIANT_NULL: @@ -208,7 +209,7 @@ class VariantVisitor { array_items.reserve(array_data.child_count); for (idx_t i = 0; i < array_data.child_count; i++) { auto values_index = variant.GetValuesIndex(row, array_data.children_idx + i); - array_items.emplace_back(Visit(variant, row, values_index, std::forward(args)...)); + array_items.emplace_back(Visit(variant, row, values_index, args...)); } return array_items; } @@ -220,7 +221,7 @@ class VariantVisitor { Args &&...args) { for (idx_t i = 0; i < array_data.child_count; i++) { auto values_index = variant.GetValuesIndex(row, array_data.children_idx + i); - Visit(variant, row, values_index, std::forward(args)...); + Visit(variant, row, values_index, args...); } } @@ -230,7 +231,7 @@ class VariantVisitor { vector array_items; array_items.reserve(array.GetArrayChildren().size()); for (const auto &child : array.GetArrayChildren()) { - array_items.emplace_back(Visit(child, std::forward(args)...)); + array_items.emplace_back(Visit(child, args...)); } return array_items; } @@ -239,7 +240,7 @@ class VariantVisitor { template static std::enable_if_t, void> VisitArrayItems(const VariantNode &array, Args &&...args) { for (const auto &child : array.GetArrayChildren()) { - Visit(child, std::forward(args)...); + Visit(child, args...); } } @@ -249,13 +250,18 @@ class VariantVisitor { child_list_t object_items; for (idx_t i = 0; i < object_data.child_count; i++) { auto values_index = variant.GetValuesIndex(row, object_data.children_idx + i); - auto val = Visit(variant, row, values_index, std::forward(args)...); + auto val = Visit(variant, row, values_index, args...); auto keys_index = variant.GetKeysIndex(row, object_data.children_idx + i); auto &key = variant.GetKey(row, keys_index); object_items.emplace_back(key.GetString(), std::move(val)); } + std::stable_sort( + object_items.begin(), object_items.end(), + [](const std::pair &lhs, const std::pair &rhs) { + return lhs.first.GetIdentifierName() < rhs.first.GetIdentifierName(); + }); return object_items; } diff --git a/src/duckdb/src/include/duckdb/common/vector/vector_writer.hpp b/src/duckdb/src/include/duckdb/common/vector/vector_writer.hpp index 7cf533a69..1681a9aa7 100644 --- a/src/duckdb/src/include/duckdb/common/vector/vector_writer.hpp +++ b/src/duckdb/src/include/duckdb/common/vector/vector_writer.hpp @@ -500,7 +500,7 @@ class DynamicListAppender { } DynamicListAppender(const DynamicListAppender &) = delete; DynamicListAppender(DynamicListAppender &&) = delete; - ~DynamicListAppender() { + ~DynamicListAppender() { // NOLINT(bugprone-exception-escape): writer invariants make these setters non-throwing. parent.list_data[row_idx] = {base_offset, current_length}; parent.child_offset = base_offset + current_length; VectorWriterSetListSize(parent.list_vec, base_offset + current_length); diff --git a/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp b/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp index 693c06239..82375f252 100644 --- a/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp +++ b/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp @@ -312,9 +312,9 @@ class AggregateExecutor { // COUNT(*) can add run lengths directly. if (aggr_input_data.clustered) { auto &cs = *aggr_input_data.clustered; - for (idx_t r = 0; r < cs.n_group_runs; r++) { - OP::template ConstantOperation(*reinterpret_cast(cs.group_runs[r].state), - aggr_input_data, cs.group_runs[r].count); + for (auto &run : cs.runs()) { + OP::template ConstantOperation(*reinterpret_cast(run.state), + aggr_input_data, run.count); } return; } @@ -335,10 +335,9 @@ class AggregateExecutor { template static void NullaryClustUpdate(AggregateInputData &aggr_input_data, const ClusteredAggr &clustered, idx_t count) { - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - OP::template ConstantOperation( - *reinterpret_cast(clustered.group_runs[r].state), aggr_input_data, - clustered.group_runs[r].count); + for (auto &run : clustered.runs()) { + OP::template ConstantOperation(*reinterpret_cast(run.state), aggr_input_data, + run.count); } } @@ -451,34 +450,34 @@ class AggregateExecutor { idx_t pos = 0; using local_type = clustered_local_state_t; if (cluster_iter) { - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); local_type local; OP::template InitializeClusteredLocal(local, state); - auto run_count = clustered.group_runs[r].count; + auto run_count = run.count; auto saw_value = UpdateUnaryClusteredOpt( vals, local, run_count, validity, cluster_iter + pos); OP::template FlushClusteredLocal(state, local, saw_value); pos += run_count; } } else if (isel) { - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); local_type local; OP::template InitializeClusteredLocal(local, state); - auto run_count = clustered.group_runs[r].count; + auto run_count = run.count; auto saw_value = UpdateUnaryClusteredOpt( - vals, local, run_count, validity, clustered.group_runs[r].sel, isel); + vals, local, run_count, validity, run.sel, isel); OP::template FlushClusteredLocal(state, local, saw_value); } } else { - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); local_type local; OP::template InitializeClusteredLocal(local, state); - auto run_count = clustered.group_runs[r].count; + auto run_count = run.count; auto saw_value = UpdateUnaryClusteredOpt( - vals, local, run_count, validity, clustered.group_runs[r].sel); + vals, local, run_count, validity, run.sel); OP::template FlushClusteredLocal(state, local, saw_value); } } @@ -502,8 +501,8 @@ class AggregateExecutor { } static inline bool IsDenseSingleRun(const ClusteredAggr &clustered, idx_t count) { - return clustered.n_group_runs == 1 && clustered.group_runs[0].count == count && - clustered.group_runs[0].sel == nullptr; + auto runs = clustered.runs(); + return runs.size() == 1 && runs[0].count == count && runs[0].sel == nullptr; } template @@ -525,7 +524,8 @@ class AggregateExecutor { auto vals = FlatVector::GetData(input); auto &validity = FlatVector::Validity(input); if (IsDenseSingleRun(clustered, count)) { - auto &state = *reinterpret_cast(clustered.group_runs[0].state); + auto runs = clustered.runs(); + auto &state = *reinterpret_cast(runs[0].state); using local_type = clustered_local_state_t; local_type local; OP::template InitializeClusteredLocal(local, state); @@ -544,11 +544,11 @@ class AggregateExecutor { } const auto &constant_input = *ConstantVector::GetData(input); using has_repeat_count = HasClusteredLocalRepeatCount; - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); local_type local; OP::template InitializeClusteredLocal(local, state); - auto run_count = clustered.group_runs[r].count; + auto run_count = run.count; if (run_count != 0) { UpdateUnaryClusteredLocalRepeat(local, constant_input, run_count, has_repeat_count {}); @@ -589,10 +589,9 @@ class AggregateExecutor { } auto idata = ConstantVector::GetData(input); AggregateUnaryInput unary_input(aggr_input_data, ConstantVector::Validity(input)); - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); - OP::template ConstantOperation(state, *idata, unary_input, - clustered.group_runs[r].count); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); + OP::template ConstantOperation(state, *idata, unary_input, run.count); } } @@ -608,11 +607,10 @@ class AggregateExecutor { input.ToUnifiedFormat(idata); auto vals = UnifiedVectorFormat::GetData(idata); AggregateUnaryInput unary_input(aggr_input_data, idata.validity); - for (idx_t r = 0; r < clustered.n_group_runs; r++) { - auto &state = *reinterpret_cast(clustered.group_runs[r].state); - OP::template ClusteredOp(state, vals, unary_input, clustered.group_runs[r].sel, - *idata.sel, idata.validity, 0, - clustered.group_runs[r].count); + for (auto &run : clustered.runs()) { + auto &state = *reinterpret_cast(run.state); + OP::template ClusteredOp(state, vals, unary_input, run.sel, *idata.sel, + idata.validity, 0, run.count); } } @@ -637,7 +635,7 @@ class AggregateExecutor { } } } - auto *cluster_iter = clustered.ClusterIter(input, count); + auto *cluster_iter = clustered.ClusterIter(input); if (cluster_iter) { ExecuteUnaryClusteredDictOpt(input, clustered, count, cluster_iter); diff --git a/src/duckdb/src/include/duckdb/common/virtual_file_system.hpp b/src/duckdb/src/include/duckdb/common/virtual_file_system.hpp index 45b39856f..50fbefecc 100644 --- a/src/duckdb/src/include/duckdb/common/virtual_file_system.hpp +++ b/src/duckdb/src/include/duckdb/common/virtual_file_system.hpp @@ -37,6 +37,8 @@ class VirtualFileSystem : public FileSystem { string GetVersionTag(FileHandle &handle) override; FileType GetFileType(FileHandle &handle) override; FileMetadata Stats(FileHandle &handle) override; + optional GetStatsIfExists(const OpenFileInfo &file, + optional_ptr opener = nullptr) override; void Truncate(FileHandle &handle, int64_t new_size) override; diff --git a/src/duckdb/src/include/duckdb/common/winapi.hpp b/src/duckdb/src/include/duckdb/common/winapi.hpp index 67287565f..3bde64945 100644 --- a/src/duckdb/src/include/duckdb/common/winapi.hpp +++ b/src/duckdb/src/include/duckdb/common/winapi.hpp @@ -13,7 +13,7 @@ #ifdef DUCKDB_STATIC_BUILD #define DUCKDB_API #else -#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION) +#ifdef DUCKDB_BUILD_LIBRARY #define DUCKDB_API __declspec(dllexport) #else #define DUCKDB_API __declspec(dllimport) diff --git a/src/duckdb/src/include/duckdb/execution/executor.hpp b/src/duckdb/src/include/duckdb/execution/executor.hpp index 1ccf7468f..9e17a1736 100644 --- a/src/duckdb/src/include/duckdb/execution/executor.hpp +++ b/src/duckdb/src/include/duckdb/execution/executor.hpp @@ -9,7 +9,7 @@ #pragma once #include "duckdb/common/common.hpp" -#include "duckdb/common/enums/pending_execution_result.hpp" +#include "duckdb/common/enums/query_result_state.hpp" #include "duckdb/common/mutex.hpp" #include "duckdb/common/pair.hpp" #include "duckdb/common/reference_map.hpp" @@ -21,10 +21,12 @@ #include namespace duckdb { +class BufferedData; class ClientContext; class DataChunk; class PhysicalOperator; class PipelineExecutor; +class ProgressVerifier; class OperatorState; class QueryProfiler; class ThreadContext; @@ -60,7 +62,10 @@ class Executor { bool HasTaskInProgress() const { return task != nullptr; } - PendingExecutionResult ExecuteTask(bool dry_run = false); + //! Run one partial task slice on the calling thread and report the resulting state + QueryResultState ExecuteTask(); + //! Report the execution state without running any task + QueryResultState Poll(); void WaitForTask(); void SignalTaskRescheduled(lock_guard &); @@ -120,6 +125,10 @@ class Executor { } void UnregisterTask(); + //! Set the buffer of the result this query produces. Called at submission, before execution starts + void SetResultBuffer(shared_ptr result_buffer_p); + shared_ptr GetResultBuffer(); + idx_t GetTotalPipelines() const { return total_pipelines; } @@ -128,10 +137,18 @@ class Executor { return completed_pipelines.load(); } + //! The progress verifier of this query (if debug_verify_progress is enabled) + optional_ptr GetProgressVerifier() { + return progress_verifier.get(); + } + private: - //! Whether a producer is parked on the result sink's buffer. A parked producer - //! implies a poppable chunk, and only consumption restarts it + //! Whether the result sink waits on the consumer: a producer is parked for the retention + //! decision, or for space that only a pop frees bool ResultCollectorIsBlocked(); + //! Whether this query's store can park a producer for the consumer at all. A store settled on + //! retained never parks, so the retained hot path skips the readiness checks + bool ResultStoreCanPark(); void InitializeInternal(PhysicalOperator &physical_plan); void ScheduleEvents(const vector> &meta_pipelines); @@ -142,6 +159,12 @@ class Executor { vector &visited, vector &recursion_stack); bool NextExecutor(); + //! The state to report when this thread has no task to run + QueryResultState IdleState(); + //! Cancel all tasks and throw the recorded error + void FailExecution(); + //! Advance to the next executor, or record and return FINISHED + QueryResultState FinishExecution(); shared_ptr CreateChildPipeline(Pipeline ¤t, PhysicalOperator &op); @@ -171,6 +194,8 @@ class Executor { shared_ptr profiler; //! Task error manager TaskErrorManager error_manager; + //! Verifies the progress reported by the pipelines (debug setting) + unique_ptr progress_verifier; //! The amount of completed pipelines of the query atomic completed_pipelines; @@ -180,7 +205,7 @@ class Executor { bool cancelled; //! The last pending execution result (if any) - PendingExecutionResult execution_result; + QueryResultState execution_result; //! The current task in process (if any) shared_ptr task; @@ -191,6 +216,11 @@ class Executor { //! Currently alive executor tasks atomic executor_tasks; + //! Leaf lock for the result buffer slot. It must not share executor_lock, which is held while + //! readiness is checked + mutex result_buffer_lock; + //! The buffer of the result this query produces, or null for a query that has none + shared_ptr result_buffer; //! Total time blocked while waiting on tasks, in microseconds atomic blocked_thread_time; diff --git a/src/duckdb/src/include/duckdb/execution/ie_join_union.hpp b/src/duckdb/src/include/duckdb/execution/ie_join_union.hpp new file mode 100644 index 000000000..9ab28bfb9 --- /dev/null +++ b/src/duckdb/src/include/duckdb/execution/ie_join_union.hpp @@ -0,0 +1,209 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/ie_join_union.hpp +// +//===----------------------------------------------------------------------===// +#pragma once +#include "duckdb/execution/operator/join/physical_range_join.hpp" +#include "duckdb/common/types/column/column_data_collection.hpp" +#include "duckdb/common/types/column/column_data_scan_states.hpp" +#include "duckdb/common/vector/flat_vector.hpp" + +namespace duckdb { + +template +class IEJoinCursor { +public: + explicit IEJoinCursor(ColumnDataCollection &collection) : collection(collection) { + collection.InitializeScan(state); + collection.InitializeScanChunk(state, chunk); + } + + //! The row count of the paged collection + idx_t size() const { // NOLINT + return collection.Count(); + } + + //! Read a typed cell + const T &operator[](idx_t row_idx) { + auto index = Seek(row_idx); + const auto &source = chunk.data[0]; + const auto data_ptr = reinterpret_cast(FlatVector::GetData(source)); + return data_ptr[index]; + } + +private: + //! Is the scan in range? + inline bool RowIsVisible(idx_t row_idx) const { + return (row_idx < state.next_row_index && state.current_row_index <= row_idx); + } + //! The offset of the row in the given state + inline sel_t RowOffset(idx_t row_idx) const { + D_ASSERT(RowIsVisible(row_idx)); + return UnsafeNumericCast(row_idx - state.current_row_index); + } + //! Scan the next chunk + inline bool Scan() { + return collection.Scan(state, chunk); + } + //! Seek to the given row + inline idx_t Seek(idx_t row_idx) { + if (!RowIsVisible(row_idx)) { + collection.Seek(row_idx, state, chunk); + } + return RowOffset(row_idx); + } + + //! The pageable data + const ColumnDataCollection &collection; + //! The state used for reading the collection + ColumnDataScanState state; + //! The data chunk read into + DataChunk chunk; +}; + +struct IEJoinUnion { + using SortedTable = PhysicalRangeJoin::GlobalSortedTable; + using ChunkRange = std::pair; + + // Comparison utilities + static bool IsStrictComparison(ExpressionType comparison) { + switch (comparison) { + case ExpressionType::COMPARE_LESSTHAN: + case ExpressionType::COMPARE_GREATERTHAN: + return true; + case ExpressionType::COMPARE_LESSTHANOREQUALTO: + case ExpressionType::COMPARE_GREATERTHANOREQUALTO: + return false; + default: + throw InternalException("Unimplemented comparison type for IEJoin!"); + } + } + + template + static inline bool Compare(const T &lhs, const T &rhs, const bool strict) { + const bool less_than = lhs < rhs; + if (!less_than && !strict) { + return !(rhs < lhs); + } + return less_than; + } + + static idx_t AppendKey(ExecutionContext &context, InterruptState &interrupt, SortedTable &table, + ExpressionExecutor &executor, SortedTable &marked, int64_t increment, int64_t rid, + const ChunkRange &range); + + static unique_ptr ExtractColumn(SortedTable &table, idx_t col_idx, + BufferManager &buffer_manager) { + auto &collection = *table.sorted->payload_data; + vector scan_ids(1, col_idx); + TupleDataScanState scan_state; + collection.InitializeScan(scan_state, scan_ids); + + DataChunk payload; + collection.InitializeScanChunk(scan_state, payload); + + auto result = make_uniq(buffer_manager, payload.GetTypes()); + ColumnDataAppendState append_state; + result->InitializeAppend(append_state); + while (collection.Scan(scan_state, payload)) { + result->Append(append_state, payload); + } + + return result; + } + + class UnionIterator { + public: + UnionIterator(SortedTable &table, bool strict) : state(table.CreateIteratorState()), strict(strict) { + } + + inline idx_t GetIndex() const { + return index; + } + + inline void SetIndex(idx_t i) { + index = i; + } + + inline idx_t GetChunkIndex() const { + idx_t chunk_idx; + idx_t tuple_idx; + state->RandomAccess(chunk_idx, tuple_idx, index); + return chunk_idx; + } + + inline void SetChunkIndex(idx_t chunk_idx) { + index = state->GetDivisor() * chunk_idx; + } + + UnionIterator &operator++() { + ++index; + return *this; + } + + void Repin() { + state->SetKeepPinned(true); + state->SetPinPayload(true); + } + + unique_ptr state; + idx_t index = 0; + const bool strict; + }; + + IEJoinUnion(SortedTable &l2, ColumnDataCollection &li, ColumnDataCollection &p, + const vector &conditions, const ChunkRange &chunks); + + static void InitializeTables(ClientContext &client, const PhysicalComparisonJoin &op, + const vector &conditions, unique_ptr &l1, + unique_ptr &l2); + + //! Start the current row. + //! Returns false if there are no more rows to process + template + bool NextRow(); + + //! NextRow pointer to member for the sort key type. + using next_row_t = bool (duckdb::IEJoinUnion::*)(); + next_row_t next_row_func; + + //! Finish this row and move to the next one. + //! Returns false if there are no more rows to process + bool FinishRow() { + ++i; + return (this->*next_row_func)(); + } + + //! Inverted loop + idx_t JoinBlocks(unsafe_vector &lsel, unsafe_vector &rsel); + + //! B + vector bit_array; + ValidityMask bit_mask; + //! Bloom Filter + static constexpr idx_t BLOOM_CHUNK_BITS = 1024; + idx_t bloom_count; + vector bloom_array; + ValidityMask bloom_filter; + + //! Iteration state + idx_t n; + idx_t i; + idx_t n_j; + idx_t j; + unique_ptr op2; + unique_ptr off2; + int64_t lrid = std::numeric_limits::max(); + + //! ANTI JOIN bookmark + idx_t anti_i; + + //! Li + IEJoinCursor li; + //! P + IEJoinCursor p; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/mark_join_row_comparison.hpp b/src/duckdb/src/include/duckdb/execution/mark_join_row_comparison.hpp index 4ea7bc3a8..11cd76c06 100644 --- a/src/duckdb/src/include/duckdb/execution/mark_join_row_comparison.hpp +++ b/src/duckdb/src/include/duckdb/execution/mark_join_row_comparison.hpp @@ -8,13 +8,27 @@ #pragma once -#include "duckdb/common/types/vector.hpp" +#include "duckdb/common/enums/expression_type.hpp" +#include "duckdb/common/types/data_chunk.hpp" namespace duckdb { +struct JoinCondition; + struct MarkJoinRowComparison { + explicit MarkJoinRowComparison(const DataChunk &left); + + static void Compare(const Vector &left, const Vector &right, ExpressionType comparison_type, Vector &result); + void CompareConjunction(DataChunk &left, idx_t left_row, DataChunk &right, const vector &conditions, + Vector &result); + static void Perform(DataChunk &left, DataChunk &right, bool found_match[], const vector &conditions, + optional_ptr found_unknown); static void CompareEquality(const Vector &left, idx_t left_row, idx_t left_count, const Vector &right, idx_t right_count, bool row_is_false[], bool row_is_unknown[]); + +private: + DataChunk left_reference; + Vector comparison; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_limited_distinct.hpp b/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_limited_distinct.hpp index 3d154a6ca..64a6705f4 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_limited_distinct.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_limited_distinct.hpp @@ -40,6 +40,9 @@ class PhysicalLimitedDistinct : public PhysicalOperator { SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; + void SourceFinished(ClientContext &context, GlobalSourceState &gstate) const override; + bool IsSource() const override { return true; } diff --git a/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp b/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp index 06db430a0..ee191422a 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp @@ -35,6 +35,8 @@ class PhysicalPerfectHashAggregate : public PhysicalOperator { public: // Source interface unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; + void SourceFinished(ClientContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; diff --git a/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_ungrouped_aggregate.hpp b/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_ungrouped_aggregate.hpp index b46987e63..f2ff51ad7 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_ungrouped_aggregate.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_ungrouped_aggregate.hpp @@ -35,6 +35,8 @@ class PhysicalUngroupedAggregate : public PhysicalOperator { public: // Source interface + unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_error.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_error.hpp index 597bcb169..765421621 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_error.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_error.hpp @@ -143,7 +143,7 @@ class CSVErrorHandler { idx_t GetSize(); void FillRejectsTable(InternalAppender &errors_appender, idx_t file_idx, idx_t scan_idx, const CSVFileScan &file, - CSVRejectsTable &rejects, const MultiFileBindData &bind_data, idx_t limit); + CSVRejectsTable &rejects, const vector &column_names, idx_t limit); private: //! Private methods should always be locked by parent method. diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp index b55af49d5..ca864a0cf 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp @@ -14,22 +14,14 @@ #include "duckdb/execution/operator/csv_scanner/csv_error.hpp" #include "duckdb/execution/operator/csv_scanner/csv_schema.hpp" #include "duckdb/execution/operator/csv_scanner/csv_validator.hpp" -#include "duckdb/common/multi_file/base_file_reader.hpp" +#include "duckdb/common/multi_file/multi_file_data.hpp" namespace duckdb { struct ReadCSVData; class CSVFileScan; -struct CSVUnionData : public BaseUnionData { - explicit CSVUnionData(OpenFileInfo file_p) : BaseUnionData(std::move(file_p)) { - } - ~CSVUnionData() override; - - CSVReaderOptions options; -}; - //! Struct holding information over a CSV File we will scan -class CSVFileScan : public BaseFileReader { +class CSVFileScan { public: //! Constructor for new CSV Files, we must initialize the buffer manager and the state machine //! Path to this file @@ -46,27 +38,12 @@ class CSVFileScan : public BaseFileReader { void SetNamesAndTypes(const vector &names, const vector &types); public: - string GetReaderType() const override { - return "CSV"; - } + //! How far along we are in reading this file + double GetProgressInFile(ClientContext &context); - bool UseCastMap() const override { - //! Whether or not to push casts into the cast map - return true; + const string &GetFileName() const { + return file.path; } - - shared_ptr GetUnionData(idx_t file_idx) override; - void PrepareReader(ClientContext &context, GlobalTableFunctionState &) override; - bool TryInitializeScan(ClientContext &context, GlobalTableFunctionState &gstate, - LocalTableFunctionState &lstate) override; - AsyncResult ScheduleIO(ClientContext &context, GlobalTableFunctionState &gstate, - LocalTableFunctionState &lstate) override; - AsyncResult Scan(ClientContext &context, GlobalTableFunctionState &global_state, - LocalTableFunctionState &local_state, DataChunk &chunk) override; - void FinishFile(ClientContext &context, GlobalTableFunctionState &gstate_p) override; - double GetProgressInFile(ClientContext &context) override; - -public: idx_t GetFileIndex() const { return file_list_idx.GetIndex(); } @@ -79,6 +56,16 @@ class CSVFileScan : public BaseFileReader { void InitializeFileNamesTypes(); public: + //! The file that is read + OpenFileInfo file; + //! The index of this file within the scan it is part of - it identifies the file in the rejects tables + optional_idx file_list_idx; + //! The columns of this file + vector columns; + //! The columns that are read from this file, in the order they are emitted + MultiFileLocalColumnIds column_ids; + //! The types the columns must be read as, when they differ from the types this file has + unordered_map cast_map; //! Buffer Manager for the CSV File shared_ptr buffer_manager; //! State Machine for this file diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp deleted file mode 100644 index a9dc55f1a..000000000 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp +++ /dev/null @@ -1,71 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/multi_file/multi_file_function.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_reader_options.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_schema.hpp" - -namespace duckdb { - -class CSVFileReaderOptions : public BaseFileReaderOptions { -public: - CSVFileReaderOptions() = default; - explicit CSVFileReaderOptions(CSVReaderOptions options_p) : options(std::move(options_p)) { - } - - CSVReaderOptions options; -}; - -struct CSVSchemaDiscovery { - static CSVSchema SchemaDiscovery(ClientContext &context, shared_ptr &buffer_manager, - CSVReaderOptions &options, const MultiFileOptions &file_options, - vector &return_types, vector &names, - MultiFileList &multi_file_list); -}; - -struct CSVMultiFileInfo : MultiFileReaderInterface { - static unique_ptr CreateInterface(ClientContext &context); - - unique_ptr InitializeOptions(ClientContext &context, - optional_ptr info) override; - bool ParseCopyOption(ClientContext &context, const Identifier &key, const vector &values, - BaseFileReaderOptions &options, vector &expected_names, - vector &expected_types) override; - bool ParseOption(ClientContext &context, const Identifier &key, const Value &val, MultiFileOptions &file_options, - BaseFileReaderOptions &options) override; - void FinalizeCopyBind(ClientContext &context, BaseFileReaderOptions &options, - const vector &expected_names, const vector &expected_types) override; - unique_ptr InitializeBindData(MultiFileBindData &multi_file_data, - unique_ptr options) override; - void BindReader(ClientContext &context, vector &return_types, vector &names, - MultiFileBindData &bind_data) override; - void FinalizeBindData(MultiFileBindData &multi_file_data) override; - optional_idx MaxThreads(const MultiFileBindData &bind_data_p, const MultiFileGlobalState &global_state, - FileExpandResult expand_result) override; - bool SupportsReadAhead(const MultiFileBindData &bind_data) const override; - unique_ptr InitializeGlobalState(ClientContext &context, MultiFileBindData &bind_data, - MultiFileGlobalState &global_state) override; - unique_ptr InitializeLocalState(ClientContext &, GlobalTableFunctionState &) override; - shared_ptr CreateReader(ClientContext &context, GlobalTableFunctionState &gstate, - BaseUnionData &union_data, const MultiFileBindData &bind_data_p) override; - shared_ptr CreateReader(ClientContext &context, GlobalTableFunctionState &gstate, - const OpenFileInfo &file, idx_t file_idx, - const MultiFileBindData &bind_data) override; - shared_ptr CreateReader(ClientContext &context, const OpenFileInfo &file, - BaseFileReaderOptions &options, - const MultiFileOptions &file_options) override; - void FinishReading(ClientContext &context, GlobalTableFunctionState &global_state, - LocalTableFunctionState &local_state) override; - unique_ptr GetCardinality(const MultiFileBindData &bind_data, idx_t file_count) override; - FileGlobInput GetGlobInput() override; -}; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_option.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_option.hpp index 7e02f9ba5..cb19031dc 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_option.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_option.hpp @@ -41,7 +41,7 @@ struct CSVOption { // NOLINT: work-around bug in clang-tidy D_ASSERT(!(by_user && set_by_user)); if (!set_by_user) { // If it's not set by user we can change the value - value = value_p; + value = std::move(value_p); // NOLINT(performance-move-const-arg) set_by_user = by_user; } } diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp index a7c40001e..2d303e551 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema.hpp @@ -34,6 +34,11 @@ struct CSVSchema { //! If the schema is empty bool Empty() const; + //! Whether this schema was determined on a file without any data + bool IsEmptyFile() const { + return empty; + } + //! If the columns of the schema match bool MatchColumns(const CSVSchema &other) const; diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp new file mode 100644 index 000000000..c52435df0 --- /dev/null +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/multi_file/multi_file_list.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_reader_options.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_buffer_manager.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema.hpp" + +namespace duckdb { + +struct CSVSchemaDiscovery { + //! "replace_null_with_varchar" is false when the caller combines this schema with the schemas of other files - + //! columns without any value must stay SQLNULL until every file has been seen, or they widen the other schemas + static CSVSchema SchemaDiscovery(ClientContext &context, shared_ptr &buffer_manager, + CSVReaderOptions &options, const MultiFileOptions &file_options, + vector &return_types, vector &names, + MultiFileList &multi_file_list, bool replace_null_with_varchar = true); +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/global_csv_state.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/global_csv_state.hpp index 7232ccf8c..a40a9e4bd 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/global_csv_state.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/global_csv_state.hpp @@ -18,6 +18,7 @@ #include "duckdb/execution/operator/csv_scanner/csv_validator.hpp" namespace duckdb { +class PhysicalOperator; struct MultiFileBindData; //! Local state of the CSV scan @@ -46,8 +47,8 @@ struct CSVLocalState : public LocalTableFunctionState { //! CSV Global State is used in the CSV Reader Table Function, it controls what each thread struct CSVGlobalState : public GlobalTableFunctionState { public: - CSVGlobalState(ClientContext &context_p, const CSVReaderOptions &options, idx_t total_file_count, - const MultiFileBindData &bind_data); + CSVGlobalState(ClientContext &context_p, ReadCSVData &csv_data, const vector &column_names, + idx_t total_file_count, optional_ptr scan_op = nullptr); ~CSVGlobalState() override { } @@ -70,7 +71,13 @@ struct CSVGlobalState : public GlobalTableFunctionState { private: //! Reference to the client context that created this scan ClientContext &context; - const MultiFileBindData &bind_data; + ReadCSVData &csv_data; + //! The operator the files are scanned for, and how many files it scans - together they tell the rejects tables + //! which file of which scan an error belongs to + optional_ptr scan_op; + idx_t total_file_count; + //! The names of the columns that are read - used when filling the rejects table + const vector &column_names; string sniffer_mismatch_error; @@ -84,8 +91,9 @@ struct CSVGlobalState : public GlobalTableFunctionState { //! We hold information on the current scanner boundary CSVIterator current_boundary; - - vector rejects_file_indexes; }; +//! The I/O tasks needed by the part of the file a local state has claimed, for the buffers that are not in memory +vector> CSVCollectClaimIOTasks(CSVLocalState &lstate); + } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit_percent.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit_percent.hpp index eab1186b6..82da6e783 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit_percent.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit_percent.hpp @@ -37,6 +37,9 @@ class PhysicalLimitPercent : public PhysicalOperator { SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; + void SourceFinished(ClientContext &context, GlobalSourceState &gstate) const override; + bool IsSource() const override { return true; } diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_reservoir_sample.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_reservoir_sample.hpp index c38844e59..a51ad1cfb 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_reservoir_sample.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_reservoir_sample.hpp @@ -29,6 +29,9 @@ class PhysicalReservoirSample : public PhysicalOperator { public: // Source interface + unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; + void SourceFinished(ClientContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp index bc08e1a34..c18023252 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_collector.hpp @@ -10,6 +10,7 @@ #include "duckdb/execution/physical_operator.hpp" #include "duckdb/main/query_result.hpp" +#include "duckdb/common/enums/query_result_memory_type.hpp" #include "duckdb/common/enums/statement_type.hpp" namespace duckdb { @@ -56,11 +57,9 @@ class PhysicalResultCollector : public PhysicalOperator { virtual bool IsStreaming() const { return false; } - //! Whether a producer is parked on this sink and only the consumer can release it. A streaming - //! collector without a parked-producer notion reports true: it is never waited on forever, at - //! the price of returning to the consumer on every unrelated block - virtual bool HasBlockedResultProducer(GlobalSinkState &state) const { - return IsStreaming(); + //! Whether this collector builds its own result object, rather than serving it through a result buffer + virtual bool BuildsOwnResult() const { + return true; } protected: diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_sink.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_sink.hpp index e331a2506..47f2381a5 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_sink.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_result_sink.hpp @@ -13,6 +13,8 @@ namespace duckdb { +class BufferedData; + class ResultSinkGlobalState; class ResultSinkLocalState; @@ -38,7 +40,8 @@ class PhysicalResultSink : public PhysicalResultCollector { public: unique_ptr GetResult(GlobalSinkState &state) const override; - bool HasBlockedResultProducer(GlobalSinkState &state) const override; + //! Hand the sink the buffer created at submission. Called once, before execution starts + void SetResultBuffer(shared_ptr buffer); // Sink interface SinkResultType Sink(ExecutionContext &context, DataChunk &chunk, OperatorSinkInput &input) const override; @@ -55,6 +58,9 @@ class PhysicalResultSink : public PhysicalResultCollector { PipelineExternalInputSupport GetExternalInputSupport() const override; //! The plan-time answer: a deferred sink may stream, whatever the consumer decides later bool IsStreaming() const override; + bool BuildsOwnResult() const override { + return false; + } private: bool BatchOrdered() const { @@ -68,8 +74,11 @@ class PhysicalResultSink : public PhysicalResultCollector { SinkResultType SinkRetained(ExecutionContext &context, ResultSinkLocalState &lstate, DataChunk &chunk) const; SinkCombineResultType CombineDraining(ResultSinkGlobalState &gstate, ResultSinkLocalState &lstate) const; SinkCombineResultType CombineRetained(ResultSinkGlobalState &gstate, ResultSinkLocalState &lstate) const; - unique_ptr GetStreamResult(ResultSinkGlobalState &gstate) const; unique_ptr GetMaterializedResult(ResultSinkGlobalState &gstate) const; + +private: + //! The buffer created at submission, which also holds the retention decision + shared_ptr result_buffer; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp index 07663cd2a..17de0f8cf 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/outer_join_marker.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/atomic.hpp" #include "duckdb/common/mutex.hpp" #include "duckdb/common/types/column/column_data_collection.hpp" #include "duckdb/execution/operator/join/physical_comparison_join.hpp" @@ -19,6 +20,9 @@ struct OuterJoinGlobalScanState { mutex lock; ColumnDataCollection *data = nullptr; ColumnDataParallelScanState global_scan; + atomic rows_scanned {0}; + + ProgressData GetProgress() const; }; struct OuterJoinLocalScanState { diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/physical_blockwise_nl_join.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/physical_blockwise_nl_join.hpp index 304479383..8a340e6de 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/physical_blockwise_nl_join.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/physical_blockwise_nl_join.hpp @@ -41,6 +41,7 @@ class PhysicalBlockwiseNLJoin : public PhysicalJoin { public: // Source interface + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; unique_ptr GetGlobalSourceState(ClientContext &context) const override; unique_ptr GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const override; diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/physical_nested_loop_join.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/physical_nested_loop_join.hpp index ef7cc91e4..718b50c0a 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/physical_nested_loop_join.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/physical_nested_loop_join.hpp @@ -40,6 +40,7 @@ class PhysicalNestedLoopJoin : public PhysicalComparisonJoin { public: // Source interface + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; unique_ptr GetGlobalSourceState(ClientContext &context) const override; unique_ptr GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const override; @@ -75,6 +76,10 @@ class PhysicalNestedLoopJoin : public PhysicalComparisonJoin { //! Returns a list of the types of the join conditions vector GetJoinTypes() const; +private: + vector mark_projection_map; + bool track_unknown; + private: // resolve joins that output max N elements (SEMI, ANTI, MARK) void ResolveSimpleJoin(ExecutionContext &context, DataChunk &input, DataChunk &chunk, OperatorState &state) const; diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/physical_piecewise_merge_join.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/physical_piecewise_merge_join.hpp index faed6e0c1..f9cfb756a 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/physical_piecewise_merge_join.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/physical_piecewise_merge_join.hpp @@ -46,6 +46,7 @@ class PhysicalPiecewiseMergeJoin : public PhysicalRangeJoin { public: // Source interface unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; unique_ptr GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/physical_positional_join.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/physical_positional_join.hpp index 51fd38043..abab010c4 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/physical_positional_join.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/physical_positional_join.hpp @@ -32,6 +32,9 @@ class PhysicalPositionalJoin : public PhysicalOperator { SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; + void SourceFinished(ClientContext &context, GlobalSourceState &gstate) const override; + bool IsSource() const override { return true; } diff --git a/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp b/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp index 9cee4889e..bc37edaa6 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp @@ -51,7 +51,7 @@ class PhysicalRangeJoin : public PhysicalComparisonJoin { class GlobalSortedTable { public: GlobalSortedTable(ClientContext &client, const vector &orders, - const vector &payload_layout, const PhysicalRangeJoin &op); + const vector &payload_layout, const PhysicalComparisonJoin &op); inline idx_t Count() const { return count; @@ -121,7 +121,7 @@ class PhysicalRangeJoin : public PhysicalComparisonJoin { } //! The hosting operator - const PhysicalRangeJoin &op; + const PhysicalComparisonJoin &op; //! The sort description unique_ptr sort; //! The shared sort state diff --git a/src/duckdb/src/include/duckdb/execution/operator/order/physical_top_n.hpp b/src/duckdb/src/include/duckdb/execution/operator/order/physical_top_n.hpp index dd79b094f..c99b9ef4f 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/order/physical_top_n.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/order/physical_top_n.hpp @@ -36,6 +36,7 @@ class PhysicalTopN : public PhysicalOperator { unique_ptr GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const override; unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; OperatorPartitionData GetPartitionData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, diff --git a/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_rejects_table.hpp b/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_rejects_table.hpp index 415f217b2..daa7b961d 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_rejects_table.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_rejects_table.hpp @@ -13,6 +13,8 @@ #include "duckdb/common/typedefs.hpp" #include "duckdb/common/shared_ptr.hpp" #include "duckdb/common/string.hpp" +#include "duckdb/common/constants.hpp" +#include "duckdb/common/unordered_map.hpp" namespace duckdb { @@ -26,6 +28,11 @@ class CSVRejectsTable : public ObjectCacheEntry { : count(0), scan_table(std::move(rejects_scan)), errors_table(std::move(rejects_error)) { } mutex write_lock; + //! Guards the file indexes below - separate from the write lock, which is held while the tables are written + mutex file_index_lock; + idx_t file_index_query_id = DConstants::INVALID_INDEX; + idx_t next_file_index = 0; + unordered_map scan_file_index_base; string name; idx_t count; string scan_table; @@ -35,11 +42,12 @@ class CSVRejectsTable : public ObjectCacheEntry { const string &rejects_error); void InitializeTable(ClientContext &context, const ReadCSVData &options); + //! The first file index of a scan. The files of a scan get a block of indexes, so that they keep the order they + //! have in the scan, and the scans of a query do not report their files under the same indexes + idx_t GetFileIndexBase(idx_t query_id, const void *scan_key, idx_t file_count); TableCatalogEntry &GetErrorsTable(ClientContext &context); TableCatalogEntry &GetScansTable(ClientContext &context); - idx_t GetCurrentFileIndex(idx_t query_id); - static string ObjectType() { return "csv_rejects_table_cache"; } @@ -55,9 +63,7 @@ class CSVRejectsTable : public ObjectCacheEntry { private: //! Current File Index being used in the query - idx_t current_file_idx = 0; //! Current Query ID being executed - idx_t current_query_id = 0; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_copy_to_file.hpp b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_copy_to_file.hpp index 5c53acb77..8d0352529 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_copy_to_file.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_copy_to_file.hpp @@ -143,6 +143,9 @@ class PhysicalCopyToFile : public PhysicalOperator { bool partition_output; bool write_partition_columns; bool hive_file_pattern; + //! Directory (relative to file_path) of a partition's files, replacing the hive layout if set. Evaluated per + //! partition over a single row holding the partition values, in partition_columns order. + unique_ptr partition_path_expression; //! If the data should be sorted vector order_columns; diff --git a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp index 9673d84d2..b67be1ab7 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp @@ -131,6 +131,8 @@ class PhysicalInsert : public PhysicalOperator { SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; + bool IsSource() const override { return true; } diff --git a/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp b/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp index 17bec3b99..5ceecbff5 100644 --- a/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp +++ b/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp @@ -28,6 +28,10 @@ class PerfectAggregateHashTable : public BaseAggregateHashTable { //! Combines the target perfect aggregate HT into this one void Combine(PerfectAggregateHashTable &other); + idx_t Capacity() const { + return total_groups; + } + //! Scan the HT starting from the scan_position void Scan(idx_t &scan_position, DataChunk &result); diff --git a/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp b/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp index a751260b5..63fabfc3f 100644 --- a/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp +++ b/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp @@ -299,6 +299,7 @@ class ReservoirSamplePercentage : public BlockingSample { //! Fetches a chunk from the sample. If destroy = true this method is descructive unique_ptr GetChunk() override; void Finalize() override; + idx_t GetActiveSampleCount() const; void Serialize(Serializer &serializer) const override; static unique_ptr Deserialize(Deserializer &deserializer); diff --git a/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp b/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp index f29d0961d..c704a26bf 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp @@ -73,7 +73,7 @@ struct AnyValueFun { struct MinFun { static constexpr const char *Name = "min"; - static constexpr const char *Parameters = "arg"; + static constexpr const char *Parameters = "arg,n"; static constexpr const char *Description = "Returns the minimum value present in arg."; static constexpr const char *Example = "min(A)"; static constexpr const char *Categories = ""; @@ -83,7 +83,7 @@ struct MinFun { struct MaxFun { static constexpr const char *Name = "max"; - static constexpr const char *Parameters = "arg"; + static constexpr const char *Parameters = "arg,n"; static constexpr const char *Description = "Returns the maximum value present in arg."; static constexpr const char *Example = "max(A)"; static constexpr const char *Categories = ""; @@ -103,7 +103,7 @@ struct DecimalAverageFun { struct CombineAggrFun { static constexpr const char *Name = "combine_aggr"; - static constexpr const char *Parameters = "arg"; + static constexpr const char *Parameters = "arg,multiplicities"; static constexpr const char *Description = "Combines exported aggregate states"; static constexpr const char *Example = "combine_aggr(state_column)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp b/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp index d663c4d61..32c7d73b8 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate/list_aggregate.hpp @@ -72,8 +72,7 @@ inline void ListClusterUpdate(Vector inputs[], AggregateInputData &aggr_input_da ListSegmentFunctions functions; GetSegmentDataFunctions(functions, input.GetType()); - for (idx_t run_idx = 0; run_idx < clustered.n_group_runs; run_idx++) { - auto &run = clustered.group_runs[run_idx]; + for (auto &run : clustered.runs()) { auto &state = *reinterpret_cast(run.state); auto run_sel = run.sel; diff --git a/src/duckdb/src/include/duckdb/function/aggregate_function.hpp b/src/duckdb/src/include/duckdb/function/aggregate_function.hpp index b94c78966..dcd12f078 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate_function.hpp @@ -646,7 +646,7 @@ class AggregateFunction : public BaseAggregateFunction, public SimpleFunction { } template - static AggregateFunction NullaryAggregate(LogicalType return_type) { + static AggregateFunction NullaryAggregate(const LogicalType &return_type) { AggregateFunction result( Identifier(), {}, return_type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, AggregateFunction::NullaryScatterUpdate, @@ -659,7 +659,7 @@ class AggregateFunction : public BaseAggregateFunction, public SimpleFunction { template static AggregateFunction - UnaryAggregate(const LogicalType &input_type, LogicalType return_type, + UnaryAggregate(const LogicalType &input_type, const LogicalType &return_type, FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING) { AggregateFunction result(Identifier(), {input_type}, return_type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, @@ -689,7 +689,7 @@ class AggregateFunction : public BaseAggregateFunction, public SimpleFunction { template static AggregateFunction BinaryAggregate(const LogicalType &a_type, const LogicalType &b_type, - LogicalType return_type) { + const LogicalType &return_type) { AggregateFunction result({a_type, b_type}, return_type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, AggregateFunction::BinaryScatterUpdate, @@ -861,8 +861,7 @@ class BoundAggregateFunction : public BaseAggregateFunction, public BoundSimpleF void SetDefinition(shared_ptr definition_p) { definition = std::move(definition_p); if (definition) { - schema_name = definition->GetSchemaName(); - catalog_name = definition->GetCatalogName(); + qualified_name = definition->GetQualifiedName().WithName(GetName()); } } const vector &GetLogicalArguments() const { diff --git a/src/duckdb/src/include/duckdb/function/cast/variant/primitive_to_variant.hpp b/src/duckdb/src/include/duckdb/function/cast/variant/primitive_to_variant.hpp index 54635f12f..0c972435e 100644 --- a/src/duckdb/src/include/duckdb/function/cast/variant/primitive_to_variant.hpp +++ b/src/duckdb/src/include/duckdb/function/cast/variant/primitive_to_variant.hpp @@ -240,7 +240,7 @@ static bool ConvertPrimitiveTemplated(ToVariantSourceData &source, ToVariantGlob } for (idx_t j = 0; j < lengths_size; j++) { - blob_offset += lengths[j]; + OffsetData::AddBlobOffset(blob_offset, lengths[j]); } } return true; diff --git a/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp b/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp index 2924ecf51..fbc32bf5c 100644 --- a/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp +++ b/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp @@ -11,6 +11,7 @@ #include "duckdb/common/serializer/varint.hpp" #include "duckdb/common/types/decimal.hpp" #include "duckdb/common/exception/conversion_exception.hpp" +#include "duckdb/common/checked_integer.hpp" namespace duckdb { namespace variant { @@ -31,6 +32,16 @@ struct OffsetData { static uint32_t *GetBlob(DataChunk &offsets) { return FlatVector::GetDataMutable(offsets.data[3]); } + //! Adds len to offset, throwing if the running total would exceed what a uint32_t blob offset can represent. + static void AddBlobOffset(uint32_t &offset, uint32_t len) { + try { + offset = uinteger_t(offset) += len; + } catch (OutOfRangeException &) { + throw InvalidInputException( + "Cannot convert value to VARIANT: encoded row size exceeds the maximum supported %u bytes", + NumericLimits::Maximum()); + } + } }; struct ToVariantGlobalResultData { diff --git a/src/duckdb/src/include/duckdb/function/cast/variant/variant_to_variant.hpp b/src/duckdb/src/include/duckdb/function/cast/variant/variant_to_variant.hpp index c71dd269f..f437e8929 100644 --- a/src/duckdb/src/include/duckdb/function/cast/variant/variant_to_variant.hpp +++ b/src/duckdb/src/include/duckdb/function/cast/variant/variant_to_variant.hpp @@ -290,9 +290,6 @@ bool ConvertVariantToVariant(ToVariantSourceData &source_data, ToVariantGlobalRe result.values_index_data[values_index_selvec->get_index(source_index)] = values_offset; } - //! FIXME: we might want to add some checks to make sure the NumericLimits::Maximum isn't exceeded, - //! but that's hard to test - //! First write all children //! NOTE: this has to happen first because we use 'values_offset', which is increased when we write the values auto source_children_list_entry = source.GetChildrenListEntry(scan_index); @@ -345,14 +342,14 @@ bool ConvertVariantToVariant(ToVariantSourceData &source_data, ToVariantGlobalRe for (uint32_t source_value_index = 0; source_value_index < source_values_list_entry.length; source_value_index++) { values_offset_data[result_index]++; - blob_size += VariantVisitor::Visit(source, scan_index, source_value_index, - analyze_state); + OffsetData::AddBlobOffset(blob_size, VariantVisitor::Visit( + source, scan_index, source_value_index, analyze_state)); } } keys_offset += keys_count; children_offset += source_children_list_entry.length; - blob_offset += blob_size; + OffsetData::AddBlobOffset(blob_offset, blob_size); } return true; } diff --git a/src/duckdb/src/include/duckdb/function/copy_function.hpp b/src/duckdb/src/include/duckdb/function/copy_function.hpp index 2dbd41a69..a7790c7ab 100644 --- a/src/duckdb/src/include/duckdb/function/copy_function.hpp +++ b/src/duckdb/src/include/duckdb/function/copy_function.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/optional_idx.hpp" #include "duckdb/function/function.hpp" #include "duckdb/function/table_function.hpp" #include "duckdb/parser/parsed_data/copy_info.hpp" @@ -168,7 +169,7 @@ typedef optional_idx (*copy_default_batch_size_t)(); typedef optional_idx (*copy_default_batch_size_bytes_t)(); typedef idx_t (*copy_file_size_bytes_t)(GlobalFunctionData &gstate); -typedef idx_t (*copy_desired_batch_size_t)(ClientContext &context, FunctionData &bind_data); +typedef optional_idx (*copy_desired_batch_size_t)(ClientContext &context, FunctionData &bind_data); typedef void (*copy_to_get_written_statistics_t)(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate, CopyFunctionFileStatistics &statistics); diff --git a/src/duckdb/src/include/duckdb/function/create_sort_key.hpp b/src/duckdb/src/include/duckdb/function/create_sort_key.hpp index eeffb0b42..f2e0e235a 100644 --- a/src/duckdb/src/include/duckdb/function/create_sort_key.hpp +++ b/src/duckdb/src/include/duckdb/function/create_sort_key.hpp @@ -12,6 +12,8 @@ namespace duckdb { +class Expression; + struct OrderModifiers { OrderModifiers(OrderType order_type, OrderByNullType null_type) : order_type(order_type), null_type(null_type) { } @@ -69,6 +71,9 @@ struct DecodeSortKeyFun { static constexpr const char *Categories = ""; static ScalarFunction GetFunction(); + //! Binds decode_sort_key from bound column types, bypassing the VARCHAR column definitions the SQL form parses + static unique_ptr Bind(unique_ptr sort_key, child_list_t columns, + vector modifiers); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/function.hpp b/src/duckdb/src/include/duckdb/function/function.hpp index 9fc1bd567..7cf2b7a9d 100644 --- a/src/duckdb/src/include/duckdb/function/function.hpp +++ b/src/duckdb/src/include/duckdb/function/function.hpp @@ -17,6 +17,7 @@ #include "duckdb/common/optional_idx.hpp" #include "duckdb/common/optional.hpp" #include "duckdb/common/optional_ptr.hpp" +#include "duckdb/parser/qualified_name.hpp" namespace duckdb { class CatalogEntry; @@ -40,10 +41,6 @@ class WindowFunction; class WindowFunctionSet; class BoundSimpleFunction; -struct BoundBetweenExpression; -struct BoundCastExpression; -struct BetweenFunctionData; -struct CastFunctionData; struct PragmaInfo; //! The default null handling is NULL in, NULL out @@ -67,23 +64,6 @@ enum class FunctionCollationHandling : uint8_t { struct FunctionData { public: - FunctionData() = default; - FunctionData(const FunctionData &) : internal_kind(InternalKind::GENERIC) { - } - FunctionData(FunctionData &&) : internal_kind(InternalKind::GENERIC) { - } - FunctionData &operator=(const FunctionData &other) { - if (this != &other) { - internal_kind = InternalKind::GENERIC; - } - return *this; - } - FunctionData &operator=(FunctionData &&other) { - if (this != &other) { - internal_kind = InternalKind::GENERIC; - } - return *this; - } DUCKDB_API virtual ~FunctionData(); DUCKDB_API virtual unique_ptr Copy() const = 0; @@ -106,22 +86,6 @@ struct FunctionData { TARGET &CastNoConst() const { return const_cast(Cast()); // NOLINT: FIXME } - -private: - enum InternalKind : uint8_t { GENERIC = 0, BOUND_CAST, BOUND_BETWEEN }; - - explicit FunctionData(InternalKind internal_kind_p) : internal_kind(internal_kind_p) { - } - InternalKind GetInternalKind() const { - return internal_kind; - } - - InternalKind internal_kind = InternalKind::GENERIC; - - friend struct BoundBetweenExpression; - friend struct BoundCastExpression; - friend struct BetweenFunctionData; - friend struct CastFunctionData; }; struct TableFunctionData : public FunctionData { @@ -341,20 +305,34 @@ class Function { name = std::move(name_p); } auto SetSchemaName(Identifier schema_name_p) -> void { - schema_name = std::move(schema_name_p); + qualified_name = QualifiedName(GetCatalogName(), std::move(schema_name_p), name); } auto SetCatalogName(Identifier catalog_name_p) -> void { - catalog_name = std::move(catalog_name_p); + auto path = qualified_name.Path(); + if (path.size() < 3) { + qualified_name = QualifiedName(std::move(catalog_name_p), GetSchemaName(), name); + } else { + path.pop_back(); + path[0] = std::move(catalog_name_p); + qualified_name = QualifiedName(std::move(path), name); + } + } + void SetQualifiedName(QualifiedName name_p) { + name = name_p.Name(); + qualified_name = std::move(name_p); + } + QualifiedName GetQualifiedName() const { + return qualified_name.WithName(name); } const Identifier &GetName() const { return name; } const Identifier &GetSchemaName() const { - return schema_name; + return qualified_name.Schema(); } const Identifier &GetCatalogName() const { - return catalog_name; + return qualified_name.Catalog(); } //! Returns the formatted string name(arg1, arg2, ...) @@ -372,10 +350,7 @@ class Function { const named_parameter_type_map_t &named_parameters); private: - //! Optional catalog name of the function - Identifier catalog_name; - //! Optional schema name of the function - Identifier schema_name; + QualifiedName qualified_name; }; class SimpleFunction : public Function { @@ -541,9 +516,7 @@ class FunctionProperties { class BoundSimpleFunction { protected: - Identifier name; - Identifier schema_name; - Identifier catalog_name; + QualifiedName qualified_name; string extra_info; //! The set of arguments of the function @@ -553,17 +526,24 @@ class BoundSimpleFunction { public: void SetName(Identifier name_p) { - name = std::move(name_p); + qualified_name = qualified_name.WithName(std::move(name_p)); } const Identifier &GetName() const { - return name; + return qualified_name.Name(); } const Identifier &GetSchemaName() const { - return schema_name; + return qualified_name.Schema(); } const Identifier &GetCatalogName() const { - return catalog_name; + return qualified_name.Catalog(); + } + + const QualifiedName &GetQualifiedName() const { + return qualified_name; + } + void SetQualifiedName(QualifiedName name_p) { + qualified_name = std::move(name_p); } const string &GetExtraInfo() const { diff --git a/src/duckdb/src/include/duckdb/function/function_serialization.hpp b/src/duckdb/src/include/duckdb/function/function_serialization.hpp index e6ec89f17..386642779 100644 --- a/src/duckdb/src/include/duckdb/function/function_serialization.hpp +++ b/src/duckdb/src/include/duckdb/function/function_serialization.hpp @@ -20,6 +20,21 @@ class ClientContext; class FunctionSerializer { private: + static QualifiedName DeserializeQualifiedName(Deserializer &deserializer, Identifier name) { + auto catalog = deserializer.ReadPropertyWithDefault(505, "catalog_name"); + auto schema = deserializer.ReadPropertyWithDefault(506, "schema_name"); + auto qname = deserializer.ReadPropertyWithExplicitDefault(507, "qname", QualifiedName()); + if (!qname.Name().empty()) { + if (qname.Schema().empty()) { + return QualifiedName(qname.Catalog().empty() ? Identifier::SystemCatalog() : qname.Catalog(), + Identifier::DefaultSchema(), qname.Name()); + } + return qname.Catalog().empty() ? qname.WithCatalog(Identifier::SystemCatalog()) : qname; + } + return QualifiedName(catalog.empty() ? Identifier::SystemCatalog() : catalog, + schema.empty() ? Identifier::DefaultSchema() : schema, std::move(name)); + } + class DeserializeContext { public: DeserializeContext(Deserializer &deserializer_p, const LogicalType &return_type, @@ -33,7 +48,8 @@ class FunctionSerializer { throw; } } - ~DeserializeContext() { + ~DeserializeContext() { // NOLINT(bugprone-exception-escape): Unset only throws if the stack invariant is + // broken. deserializer.Unset(); deserializer.Unset(); } @@ -57,26 +73,26 @@ class FunctionSerializer { function.SetLogicalReturnType(return_type.IsAggregateState() ? function.GetReturnType() : return_type); } - static void RestoreLogicalSignature(BoundWindowFunction &, const vector> &, - const LogicalType &) { - } - public: template static void Serialize(Serializer &serializer, const FUNC &function, optional_ptr bind_info) { D_ASSERT(!function.GetName().empty()); - serializer.WriteProperty(500, "name", function.GetName()); + if (!serializer.ShouldSerialize(StorageVersion::V2_0_0)) { + serializer.WriteProperty(500, "name", function.GetName()); + } serializer.WriteProperty(501, "arguments", function.GetArguments()); if (!serializer.ShouldSerialize(StorageVersion::V2_0_0)) { // binds no longer erase the arguments they fold into their bind data, so the argument list above is // always the full one - older versions read this field unconditionally, so write it (empty) for them serializer.WriteProperty(502, "original_arguments", vector()); } - // These are optional fields that are written out of numeric order, older - // databases won't contain the fields, so the defaults will be used, but if - // the fields are present, they will be used. - serializer.WritePropertyWithDefault(505, "catalog_name", function.GetCatalogName(), Identifier()); - serializer.WritePropertyWithDefault(506, "schema_name", function.GetSchemaName(), Identifier()); + + if (serializer.ShouldSerialize(StorageVersion::V2_0_0)) { + serializer.WriteProperty(507, "qname", function.GetQualifiedName()); + } else { + serializer.WritePropertyWithDefault(505, "catalog_name", function.GetCatalogName(), Identifier()); + serializer.WritePropertyWithDefault(506, "schema_name", function.GetSchemaName(), Identifier()); + } bool has_serialize = function.HasSerializationCallbacks(); serializer.WriteProperty(503, "has_serialize", has_serialize); @@ -96,18 +112,13 @@ class FunctionSerializer { } template - static FUNC DeserializeFunction(ClientContext &context, CatalogType catalog_type, const Identifier &catalog_name, - const Identifier &schema_name, const Identifier &name, - const vector &arguments) { - EntryLookupInfo lookup_info(catalog_type, QualifiedName(name)); - auto &func_catalog = - Catalog::GetEntry(context, catalog_type, - QualifiedName(catalog_name.empty() ? Identifier::SystemCatalog() : catalog_name, - schema_name.empty() ? Identifier::DefaultSchema() : schema_name, name)); + static FUNC DeserializeFunction(ClientContext &context, CatalogType catalog_type, + const QualifiedName &qualified_name, const vector &arguments) { + auto &func_catalog = Catalog::GetEntry(context, catalog_type, qualified_name); if (func_catalog.type != catalog_type) { throw InternalException("DeserializeFunction - cant find catalog entry for function %s", - name.GetIdentifierName()); + qualified_name.Name().GetIdentifierName()); } auto &functions = func_catalog.Cast(); return *functions.functions.GetFunctionByArguments(context, arguments); @@ -117,17 +128,10 @@ class FunctionSerializer { static pair DeserializeBase(Deserializer &deserializer, CatalogType catalog_type, optional_ptr>> children = nullptr) { auto &context = deserializer.Get(); - auto name = deserializer.ReadProperty(500, "name"); + auto name = deserializer.ReadPropertyWithDefault(500, "name"); auto arguments = deserializer.ReadProperty>(501, "arguments"); auto original_arguments = deserializer.ReadPropertyWithDefault>(502, "original_arguments"); - auto catalog_name = deserializer.ReadPropertyWithDefault(505, "catalog_name"); - auto schema_name = deserializer.ReadPropertyWithDefault(506, "schema_name"); - if (catalog_name.empty()) { - catalog_name = Identifier::SystemCatalog(); - } - if (schema_name.empty()) { - schema_name = Identifier::DefaultSchema(); - } + auto qualified_name = DeserializeQualifiedName(deserializer, std::move(name)); RestoreErasedArguments(arguments, original_arguments); if (arguments.empty() && children && !children->empty()) { @@ -140,8 +144,7 @@ class FunctionSerializer { } } - auto function = - DeserializeFunction(context, catalog_type, catalog_name, schema_name, name, arguments); + auto function = DeserializeFunction(context, catalog_type, qualified_name, arguments); auto has_serialize = deserializer.ReadProperty(503, "has_serialize"); if (has_serialize) { function.GetArguments() = std::move(arguments); @@ -205,19 +208,12 @@ class FunctionSerializer { LogicalType return_type) { // NOLINT: clang-tidy bug auto &context = deserializer.Get(); - auto name = deserializer.ReadProperty(500, "name"); + auto name = deserializer.ReadPropertyWithDefault(500, "name"); auto arguments = deserializer.ReadProperty>(501, "arguments"); auto original_arguments = deserializer.ReadPropertyWithDefault>(502, "original_arguments"); - auto catalog_name = deserializer.ReadPropertyWithDefault(505, "catalog_name"); - auto schema_name = deserializer.ReadPropertyWithDefault(506, "schema_name"); + auto qualified_name = DeserializeQualifiedName(deserializer, std::move(name)); auto has_serialize = deserializer.ReadProperty(503, "has_serialize"); - if (catalog_name.empty()) { - catalog_name = Identifier::SystemCatalog(); - } - if (schema_name.empty()) { - schema_name = Identifier::DefaultSchema(); - } RestoreErasedArguments(arguments, original_arguments); if (arguments.empty() && !children.empty()) { @@ -231,12 +227,11 @@ class FunctionSerializer { } // Now lookup the function in the catalog. - EntryLookupInfo lookup_info(catalog_type, QualifiedName(name)); - auto &func_catalog = Catalog::GetEntry(context, catalog_type, QualifiedName(catalog_name, schema_name, name)); + auto &func_catalog = Catalog::GetEntry(context, catalog_type, qualified_name); if (func_catalog.type != catalog_type) { throw InternalException("DeserializeFunction - cant find catalog entry for function %s", - name.GetIdentifierName()); + qualified_name.Name().GetIdentifierName()); } auto &functions = func_catalog.Cast(); const auto function = functions.functions.GetFunctionByArguments(context, arguments); diff --git a/src/duckdb/src/include/duckdb/function/function_set_base.hpp b/src/duckdb/src/include/duckdb/function/function_set_base.hpp index 50cc73f71..181588c78 100644 --- a/src/duckdb/src/include/duckdb/function/function_set_base.hpp +++ b/src/duckdb/src/include/duckdb/function/function_set_base.hpp @@ -56,7 +56,7 @@ class FunctionSet { } } - bool MergeFunctionSet(FunctionSet new_functions, bool override = false) { + bool MergeFunctionSet(const FunctionSet &new_functions, bool override = false) { D_ASSERT(!new_functions.functions.empty()); for (auto &new_func : new_functions.functions) { bool overwritten = false; diff --git a/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_functions.hpp index 606a7394a..9cfe05c52 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_functions.hpp @@ -17,7 +17,7 @@ namespace duckdb { struct InternalCompressIntegralUtinyintFun { static constexpr const char *Name = "__internal_compress_integral_utinyint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -27,7 +27,7 @@ struct InternalCompressIntegralUtinyintFun { struct InternalCompressIntegralUsmallintFun { static constexpr const char *Name = "__internal_compress_integral_usmallint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -37,7 +37,7 @@ struct InternalCompressIntegralUsmallintFun { struct InternalCompressIntegralUintegerFun { static constexpr const char *Name = "__internal_compress_integral_uinteger"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -47,7 +47,7 @@ struct InternalCompressIntegralUintegerFun { struct InternalCompressIntegralUbigintFun { static constexpr const char *Name = "__internal_compress_integral_ubigint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -57,7 +57,7 @@ struct InternalCompressIntegralUbigintFun { struct InternalCompressStringUtinyintFun { static constexpr const char *Name = "__internal_compress_string_utinyint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -67,7 +67,7 @@ struct InternalCompressStringUtinyintFun { struct InternalCompressStringUsmallintFun { static constexpr const char *Name = "__internal_compress_string_usmallint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -77,7 +77,7 @@ struct InternalCompressStringUsmallintFun { struct InternalCompressStringUintegerFun { static constexpr const char *Name = "__internal_compress_string_uinteger"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -87,7 +87,7 @@ struct InternalCompressStringUintegerFun { struct InternalCompressStringUbigintFun { static constexpr const char *Name = "__internal_compress_string_ubigint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -97,7 +97,7 @@ struct InternalCompressStringUbigintFun { struct InternalCompressStringUhugeintFun { static constexpr const char *Name = "__internal_compress_string_uhugeint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -107,7 +107,7 @@ struct InternalCompressStringUhugeintFun { struct InternalCompressStringHugeintFun { static constexpr const char *Name = "__internal_compress_string_hugeint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -117,7 +117,7 @@ struct InternalCompressStringHugeintFun { struct InternalCompressGeometryPointFun { static constexpr const char *Name = "__internal_compress_geometry_point"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -127,7 +127,7 @@ struct InternalCompressGeometryPointFun { struct InternalDecompressGeometryPointFun { static constexpr const char *Name = "__internal_decompress_geometry_point"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -137,7 +137,7 @@ struct InternalDecompressGeometryPointFun { struct InternalDecompressIntegralSmallintFun { static constexpr const char *Name = "__internal_decompress_integral_smallint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -147,7 +147,7 @@ struct InternalDecompressIntegralSmallintFun { struct InternalDecompressIntegralIntegerFun { static constexpr const char *Name = "__internal_decompress_integral_integer"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -157,7 +157,7 @@ struct InternalDecompressIntegralIntegerFun { struct InternalDecompressIntegralBigintFun { static constexpr const char *Name = "__internal_decompress_integral_bigint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -167,7 +167,7 @@ struct InternalDecompressIntegralBigintFun { struct InternalDecompressIntegralHugeintFun { static constexpr const char *Name = "__internal_decompress_integral_hugeint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -177,7 +177,7 @@ struct InternalDecompressIntegralHugeintFun { struct InternalDecompressIntegralUsmallintFun { static constexpr const char *Name = "__internal_decompress_integral_usmallint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -187,7 +187,7 @@ struct InternalDecompressIntegralUsmallintFun { struct InternalDecompressIntegralUintegerFun { static constexpr const char *Name = "__internal_decompress_integral_uinteger"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -197,7 +197,7 @@ struct InternalDecompressIntegralUintegerFun { struct InternalDecompressIntegralUbigintFun { static constexpr const char *Name = "__internal_decompress_integral_ubigint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -207,7 +207,7 @@ struct InternalDecompressIntegralUbigintFun { struct InternalDecompressIntegralUhugeintFun { static constexpr const char *Name = "__internal_decompress_integral_uhugeint"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value,min"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -217,7 +217,7 @@ struct InternalDecompressIntegralUhugeintFun { struct InternalDecompressStringFun { static constexpr const char *Name = "__internal_decompress_string"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "value"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -225,4 +225,14 @@ struct InternalDecompressStringFun { static ScalarFunctionSet GetFunctions(); }; +struct InternalCompressedMaterializationCastFun { + static constexpr const char *Name = "__internal_compressed_materialization_cast"; + static constexpr const char *Parameters = ""; + static constexpr const char *Description = ""; + static constexpr const char *Example = ""; + static constexpr const char *Categories = ""; + + static ScalarFunction GetFunction(); +}; + } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_utils.hpp b/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_utils.hpp index 51bd0dce2..cc87c047f 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_utils.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_utils.hpp @@ -13,6 +13,8 @@ namespace duckdb { +enum class CMExpressionType : uint8_t { NONE, CAST, COMPRESS, DECOMPRESS }; + struct CMUtils { //! The types we compress integral types to static const vector IntegralTypes(); @@ -20,6 +22,13 @@ struct CMUtils { static const vector StringTypes(); static unique_ptr Bind(BindScalarFunctionInput &input); + static CMExpressionType GetExpressionType(const BoundFunctionExpression &expression); + static void MarkCast(BoundFunctionExpression &expression); + +private: + static CMExpressionType GetIntegralType(const BoundScalarFunction &function); + static CMExpressionType GetStringType(const BoundScalarFunction &function); + static CMExpressionType GetGeometryType(const BoundScalarFunction &function); }; //! Needed for (de)serialization without binding diff --git a/src/duckdb/src/include/duckdb/function/scalar/generic_common.hpp b/src/duckdb/src/include/duckdb/function/scalar/generic_common.hpp index 1987825ac..4a4361232 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/generic_common.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/generic_common.hpp @@ -31,6 +31,7 @@ struct ExportAggregateFunctionBindData : public FunctionData { struct ExportAggregateFunction { static unique_ptr Bind(unique_ptr child_aggregate); static void SetStateExport(BoundAggregateExpression &aggregate, LogicalType state_layout); + static unique_ptr StateToSQL(const LogicalType &type, unique_ptr value); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/scalar/generic_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/generic_functions.hpp index 01b6b0f79..eb9c2fc3d 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/generic_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/generic_functions.hpp @@ -57,7 +57,7 @@ struct BarrierFun { struct CreateSortKeyFun { static constexpr const char *Name = "create_sort_key"; - static constexpr const char *Parameters = "parameters..."; + static constexpr const char *Parameters = "key1,..."; static constexpr const char *Description = "Constructs a binary-comparable sort key based on a set of input parameters and sort qualifiers"; static constexpr const char *Example = "create_sort_key('A', 'DESC')"; static constexpr const char *Categories = ""; @@ -67,7 +67,7 @@ struct CreateSortKeyFun { struct InvokeFun { static constexpr const char *Name = "invoke"; - static constexpr const char *Parameters = "lambda,arg1,arg2,..."; + static constexpr const char *Parameters = "lambda,arg1,..."; static constexpr const char *Description = "Invokes a lambda function with the given arguments"; static constexpr const char *Example = "invoke(x -> x + 1, 5)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar/list_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/list_functions.hpp index 3211731c6..466f339f2 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/list_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/list_functions.hpp @@ -153,7 +153,7 @@ struct ListElementFun { struct ListResizeFun { static constexpr const char *Name = "list_resize"; - static constexpr const char *Parameters = "list,size[,value]"; + static constexpr const char *Parameters = "list,size,value"; static constexpr const char *Description = "Resizes the `list` to contain `size` elements. Initializes new elements with `value` or `NULL` if `value` is not set."; static constexpr const char *Example = "list_resize([1, 2, 3], 5, 0)"; static constexpr const char *Categories = "list"; @@ -169,7 +169,7 @@ struct ArrayResizeFun { struct ArrayExtractFun { static constexpr const char *Name = "array_extract"; - static constexpr const char *Parameters = "string::VARCHAR,index::ANY\001struct::STRUCT,entry::VARCHAR\001struct::STRUCT,index::ANY\001list::ANY[],index::ANY"; + static constexpr const char *Parameters = "string::VARCHAR,index::ANY\001struct::STRUCT,entry::VARCHAR\001tuple::STRUCT,index::ANY\001list::ANY[],index::ANY"; static constexpr const char *Description = "Extracts a single character from a `string` using a (1-based) `index`.\001Extracts the named `entry` from the `STRUCT`.\001Extracts the entry from an unnamed `STRUCT` (tuple) using an index (1-based).\001Extracts the `index`th (1-based) value from the `list`."; static constexpr const char *Example = "array_extract('DuckDB', 2)\001array_extract({'i': 3, 'v2': 3, 'v3': 0}, 'i')\001array_extract(row(42, 84), 1)\001array_extract([4, 5, 6], 3)"; static constexpr const char *Categories = "string\001struct\001struct\001list"; diff --git a/src/duckdb/src/include/duckdb/function/scalar/operator_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/operator_functions.hpp index 1e0c6fd7e..a1aa59cc6 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/operator_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/operator_functions.hpp @@ -17,7 +17,7 @@ namespace duckdb { struct OperatorAddFun { static constexpr const char *Name = "+"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "left,right"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -33,7 +33,7 @@ struct AddFun { struct OperatorSubtractFun { static constexpr const char *Name = "-"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "left,right"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -49,7 +49,7 @@ struct SubtractFun { struct OperatorMultiplyFun { static constexpr const char *Name = "*"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "left,right"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -65,7 +65,7 @@ struct MultiplyFun { struct OperatorFloatDivideFun { static constexpr const char *Name = "/"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "left,right"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -75,7 +75,7 @@ struct OperatorFloatDivideFun { struct OperatorIntegerDivideFun { static constexpr const char *Name = "//"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "left,right"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -91,7 +91,7 @@ struct DivideFun { struct OperatorModuloFun { static constexpr const char *Name = "%"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "left,right"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -117,7 +117,7 @@ struct CastFun { struct DecimalDivisionFun { static constexpr const char *Name = "decimal_division"; - static constexpr const char *Parameters = "x,y[,scale]"; + static constexpr const char *Parameters = "x,y,scale"; static constexpr const char *Description = "Divides two DECIMAL values using exact integer arithmetic and round-half-to-even, returning a DECIMAL result with scale determined by SQL Server semantics (result_scale = max(6, s1 + p2 + 1))."; static constexpr const char *Example = "decimal_division(10.00::DECIMAL(10,2), 3.00::DECIMAL(10,2))"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar/sequence_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/sequence_functions.hpp index e264ee11c..05e96dcdf 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/sequence_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/sequence_functions.hpp @@ -37,7 +37,7 @@ struct NextvalFun { struct SetvalFun { static constexpr const char *Name = "setval"; - static constexpr const char *Parameters = "sequence_name,value[,is_called]"; + static constexpr const char *Parameters = "sequence_name,value,is_called"; static constexpr const char *Description = "Set the value of the sequence to the specified value. If is_called is true, the sequence is called. If is_called is false, the sequence is not called."; static constexpr const char *Example = "setval('my_sequence_name', 100, true)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp index 39cdba409..5851885cf 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp @@ -327,7 +327,7 @@ struct RegexpSplitToArrayFun { struct RegexpFun { static constexpr const char *Name = "regexp_full_match"; - static constexpr const char *Parameters = "string,regex"; + static constexpr const char *Parameters = "string,regex,options"; static constexpr const char *Description = "Returns `true` if the entire `string` matches the `regex`. A set of optional regex `options` can be set."; static constexpr const char *Example = "regexp_full_match('anabanana', '(an)*')"; static constexpr const char *Categories = "regex"; @@ -395,9 +395,19 @@ struct PathJoinFun { static ScalarFunction GetFunction(); }; +struct HivePartitionComponentFun { + static constexpr const char *Name = "hive_partition_component"; + static constexpr const char *Parameters = "name,value"; + static constexpr const char *Description = "Returns the hive partition directory for a partition column and its value, e.g. name=value. The name and the value are escaped like url_encode does, a NULL value becomes __HIVE_DEFAULT_PARTITION__."; + static constexpr const char *Example = "hive_partition_component('year', 2024)"; + static constexpr const char *Categories = "string"; + + static ScalarFunction GetFunction(); +}; + struct LikeFun { static constexpr const char *Name = "~~"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "string,pattern"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -407,7 +417,7 @@ struct LikeFun { struct NotLikeFun { static constexpr const char *Name = "!~~"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "string,pattern"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -417,7 +427,7 @@ struct NotLikeFun { struct GlobPatternFun { static constexpr const char *Name = "~~~"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "string,pattern"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -427,7 +437,7 @@ struct GlobPatternFun { struct ILikeFun { static constexpr const char *Name = "~~*"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "string,pattern"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -437,7 +447,7 @@ struct ILikeFun { struct NotILikeFun { static constexpr const char *Name = "!~~*"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "string,pattern"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar/struct_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/struct_functions.hpp index 4e481653d..70c78173d 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/struct_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/struct_functions.hpp @@ -17,7 +17,7 @@ namespace duckdb { struct StructExtractFun { static constexpr const char *Name = "struct_extract"; - static constexpr const char *Parameters = "struct,'entry'"; + static constexpr const char *Parameters = "struct,entry"; static constexpr const char *Description = "Extract the named entry from the STRUCT."; static constexpr const char *Example = "struct_extract({'i': 3, 'v2': 3, 'v3': 0}, 'i')"; static constexpr const char *Categories = ""; @@ -27,7 +27,7 @@ struct StructExtractFun { struct StructExtractAtFun { static constexpr const char *Name = "struct_extract_at"; - static constexpr const char *Parameters = "struct,'entry'"; + static constexpr const char *Parameters = "struct,index"; static constexpr const char *Description = "Extract the entry from the STRUCT by position (starts at 1!)."; static constexpr const char *Example = "struct_extract_at({'i': 3, 'v2': 3, 'v3': 0}, 2)"; static constexpr const char *Categories = ""; @@ -78,7 +78,7 @@ struct StructConcatFun { struct StructContainsFun { static constexpr const char *Name = "struct_contains"; - static constexpr const char *Parameters = "struct,'entry'"; + static constexpr const char *Parameters = "struct,entry"; static constexpr const char *Description = "Check if an unnamed STRUCT contains the value."; static constexpr const char *Example = "struct_contains(ROW(3, 3, 0), 3)"; static constexpr const char *Categories = ""; @@ -94,7 +94,7 @@ struct StructHasFun { struct StructPositionFun { static constexpr const char *Name = "struct_position"; - static constexpr const char *Parameters = "struct,'entry'"; + static constexpr const char *Parameters = "struct,entry"; static constexpr const char *Description = "Get the position of the entry in an unnamed STRUCT, starting at 1."; static constexpr const char *Example = "struct_position(ROW(3, 3, 0), 3)"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar/system_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/system_functions.hpp index 14161572a..774b6d2a3 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/system_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/system_functions.hpp @@ -37,7 +37,7 @@ struct CombineFun { struct ToAggregateStateFun { static constexpr const char *Name = "to_aggregate_state"; - static constexpr const char *Parameters = "data,name,signature"; + static constexpr const char *Parameters = "data,name,signature,constant_parameters,order_by"; static constexpr const char *Description = "Converts a value into the aggregate state of the aggregate function with the given name and signature. The type of the value must exactly match the state layout of the aggregate function. An optional fourth argument supplies constant parameter values (e.g. string_agg's separator) as a list with one entry per argument, using NULL for arguments that are not bound to a constant."; static constexpr const char *Example = "to_aggregate_state({'count': 1, 'value': 42.0}, 'avg', ['DOUBLE'])"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar/tablefilter_functions.hpp b/src/duckdb/src/include/duckdb/function/scalar/tablefilter_functions.hpp index 6d1a27029..6ea5f6212 100644 --- a/src/duckdb/src/include/duckdb/function/scalar/tablefilter_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar/tablefilter_functions.hpp @@ -17,7 +17,7 @@ namespace duckdb { struct TableFilterBloomFilterFun { static constexpr const char *Name = "__internal_tablefilter_bloom_filter"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "col"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -27,7 +27,7 @@ struct TableFilterBloomFilterFun { struct TableFilterDynamicFun { static constexpr const char *Name = "__internal_tablefilter_dynamic"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "col"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -37,7 +37,7 @@ struct TableFilterDynamicFun { struct TableFilterOptionalFun { static constexpr const char *Name = "__internal_tablefilter_optional"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "col"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -47,7 +47,7 @@ struct TableFilterOptionalFun { struct TableFilterPrefixRangeFun { static constexpr const char *Name = "__internal_tablefilter_prefix_range"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "col"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; @@ -57,7 +57,7 @@ struct TableFilterPrefixRangeFun { struct TableFilterSelectivityOptionalFun { static constexpr const char *Name = "__internal_tablefilter_selectivity_optional"; - static constexpr const char *Parameters = ""; + static constexpr const char *Parameters = "col"; static constexpr const char *Description = ""; static constexpr const char *Example = ""; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/scalar_function.hpp b/src/duckdb/src/include/duckdb/function/scalar_function.hpp index c0df75185..52faf2319 100644 --- a/src/duckdb/src/include/duckdb/function/scalar_function.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar_function.hpp @@ -56,6 +56,7 @@ struct BindLambdaContext { class Binder; class BoundFunctionExpression; class BoundScalarFunction; +class ParsedExpression; class ScalarFunctionCatalogEntry; struct StatementProperties; @@ -112,6 +113,14 @@ struct FunctionBindExpressionInput { vector> &children; }; +struct FunctionUnbindInput { + FunctionUnbindInput(const BoundFunctionExpression &expression_p, vector> children_p); + ~FunctionUnbindInput(); + + const BoundFunctionExpression &expression; + vector> children; +}; + struct FunctionToStringInput { FunctionToStringInput(const BoundScalarFunction &bound_function, optional_ptr bind_data_p, const vector> &children_p) @@ -165,6 +174,9 @@ typedef unique_ptr (*function_bind_expression_t)(FunctionBindExpress //! Convert a scalar function to string typedef string (*function_to_string_t)(FunctionToStringInput &input); +//! Reconstruct an invocation from children exported in the current binding scope +typedef unique_ptr (*scalar_function_unbind_t)(FunctionUnbindInput &input); + //! Get the expression type of a function typedef ExpressionType (*function_get_expression_type_t)(FunctionToStringInput &input); @@ -191,6 +203,8 @@ class ScalarFunctionCallbacks { get_modified_databases_t get_modified_databases = nullptr; //! Convert a scalar function to string function_to_string_t to_string = nullptr; + //! Reconstruct the bound SQL invocation + scalar_function_unbind_t unbind = nullptr; //! Get the expression type function_get_expression_type_t get_expression_type = nullptr; @@ -299,6 +313,10 @@ class BaseScalarFunction { auto SetToStringCallback(function_to_string_t callback) -> void { callbacks.to_string = callback; } auto FunctionToString(FunctionToStringInput &input) const -> string { return callbacks.to_string(input); } + auto HasUnbindCallback() const -> bool { return callbacks.unbind != nullptr; } + auto SetUnbindCallback(scalar_function_unbind_t callback) -> void { callbacks.unbind = callback; } + auto GetUnbindCallback() const -> scalar_function_unbind_t { return callbacks.unbind; } + auto HasLegacySerializeCallback() const -> bool { return callbacks.legacy_serialize != nullptr; } auto SetLegacySerializeCallback(function_legacy_serialize_t callback) -> void { callbacks.legacy_serialize = callback; } auto GetLegacySerializeCallback() const -> function_legacy_serialize_t { return callbacks.legacy_serialize; } @@ -365,7 +383,11 @@ class BaseScalarFunction { protected: FunctionProperties properties; + +private: ScalarFunctionCallbacks callbacks; + +protected: shared_ptr function_info; //! Per-argument declarative properties (monotonicity). Empty = no claims made. @@ -581,8 +603,7 @@ class BoundScalarFunction : public BaseScalarFunction, publ void SetDefinition(shared_ptr definition_p) { definition = std::move(definition_p); if (definition) { - schema_name = definition->GetSchemaName(); - catalog_name = definition->GetCatalogName(); + qualified_name = definition->GetQualifiedName().WithName(GetName()); } } const vector &GetLogicalArguments() const { diff --git a/src/duckdb/src/include/duckdb/function/table/arrow.hpp b/src/duckdb/src/include/duckdb/function/table/arrow.hpp index bd0b78398..27760b48b 100644 --- a/src/duckdb/src/include/duckdb/function/table/arrow.hpp +++ b/src/duckdb/src/include/duckdb/function/table/arrow.hpp @@ -42,28 +42,24 @@ struct ArrowStreamParameters { TableFilterSet *filters; }; -typedef unique_ptr (*stream_factory_produce_t)(uintptr_t stream_factory_ptr, - ArrowStreamParameters ¶meters); -typedef void (*stream_factory_get_schema_t)(ArrowArrayStream *stream_factory_ptr, ArrowSchema &schema); +//! Produces Arrow schemas and streams for a single scan invocation. +//! Implementations retain any external objects needed by the produced streams. +struct ArrowScanFactory : public TableFunctionInfo { + virtual void GetSchema(ArrowSchema &schema) = 0; + virtual unique_ptr ProduceStream(ArrowStreamParameters ¶meters) = 0; +}; struct ArrowScanFunctionData : public TableFunctionData { public: - ArrowScanFunctionData(stream_factory_produce_t scanner_producer_p, uintptr_t stream_factory_ptr_p, - shared_ptr dependency = nullptr) - : lines_read(0), rows_per_thread(0), stream_factory_ptr(stream_factory_ptr_p), - scanner_producer(scanner_producer_p), dependency(std::move(dependency)) { + explicit ArrowScanFunctionData(shared_ptr factory_p) + : lines_read(0), rows_per_thread(0), factory(std::move(factory_p)) { } vector all_types; atomic lines_read; ArrowSchemaWrapper schema_root; idx_t rows_per_thread; - //! Pointer to the scanner factory - uintptr_t stream_factory_ptr; - //! Pointer to the scanner factory produce - stream_factory_produce_t scanner_producer; - //! The (optional) dependency of this function (used in Python for example) - shared_ptr dependency; + shared_ptr factory; //! Arrow table data ArrowTableSchema arrow_table; //! Whether projection pushdown is enabled on the scan diff --git a/src/duckdb/src/include/duckdb/function/table/read_csv.hpp b/src/duckdb/src/include/duckdb/function/table/read_csv.hpp index c8eb1a9f7..4e2d07fe1 100644 --- a/src/duckdb/src/include/duckdb/function/table/read_csv.hpp +++ b/src/duckdb/src/include/duckdb/function/table/read_csv.hpp @@ -72,8 +72,6 @@ struct ReadCSVData : public BaseCSVData { //! The buffer manager (if any): this is used when automatic detection is used during binding. //! In this case, some CSV buffers have already been read and can be reused. shared_ptr buffer_manager; - //! Column info (used for union reader serialization) - vector column_info; //! The CSV schema, in case there is a unified schema that all files must read CSVSchema csv_schema; @@ -114,6 +112,10 @@ struct CSVCopyFunction { struct ReadCSVTableFunction { static TableFunction GetFunction(); static TableFunction GetAutoFunction(); + //! The CSV reader that reads a single file - this is what the multi-file CSV reader wraps + static TableFunction GetSingleFileFunction(); + //! The single-file CSV reader wrapped into a multi-file function + static TableFunction GetMultiFileFunction(Identifier name); static void ReadCSVAddNamedParameters(TableFunction &table_function); static void RegisterFunction(BuiltinFunctions &set); }; diff --git a/src/duckdb/src/include/duckdb/function/table/read_file.hpp b/src/duckdb/src/include/duckdb/function/table/read_file.hpp index e0d2a51c2..9e2531c63 100644 --- a/src/duckdb/src/include/duckdb/function/table/read_file.hpp +++ b/src/duckdb/src/include/duckdb/function/table/read_file.hpp @@ -30,6 +30,7 @@ struct ReadFileGlobalState : public GlobalTableFunctionState { shared_ptr file_list; vector column_ids; bool requires_file_open = false; + bool requires_file_metadata = false; unique_ptr stream; }; diff --git a/src/duckdb/src/include/duckdb/function/table_function.hpp b/src/duckdb/src/include/duckdb/function/table_function.hpp index 736e2a477..ccfffd14d 100644 --- a/src/duckdb/src/include/duckdb/function/table_function.hpp +++ b/src/duckdb/src/include/duckdb/function/table_function.hpp @@ -25,6 +25,7 @@ namespace duckdb { enum class TablePartitionInfo : uint8_t; struct PartitionStatistics; +struct MultiFileOptions; //! Controls how a table function manages parallelism. enum class TableFunctionParallelism : uint8_t { @@ -135,6 +136,13 @@ struct TableFunctionBindInput { //! function. This lets the bind read the file exactly the way the schema was determined, rather than deriving //! that from the names and types alone optional_ptr expected_bind_data; + //! (Optional) The options of the multi-file scan this file is part of. They tell the bind how its file is + //! combined with the other files of the scan - e.g. whether their columns are unified by name, in which case a + //! type that could not be determined should be reported as SQLNULL so the other files can determine it + optional_ptr multi_file_options; + //! Whether the caller reads several files with this function. Options that describe the schema then describe the + //! scan rather than this one file, so the bind should not hold this file to them exactly + bool multi_file_scan = false; bool HasExpectedSchema() const { return expected_names && expected_types; @@ -171,6 +179,14 @@ struct TableFunctionInitInput { optional_ptr filters; optional_ptr sample_options; optional_ptr op; + //! (Optional) The types the columns above must be produced as, when they differ from the types the function + //! bound to. Only set for functions that declare "supports_cast_map" - the function converts to these types + //! while reading, rather than having the conversion applied to its output + optional_ptr> cast_map; + //! (Optional) When the caller reads several files with this function, the index of the file this scan reads + //! and the number of files it reads in total. "op" is then the operator all those files are read for + optional_idx file_index; + idx_t file_count = 1; bool CanRemoveFilterColumns() const { if (projection_ids.empty()) { @@ -188,12 +204,16 @@ struct TableFunctionInitInput { //! Input for combining the schemas of several files that were bound individually into one schema struct TableFunctionCombineSchemaInput { - explicit TableFunctionCombineSchemaInput(const vector> &bind_data_p) - : bind_data(bind_data_p) { + TableFunctionCombineSchemaInput(const vector> &bind_data_p, bool union_by_name_p) + : bind_data(bind_data_p), union_by_name(union_by_name_p) { } //! The bind data of each of the files whose schemas are being combined - in file order const vector> &bind_data; + //! Whether the schemas are combined because of union_by_name - the files are then expected to have different + //! columns, which are unified by name. Otherwise the files are expected to have the same columns, and the + //! schemas are combined to determine the schema of the scan more accurately + bool union_by_name; }; struct TableFunctionInput { @@ -391,9 +411,15 @@ typedef bool (*table_function_claim_batch_t)(ClientContext &context, TableFuncti //! Called when a local state will not scan any more batches - lets the function release the resources of the batch //! it scanned last. The counterpart of table_function_claim_batch_t typedef void (*table_function_finish_batch_t)(ClientContext &context, TableFunctionInput &input); -//! Combines the schemas of several individually bound files into one. Returns the bind data describing the combined -//! schema, which is handed to the bind of every file that is read - or nullptr if the schemas could not be combined, -//! in which case the caller falls back to combining the return types +//! Whether the scan of this function can be driven by read-ahead - the caller then claims batches and schedules +//! their I/O ahead of scanning them. Only meaningful together with table_function_claim_batch_t +typedef bool (*table_function_supports_read_ahead_t)(const FunctionData &bind_data); +//! Schedules the I/O needed by the batch a local state has claimed, so it can be loaded before it is scanned +typedef AsyncResult (*table_function_schedule_io_t)(ClientContext &context, TableFunctionInput &input); +//! Combines the schemas of several individually bound files into one. The names and types are pre-filled with the +//! schemas of the files combined by name - the function can replace or adjust them. Returns the bind data describing +//! the combined schema, which is then handed to the bind of every file that is read - or nullptr when the files must +//! be bound individually and reconciled with the combined schema by the caller typedef unique_ptr (*table_function_combine_schema_t)(ClientContext &context, TableFunctionCombineSchemaInput &input, vector &return_types, @@ -525,6 +551,10 @@ class TableFunction : public SimpleNamedParameterFunction { // NOLINT: work-arou table_function_claim_batch_t claim_batch; //! (Optional) called when a local state will not scan any more batches - see table_function_finish_batch_t table_function_finish_batch_t finish_batch; + //! (Optional) whether the scan can be driven by read-ahead - see table_function_supports_read_ahead_t + table_function_supports_read_ahead_t supports_read_ahead; + //! (Optional) schedules the I/O of a claimed batch - see table_function_schedule_io_t + table_function_schedule_io_t schedule_io; //! (Optional) function for rendering the operator to a string in explain/profiling output (invoked pre-execution) table_function_to_string_t to_string; //! (Optional) return how much of the table we have scanned up to this point (% of the data) @@ -565,6 +595,10 @@ class TableFunction : public SimpleNamedParameterFunction { // NOLINT: work-arou //! Whether or not the table function supports projection pushdown. If not supported a projection will be added //! that filters out unused columns. bool projection_pushdown; + //! Whether the function can produce columns as a different type than it bound them - see + //! TableFunctionInitInput::cast_map. A function that reads one file of a multi-file scan uses this to report the + //! schema of its own file, and still produce the types of the scan + bool supports_cast_map; //! Whether or not the table function supports filter pushdown. If not supported a filter will be added //! that applies the table filter directly. bool filter_pushdown; diff --git a/src/duckdb/src/include/duckdb/function/window/value_functions.hpp b/src/duckdb/src/include/duckdb/function/window/value_functions.hpp index 121266c51..fa04466c0 100644 --- a/src/duckdb/src/include/duckdb/function/window/value_functions.hpp +++ b/src/duckdb/src/include/duckdb/function/window/value_functions.hpp @@ -47,7 +47,7 @@ struct NthValueFun { struct LeadFun { static constexpr const char *Name = "lead"; - static constexpr const char *Parameters = "expr[,n[,default]]"; + static constexpr const char *Parameters = "col,offset,default"; static constexpr const char *Description = "The value of expr n rows after the current row, or the default. Can IGNORE or RESPECT NULLS."; static constexpr const char *Example = "LEAD(athlete, 1, NULL) OVER (PARTITION BY event ORDER BY points) AS victorious_over"; static constexpr const char *Categories = ""; @@ -58,7 +58,7 @@ struct LeadFun { struct LagFun { static constexpr const char *Name = "lag"; - static constexpr const char *Parameters = "expr[,n[,default]]"; + static constexpr const char *Parameters = "col,offset,default"; static constexpr const char *Description = "The value of expr n rows after the current row, or the default. Can IGNORE or RESPECT NULLS."; static constexpr const char *Example = "LAG(athlete, 1, NULL) OVER (PARTITION BY event ORDER BY points) AS defeated_by"; static constexpr const char *Categories = ""; diff --git a/src/duckdb/src/include/duckdb/function/window_function.hpp b/src/duckdb/src/include/duckdb/function/window_function.hpp index ed62bdee6..49244638d 100644 --- a/src/duckdb/src/include/duckdb/function/window_function.hpp +++ b/src/duckdb/src/include/duckdb/function/window_function.hpp @@ -378,13 +378,18 @@ class BoundWindowFunction : public BaseWindowFunction, public BoundSimpleFunctio const shared_ptr &GetDefinition() const { return definition; } + const vector &GetLogicalArguments() const { + return logical_arguments; + } + const LogicalType &GetLogicalReturnType() const { + return logical_return_type; + } //! Restore the definition after the bound function has been replaced wholesale, together with the //! qualification it carries - the replacement is a specialized implementation, not a different function void SetDefinition(shared_ptr definition_p) { definition = std::move(definition_p); if (definition) { - schema_name = definition->GetSchemaName(); - catalog_name = definition->GetCatalogName(); + qualified_name = definition->GetQualifiedName().WithName(GetName()); } } @@ -446,7 +451,18 @@ class BoundWindowFunction : public BaseWindowFunction, public BoundSimpleFunctio } private: + void SetLogicalArguments(vector arguments_p) { + logical_arguments = std::move(arguments_p); + } + void SetLogicalReturnType(LogicalType return_type_p) { + logical_return_type = std::move(return_type_p); + } shared_ptr definition; + vector logical_arguments; + LogicalType logical_return_type; + + friend class FunctionBinder; + friend class FunctionSerializer; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/logging/log_type.hpp b/src/duckdb/src/include/duckdb/logging/log_type.hpp index 874f9ea85..3da7f584a 100644 --- a/src/duckdb/src/include/duckdb/logging/log_type.hpp +++ b/src/duckdb/src/include/duckdb/logging/log_type.hpp @@ -200,6 +200,19 @@ class AsyncTaskScheduleLogType : public LogType { static string ConstructLogMessage(const string &pool, idx_t task_count); }; +class ProgressVerificationLogType : public LogType { +public: + static constexpr const char *NAME = "ProgressVerification"; + static constexpr LogLevel LEVEL = LogLevel::LOG_INFO; + + ProgressVerificationLogType(); + + static LogicalType GetLogType(); + + static string ConstructLogMessage(const string &invariant, const string &operator_name, const string &pipeline, + const string &detail); +}; + class ExternalResourceLogType : public LogType { public: static constexpr const char *NAME = "ExternalResource"; diff --git a/src/duckdb/src/include/duckdb/logging/logger.hpp b/src/duckdb/src/include/duckdb/logging/logger.hpp index 01655bde1..a5b6d1243 100644 --- a/src/duckdb/src/include/duckdb/logging/logger.hpp +++ b/src/duckdb/src/include/duckdb/logging/logger.hpp @@ -70,7 +70,7 @@ class Logger { // Syntactic sugar for formatted strings template - void WriteLog(const char *log_type, LogLevel log_level, const char *format_string, ARGS... params) { + void WriteLog(const char *log_type, LogLevel log_level, const char *format_string, const ARGS &...params) { auto formatted_string = StringUtil::Format(format_string, params...); WriteLog(log_type, log_level, formatted_string.c_str()); } diff --git a/src/duckdb/src/include/duckdb/main/attached_database.hpp b/src/duckdb/src/include/duckdb/main/attached_database.hpp index ffd5fc124..b6bbfe719 100644 --- a/src/duckdb/src/include/duckdb/main/attached_database.hpp +++ b/src/duckdb/src/include/duckdb/main/attached_database.hpp @@ -21,6 +21,7 @@ class StorageManager; class TransactionManager; class StorageExtension; class DatabaseManager; +class ResourceDeleter; struct AttachInfo; struct StoredDatabasePath; @@ -67,6 +68,11 @@ struct AttachOptions { //! Constructor for databases we attach when using ATTACH DATABASE. AttachOptions(const unordered_map &options, const AccessMode default_access_mode); + //! The setting an attach option controls, lower-cased. All four spellings of the access mode + //! (readonly, read_only, readwrite, read_write) share one setting, so two of them in the same + //! statement are a collision rather than two independent options. + static string OptionSetting(const string &name); + //! Defaults to the access mode configured in the DBConfig, unless specified otherwise. AccessMode access_mode; //! The recovery type of the database. @@ -90,6 +96,17 @@ struct AttachOptions { unique_ptr stored_database_path; //! Per-database override of vacuum_rebuild_indexes. If not set, the global setting value is used. optional_idx vacuum_rebuild_indexes_threshold; + //! Deleter binding (from ATTACH/CONNECT TO EXTERNAL RESOURCE): on detach, `()` + //! runs to tear down the external resource the attachment owns. + string deleter_function; + Value deleter_payload; + //! Type and name of the owned resource, for teardown logging only. The name is the database alias, + //! or empty where there is none (CONNECT). + string deleter_resource_type; + string deleter_resource_name; + //! Registered resource this attachment BORROWS (from `ATTACH/CONNECT TO EXTERNAL RESOURCE `): it binds + //! no deleter and does not block DESTROY, it only lets DESTROY report what it invalidated. Empty if none. + string borrowed_resource_name; //! Header prefetched during file-type detection, reused when opening the file. Empty for non-DuckDB files. PrefetchedFileData prefetched; }; @@ -137,6 +154,9 @@ class AttachedDatabase : public CatalogEntry, public enable_shared_from_this ExtractDeleter(); bool IsSystem() const; bool IsTemporary() const; bool IsReadOnly() const; @@ -154,6 +174,10 @@ class AttachedDatabase : public CatalogEntry, public enable_shared_from_this attach_options; optional original_path; + //! Deleter binding (from ATTACH/CONNECT TO EXTERNAL RESOURCE): moved out via ExtractDeleter on detach. + string deleter_function; + Value deleter_payload; + string deleter_resource_type; + string deleter_resource_name; + //! Registered resource this attachment borrows without owning; see AttachOptions. + string borrowed_resource_name; private: //! Clean any (shared) resources held by the database. diff --git a/src/duckdb/src/include/duckdb/main/buffered_data/batched_buffered_data.hpp b/src/duckdb/src/include/duckdb/main/buffered_data/batched_buffered_data.hpp index faf5cd8ef..c3c9062e4 100644 --- a/src/duckdb/src/include/duckdb/main/buffered_data/batched_buffered_data.hpp +++ b/src/duckdb/src/include/duckdb/main/buffered_data/batched_buffered_data.hpp @@ -19,18 +19,18 @@ namespace duckdb { -class StreamQueryResult; +class QueryResult; class InProgressBatch { public: - //! The batch's chunks, in arrival order. - vector chunk_refs; + //! The batch's units, in arrival order. + vector> units; //! Whether the batch is completed (CompleteBatch has been called). bool completed = false; }; -//! The order-preserving streaming buffer: chunks wait in `buffer` until their batch becomes the minimum, then move -//! to the `read_queue` the consumer pops. A minimum-batch producer only parks while chunks are poppable, so a pop +//! The order-preserving streaming buffer: units wait in `buffer` until their batch becomes the minimum, then move +//! to the `read_queue` the consumer pops. A minimum-batch producer only parks while units are poppable, so a pop //! always wakes it class BatchedBufferedData : public BufferedData { public: @@ -40,10 +40,10 @@ class BatchedBufferedData : public BufferedData { BatchedBufferedData(ClientContext &context, ResultLifetime lifetime); public: - //! Buffer a copy of the chunk, or block the sink when the chunk does not fit. Returns true on block. - bool AppendOrBlock(DataChunk &chunk, idx_t batch, const InterruptState &blocked_sink); + //! Buffer the finished unit under its batch, or block the sink when the unit does not fit. Returns true on block. + bool AppendOrBlock(unique_ptr unit, idx_t batch, const InterruptState &blocked_sink); - unique_ptr Scan() override; + unique_ptr Scan() override; void UpdateMinBatchIndex(idx_t min_batch_index); bool IsMinimumBatchIndex(annotated_lock_guard &lock, idx_t batch) DUCKDB_REQUIRES(glock); void CompleteBatch(idx_t batch); @@ -52,6 +52,9 @@ class BatchedBufferedData : public BufferedData { annotated_lock_guard lock(glock); return !blocked_sinks.empty(); } + bool HasObservableUnit() override { + return !BufferIsEmpty(); + } void UnblockSinks() override; void AssertNoBlockedSinks() override; @@ -62,30 +65,30 @@ class BatchedBufferedData : public BufferedData { } protected: - //! Consumption order is the read queue, so the replenish stops once it holds a chunk + //! Consumption order is the read queue, so the replenish stops once it holds a unit bool ReplenishSatisfied() override { return !BufferIsEmpty(); } void MoveCompletedBatches(annotated_lock_guard &lock) DUCKDB_REQUIRES(glock); - //! Whether a chunk of incoming_bytes may not be buffered for this batch right now. + //! Whether a unit of incoming_bytes may not be buffered for this batch right now. bool ShouldBlockBatch(annotated_lock_guard &lock, idx_t batch, idx_t incoming_bytes) DUCKDB_REQUIRES(glock); //! Pop restartable sinks into to_unblock. void CollectRestartableSinks(annotated_lock_guard &lock, vector> &to_unblock) DUCKDB_REQUIRES(glock); - //! Deposit a restarting sink's parked chunk. + //! Deposit a restarting sink's parked unit. void DepositParked(annotated_lock_guard &lock, idx_t batch, BlockedSink &sink) DUCKDB_REQUIRES(glock); //! Invoke the collected restartable sinks in to_unblock. void InvokeUnblocks(const vector> &to_unblock) DUCKDB_EXCLUDES(glock); protected: - //! The buffer where chunks are written before they are ready to be read. + //! The buffer where units are written before they are ready to be read. map buffer DUCKDB_GUARDED_BY(glock); idx_t buffer_byte_count DUCKDB_GUARDED_BY(glock); - //! The readable chunks, in consumption order - queue read_queue DUCKDB_GUARDED_BY(glock); + //! The readable units, in consumption order + queue> read_queue DUCKDB_GUARDED_BY(glock); idx_t read_queue_byte_count DUCKDB_GUARDED_BY(glock); map blocked_sinks DUCKDB_GUARDED_BY(glock); @@ -95,8 +98,8 @@ class BatchedBufferedData : public BufferedData { idx_t lowest_moved_batch DUCKDB_GUARDED_BY(glock) = 0; //! The highest number of bytes ever buffered idx_t peak_buffered_bytes DUCKDB_GUARDED_BY(glock) = 0; - //! The largest single chunk seen so far - idx_t max_seen_chunk_bytes DUCKDB_GUARDED_BY(glock) = 0; + //! The largest single unit seen so far + idx_t max_seen_unit_bytes DUCKDB_GUARDED_BY(glock) = 0; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/buffered_data/buffered_data.hpp b/src/duckdb/src/include/duckdb/main/buffered_data/buffered_data.hpp index ece32aedd..197373a7a 100644 --- a/src/duckdb/src/include/duckdb/main/buffered_data/buffered_data.hpp +++ b/src/duckdb/src/include/duckdb/main/buffered_data/buffered_data.hpp @@ -16,33 +16,29 @@ #include "duckdb/common/types/data_chunk.hpp" #include "duckdb/common/optional_idx.hpp" #include "duckdb/execution/physical_operator_states.hpp" -#include "duckdb/common/enums/pending_execution_result.hpp" +#include "duckdb/common/enums/query_result_state.hpp" #include "duckdb/common/enums/result_lifetime.hpp" -#include "duckdb/common/enums/stream_execution_result.hpp" #include "duckdb/common/mutex.hpp" #include "duckdb/common/shared_ptr.hpp" #include "duckdb/common/thread_annotation.hpp" +#include "duckdb/main/result_unit.hpp" namespace duckdb { -class StreamQueryResult; +class QueryResult; class ClientContextLock; -//! A blocked sink. Holds the InterruptState and owns the finished copy of the chunk it could not append. +//! A blocked sink. Holds the InterruptState and owns the finished unit it could not append. struct BlockedSink { public: InterruptState state; - idx_t pending_bytes; - unique_ptr pending_chunk; -}; + unique_ptr pending_unit; -//! One unread buffered chunk, in consumption order. The buffer owns the copy until it is popped, and the consumer -//! owns it afterwards. -struct BufferedChunk { public: - unique_ptr chunk; - //! The bytes this chunk counts against the cap - idx_t data_size; + //! The bytes the parked unit counts against the cap, zero once the unit has been deposited + idx_t PendingBytes() const { + return pending_unit ? pending_unit->byte_size : 0; + } }; class BufferedData { @@ -64,22 +60,28 @@ class BufferedData { void DecideDraining(); //! Park a producer until the retention is decided. False when it already is bool ParkUndecided(const InterruptState &blocked_sink); - //! Whether a producer is parked on this buffer, for a decision or for space. Only the consumer releases it - bool HasParkedProducer(); - //! Blocking call that executes tasks on the calling thread until a chunk is buffered or execution reaches a + //! Whether the engine waits on the consumer: a producer is parked for the retention decision, or for + //! space that only a pop frees + bool WaitsOnConsumer(); + //! Blocking call that executes tasks on the calling thread until a unit is buffered or execution reaches a //! terminal state. - StreamExecutionResult ReplenishBuffer(StreamQueryResult &result, ClientContextLock &context_lock); - //! One blocking replenish step: run executor tasks until a chunk is poppable - StreamExecutionResult ExecuteTaskInternal(StreamQueryResult &result, ClientContextLock &context_lock); - virtual unique_ptr Scan() = 0; + QueryResultState ReplenishBuffer(ClientContextLock &context_lock, QueryResult &result); + //! Lend the calling thread to production: settle draining, wake parked producers and run at most one + //! task slice. Reports whether a unit is poppable. Never waits + QueryResultState Participate(ClientContextLock &context_lock, QueryResult &result); + //! Reports whether a unit is poppable, else where execution stands. Runs no task, never waits + QueryResultState Poll(ClientContextLock &context_lock, QueryResult &result); + virtual unique_ptr Scan() = 0; virtual void UnblockSinks() = 0; shared_ptr GetContext() { return context.lock(); } //! The highest number of bytes the buffer ever held. virtual idx_t PeakBufferedBytes() = 0; - //! Whether a producer is parked for space. A parked producer implies a poppable chunk. + //! Whether a producer is parked for space. virtual bool HasBlockedSink() = 0; + //! Whether a unit is ready for the consumer to pop. + virtual bool HasObservableUnit() = 0; //! Debug assert that no blocked sinks exist. virtual void AssertNoBlockedSinks() = 0; //! An owned, exactly-sized copy: the producer reuses its output chunk, and the copy's GetDataSize is what the @@ -114,8 +116,10 @@ class BufferedData { } protected: - static StreamExecutionResult MapExecutionResult(PendingExecutionResult execution_result); - //! Whether the blocking replenish can stop: a chunk is poppable, and the buffer will + //! Record on the result that it is no longer the connection's active query, and report it as an + //! error state + static QueryResultState Cancelled(QueryResult &result); + //! Whether the blocking replenish can stop: a unit is poppable, and the buffer will //! not accept more input right now virtual bool ReplenishSatisfied() = 0; //! Pops below this mark restart blocked sinks. The floor keeps it reachable for tiny buffers diff --git a/src/duckdb/src/include/duckdb/main/buffered_data/simple_buffered_data.hpp b/src/duckdb/src/include/duckdb/main/buffered_data/simple_buffered_data.hpp index 0a79d4eea..07de7c619 100644 --- a/src/duckdb/src/include/duckdb/main/buffered_data/simple_buffered_data.hpp +++ b/src/duckdb/src/include/duckdb/main/buffered_data/simple_buffered_data.hpp @@ -18,7 +18,7 @@ namespace duckdb { -class StreamQueryResult; +class QueryResult; class SimpleBufferedData : public BufferedData { public: @@ -29,23 +29,24 @@ class SimpleBufferedData : public BufferedData { ~SimpleBufferedData() override; public: - //! Buffer a copy of the chunk, or block the sink when the chunk does not fit. - bool AppendOrBlock(DataChunk &chunk, const InterruptState &blocked_sink); - //! Whether the buffer is saturated, t.e. can't accept a new chunk right now. + //! Buffer the finished unit, or block the sink when the unit does not fit. + bool AppendOrBlock(unique_ptr unit, const InterruptState &blocked_sink); + //! Whether the buffer is saturated, t.e. can't accept a new unit right now. bool BufferSaturated(); //! The highest number of bytes the buffer ever held. idx_t PeakBufferedBytes() override; bool HasBlockedSink() override; + bool HasObservableUnit() override; void UnblockSinks() override; void AssertNoBlockedSinks() override; - unique_ptr Scan() override; + unique_ptr Scan() override; inline idx_t BufferSize() const { return buffer_size; } protected: //! The buffer will not accept more input, and blocking requires a non-empty buffer, - //! so a saturated buffer always holds a poppable chunk + //! so a saturated buffer always holds a poppable unit bool ReplenishSatisfied() override { return BufferSaturated(); } @@ -60,8 +61,8 @@ class SimpleBufferedData : public BufferedData { private: //! Our handles to reschedule the blocked sink tasks queue blocked_sinks DUCKDB_GUARDED_BY(glock); - //! The unread chunks, in arrival order. The buffer owns each copy until its pop - queue unread_chunks DUCKDB_GUARDED_BY(glock); + //! The unread units, in arrival order. The buffer owns each unit until its pop + queue> unread_units DUCKDB_GUARDED_BY(glock); //! The bytes currently buffered atomic buffered_count; //! The byte cap of the buffer diff --git a/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp b/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp index 2434b9c41..6fbdeda74 100644 --- a/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +++ b/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp @@ -62,12 +62,12 @@ struct ExtractStatementsWrapper { }; struct PendingStatementWrapper { - unique_ptr statement; + unique_ptr statement; bool allow_streaming; }; struct ArrowResultWrapper { - unique_ptr result; + unique_ptr result; unique_ptr current_chunk; }; @@ -97,12 +97,55 @@ enum class CAPIResultSetType : uint8_t { CAPI_RESULT_TYPE_DEPRECATED }; +//! Either a query handle or a stream opened from one. Only the streaming entry points care which; +//! everything else reads the metadata and the error, which both carry struct DuckDBResultData { - //! The underlying query result + //! The query handle, or null once a stream was opened from it unique_ptr result; + //! The stream opened from the handle (may be null) + unique_ptr stream; // Results can only use either the new API or the old API, not a mix of the two // They start off as "none" and switch to one or the other when an API method is used CAPIResultSetType result_set_type; + + bool IsStreaming() const { + return stream != nullptr; + } + //! The retained result. Only valid when the result is not streaming + QueryResult &Retained() const { + D_ASSERT(result); + return *result; + } + bool HasError() const { + return stream ? stream->HasError() : result->HasError(); + } + const string &GetError() const { + return stream ? stream->GetError() : result->GetError(); + } + const ExceptionType &GetErrorType() const { + return stream ? stream->GetErrorType() : result->GetErrorType(); + } + idx_t ColumnCount() const { + return stream ? stream->ColumnCount() : result->ColumnCount(); + } + const vector &GetTypes() const { + return stream ? stream->GetTypes() : result->GetTypes(); + } + const Identifier &ColumnName(idx_t index) const { + return stream ? stream->ColumnName(index) : result->ColumnName(index); + } + StatementType GetStatementType() const { + return stream ? stream->GetStatementType() : result->GetStatementType(); + } + const StatementProperties &GetStatementProperties() const { + return stream ? stream->GetStatementProperties() : result->GetStatementProperties(); + } + ClientProperties &GetClientProperties() { + return stream ? stream->GetClientProperties() : result->client_properties; + } + unique_ptr Fetch() { + return stream ? stream->Fetch() : result->Fetch(); + } }; duckdb_type LogicalTypeIdToC(const LogicalTypeId type); @@ -113,6 +156,7 @@ duckdb_error_type ErrorTypeToC(const ExceptionType type); ExceptionType ErrorTypeFromC(const duckdb_error_type type); duckdb_state DuckDBTranslateResult(unique_ptr result, duckdb_result *out); +duckdb_state DuckDBTranslateStreamResult(unique_ptr stream, duckdb_result *out); bool DeprecatedMaterializeResult(duckdb_result *result); } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp b/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp index abb10bcaa..b86090aa8 100644 --- a/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp +++ b/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp @@ -21,8 +21,6 @@ #include "duckdb/main/client_context_state.hpp" #include "duckdb/main/extension/extension_loader.hpp" #include "duckdb/main/parse_iterator.hpp" -#include "duckdb/main/pending_query_result.hpp" -#include "duckdb/main/stream_query_result.hpp" #include "duckdb/main/table_description.hpp" #include "duckdb/parser/qualified_name.hpp" #include "duckdb/parser/sql_statement.hpp" @@ -108,8 +106,8 @@ inline auto Convert(duckdb_v2_interval_t value) -> interval_t { return out; } -// The V2 enum surfaces core's StatementType under the same numeric values; every spec member is pinned. Core has no -// count sentinel, so a member appended in core is caught by the test over the values past the last spec member. +// The V2 enum surfaces core's StatementType under the same numeric values; every spec member is pinned, and the count +// pins the highest one - appending a member in core fails to compile until the v2 spec mirrors it. #define DUCKDB_V2_ASSERT_STATEMENT_TYPE(member) \ static_assert(static_cast(StatementType::member##_STATEMENT) == DUCKDB_V2_STATEMENT_TYPE_##member, \ "StatementType::" #member "_STATEMENT must mirror DUCKDB_V2_STATEMENT_TYPE_" #member) @@ -148,6 +146,8 @@ DUCKDB_V2_ASSERT_STATEMENT_TYPE(CONNECT); DUCKDB_V2_ASSERT_STATEMENT_TYPE(DISCONNECT); DUCKDB_V2_ASSERT_STATEMENT_TYPE(EXTERNAL_RESOURCE); #undef DUCKDB_V2_ASSERT_STATEMENT_TYPE +static_assert(static_cast(StatementType::ENUM_SIZE) == DUCKDB_V2_STATEMENT_TYPE_EXTERNAL_RESOURCE + 1, + "a StatementType was added: give it a DUCKDB_V2_STATEMENT_TYPE id in the v2 spec and pin it above"); inline auto Convert(StatementType type) -> DUCKDB_V2_STATEMENT_TYPE { return static_cast(type); } @@ -159,7 +159,7 @@ inline auto Convert(StatementType type) -> DUCKDB_V2_STATEMENT_TYPE { class CV2Environment { public: unique_ptr cache; - std::atomic open_database_count {0}; + std::atomic instance_count {0}; }; inline auto Convert(CV2Environment *env) -> duckdb_v2_environment_handle { @@ -170,23 +170,75 @@ inline auto Convert(duckdb_v2_environment_handle env) -> CV2Environment * { return reinterpret_cast(env); } -class CV2Database { +class CV2Option; +class CV2Instance; + +//! The SQL ATTACH `(KEY value)` options of one attach, as the text values a quoted literal produces. Bound to the +//! instance handle it was created from, which is what future per-instance resources (an allocator, say) would be +//! taken from. +class CV2AttachOptions { public: - CV2Database(CV2Environment &env, shared_ptr database) : env(env), database(std::move(database)) { - internal_connection = make_uniq(*this->database); + explicit CV2AttachOptions(CV2Instance &instance) : instance(instance) { } + CV2Instance &instance; + unordered_map options; +}; + +inline auto Convert(duckdb_v2_attach_options_handle options) -> CV2AttachOptions * { + return reinterpret_cast(options); +} + +inline auto Convert(CV2AttachOptions *options) -> duckdb_v2_attach_options_handle { + return reinterpret_cast(options); +} + +//! An instance handle: a DuckDB instance plus the configuration it starts with. The instance starts on first use +//! (instance_attach or connection_create); until then options are staged in the startup config. Every entry point +//! holds `lock`, which also serializes use of the internal connection. +class CV2Instance { +public: + explicit CV2Instance(CV2Environment &env); + + bool IsStarted() const { + return database != nullptr; + } + //! Starts the instance if it has not started yet, consuming the staged config. + void Start(); + //! Attaches the database at `path` under `name` (derived from the path when empty), like ATTACH, optionally as + //! the default for new connections; starts the instance first if needed. + void Attach(const string &path, const Identifier &name, optional_ptr options, + bool make_default); + //! Detaches the database attached from `path`, or attached under that name. + void Detach(const string &path); + //! Makes the database attached from `path`, or attached under that name, the default for new connections. + void SetDefault(const string &path); + //! Stages a startup option, or SET GLOBAL once started. + void SetOption(const Identifier &name, const string &setting); + unique_ptr GetOption(std::string_view name); + idx_t GetOptionCount(); + unique_ptr GetOptionByIndex(idx_t index); + //! The started instance; starts it if needed. + DuckDB &GetDatabase(); + CV2Environment &env; + mutex lock; + +private: + //! Staged until Start consumes it. + unique_ptr config; + //! The staged settings as written, by canonical name: legacy options cannot be read back from a DBConfig. + identifier_map_t staged_settings; shared_ptr database; unique_ptr internal_connection; }; -inline auto Convert(duckdb_v2_database_handle db) -> CV2Database * { - return reinterpret_cast(db); +inline auto Convert(duckdb_v2_instance_handle instance) -> CV2Instance * { + return reinterpret_cast(instance); } -inline auto Convert(CV2Database *db) -> duckdb_v2_database_handle { - return reinterpret_cast(db); +inline auto Convert(CV2Instance *instance) -> duckdb_v2_instance_handle { + return reinterpret_cast(instance); } using CV2Connection = duckdb::Connection; @@ -240,6 +292,28 @@ inline auto Convert(CV2FunctionSignature *func) -> duckdb_v2_function_signature_ return reinterpret_cast(func); } +//! Where an option's current setting is read from: a started instance's context (LOCAL -> GLOBAL -> default), or the +//! startup config of an instance that has not started (staged GLOBAL -> default). +class CV2OptionSource { +public: + explicit CV2OptionSource(ClientContext &context) : context(&context), config(DBConfig::GetConfig(context)) { + } + CV2OptionSource(const DBConfig &config, const identifier_map_t &staged_settings) + : config(config), staged_settings(&staged_settings) { + } + + const DBConfig &GetConfig() const { + return config; + } + //! The effective setting of `name`, or `fallback` when the cascade yields NULL. + string ReadSetting(const Identifier &name, const string &fallback) const; + +private: + optional_ptr context; + const DBConfig &config; + optional_ptr> staged_settings; +}; + class CV2Option { public: Identifier name; @@ -249,8 +323,9 @@ class CV2Option { DUCKDB_V2_OPTION_TARGET_SCOPE target_scope = DUCKDB_V2_OPTION_TARGET_SCOPE_UNKNOWN; vector aliases; - static unique_ptr FromIndex(ClientContext &context, DBConfig &config, idx_t index); - static unique_ptr FromName(ClientContext &context, DBConfig &config, std::string_view name); + static unique_ptr FromIndex(const CV2OptionSource &source, idx_t index); + static unique_ptr FromName(const CV2OptionSource &source, std::string_view name); + static idx_t Count(const CV2OptionSource &source); }; inline auto Convert(duckdb_v2_option_handle opt) -> CV2Option * { @@ -297,6 +372,15 @@ inline auto Convert(CV2ColumnDescription *column) -> duckdb_v2_column_descriptio return reinterpret_cast(column); } +using CV2ColumnDataCollection = duckdb::ColumnDataCollection; + +inline auto Convert(duckdb_v2_column_data_collection_handle cdc) -> CV2ColumnDataCollection * { + return reinterpret_cast(cdc); +} +inline auto Convert(CV2ColumnDataCollection *cdc) -> duckdb_v2_column_data_collection_handle { + return reinterpret_cast(cdc); +} + using CV2Value = duckdb::Value; inline auto Convert(duckdb_v2_value_handle val) -> CV2Value * { @@ -364,7 +448,7 @@ auto NullArgumentError(duckdb_v2_error_info_handle *err, const char *function, c // Classify the exception currently being handled into a V2 error code and detail strings. Must be called from inside // a catch block. Never throws: if rendering the detail itself fails, it degrades to a bare code with empty detail // (RESOURCE_OUT_OF_MEMORY on allocation failure). Defined in capi_v2.cpp. -auto RenderCaughtError(DUCKDB_V2_ERROR &code, string &text, string &raw_message) noexcept -> void; +auto RenderCaughtError(DUCKDB_V2_ERROR &code, string &text, optional &raw_message) noexcept -> void; // The null test behind DUCKDB_CHECK_ARG: a pointer/handle is invalid when null; a string/identifier view is invalid // when its pointer is null while it carries a non-zero length. @@ -402,7 +486,7 @@ struct CV2ErrorInfo { // rendered form (caret block, or JSON under errors_as_json); empty for a // directly-set message. Both written on the error path (WithErrorHandler). string message; - string raw_message; + optional raw_message; bool HasError() const { return code != DUCKDB_V2_ERROR_NONE; @@ -437,7 +521,7 @@ template DUCKDB_V2_ERROR WithErrorHandler(duckdb_v2_error_info_handle *err, T callback) noexcept { auto code = static_cast(DUCKDB_V2_ERROR_NONE); auto text = string(); - auto raw_message = string(); + optional raw_message; try { // Invoke the callback diff --git a/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_result_internal.hpp b/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_result_internal.hpp index d76fc2861..50f649299 100644 --- a/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_result_internal.hpp +++ b/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_result_internal.hpp @@ -23,16 +23,17 @@ struct ResultWrapperV2 { ~ResultWrapperV2() { // Finalize() (engine cleanup) runs in duckdb_v2_result_destroy, not here: // a destructor must not drive locked engine state behind a catch-all. - pending.reset(); - result.reset(); + stream.reset(); + handle.reset(); ReleaseBusySlot(); } State state = State::PENDING; - //! Live while state == PENDING. - unique_ptr pending; - //! Live while state == STREAMING. - unique_ptr result; + //! The handle of the running query. Live while state == PENDING, and afterwards for a result + //! that is retained rather than streamed. + unique_ptr handle; + //! Live while state == STREAMING, for a statement whose result can be streamed. + unique_ptr stream; //! Keeps the ClientContext alive for starting subsequent fragments and //! preserves the guarantee that an undrained result survives disconnect: @@ -92,7 +93,7 @@ struct ResultWrapperV2 { if (context->transaction.HasActiveTransaction()) { // Mirrors Connection::Rollback (Query("ROLLBACK") + throw on error), // driven through the retained context so it works after disconnect. - auto result = context->Query("ROLLBACK", QueryResultOutputType::FORCE_MATERIALIZED); + auto result = context->Query("ROLLBACK", QueryParameters()); if (result->HasError()) { result->ThrowError(); } @@ -104,10 +105,10 @@ struct ResultWrapperV2 { //! then roll back an injected group transaction. May throw; the terminal //! states leave pending/result null, so this is then a no-op. void Finalize() { - if (pending) { - pending->Close(); - } else if (result && result->GetResultType() == QueryResultType::STREAM_RESULT) { - result->Cast().Close(); + if (stream) { + stream->Close(); + } else if (handle) { + handle->Close(); } RollbackIncompleteGroup(); } @@ -127,10 +128,10 @@ struct ResultWrapperV2 { // them throw DuckDB exceptions on failure (callers wrap in // WithErrorHandler) and record sticky errors before throwing. - //! Adopts an already-produced pending query into the state machine: the single - //! seam both the stateless (fragment) and prepared paths reach. When is_principal, - //! captures its metadata and surfaces its chunks. Throws on a pending prepare error. - void BeginPending(unique_ptr pending, bool is_principal); + //! Adopts an already-submitted query into the state machine: the single seam both the + //! stateless (fragment) and prepared paths reach. When is_principal, captures its metadata and + //! surfaces its chunks. Throws on a submission error. + void BeginPending(unique_ptr handle, bool is_principal); //! Starts the pending query for the next fragment, selecting it as //! principal per the engine-mirrored rule and adopting it via BeginPending. //! Throws on prepare errors. diff --git a/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp b/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp index 792fcac7b..28518ba4e 100644 --- a/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp +++ b/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp @@ -15,7 +15,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_bignum_encode) (const uint8_t *in_data, idx_t in_length, bool is_negative, uint8_t *out_data, idx_t out_capacity, idx_t *out_length, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR (*duckdb_v2_close)(duckdb_v2_database_handle *db); DUCKDB_V2_ERROR(*duckdb_v2_column_data_collection_append) (duckdb_v2_column_data_collection_handle collection, duckdb_v2_column_data_collection_append_state_handle state, duckdb_v2_data_chunk_handle chunk, duckdb_v2_error_info_handle *err); @@ -53,8 +52,8 @@ typedef struct { duckdb_v2_column_data_collection_worker_scan_state_handle *out_state, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_column_data_collection_worker_scan_state_destroy) (duckdb_v2_column_data_collection_worker_scan_state_handle *state); - DUCKDB_V2_ERROR(*duckdb_v2_connect) - (duckdb_v2_database_handle db, duckdb_v2_connection_handle *out_conn, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_create) + (duckdb_v2_instance_handle instance, duckdb_v2_connection_handle *out_conn, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_connection_create_type_from_id) (duckdb_v2_connection_handle conn, DUCKDB_V2_LOGICAL_TYPE_ID type_id, const duckdb_v2_identifier_t *param_names, const duckdb_v2_value_handle *param_values, idx_t param_count, duckdb_v2_logical_type_handle *out_type, @@ -69,21 +68,23 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_connection_create_type_with_alias) (duckdb_v2_connection_handle conn, duckdb_v2_logical_type_handle base_type, duckdb_v2_identifier_t alias_name, duckdb_v2_logical_type_handle *out_type, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_interrupt) - (duckdb_v2_connection_handle conn, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_get) - (duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_get_by_index) + DUCKDB_V2_ERROR (*duckdb_v2_connection_destroy)(duckdb_v2_connection_handle *conn); + DUCKDB_V2_ERROR(*duckdb_v2_connection_get_option_by_index) (duckdb_v2_connection_handle conn, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_get_count) - (duckdb_v2_connection_handle conn, idx_t *out_count, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_set) - (duckdb_v2_connection_handle conn, duckdb_v2_option_handle option, DUCKDB_V2_SETTING_SCOPE scope, + DUCKDB_V2_ERROR(*duckdb_v2_connection_get_option_by_name) + (duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_query_progress) - (duckdb_v2_connection_handle conn, duckdb_v2_query_progress_handle *out_progress, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_get_option_count) + (duckdb_v2_connection_handle conn, idx_t *out_count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_interrupt) + (duckdb_v2_connection_handle conn, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_progress_get) + (duckdb_v2_connection_handle conn, double *out_percentage, uint64_t *out_rows_processed, + uint64_t *out_total_rows_to_process, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_set_option) + (duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, duckdb_v2_str setting, + DUCKDB_V2_SETTING_SCOPE scope, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_context_create_type_from_id) (duckdb_v2_context_handle ctx, DUCKDB_V2_LOGICAL_TYPE_ID type_id, const duckdb_v2_identifier_t *param_names, const duckdb_v2_value_handle *param_values, idx_t param_count, duckdb_v2_logical_type_handle *out_type, @@ -98,8 +99,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_context_create_type_with_alias) (duckdb_v2_context_handle ctx, duckdb_v2_logical_type_handle base_type, duckdb_v2_identifier_t alias_name, duckdb_v2_logical_type_handle *out_type, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_create_environment) - (duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_data_chunk_copy_with_connection) (duckdb_v2_connection_handle conn, duckdb_v2_data_chunk_handle chunk, duckdb_v2_data_chunk_handle *out_chunk, duckdb_v2_error_info_handle *err); @@ -123,26 +122,36 @@ typedef struct { duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_data_chunk_get_vector_count) (duckdb_v2_data_chunk_handle chunk, idx_t *out_count, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_get) - (duckdb_v2_database_handle db, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_get_by_index) - (duckdb_v2_database_handle db, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_get_count) - (duckdb_v2_database_handle db, idx_t *out_count, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_set) - (duckdb_v2_database_handle db, duckdb_v2_option_handle option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR (*duckdb_v2_destroy_environment)(duckdb_v2_environment_handle *env); - DUCKDB_V2_ERROR (*duckdb_v2_disconnect)(duckdb_v2_connection_handle *conn); - DUCKDB_V2_ERROR(*duckdb_v2_environment_database_count) + DUCKDB_V2_ERROR(*duckdb_v2_environment_create) + (duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_environment_destroy)(duckdb_v2_environment_handle *env); + DUCKDB_V2_ERROR(*duckdb_v2_environment_get_instance_count) (duckdb_v2_environment_handle env, idx_t *out_count, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_error_info_destroy)(duckdb_v2_error_info_handle *info); DUCKDB_V2_ERROR (*duckdb_v2_error_info_get_code)(duckdb_v2_error_info_handle info, DUCKDB_V2_ERROR *out_code); - DUCKDB_V2_ERROR(*duckdb_v2_error_info_get_raw_message) - (duckdb_v2_error_info_handle info, duckdb_v2_str *out_raw_message); + DUCKDB_V2_ERROR (*duckdb_v2_error_info_get_raw_text)(duckdb_v2_error_info_handle info, duckdb_v2_str *out_raw_text); DUCKDB_V2_ERROR (*duckdb_v2_error_info_get_text)(duckdb_v2_error_info_handle info, duckdb_v2_str *out_text); DUCKDB_V2_ERROR (*duckdb_v2_error_info_set_code)(duckdb_v2_error_info_handle info, DUCKDB_V2_ERROR code); DUCKDB_V2_ERROR (*duckdb_v2_error_info_set_text)(duckdb_v2_error_info_handle info, duckdb_v2_str text); + DUCKDB_V2_ERROR(*duckdb_v2_instance_attach) + (duckdb_v2_instance_handle instance, duckdb_v2_str path, duckdb_v2_identifier_t *name, + duckdb_v2_attach_options_handle options, bool make_default, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_create) + (duckdb_v2_environment_handle env, duckdb_v2_instance_handle *out_instance, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_instance_destroy)(duckdb_v2_instance_handle *instance); + DUCKDB_V2_ERROR(*duckdb_v2_instance_detach) + (duckdb_v2_instance_handle instance, duckdb_v2_str path, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_get_option_by_index) + (duckdb_v2_instance_handle instance, idx_t index, duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_get_option_by_name) + (duckdb_v2_instance_handle instance, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_get_option_count) + (duckdb_v2_instance_handle instance, idx_t *out_count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_set_option) + (duckdb_v2_instance_handle instance, duckdb_v2_identifier_t name, duckdb_v2_str setting, + duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_library_version)(duckdb_v2_str *out_version, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_logical_type_copy) (duckdb_v2_logical_type_handle type, duckdb_v2_logical_type_handle *out_type, duckdb_v2_error_info_handle *err); @@ -162,12 +171,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_logical_type_to_text) (duckdb_v2_logical_type_handle type, char *out_text, idx_t out_capacity, idx_t *out_length, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_open) - (duckdb_v2_environment_handle env, duckdb_v2_str path, duckdb_v2_option_handle *options, idx_t option_count, - duckdb_v2_database_handle *out_db, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_option_create) - (duckdb_v2_identifier_t name, duckdb_v2_str setting, duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_option_destroy)(duckdb_v2_option_handle *option); DUCKDB_V2_ERROR(*duckdb_v2_option_get_alias) (duckdb_v2_option_handle option, idx_t index, duckdb_v2_identifier_t *out_alias, duckdb_v2_error_info_handle *err); @@ -186,13 +189,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_parse_sql) (duckdb_v2_connection_handle conn, const char *sql, duckdb_v2_statement_iterator_handle *out_iterator, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR (*duckdb_v2_query_progress_destroy)(duckdb_v2_query_progress_handle *progress); - DUCKDB_V2_ERROR(*duckdb_v2_query_progress_get_percentage) - (duckdb_v2_query_progress_handle progress, double *out_percentage, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_query_progress_get_rows_processed) - (duckdb_v2_query_progress_handle progress, uint64_t *out_rows_processed, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_query_progress_get_total_rows_to_process) - (duckdb_v2_query_progress_handle progress, uint64_t *out_total_rows_to_process, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_result_destroy)(duckdb_v2_result_handle *result); DUCKDB_V2_ERROR(*duckdb_v2_result_drain) (duckdb_v2_result_handle result, idx_t *out_rows_changed, duckdb_v2_error_info_handle *err); @@ -939,10 +935,10 @@ typedef struct { duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_connection) (duckdb_v2_connection_handle connection, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_database) - (duckdb_v2_database_handle database, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_extension) (duckdb_v2_extension_handle extension, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_instance) + (duckdb_v2_instance_handle instance, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_replacement_scan_destroy)(duckdb_v2_replacement_scan_handle *scan); DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_get_name) (duckdb_v2_replacement_scan_info_handle info, duckdb_v2_qname_handle *name, duckdb_v2_error_info_handle *err); @@ -1262,6 +1258,63 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_tokenize_sql) (duckdb_v2_connection_handle conn, duckdb_v2_str sql, duckdb_v2_token_iterator_handle *out_iterator, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_attach_options_create) + (duckdb_v2_instance_handle instance, duckdb_v2_attach_options_handle *out_options, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_attach_options_destroy)(duckdb_v2_attach_options_handle *options); + DUCKDB_V2_ERROR(*duckdb_v2_attach_options_set) + (duckdb_v2_attach_options_handle options, duckdb_v2_identifier_t key, duckdb_v2_str setting, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_context_get_option_by_index) + (duckdb_v2_context_handle ctx, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_context_get_option_by_name) + (duckdb_v2_context_handle ctx, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_context_get_option_count) + (duckdb_v2_context_handle ctx, idx_t *out_count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_set_default) + (duckdb_v2_instance_handle instance, duckdb_v2_str path, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_bind_data) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_global_state) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_local_state) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_partition_column_count) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_partition_column_index) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_user_data) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_requires_batch_index) + (duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_requires_partition_columns) + (duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_set_batch_index) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t batch_index, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_set_partition_value) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t index, duckdb_v2_value_handle value, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_bind_data) + (duckdb_v2_table_function_partitioning_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_partition_column_count) + (duckdb_v2_table_function_partitioning_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_partition_column_index) + (duckdb_v2_table_function_partitioning_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_user_data) + (duckdb_v2_table_function_partitioning_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_set_partition_info) + (duckdb_v2_table_function_partitioning_info_handle info, DUCKDB_V2_TABLE_PARTITION_INFO partition_info, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_partition_data_callback) + (duckdb_v2_table_function_handle function, duckdb_v2_table_function_partition_data_callback_fn callback, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_partitioning_callback) + (duckdb_v2_table_function_handle function, duckdb_v2_table_function_partitioning_callback_fn callback, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_validate_utf8)(duckdb_v2_str text, duckdb_v2_error_info_handle *err); } duckdb_ext_api_v2; //===--------------------------------------------------------------------===// @@ -1272,7 +1325,6 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { result.duckdb_v2_arena_allocate = duckdb_v2_arena_allocate; result.duckdb_v2_bignum_decode = duckdb_v2_bignum_decode; result.duckdb_v2_bignum_encode = duckdb_v2_bignum_encode; - result.duckdb_v2_close = duckdb_v2_close; result.duckdb_v2_column_data_collection_append = duckdb_v2_column_data_collection_append; result.duckdb_v2_column_data_collection_append_state_create = duckdb_v2_column_data_collection_append_state_create; result.duckdb_v2_column_data_collection_append_state_destroy = @@ -1293,22 +1345,22 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { duckdb_v2_column_data_collection_worker_scan_state_create; result.duckdb_v2_column_data_collection_worker_scan_state_destroy = duckdb_v2_column_data_collection_worker_scan_state_destroy; - result.duckdb_v2_connect = duckdb_v2_connect; + result.duckdb_v2_connection_create = duckdb_v2_connection_create; result.duckdb_v2_connection_create_type_from_id = duckdb_v2_connection_create_type_from_id; result.duckdb_v2_connection_create_type_from_name = duckdb_v2_connection_create_type_from_name; result.duckdb_v2_connection_create_type_from_text = duckdb_v2_connection_create_type_from_text; result.duckdb_v2_connection_create_type_with_alias = duckdb_v2_connection_create_type_with_alias; + result.duckdb_v2_connection_destroy = duckdb_v2_connection_destroy; + result.duckdb_v2_connection_get_option_by_index = duckdb_v2_connection_get_option_by_index; + result.duckdb_v2_connection_get_option_by_name = duckdb_v2_connection_get_option_by_name; + result.duckdb_v2_connection_get_option_count = duckdb_v2_connection_get_option_count; result.duckdb_v2_connection_interrupt = duckdb_v2_connection_interrupt; - result.duckdb_v2_connection_option_get = duckdb_v2_connection_option_get; - result.duckdb_v2_connection_option_get_by_index = duckdb_v2_connection_option_get_by_index; - result.duckdb_v2_connection_option_get_count = duckdb_v2_connection_option_get_count; - result.duckdb_v2_connection_option_set = duckdb_v2_connection_option_set; - result.duckdb_v2_connection_query_progress = duckdb_v2_connection_query_progress; + result.duckdb_v2_connection_progress_get = duckdb_v2_connection_progress_get; + result.duckdb_v2_connection_set_option = duckdb_v2_connection_set_option; result.duckdb_v2_context_create_type_from_id = duckdb_v2_context_create_type_from_id; result.duckdb_v2_context_create_type_from_name = duckdb_v2_context_create_type_from_name; result.duckdb_v2_context_create_type_from_text = duckdb_v2_context_create_type_from_text; result.duckdb_v2_context_create_type_with_alias = duckdb_v2_context_create_type_with_alias; - result.duckdb_v2_create_environment = duckdb_v2_create_environment; result.duckdb_v2_data_chunk_copy_with_connection = duckdb_v2_data_chunk_copy_with_connection; result.duckdb_v2_data_chunk_copy_with_context = duckdb_v2_data_chunk_copy_with_context; result.duckdb_v2_data_chunk_create = duckdb_v2_data_chunk_create; @@ -1318,19 +1370,23 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { result.duckdb_v2_data_chunk_get_size = duckdb_v2_data_chunk_get_size; result.duckdb_v2_data_chunk_get_vector = duckdb_v2_data_chunk_get_vector; result.duckdb_v2_data_chunk_get_vector_count = duckdb_v2_data_chunk_get_vector_count; - result.duckdb_v2_database_option_get = duckdb_v2_database_option_get; - result.duckdb_v2_database_option_get_by_index = duckdb_v2_database_option_get_by_index; - result.duckdb_v2_database_option_get_count = duckdb_v2_database_option_get_count; - result.duckdb_v2_database_option_set = duckdb_v2_database_option_set; - result.duckdb_v2_destroy_environment = duckdb_v2_destroy_environment; - result.duckdb_v2_disconnect = duckdb_v2_disconnect; - result.duckdb_v2_environment_database_count = duckdb_v2_environment_database_count; + result.duckdb_v2_environment_create = duckdb_v2_environment_create; + result.duckdb_v2_environment_destroy = duckdb_v2_environment_destroy; + result.duckdb_v2_environment_get_instance_count = duckdb_v2_environment_get_instance_count; result.duckdb_v2_error_info_destroy = duckdb_v2_error_info_destroy; result.duckdb_v2_error_info_get_code = duckdb_v2_error_info_get_code; - result.duckdb_v2_error_info_get_raw_message = duckdb_v2_error_info_get_raw_message; + result.duckdb_v2_error_info_get_raw_text = duckdb_v2_error_info_get_raw_text; result.duckdb_v2_error_info_get_text = duckdb_v2_error_info_get_text; result.duckdb_v2_error_info_set_code = duckdb_v2_error_info_set_code; result.duckdb_v2_error_info_set_text = duckdb_v2_error_info_set_text; + result.duckdb_v2_instance_attach = duckdb_v2_instance_attach; + result.duckdb_v2_instance_create = duckdb_v2_instance_create; + result.duckdb_v2_instance_destroy = duckdb_v2_instance_destroy; + result.duckdb_v2_instance_detach = duckdb_v2_instance_detach; + result.duckdb_v2_instance_get_option_by_index = duckdb_v2_instance_get_option_by_index; + result.duckdb_v2_instance_get_option_by_name = duckdb_v2_instance_get_option_by_name; + result.duckdb_v2_instance_get_option_count = duckdb_v2_instance_get_option_count; + result.duckdb_v2_instance_set_option = duckdb_v2_instance_set_option; result.duckdb_v2_library_version = duckdb_v2_library_version; result.duckdb_v2_logical_type_copy = duckdb_v2_logical_type_copy; result.duckdb_v2_logical_type_destroy = duckdb_v2_logical_type_destroy; @@ -1340,8 +1396,6 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { result.duckdb_v2_logical_type_get_param_count = duckdb_v2_logical_type_get_param_count; result.duckdb_v2_logical_type_is_equal = duckdb_v2_logical_type_is_equal; result.duckdb_v2_logical_type_to_text = duckdb_v2_logical_type_to_text; - result.duckdb_v2_open = duckdb_v2_open; - result.duckdb_v2_option_create = duckdb_v2_option_create; result.duckdb_v2_option_destroy = duckdb_v2_option_destroy; result.duckdb_v2_option_get_alias = duckdb_v2_option_get_alias; result.duckdb_v2_option_get_alias_count = duckdb_v2_option_get_alias_count; @@ -1351,10 +1405,6 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { result.duckdb_v2_option_get_setting = duckdb_v2_option_get_setting; result.duckdb_v2_option_get_target_scope = duckdb_v2_option_get_target_scope; result.duckdb_v2_parse_sql = duckdb_v2_parse_sql; - result.duckdb_v2_query_progress_destroy = duckdb_v2_query_progress_destroy; - result.duckdb_v2_query_progress_get_percentage = duckdb_v2_query_progress_get_percentage; - result.duckdb_v2_query_progress_get_rows_processed = duckdb_v2_query_progress_get_rows_processed; - result.duckdb_v2_query_progress_get_total_rows_to_process = duckdb_v2_query_progress_get_total_rows_to_process; result.duckdb_v2_result_destroy = duckdb_v2_result_destroy; result.duckdb_v2_result_drain = duckdb_v2_result_drain; result.duckdb_v2_result_fetch_chunk = duckdb_v2_result_fetch_chunk; @@ -1671,8 +1721,8 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { result.duckdb_v2_replacement_scan_add_argument = duckdb_v2_replacement_scan_add_argument; result.duckdb_v2_replacement_scan_add_named_argument = duckdb_v2_replacement_scan_add_named_argument; result.duckdb_v2_replacement_scan_create_with_connection = duckdb_v2_replacement_scan_create_with_connection; - result.duckdb_v2_replacement_scan_create_with_database = duckdb_v2_replacement_scan_create_with_database; result.duckdb_v2_replacement_scan_create_with_extension = duckdb_v2_replacement_scan_create_with_extension; + result.duckdb_v2_replacement_scan_create_with_instance = duckdb_v2_replacement_scan_create_with_instance; result.duckdb_v2_replacement_scan_destroy = duckdb_v2_replacement_scan_destroy; result.duckdb_v2_replacement_scan_get_name = duckdb_v2_replacement_scan_get_name; result.duckdb_v2_replacement_scan_get_user_data = duckdb_v2_replacement_scan_get_user_data; @@ -1822,6 +1872,44 @@ inline duckdb_ext_api_v2 CreateAPIv2(void) { result.duckdb_v2_token_iterator_ends_unterminated = duckdb_v2_token_iterator_ends_unterminated; result.duckdb_v2_token_iterator_next = duckdb_v2_token_iterator_next; result.duckdb_v2_tokenize_sql = duckdb_v2_tokenize_sql; + result.duckdb_v2_attach_options_create = duckdb_v2_attach_options_create; + result.duckdb_v2_attach_options_destroy = duckdb_v2_attach_options_destroy; + result.duckdb_v2_attach_options_set = duckdb_v2_attach_options_set; + result.duckdb_v2_context_get_option_by_index = duckdb_v2_context_get_option_by_index; + result.duckdb_v2_context_get_option_by_name = duckdb_v2_context_get_option_by_name; + result.duckdb_v2_context_get_option_count = duckdb_v2_context_get_option_count; + result.duckdb_v2_instance_set_default = duckdb_v2_instance_set_default; + result.duckdb_v2_table_function_partition_data_get_bind_data = + duckdb_v2_table_function_partition_data_get_bind_data; + result.duckdb_v2_table_function_partition_data_get_global_state = + duckdb_v2_table_function_partition_data_get_global_state; + result.duckdb_v2_table_function_partition_data_get_local_state = + duckdb_v2_table_function_partition_data_get_local_state; + result.duckdb_v2_table_function_partition_data_get_partition_column_count = + duckdb_v2_table_function_partition_data_get_partition_column_count; + result.duckdb_v2_table_function_partition_data_get_partition_column_index = + duckdb_v2_table_function_partition_data_get_partition_column_index; + result.duckdb_v2_table_function_partition_data_get_user_data = + duckdb_v2_table_function_partition_data_get_user_data; + result.duckdb_v2_table_function_partition_data_requires_batch_index = + duckdb_v2_table_function_partition_data_requires_batch_index; + result.duckdb_v2_table_function_partition_data_requires_partition_columns = + duckdb_v2_table_function_partition_data_requires_partition_columns; + result.duckdb_v2_table_function_partition_data_set_batch_index = + duckdb_v2_table_function_partition_data_set_batch_index; + result.duckdb_v2_table_function_partition_data_set_partition_value = + duckdb_v2_table_function_partition_data_set_partition_value; + result.duckdb_v2_table_function_partitioning_get_bind_data = duckdb_v2_table_function_partitioning_get_bind_data; + result.duckdb_v2_table_function_partitioning_get_partition_column_count = + duckdb_v2_table_function_partitioning_get_partition_column_count; + result.duckdb_v2_table_function_partitioning_get_partition_column_index = + duckdb_v2_table_function_partitioning_get_partition_column_index; + result.duckdb_v2_table_function_partitioning_get_user_data = duckdb_v2_table_function_partitioning_get_user_data; + result.duckdb_v2_table_function_partitioning_set_partition_info = + duckdb_v2_table_function_partitioning_set_partition_info; + result.duckdb_v2_table_function_set_partition_data_callback = duckdb_v2_table_function_set_partition_data_callback; + result.duckdb_v2_table_function_set_partitioning_callback = duckdb_v2_table_function_set_partitioning_callback; + result.duckdb_v2_validate_utf8 = duckdb_v2_validate_utf8; return result; } diff --git a/src/duckdb/src/include/duckdb/main/chunk_scan_state/query_result_stream.hpp b/src/duckdb/src/include/duckdb/main/chunk_scan_state/query_result_stream.hpp new file mode 100644 index 000000000..0b2a40780 --- /dev/null +++ b/src/duckdb/src/include/duckdb/main/chunk_scan_state/query_result_stream.hpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/chunk_scan_state/query_result_stream.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/main/chunk_scan_state.hpp" +#include "duckdb/common/error_data.hpp" + +namespace duckdb { + +class QueryResultStream; + +class QueryResultStreamChunkScanState : public ChunkScanState { +public: + explicit QueryResultStreamChunkScanState(QueryResultStream &stream); + ~QueryResultStreamChunkScanState() override; + +public: + bool LoadNextChunk(ErrorData &error) override; + bool HasError() const override; + ErrorData &GetError() override; + const vector &Types() const override; + const vector &Names() const override; + +private: + QueryResultStream &stream; + ErrorData error; + bool has_error = false; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/client_config.hpp b/src/duckdb/src/include/duckdb/main/client_config.hpp index c3e85861f..674b172b0 100644 --- a/src/duckdb/src/include/duckdb/main/client_config.hpp +++ b/src/duckdb/src/include/duckdb/main/client_config.hpp @@ -65,7 +65,7 @@ struct ClientConfig { vector> replacement_scans; //! The maximum amount of memory to keep buffered in a streaming query result. Default: 10mb. - idx_t max_streaming_buffer_size = 10 * 1024 * 1024; + idx_t max_streaming_buffer_size = idx_t(10) * 1024 * 1024; //! The maximum memory for query intermediates (sorts, hash tables) per connection (in bytes). Default: Global //! memory limit. @@ -89,7 +89,7 @@ struct ClientConfig { optional current_dialect; //! The (ordered) list of grammar extensions currently used by the parser - case_insensitive_set_t active_grammar_extensions; + vector active_grammar_extensions; //! The compiled grammar active for the connection shared_ptr cached_grammar; diff --git a/src/duckdb/src/include/duckdb/main/client_context.hpp b/src/duckdb/src/include/duckdb/main/client_context.hpp index 11f00180b..c4d68a847 100644 --- a/src/duckdb/src/include/duckdb/main/client_context.hpp +++ b/src/duckdb/src/include/duckdb/main/client_context.hpp @@ -13,7 +13,7 @@ #include "duckdb/common/atomic.hpp" #include "duckdb/common/deque.hpp" #include "duckdb/common/optional_idx.hpp" -#include "duckdb/common/enums/pending_execution_result.hpp" +#include "duckdb/common/enums/query_result_state.hpp" #include "duckdb/common/enums/prepared_statement_mode.hpp" #include "duckdb/common/error_data.hpp" #include "duckdb/common/pair.hpp" @@ -23,12 +23,12 @@ #include "duckdb/main/client_context_state.hpp" #include "duckdb/main/client_properties.hpp" #include "duckdb/main/external_dependencies.hpp" -#include "duckdb/main/pending_query_result.hpp" +#include "duckdb/main/query_result.hpp" #include "duckdb/main/table_description.hpp" #include "duckdb/planner/expression/bound_parameter_data.hpp" #include "duckdb/transaction/transaction_context.hpp" #include "duckdb/common/query_context.hpp" -#include "duckdb/common/query_parameters.hpp" +#include "duckdb/main/query_parameters.hpp" namespace duckdb { class Logger; @@ -43,7 +43,6 @@ class FileOpener; class LogicalOperator; class PreparedStatement; class PreparedStatementData; -class StreamQueryResult; class StatementIterator; class Relation; class BufferedFileWriter; @@ -62,13 +61,6 @@ class PhysicalTransaction; class RegisteredStateManager; struct TransactionInfo; -struct PendingQueryParameters { - //! Prepared statement parameters (if any) - optional_ptr> parameters; - //! Whether a stream/buffer-managed result should be allowed - QueryParameters query_parameters; -}; - //! A statement parameter: identifier ($1 -> "1"), binding index, and inferred type (UNKNOWN if not inferred). struct StatementParameter { Identifier identifier; @@ -91,11 +83,10 @@ enum class ClientInterruptState : uint8_t { NOT_INTERRUPTED, INTERRUPTED, INTERR //! The ClientContext holds information relevant to the current client session //! during execution class ClientContext : public enable_shared_from_this { - friend class PendingQueryResult; // LockContext - friend class BufferedData; // ExecuteTaskInternal - friend class SimpleBufferedData; // ExecuteTaskInternal - friend class BatchedBufferedData; // ExecuteTaskInternal - friend class StreamQueryResult; // LockContext + friend class QueryResult; // LockContext + friend class BufferedData; // ExecuteTaskInternal, PollInternal + friend class SimpleBufferedData; // ExecuteTaskInternal, PollInternal + friend class BatchedBufferedData; // ExecuteTaskInternal, PollInternal friend class ConnectionManager; friend class Connection; friend class PhysicalTransaction; @@ -136,11 +127,14 @@ class ClientContext : public enable_shared_from_this { //! directly to disambiguate "never connected" from "was connected, target was detached elsewhere"). DUCKDB_API shared_ptr TryGetConnectedCatalog() const; + bool HasActiveTransaction() const { + return transaction.HasActiveTransaction(); + } MetaTransaction &ActiveTransaction() { return transaction.ActiveTransaction(); } - //! Interrupt execution of a query + //! Interrupts the running query. Async-signal-safe: sets a flag and nothing else DUCKDB_API void Interrupt(); DUCKDB_API bool IsInterrupted() const; DUCKDB_API void ClearInterrupt(); @@ -156,34 +150,33 @@ class ClientContext : public enable_shared_from_this { //! Disable query profiling DUCKDB_API void DisableProfiling(); - //! Issue a query, returning a QueryResult. The QueryResult can be either a StreamQueryResult or a - //! MaterializedQueryResult. The StreamQueryResult will only be returned in the case of a successful SELECT - //! statement. + //! Blocking. Runs the query to completion and returns its handle. The result is retained DUCKDB_API unique_ptr Query(const string &query, QueryParameters query_parameters); DUCKDB_API unique_ptr Query(unique_ptr statement, QueryParameters query_parameters); - //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain - //! a single statement. - DUCKDB_API unique_ptr PendingQuery(const string &query, QueryParameters query_parameters); - //! Issues a query to the database and returns a Pending Query Result - DUCKDB_API unique_ptr PendingQuery(unique_ptr statement, - QueryParameters query_parameters); - - //! Create a pending query with a list of parameters - DUCKDB_API unique_ptr PendingQuery(unique_ptr statement, - identifier_map_t &values, - QueryParameters query_parameters); - DUCKDB_API unique_ptr - PendingQuery(const string &query, identifier_map_t &values, QueryParameters query_parameters); - DUCKDB_API unique_ptr PendingQuery(const string &query, PendingQueryParameters parameters); - - //! Run a statement that was generated internally rather than parsed from user SQL. Statement verification - //! is skipped, and the client context lock is held for the entire duration of the query. + //! Non-blocking. Submits the query and returns its handle. The engine runs it iff threads - external_threads > 0, + //! but produces no data until the caller either calls a materializing method on the handle or opens a + //! QueryResultStream on it. The query may only contain a single statement. + DUCKDB_API unique_ptr Submit(const string &query, const QueryParameters &query_parameters); + //! Non-blocking. As above, for a parsed statement + DUCKDB_API unique_ptr Submit(unique_ptr statement, + const QueryParameters &query_parameters); + + //! Non-blocking. As above, for bound parameter values + DUCKDB_API unique_ptr Submit(unique_ptr statement, + identifier_map_t &values, + QueryParameters query_parameters); + DUCKDB_API unique_ptr Submit(const string &query, identifier_map_t &values, + QueryParameters query_parameters); + + //! Blocking. Runs a statement that was generated internally rather than parsed from user SQL. Statement + //! verification is skipped, and the client context lock is held for the entire duration of the query. DUCKDB_API unique_ptr RunInternalStatement(unique_ptr statement, - const PendingQueryParameters ¶meters); - //! Same as RunInternalStatement, but returns a pending query result that the caller drives - DUCKDB_API unique_ptr PendingInternalStatement(unique_ptr statement, - const PendingQueryParameters ¶meters); + const QueryParameters ¶meters); + //! Non-blocking. Same as RunInternalStatement, but returns the handle of the submitted query, which the caller + //! drives + DUCKDB_API unique_ptr SubmitInternalStatement(unique_ptr statement, + const QueryParameters ¶meters); //! Destroy the client context DUCKDB_API void Destroy(); @@ -205,9 +198,10 @@ class ClientContext : public enable_shared_from_this { //! Internal function for try bind relation. It does not require a client-context lock. DUCKDB_API void InternalTryBindRelation(Relation &relation, vector &result_columns); - //! Execute a relation - DUCKDB_API unique_ptr PendingQuery(const shared_ptr &relation, - QueryParameters query_parameters); + //! Non-blocking. Submits a relation and returns its handle + DUCKDB_API unique_ptr Submit(const shared_ptr &relation, + const QueryParameters &query_parameters); + //! Blocking. Runs a relation to completion and returns its handle DUCKDB_API unique_ptr Execute(const shared_ptr &relation); //! Prepare a query @@ -256,7 +250,7 @@ class ClientContext : public enable_shared_from_this { //! Returns the parser options for this client context DUCKDB_API ParserOptions GetParserOptions(); - //! Whether or not the given result object (streaming query result or pending query result) is active + //! Whether or not the given result object is the connection's open result DUCKDB_API bool IsActiveResult(ClientContextLock &lock, BaseQueryResult &result); //! Returns the current executor @@ -291,40 +285,42 @@ class ClientContext : public enable_shared_from_this { //! Same as RunTransactionStatement, but does not obtain a lock or route CONNECT statements. void RunTransactionStatementInternal(const TransactionInfo &info); - //! Issues a query to the database and returns a Pending Query Result - unique_ptr PendingQueryInternal(ClientContextLock &lock, unique_ptr statement, - const PendingQueryParameters ¶meters, bool verify = true); - unique_ptr ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query); + //! Submits a query to the database and returns its handle + unique_ptr SubmitInternal(ClientContextLock &lock, unique_ptr statement, + const QueryParameters ¶meters, bool verify = true); + //! Drives a submitted query to completion and retains its result + unique_ptr CompleteInternal(ClientContextLock &lock, unique_ptr result); + //! Drives a query whose collector builds its own result object, and hands that object out. Null + //! when the query failed: the error is on the handle + unique_ptr CompleteDelegatedInternal(ClientContextLock &lock, QueryResult &result); //! Parse statements from a query vector> ParseStatementsInternal(ClientContextLock &lock, const string &query); void StatementVerification(ClientContextLock &lock, unique_ptr &statement, - PendingQueryParameters query_parameters); + QueryParameters query_parameters); void InitialCleanup(ClientContextLock &lock); //! Internal clean up, does not lock. Caller must hold the context_lock. void CleanupInternal(ClientContextLock &lock, BaseQueryResult *result = nullptr, bool invalidate_transaction = false); - unique_ptr PendingStatement(ClientContextLock &lock, unique_ptr statement, - const PendingQueryParameters ¶meters); - unique_ptr PendingPreparedStatementInternal(ClientContextLock &lock, - shared_ptr statement_data_p, - const PendingQueryParameters ¶meters); + unique_ptr SubmitStatement(ClientContextLock &lock, unique_ptr statement, + const QueryParameters ¶meters); + unique_ptr SubmitPreparedStatementInternal(ClientContextLock &lock, + shared_ptr statement_data_p, + const QueryParameters ¶meters); void CheckIfPreparedStatementIsExecutable(PreparedStatementData &statement); //! Internally prepare a SQL statement. Caller must hold the context_lock. shared_ptr CreatePreparedStatement(ClientContextLock &lock, unique_ptr statement, - PendingQueryParameters parameters); - unique_ptr PendingStatementInternal(ClientContextLock &lock, unique_ptr statement, - const PendingQueryParameters ¶meters); + const QueryParameters ¶meters); + unique_ptr SubmitStatementInternal(ClientContextLock &lock, unique_ptr statement, + const QueryParameters ¶meters); unique_ptr RunStatementInternal(ClientContextLock &lock, unique_ptr statement, - const PendingQueryParameters ¶meters, bool verify = true); + const QueryParameters ¶meters, bool verify = true); unique_ptr PrepareInternal(ClientContextLock &lock, unique_ptr statement); void LogQueryInternal(ClientContextLock &lock, const string &query); - unique_ptr FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending); - unique_ptr LockContext(); void BeginQueryInternal(ClientContextLock &lock, const SQLStatement &statement); @@ -333,17 +329,23 @@ class ClientContext : public enable_shared_from_this { //! Wait until a task is available to execute void WaitForTask(ClientContextLock &lock, BaseQueryResult &result); - PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock, BaseQueryResult &result, bool dry_run = false); + //! Run one partial task slice of the open result on the calling thread + QueryResultState ExecuteTaskInternal(ClientContextLock &lock, BaseQueryResult &result); + //! Report the execution state of the open result without running any task + QueryResultState PollInternal(ClientContextLock &lock, BaseQueryResult &result); + //! Record the error on the result, end the query and report EXECUTION_ERROR + QueryResultState FailQueryInternal(ClientContextLock &lock, BaseQueryResult &result, ErrorData error); + void UpdateProgressInternal(QueryResultState state); - unique_ptr PendingQueryInternal(ClientContextLock &, const shared_ptr &relation, - QueryParameters query_parameters); + unique_ptr SubmitInternal(ClientContextLock &, const shared_ptr &relation, + const QueryParameters &query_parameters); template unique_ptr ErrorResult(ErrorData error, const string &query = string()); shared_ptr CreatePreparedStatementInternal(ClientContextLock &lock, unique_ptr statement, - PendingQueryParameters parameters); + const QueryParameters ¶meters); bool ErrorInvalidatesTransaction(ExceptionType type); diff --git a/src/duckdb/src/include/duckdb/main/client_context_state.hpp b/src/duckdb/src/include/duckdb/main/client_context_state.hpp index be459bf95..92dff1106 100644 --- a/src/duckdb/src/include/duckdb/main/client_context_state.hpp +++ b/src/duckdb/src/include/duckdb/main/client_context_state.hpp @@ -21,7 +21,6 @@ class ErrorData; class MetaTransaction; class PreparedStatementData; class SQLStatement; -struct PendingQueryParameters; class RegisteredStateManager; enum class RebindQueryInfo { DO_NOT_REBIND, ATTEMPT_TO_REBIND }; diff --git a/src/duckdb/src/include/duckdb/main/client_data.hpp b/src/duckdb/src/include/duckdb/main/client_data.hpp index 44b4b71d0..405594c57 100644 --- a/src/duckdb/src/include/duckdb/main/client_data.hpp +++ b/src/duckdb/src/include/duckdb/main/client_data.hpp @@ -44,6 +44,9 @@ struct ClientData { //! The catalog search path. unique_ptr catalog_search_path; + //! The instance's default database as it was when this client connected; later DatabaseManager::SetDefaultDatabase + //! calls only affect new clients. Empty when there was none. + Identifier default_database; //! The file opener of the client context. unique_ptr file_opener; diff --git a/src/duckdb/src/include/duckdb/main/config.hpp b/src/duckdb/src/include/duckdb/main/config.hpp index 77e7afba1..a6d9758e7 100644 --- a/src/duckdb/src/include/duckdb/main/config.hpp +++ b/src/duckdb/src/include/duckdb/main/config.hpp @@ -100,6 +100,8 @@ struct DBConfigOptions { idx_t maximum_threads = DConstants::INVALID_INDEX; //! The maximum amount of async threads used by the database system. Default: all available. idx_t async_threads = DConstants::INVALID_INDEX; + //! HTTP client limit derived from thread counts unless configured + idx_t http_client_pool_capacity = DConstants::INVALID_INDEX; //! Whether or not to create and use a temporary directory to store intermediates that do not fit in memory bool use_temporary_directory = true; //! Directory to store temporary structures that do not fit in memory @@ -315,6 +317,11 @@ struct DBConfig { void AddAllowedConfig(const Identifier &config_name); void AddAllowedDirectory(const string &path); void AddAllowedPath(const string &path); + //! Allows a database file and its WAL files, so a database can be opened while external access is disabled. + //! Only possible through API calls, not SQL calls. + void AddAllowedDatabasePath(const string &database_path); + vector GetAllowedDirectories() const; + vector GetAllowedPaths() const; string SanitizeAllowedPath(const string &path) const; ExtensionCallbackManager &GetCallbackManager(); const ExtensionCallbackManager &GetCallbackManager() const; @@ -322,9 +329,12 @@ struct DBConfig { void SetHTTPUtil(const shared_ptr &new_http_util); HTTPUtil &GetHTTPUtil() const; DUCKDB_API HTTPTransportManager &GetHTTPTransportManager(); + DUCKDB_API const HTTPTransportManager &GetHTTPTransportManager() const; private: mutable mutex config_lock; + //! Guards allowed_paths and allowed_directories, which a running instance can extend while files are being opened + mutable mutex allowed_paths_lock; unique_ptr compression_functions; unique_ptr encoding_functions; unique_ptr arrow_extensions; diff --git a/src/duckdb/src/include/duckdb/main/connection.hpp b/src/duckdb/src/include/duckdb/main/connection.hpp index 644f5cfa8..6521623e7 100644 --- a/src/duckdb/src/include/duckdb/main/connection.hpp +++ b/src/duckdb/src/include/duckdb/main/connection.hpp @@ -9,14 +9,13 @@ #pragma once #include "duckdb/main/profiler/profiler_print_format.hpp" +#include "duckdb/common/enums/query_result_memory_type.hpp" #include "duckdb/common/serializer/buffered_file_writer.hpp" #include "duckdb/common/winapi.hpp" -#include "duckdb/main/materialized_query_result.hpp" -#include "duckdb/main/pending_query_result.hpp" #include "duckdb/main/prepared_statement.hpp" #include "duckdb/main/query_result.hpp" +#include "duckdb/main/query_result_stream.hpp" #include "duckdb/main/relation.hpp" -#include "duckdb/main/stream_query_result.hpp" #include "duckdb/main/table_description.hpp" #include "duckdb/parser/sql_statement.hpp" @@ -30,6 +29,7 @@ class DuckDB; class LogicalOperator; class SelectStatement; struct CSVReaderOptions; +struct TableFunctionInfo; typedef void (*warning_callback_t)(std::string); @@ -54,7 +54,7 @@ class Connection { //! (e.g. ProfilerPrintFormat::JSON()). ProfilerPrintFormat::Default() uses the configured default profiler format. DUCKDB_API string GetProfilingInformation(const ProfilerPrintFormat &format = ProfilerPrintFormat::Default()); - //! Interrupt execution of the current query + //! Interrupts the current query. Async-signal-safe DUCKDB_API void Interrupt(); //! Get query progress of current query @@ -74,22 +74,11 @@ class Connection { //! Force parallel execution, even for smaller tables. Should only be used in testing. DUCKDB_API void ForceParallelism(); - //! Issues a query to the database and returns a QueryResult. This result can be either a StreamQueryResult or a - //! MaterializedQueryResult. The result can be stepped through with calls to Fetch(). Note that there can only be - //! one active StreamQueryResult per Connection object. Calling SendQuery() will invalidate any previously existing - //! StreamQueryResult. - DUCKDB_API unique_ptr - SendQuery(const string &query, QueryParameters query_parameters = QueryResultOutputType::ALLOW_STREAMING); - DUCKDB_API unique_ptr - SendQuery(unique_ptr statement, - QueryParameters query_parameters = QueryResultOutputType::ALLOW_STREAMING); - //! Issues a query to the database and materializes the result (if necessary). Always returns a - //! MaterializedQueryResult. - DUCKDB_API unique_ptr Query(const string &query); - //! Issues a query to the database and materializes the result (if necessary). Always returns a - //! MaterializedQueryResult. - DUCKDB_API unique_ptr - Query(unique_ptr statement, QueryResultMemoryType memory_type = QueryResultMemoryType::IN_MEMORY); + //! Blocking. Runs the query to completion and returns its handle. The result is retained: it can be read + //! repeatedly and at random. + DUCKDB_API unique_ptr Query(const string &query); + DUCKDB_API unique_ptr Query(unique_ptr statement, + QueryResultMemoryType memory_type = QueryResultMemoryType::IN_MEMORY); // prepared statements template unique_ptr Query(const string &query, ARGS... args) { @@ -97,27 +86,22 @@ class Connection { return QueryParamsRecursive(query, values, args...); } - //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain - //! a single statement. - DUCKDB_API unique_ptr - PendingQuery(const string &query, QueryParameters query_parameters = QueryResultOutputType::FORCE_MATERIALIZED); - //! Issues a query to the database and returns a Pending Query Result - DUCKDB_API unique_ptr - PendingQuery(unique_ptr statement, - QueryParameters query_parameters = QueryResultOutputType::FORCE_MATERIALIZED); - DUCKDB_API unique_ptr - PendingQuery(unique_ptr statement, identifier_map_t &named_values, - QueryParameters query_parameters = QueryResultOutputType::FORCE_MATERIALIZED); - DUCKDB_API unique_ptr - PendingQuery(const string &query, identifier_map_t &named_values, - QueryParameters query_parameters = QueryResultOutputType::FORCE_MATERIALIZED); - DUCKDB_API unique_ptr - PendingQuery(const string &query, vector &values, - QueryParameters query_parameters = QueryResultOutputType::FORCE_MATERIALIZED); - DUCKDB_API unique_ptr PendingQuery(const string &query, PendingQueryParameters parameters); - DUCKDB_API unique_ptr - PendingQuery(unique_ptr statement, vector &values, - QueryParameters query_parameters = QueryResultOutputType::FORCE_MATERIALIZED); + //! Non-blocking. Submits the query and returns its handle. The engine runs it iff threads - external_threads > 0, + //! but produces no data until the caller either calls a materializing method on the handle or opens a + //! QueryResultStream on it. The query may only contain a single statement. + DUCKDB_API unique_ptr Submit(const string &query, const QueryParameters &query_parameters = {}); + //! Non-blocking. As above, for a parsed statement and for bound parameter values + DUCKDB_API unique_ptr Submit(unique_ptr statement, + const QueryParameters &query_parameters = {}); + DUCKDB_API unique_ptr Submit(unique_ptr statement, + identifier_map_t &named_values, + const QueryParameters &query_parameters = {}); + DUCKDB_API unique_ptr Submit(const string &query, identifier_map_t &named_values, + const QueryParameters &query_parameters = {}); + DUCKDB_API unique_ptr Submit(const string &query, vector &values, + const QueryParameters &query_parameters = {}); + DUCKDB_API unique_ptr Submit(unique_ptr statement, vector &values, + const QueryParameters &query_parameters = {}); //! Prepare the specified query, returning a prepared statement object DUCKDB_API unique_ptr Prepare(const string &query); @@ -154,6 +138,10 @@ class Connection { DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, const named_parameter_map_t &named_parameters); DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values); + //! Calls a table function with process-local input for this invocation + DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, + const named_parameter_map_t &named_parameters, + shared_ptr bind_info); //! Returns a relation that produces values DUCKDB_API shared_ptr Values(const vector> &values); DUCKDB_API shared_ptr Values(vector>> &&values); diff --git a/src/duckdb/src/include/duckdb/main/database.hpp b/src/duckdb/src/include/duckdb/main/database.hpp index 2cec74dc3..dac712fc9 100644 --- a/src/duckdb/src/include/duckdb/main/database.hpp +++ b/src/duckdb/src/include/duckdb/main/database.hpp @@ -94,7 +94,15 @@ class DatabaseInstance : public enable_shared_from_this { AttachOptions &options); private: + //! Initializes the instance and attaches the main database at `path` (in-memory when null). void Initialize(const char *path, DBConfig *config); + //! Initializes the instance without attaching a database: the system catalog is the only catalog until one is + //! attached (ATTACH, or DatabaseManager::AttachDatabase). + void InitializeEmpty(DBConfig *config); + //! The part of initialization shared by both, up to the main database. + void InitializeInstance(const char *path, DBConfig *config); + //! Launches the scheduler threads; last, since storage init races on the catalog otherwise. + void StartScheduler(); void LoadExtensionSettings(); void CreateMainDatabase(); @@ -136,6 +144,11 @@ class DuckDB { DUCKDB_API ~DuckDB(); + //! Creates an instance with no database attached. Databases are attached to it later (ATTACH, or + //! DatabaseManager::AttachDatabase); until then only the system catalog and each connection's temporary catalog + //! exist, and statements that need a default database fail. + DUCKDB_API static shared_ptr CreateEmpty(DBConfig *config = nullptr); + //! Reference to the actual database instance shared_ptr instance; diff --git a/src/duckdb/src/include/duckdb/main/database_manager.hpp b/src/duckdb/src/include/duckdb/main/database_manager.hpp index a139f4b76..e3e8efd7e 100644 --- a/src/duckdb/src/include/duckdb/main/database_manager.hpp +++ b/src/duckdb/src/include/duckdb/main/database_manager.hpp @@ -24,6 +24,7 @@ class CatalogEntryRetriever; class CatalogSet; class ClientContext; class DatabaseInstance; +class ResourceDeleter; class TaskScheduler; struct AttachOptions; struct AlterInfo; @@ -54,8 +55,19 @@ class DatabaseManager { //! Attach a new database shared_ptr AttachDatabase(ClientContext &context, AttachInfo &info, AttachOptions &options); - //! Detach an existing database - void DetachDatabase(ClientContext &context, const Identifier &name, OnEntryNotFound if_not_found); + //! Detach an existing database. SQL DETACH refuses the connection's default database, which would leave it + //! without one; a host closing a database it opened passes `allow_default_database` to detach it regardless. + void DetachDatabase(ClientContext &context, const Identifier &name, OnEntryNotFound if_not_found, + bool allow_default_database = false); + //! Queue the teardown of an external resource from a context that cannot run SQL (e.g. transaction + //! rollback, under the transaction lock). + void AddPendingTeardown(unique_ptr deleter); + //! Run queued teardowns, best-effort. Called once no transaction locks are held. + void DrainPendingTeardowns(); + //! Detach every attachment borrowing the named resource, once it has been destroyed. Best-effort: + //! DETACH may refuse (the default database) and DESTROY goes through regardless. Scans rather than + //! keeping a refcount -- the attachment list cannot drift, and this follows a network round-trip. + void DetachResourceBorrowers(ClientContext &context, const string &resource_name); //! Alter operation dispatcher void Alter(ClientContext &context, AlterInfo &info); //! Rollback the attach of a database @@ -63,7 +75,17 @@ class DatabaseManager { //! Returns a reference to the system catalog Catalog &GetSystemCatalog(); + //! The default database of the connection: its USE'd catalog, else the default database it connected with, as long + //! as that is still attached. Throws when there is none; TryGetDefaultDatabase returns the empty identifier + //! instead, for lookups that can skip it. static Identifier GetDefaultDatabase(ClientContext &context); + static Identifier TryGetDefaultDatabase(ClientContext &context); + //! The default database new connections start with; empty when none is set. + Identifier GetDefaultDatabase(); + //! Sets the default database for new connections, which must be attached; the empty identifier clears it. Set to + //! the main database at startup and never set implicitly by an attach; detaching it falls back to the oldest + //! remaining database, if any. + void SetDefaultDatabase(const Identifier &name); //! Inserts a path to name mapping to the database paths map InsertDatabasePathResult InsertDatabasePath(const AttachInfo &info, AttachOptions &options); @@ -124,6 +146,8 @@ class DatabaseManager { mutex databases_lock; //! The set of attached databases identifier_map_t> databases; + //! The default database for new connections; empty when none is set (guarded by databases_lock) + Identifier default_database; //! The next object id handed out by the NextOid method atomic next_oid; //! The current query number @@ -132,6 +156,11 @@ class DatabaseManager { atomic current_transaction_id; //! Count of remote catalogs currently attached; used to skip the remote pushdown optimizer when zero atomic> remote_catalog_count; + //! Lock for pending_teardowns + mutex pending_teardowns_lock; + //! External-resource teardowns queued from contexts that cannot run SQL (see AddPendingTeardown); + //! drained best-effort once no transaction locks are held. + vector> pending_teardowns; //! Manager for ensuring we never open the same database file twice in the same program shared_ptr path_manager; diff --git a/src/duckdb/src/include/duckdb/main/db_instance_cache.hpp b/src/duckdb/src/include/duckdb/main/db_instance_cache.hpp index a8a14c416..2a5a86660 100644 --- a/src/duckdb/src/include/duckdb/main/db_instance_cache.hpp +++ b/src/duckdb/src/include/duckdb/main/db_instance_cache.hpp @@ -47,6 +47,11 @@ class DBInstanceCache { CacheBehavior cache_behavior = CacheBehavior::AUTOMATIC, const std::function &on_create = nullptr); + //! Creates an uncached instance with no database attached (see DuckDB::CreateEmpty). Databases attached to it + //! later go through this cache's path manager, so opening one file twice is detected across every instance + //! created through the cache. + shared_ptr CreateEmptyInstance(DBConfig &config); + private: shared_ptr path_manager; //! A map with the cached instances diff --git a/src/duckdb/src/include/duckdb/main/error_manager.hpp b/src/duckdb/src/include/duckdb/main/error_manager.hpp index 2f1542e0a..f4849df1f 100644 --- a/src/duckdb/src/include/duckdb/main/error_manager.hpp +++ b/src/duckdb/src/include/duckdb/main/error_manager.hpp @@ -43,7 +43,7 @@ class ErrorManager { DUCKDB_API string FormatExceptionRecursive(ErrorType error_type, vector &values); template - string FormatExceptionRecursive(ErrorType error_type, vector &values, T param, + string FormatExceptionRecursive(ErrorType error_type, vector &values, const T ¶m, ARGS &&...params) { values.push_back(ExceptionFormatValue::CreateFormatValue(param)); return FormatExceptionRecursive(error_type, values, std::forward(params)...); diff --git a/src/duckdb/src/include/duckdb/main/extension_entries.hpp b/src/duckdb/src/include/duckdb/main/extension_entries.hpp index 3fda1200f..513272b68 100644 --- a/src/duckdb/src/include/duckdb/main/extension_entries.hpp +++ b/src/duckdb/src/include/duckdb/main/extension_entries.hpp @@ -1317,6 +1317,7 @@ static constexpr ExtensionEntry EXTENSION_SETTINGS[] = { {"hf_max_per_page", "httpfs"}, {"hnsw_ef_search", "vss"}, {"hnsw_enable_experimental_persistence", "vss"}, + {"hnsw_prefilter", "vss"}, {"http_keep_alive", "httpfs"}, {"http_retries", "httpfs"}, {"http_retry_backoff", "httpfs"}, @@ -1537,8 +1538,8 @@ static constexpr ExtensionEntry EXTENSION_SECRET_PROVIDERS[] = { // Note: these are currently hardcoded in scripts/generate_extensions_function.py // TODO: automate by passing though to script via duckdb static constexpr ExtensionEntry EXTENSION_LOG_TYPES[] = { - {"DuckLakeMetadata", "ducklake"}, - {"Iceberg", "iceberg"}, + {"DeltaKernel", "delta"}, {"DuckLakeMetadata", "ducklake"}, {"HTTPFSInfo", "httpfs"}, + {"Iceberg", "iceberg"}, {"PostgresQueryLog", "postgres_scanner"}, {"Quack", "quack"}, }; // END_OF_EXTENSION_LOG_TYPES static constexpr const char *AUTOLOADABLE_EXTENSIONS[] = { diff --git a/src/duckdb/src/include/duckdb/main/http/http_client_pool.hpp b/src/duckdb/src/include/duckdb/main/http/http_client_pool.hpp index caded02f3..3c5dd7a04 100644 --- a/src/duckdb/src/include/duckdb/main/http/http_client_pool.hpp +++ b/src/duckdb/src/include/duckdb/main/http/http_client_pool.hpp @@ -76,7 +76,7 @@ class HTTPClientPool { }; enum class ReservationKind : uint8_t { REUSE, NEW_CLIENT }; - enum class IdleFilter : uint8_t { PROVIDER, CONNECTION, SESSION, ALL }; + enum class IdleFilter : uint8_t { PROVIDER, CONNECTION, SESSION, EXCESS, ALL }; struct Reservation { public: @@ -104,6 +104,9 @@ class HTTPClientPool { void Close() noexcept; bool IsClosed() const; bool HasAdmissionResource() const; + //! Reserve storage before increasing the admission limit + void SetCapacity(idx_t new_capacity); + idx_t GetCapacity() const; Reservation Reserve(const ClientKey &key, const string &origin, const HTTPTransportConfig &transport_config, bool cacheable); void AdoptPreparedBucket(Reservation &reservation); diff --git a/src/duckdb/src/include/duckdb/main/http/http_retry_budget.hpp b/src/duckdb/src/include/duckdb/main/http/http_retry_budget.hpp index 635f0ec00..42305444e 100644 --- a/src/duckdb/src/include/duckdb/main/http/http_retry_budget.hpp +++ b/src/duckdb/src/include/duckdb/main/http/http_retry_budget.hpp @@ -26,7 +26,8 @@ class HTTPRetryDecision { private: enum class Type : uint8_t { FINISH, RETRY, THROTTLED }; - HTTPRetryDecision(Type type_p, string retry_after_p = {}) : type(type_p), retry_after(std::move(retry_after_p)) { + explicit HTTPRetryDecision(Type type_p, string retry_after_p = {}) + : type(type_p), retry_after(std::move(retry_after_p)) { } static HTTPRetryDecision Throttled(const string &retry_after); @@ -48,6 +49,8 @@ class HTTPRetryBudget { //! Run once, then consume budget and wait before each requested retry. Exhaustion returns normally. //! Callbacks establish replay safety; exceptions propagate without further retries. DUCKDB_API void Run(const std::function &attempt); + //! Retries admitted for HTTP 429 or 503 responses. + DUCKDB_API uint64_t ThrottledRetries() const; private: //! Core's hook runs after admission/backoff, outside the attempt's transport-error handling. @@ -62,6 +65,7 @@ class HTTPRetryBudget { //! Retries admitted across all participating requests. uint64_t retries_used = 0; + uint64_t throttled_retries = 0; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/http/http_transport_manager.hpp b/src/duckdb/src/include/duckdb/main/http/http_transport_manager.hpp index c286fe343..0176bf846 100644 --- a/src/duckdb/src/include/duckdb/main/http/http_transport_manager.hpp +++ b/src/duckdb/src/include/duckdb/main/http/http_transport_manager.hpp @@ -57,6 +57,11 @@ class HTTPTransportManager { public: DUCKDB_API ~HTTPTransportManager(); + //! Retire excess idle clients and discard excess active clients on release + DUCKDB_API void SetCapacity(idx_t capacity) DUCKDB_EXCLUDES(lock); + DUCKDB_API idx_t GetCapacity() const DUCKDB_EXCLUDES(lock); + DUCKDB_API static idx_t AutomaticCapacity(const DBConfig &config); + private: explicit HTTPTransportManager(const shared_ptr &initial_http_util); @@ -120,9 +125,10 @@ class HTTPTransportManager { //! Database lifecycle helpers. static unique_ptr Create(const shared_ptr &initial_http_util); - void Initialize(idx_t system_concurrency) DUCKDB_EXCLUDES(lock); + void Initialize(const DBConfig &config) DUCKDB_EXCLUDES(lock); void Close() noexcept DUCKDB_EXCLUDES(lock); - static idx_t CalculateCapacity(idx_t system_concurrency, optional_idx file_descriptor_limit); + static idx_t CalculateCapacity(idx_t system_concurrency, optional_idx file_descriptor_limit, + idx_t io_concurrency = 0); static optional_idx GetFileDescriptorLimit(); static bool AdvanceConnectionEpoch(uint64_t &connection_epoch, bool &reuse_poisoned) noexcept; void SetHTTPUtil(const shared_ptr &new_http_util) DUCKDB_EXCLUDES(lock); diff --git a/src/duckdb/src/include/duckdb/main/materialized_query_result.hpp b/src/duckdb/src/include/duckdb/main/materialized_query_result.hpp deleted file mode 100644 index f656a07aa..000000000 --- a/src/duckdb/src/include/duckdb/main/materialized_query_result.hpp +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/materialized_query_result.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/types/column/column_data_collection.hpp" -#include "duckdb/common/winapi.hpp" -#include "duckdb/main/query_result.hpp" - -namespace duckdb { - -class ClientContext; - -class MaterializedQueryResult : public QueryResult { -public: - static constexpr const QueryResultType TYPE = QueryResultType::MATERIALIZED_RESULT; - -public: - friend class ClientContext; - //! Creates a successful query result with the specified names and types - DUCKDB_API MaterializedQueryResult(StatementType statement_type, StatementProperties properties, - vector names, unique_ptr collection, - ClientProperties client_properties); - //! Creates an unsuccessful query result with error condition - DUCKDB_API explicit MaterializedQueryResult(ErrorData error); - -public: - //! Converts the QueryResult to a string - DUCKDB_API string ToString() override; - DUCKDB_API string ToBox(BoxRendererContext &context, const BoxRendererConfig &config) override; - - //! Gets the (index) value of the (column index) column. - //! Note: this is very slow. Scanning over the underlying collection is much faster. - DUCKDB_API Value GetValue(idx_t column, idx_t index); - - template - T GetValue(idx_t column, idx_t index) { - auto value = GetValue(column, index); - return (T)value.GetValue(); - } - - DUCKDB_API idx_t RowCount() const; - - //! Returns a reference to the underlying column data collection - ColumnDataCollection &Collection(); - - //! Takes ownership of the collection, 'collection' is null after this operation - unique_ptr TakeCollection(); - -protected: - DUCKDB_API unique_ptr FetchInternal() override; - -private: - unique_ptr collection; - //! Row collection, only created if GetValue is called - unique_ptr row_collection; - //! Scan state for Fetch calls - ColumnDataScanState scan_state; - bool scan_initialized; -}; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/pending_query_result.hpp b/src/duckdb/src/include/duckdb/main/pending_query_result.hpp deleted file mode 100644 index cf0268712..000000000 --- a/src/duckdb/src/include/duckdb/main/pending_query_result.hpp +++ /dev/null @@ -1,70 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/pending_query_result.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/main/query_result.hpp" -#include "duckdb/common/enums/pending_execution_result.hpp" -#include "duckdb/execution/executor.hpp" - -namespace duckdb { -class ClientContext; -class ClientContextLock; -class PreparedStatementData; - -class PendingQueryResult : public BaseQueryResult { - friend class ClientContext; - -public: - static constexpr const QueryResultType TYPE = QueryResultType::PENDING_RESULT; - -public: - DUCKDB_API PendingQueryResult(shared_ptr context, PreparedStatementData &statement, - vector types, bool allow_stream_result); - DUCKDB_API explicit PendingQueryResult(ErrorData error_message); - DUCKDB_API ~PendingQueryResult() override; - DUCKDB_API bool AllowStreamResult() const; - PendingQueryResult(const PendingQueryResult &) = delete; - PendingQueryResult &operator=(const PendingQueryResult &) = delete; - -public: - //! Executes a single task within the query, returning whether or not the query is ready. - //! If this returns RESULT_READY, the Execute function can be called to obtain a pointer to the result. - //! If this returns RESULT_NOT_READY, the ExecuteTask function should be called again. - //! If this returns EXECUTION_ERROR, an error occurred during execution. - //! If this returns NO_TASKS_AVAILABLE, this means currently no meaningful work can be done by the current executor, - //! but tasks may become available in the future. - //! The error message can be obtained by calling GetError() on the PendingQueryResult. - DUCKDB_API PendingExecutionResult ExecuteTask(); - DUCKDB_API PendingExecutionResult CheckPulse(); - //! Halt execution of the thread until a Task is ready to be executed (use with caution) - void WaitForTask(); - - //! Returns the result of the query as an actual query result. - //! This returns (mostly) instantly if ExecuteTask has been called until RESULT_READY was returned. - DUCKDB_API unique_ptr Execute(); - - DUCKDB_API void Close(); - - //! Function to determine whether execution is considered finished - DUCKDB_API static bool IsResultReady(PendingExecutionResult result); - DUCKDB_API static bool IsExecutionFinished(PendingExecutionResult result); - -private: - shared_ptr context; - bool allow_stream_result; - -private: - void CheckExecutableInternal(ClientContextLock &lock); - - PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock); - unique_ptr ExecuteInternal(ClientContextLock &lock); - unique_ptr LockContext(); -}; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/prepared_statement.hpp b/src/duckdb/src/include/duckdb/main/prepared_statement.hpp index 827516661..64e67ab88 100644 --- a/src/duckdb/src/include/duckdb/main/prepared_statement.hpp +++ b/src/duckdb/src/include/duckdb/main/prepared_statement.hpp @@ -12,8 +12,8 @@ #include "duckdb/common/identifier.hpp" #include "duckdb/common/pair.hpp" #include "duckdb/common/winapi.hpp" -#include "duckdb/main/materialized_query_result.hpp" -#include "duckdb/main/pending_query_result.hpp" +#include "duckdb/main/query_parameters.hpp" +#include "duckdb/main/query_result.hpp" #include "duckdb/main/client_config.hpp" #include "duckdb/common/error_data.hpp" #include "duckdb/common/case_insensitive_map.hpp" @@ -89,28 +89,27 @@ class PreparedStatement { //! Returns the map of parameter index to the expected type of parameter DUCKDB_API case_insensitive_map_t GetExpectedParameterTypes() const; - //! Create a pending query result of the prepared statement with the given set of arguments + //! Non-blocking. Submits the prepared statement with the given arguments and returns its handle template - unique_ptr PendingQuery(ARGS... args) { + unique_ptr Submit(ARGS... args) { vector values; - return PendingQueryRecursive(values, args...); + return SubmitRecursive(values, args...); } - //! Create a pending query result of the prepared statement with the given set of arguments - DUCKDB_API unique_ptr PendingQuery(vector &values, bool allow_stream_result = true); + //! Non-blocking. Submits the prepared statement with the given values and returns its handle + DUCKDB_API unique_ptr Submit(vector &values, const QueryParameters &query_parameters = {}); - //! Create a pending query result of the prepared statement with the given set named arguments - DUCKDB_API unique_ptr PendingQuery(identifier_map_t &named_values, - bool allow_stream_result = true); + //! Non-blocking. Submits the prepared statement with the given named values and returns its handle + DUCKDB_API unique_ptr Submit(identifier_map_t &named_values, + const QueryParameters &query_parameters = {}); - //! Execute the prepared statement with the given set of values - DUCKDB_API unique_ptr Execute(vector &values, bool allow_stream_result = true); + //! Blocking. Runs the prepared statement with the given values to completion + DUCKDB_API unique_ptr Execute(vector &values); - //! Execute the prepared statement with the given set of named+unnamed values - DUCKDB_API unique_ptr Execute(identifier_map_t &named_values, - bool allow_stream_result = true); + //! Blocking. Runs the prepared statement with the given named and unnamed values to completion + DUCKDB_API unique_ptr Execute(identifier_map_t &named_values); - //! Execute the prepared statement with the given set of arguments + //! Blocking. Runs the prepared statement with the given arguments to completion template unique_ptr Execute(ARGS... args) { vector values; @@ -211,14 +210,14 @@ class PreparedStatement { //! Create the `EXECUTE (...)` statement that runs this prepared statement with the given values unique_ptr CreateExecuteStatement(const identifier_map_t &named_values) const; - unique_ptr PendingQueryRecursive(vector &values) { - return PendingQuery(values); + unique_ptr SubmitRecursive(vector &values) { + return Submit(values); } template - unique_ptr PendingQueryRecursive(vector &values, T value, ARGS... args) { + unique_ptr SubmitRecursive(vector &values, T value, ARGS... args) { values.push_back(Value::CreateValue(value)); - return PendingQueryRecursive(values, args...); + return SubmitRecursive(values, args...); } unique_ptr ExecuteRecursive(vector &values) { diff --git a/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp b/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp index 5030408ca..4a1e10baa 100644 --- a/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp +++ b/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/enums/query_result_memory_type.hpp" #include "duckdb/common/enums/statement_type.hpp" #include "duckdb/common/types/value.hpp" #include "duckdb/common/unordered_map.hpp" @@ -44,8 +45,6 @@ class PreparedStatementData { //! The map of parameter index to the actual value entry bound_parameter_map_t value_map; - //! Whether we are creating a streaming result or not - QueryResultOutputType output_type; //! Whether we are creating a buffer-managed result or not QueryResultMemoryType memory_type; diff --git a/src/duckdb/src/include/duckdb/main/query_parameters.hpp b/src/duckdb/src/include/duckdb/main/query_parameters.hpp new file mode 100644 index 000000000..055c905b5 --- /dev/null +++ b/src/duckdb/src/include/duckdb/main/query_parameters.hpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/query_parameters.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/enums/query_result_memory_type.hpp" +#include "duckdb/common/enums/result_eagerness.hpp" +#include "duckdb/common/identifier.hpp" +#include "duckdb/common/optional_ptr.hpp" +#include "duckdb/planner/expression/bound_parameter_data.hpp" + +namespace duckdb { + +struct QueryParameters { + //! Arguments for a parameterized statement (may be null) + optional_ptr> statement_args; + //! FORCED by Query and Execute. AUTO defers to the statement: a statement whose eagerness is + //! FORCED is still settled at submission + ResultEagerness result_eagerness = ResultEagerness::AUTO; + //! Where a retained result keeps its rows: the default allocator, or the buffer manager so a + //! large result can spill to disk + QueryResultMemoryType memory_type = QueryResultMemoryType::IN_MEMORY; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/query_result.hpp b/src/duckdb/src/include/duckdb/main/query_result.hpp index ea605daf9..28130dfca 100644 --- a/src/duckdb/src/include/duckdb/main/query_result.hpp +++ b/src/duckdb/src/include/duckdb/main/query_result.hpp @@ -8,8 +8,11 @@ #pragma once +#include "duckdb/common/enums/query_result_state.hpp" #include "duckdb/common/enums/statement_type.hpp" #include "duckdb/common/identifier.hpp" +#include "duckdb/common/types/column/column_data_collection.hpp" +#include "duckdb/common/types/column/column_data_scan_states.hpp" #include "duckdb/common/types/data_chunk.hpp" #include "duckdb/common/winapi.hpp" #include "duckdb/common/error_data.hpp" @@ -18,8 +21,13 @@ namespace duckdb { class BoxRendererContext; struct BoxRendererConfig; +class BufferedData; +class ClientContext; +class ClientContextLock; +class ColumnDataRowCollection; +class PreparedStatementData; -enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT, PENDING_RESULT, ARROW_RESULT }; +enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, ARROW_RESULT }; class BaseQueryResult { public: @@ -31,7 +39,7 @@ class BaseQueryResult { DUCKDB_API virtual ~BaseQueryResult(); public: - //! Returns the type of the result (MATERIALIZED or STREAMING) + //! Returns the type of the result (MATERIALIZED or ARROW) DUCKDB_API QueryResultType GetResultType() const; //! Returns the type of the statement that created this result DUCKDB_API StatementType GetStatementType() const; @@ -53,7 +61,7 @@ class BaseQueryResult { DUCKDB_API const ErrorData &GetErrorObject() const; private: - //! The type of the result (MATERIALIZED or STREAMING) + //! The type of the result (MATERIALIZED or ARROW). Will be removed. QueryResultType type; //! The type of the statement that created this result StatementType statement_type; @@ -69,15 +77,28 @@ class BaseQueryResult { ErrorData error; }; -//! The QueryResult object holds the result of a query. It can either be a MaterializedQueryResult, in which case the -//! result contains the entire result set, or a StreamQueryResult in which case the Fetch method can be called to -//! incrementally fetch data from the database. +//! A query result. Calling Materialize, Collection, TakeCollection, Fetch, RowCount, and GetValue will materialize the +//! result's data into a ColumnDataCollection. If instead the caller wants a streaming interface, it can be moved into +//! a QueryResultStream. class QueryResult : public BaseQueryResult { + friend class BufferedData; + friend class ClientContext; + friend class QueryResultStream; + public: - //! Creates a successful query result with the specified names and types + //! Creates the handle of a freshly submitted query + DUCKDB_API QueryResult(shared_ptr context, PreparedStatementData &statement, + vector types, ClientProperties client_properties, + shared_ptr buffer); + //! Creates a detached result over an existing collection + DUCKDB_API QueryResult(StatementType statement_type, StatementProperties properties, vector names, + unique_ptr collection, ClientProperties client_properties); + //! Creates an unsuccessful query result with error condition + DUCKDB_API explicit QueryResult(ErrorData error); + //! Creates a successful query result of a subclass with the specified names and types DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, vector types, vector names, ClientProperties client_properties); - //! Creates an unsuccessful query result with error condition + //! Creates an unsuccessful query result of a subclass DUCKDB_API QueryResult(QueryResultType type, ErrorData error); DUCKDB_API ~QueryResult() override; @@ -109,16 +130,48 @@ class QueryResult : public BaseQueryResult { static void DeduplicateColumns(vector &names); public: + //! Returns the query's current state. Does not participate in execution. + DUCKDB_API QueryResultState Poll(); + //! Executes a single task of the query on the calling thread. Decides nothing: READY means the engine is + //! waiting for the retention decision, and every further call returns READY, running nothing, until a + //! stream is opened or a retained-side call (Materialize, Complete, Collection, ...) is made. + DUCKDB_API QueryResultState ExecuteTask(); + //! Blocks until a task is runnable or the engine is waiting on the caller. Runs no task. + DUCKDB_API void WaitForTask(); + //! Non-blocking. Tells the engine to fully materialize the result into a CDC. Call Collection(), Fetch[Raw](), or + //! ExecuteTask() to execute tasks, or (if multithreaded) Poll until the result is complete. + DUCKDB_API void Materialize(); + //! Blocking. Tells the engine to fully materialize the result into a CDC. Participates in execution of the query. + DUCKDB_API void Complete(); + //! Blocking. Same as Complete(), but will return a reference to the CDC when done. + DUCKDB_API ColumnDataCollection &Collection(); + //! Blocking. Same as Collection() but takes ownership of the collection. The QueryResult is empty afterward. + DUCKDB_API unique_ptr TakeCollection(); + //! Gets the value of the field at [ column_idx, row_idx ]. Very slow, scanning the collection is much faster. + //! Will materialize the full result into a CDC if it hadn't yet. + DUCKDB_API Value GetValue(idx_t column_idx, idx_t row_idx); + template + T GetValue(idx_t column, idx_t index) { + auto value = GetValue(column, index); + return (T)value.GetValue(); + } + //! Get the rowcount of the result. Will materialize the full result into a CDC if it hadn't yet. + DUCKDB_API idx_t RowCount(); + //! Ends the query if it is still open. Idempotent. + DUCKDB_API void Close(); + //! Whether this result is still the connection's open result. + DUCKDB_API bool IsOpen(); + //! Returns the name of the column for the given index DUCKDB_API const Identifier &ColumnName(idx_t index) const; - //! Fetches a DataChunk of normalized (flat) vectors from the query result. - //! Returns nullptr if there are no more results to fetch. + //! A cursor over the collection: fetches the next chunk of normalized (flat) vectors, or null + //! at the end. Will materialize the full result into a CDC if it hadn't yet. DUCKDB_API unique_ptr Fetch(); //! Fetches a DataChunk from the query result. The vectors are not normalized and hence any vector types can be - //! returned. + //! returned. Will materialize the full result into a CDC if it hadn't yet. DUCKDB_API unique_ptr FetchRaw(); //! Converts the QueryResult to a string - DUCKDB_API virtual string ToString() = 0; + DUCKDB_API virtual string ToString(); //! Converts the QueryResult to a box-rendered string DUCKDB_API virtual string ToBox(BoxRendererContext &context, const BoxRendererConfig &config); //! Prints the QueryResult to the console @@ -127,7 +180,7 @@ class QueryResult : public BaseQueryResult { //! Fetch() until both results are exhausted. The data in the results will be lost. DUCKDB_API bool Equals(QueryResult &other, bool compare_names = true); - bool TryFetch(unique_ptr &result, ErrorData &error) { + bool TryFetchOrError(unique_ptr &result, ErrorData &error) { try { result = Fetch(); return !HasError(); @@ -140,8 +193,45 @@ class QueryResult : public BaseQueryResult { } } + //! False for a detached result and for an error result, which never had a buffer + bool HasBufferedData() const { + return buffer != nullptr; + } + //! Test helper: the buffer created for this query. + BufferedData &GetBufferedData() const { + D_ASSERT(buffer); + return *buffer; + } + protected: - DUCKDB_API virtual unique_ptr FetchInternal() = 0; + DUCKDB_API virtual unique_ptr FetchInternal(); + +private: + unique_ptr LockContext(); + void CheckExecutableInternal(ClientContextLock &lock); + bool IsOpenInternal(ClientContextLock &lock); + //! Records that this result is no longer the connection's active query, the way an interrupt is + //! recorded, and reports it as an error state + QueryResultState Cancelled(); + void CompleteInternal(ClientContextLock &lock); + void HandleFetchFailure(ClientContextLock &lock, ErrorData error); + //! Ends the query and records a commit failure on this result without throwing + void EndQuery(ClientContextLock &lock, bool invalidate_transaction = false); + [[noreturn]] void ThrowNoCollection() const; + +private: + //! The client context this result belongs to. Null once the query has ended + shared_ptr context; + //! The buffer created for this query at submission. It carries the retention decision and, for + //! a stream, the chunks (null for a detached or an error result) + shared_ptr buffer; + //! The retained storage (may be null) + unique_ptr collection; + //! Row collection, only created if GetValue is called + unique_ptr row_collection; + //! Scan state for Fetch calls + ColumnDataScanState scan_state; + bool scan_initialized = false; private: class QueryResultIterator; diff --git a/src/duckdb/src/include/duckdb/main/query_result_stream.hpp b/src/duckdb/src/include/duckdb/main/query_result_stream.hpp new file mode 100644 index 000000000..ec890176f --- /dev/null +++ b/src/duckdb/src/include/duckdb/main/query_result_stream.hpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/query_result_stream.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/enums/query_result_state.hpp" +#include "duckdb/main/query_result.hpp" + +#include + +namespace duckdb { + +//! A stream of chunks, opened from the handle of a submitted query. Opening the stream settles the +//! query's retention on draining and consumes the handle: chunks flow through a bounded buffer and +//! are released as the consumer takes them, so there is no retained side and no random access. +class QueryResultStream { +public: + //! Opens a stream on a submitted query. Throws InvalidInputException when the handle carries an + //! error, when its retention is already retained, or when the planner marked the statement as + //! completing before its result is returned. A throw consumes the handle: it is destroyed with + //! this object, which ends the query + DUCKDB_API explicit QueryResultStream(unique_ptr result); + DUCKDB_API ~QueryResultStream(); + QueryResultStream(const QueryResultStream &) = delete; + QueryResultStream &operator=(const QueryResultStream &) = delete; + +public: + //! Pops a chunk when one is observable, else reports where execution stands. Runs no task: + //! chunks are produced by worker threads or by participating calls such as Fetch. After the end + //! of the stream the terminal state keeps repeating + DUCKDB_API QueryResultState TryFetch(unique_ptr &out_chunk); + //! Runs tasks on the calling thread until a chunk is buffered or the stream ends. Returns null at + //! the end of the stream, and on an execution error, which is recorded on the stream. After a + //! clean end it keeps returning null; after an error it throws + DUCKDB_API unique_ptr Fetch(); + + //! Reports READY while a chunk is poppable, else where execution stands. Runs no task. An interrupt + //! or an execution error is recorded on the stream and reported as EXECUTION_ERROR + DUCKDB_API QueryResultState Poll(); + //! Executes a single task of the query on the calling thread. An interrupt or an execution error + //! is recorded on the stream and reported as EXECUTION_ERROR + DUCKDB_API QueryResultState ExecuteTask(); + //! Blocks until a task is runnable or the engine is waiting on the caller. Runs no task + DUCKDB_API void WaitForTask(); + //! Ends the stream. Idempotent; the destructor calls it + DUCKDB_API void Close(); + //! Whether this stream is still the connection's open result + DUCKDB_API bool IsOpen(); + + DUCKDB_API void SetError(ErrorData error); + DUCKDB_API bool HasError() const; + DUCKDB_API const string &GetError() const; + DUCKDB_API const ErrorData &GetErrorObject() const; + DUCKDB_API const ExceptionType &GetErrorType() const; + + DUCKDB_API const vector &GetTypes() const; + DUCKDB_API const vector &GetNames() const; + DUCKDB_API const Identifier &ColumnName(idx_t index) const; + DUCKDB_API idx_t ColumnCount() const; + DUCKDB_API StatementType GetStatementType() const; + DUCKDB_API const StatementProperties &GetStatementProperties() const; + DUCKDB_API const ClientProperties &GetClientProperties() const; + DUCKDB_API ClientProperties &GetClientProperties(); + + //! Test hook: the buffer this stream drains + BufferedData &GetBufferedData() { + return handle->GetBufferedData(); + } + +private: + unique_ptr FetchInternal(ClientContextLock &lock); + //! Runs a buffer call under the context lock and maps any failure onto the stream as + //! EXECUTION_ERROR. Once the stream has ended it keeps reporting the terminal state + QueryResultState GuardedInternal(const char *name, + const std::function &call); + +private: + //! The handle of the query this stream drains. Never handed out + unique_ptr handle; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/relation.hpp b/src/duckdb/src/include/duckdb/main/relation.hpp index ad280b0f4..d96510150 100644 --- a/src/duckdb/src/include/duckdb/main/relation.hpp +++ b/src/duckdb/src/include/duckdb/main/relation.hpp @@ -83,7 +83,9 @@ class Relation : public enable_shared_from_this { DUCKDB_API virtual BoundStatement Bind(Binder &binder); DUCKDB_API virtual Identifier GetAlias(); + //! Blocking. Runs the relation to completion and returns its handle; throws on error DUCKDB_API unique_ptr ExecuteOrThrow(); + //! Blocking. Runs the relation to completion and returns its handle DUCKDB_API unique_ptr Execute(); DUCKDB_API string ToString(); DUCKDB_API virtual string ToString(idx_t depth) = 0; @@ -94,6 +96,7 @@ class Relation : public enable_shared_from_this { DUCKDB_API shared_ptr CreateView(const Identifier &name, bool replace = true, bool temporary = false); DUCKDB_API shared_ptr CreateView(const Identifier &schema_name, const Identifier &name, bool replace = true, bool temporary = false); + //! Blocking. Runs a query to completion and returns its handle; the second form exposes the relation as a view DUCKDB_API unique_ptr Query(const string &sql) const; DUCKDB_API unique_ptr Query(const Identifier &name, const string &sql); diff --git a/src/duckdb/src/include/duckdb/main/relation/table_function_relation.hpp b/src/duckdb/src/include/duckdb/main/relation/table_function_relation.hpp index efd84979d..11a7949d5 100644 --- a/src/duckdb/src/include/duckdb/main/relation/table_function_relation.hpp +++ b/src/duckdb/src/include/duckdb/main/relation/table_function_relation.hpp @@ -11,17 +11,19 @@ #include "duckdb/main/relation.hpp" namespace duckdb { +struct TableFunctionInfo; class TableFunctionRelation : public Relation { public: TableFunctionRelation(const shared_ptr &context, string name, vector parameters, named_parameter_map_t named_parameters, shared_ptr input_relation_p = nullptr, - bool auto_init = true); + bool auto_init = true, shared_ptr bind_info = nullptr); TableFunctionRelation(const shared_ptr &context, string name, vector parameters, named_parameter_map_t named_parameters, shared_ptr input_relation_p = nullptr, - bool auto_init = true); + bool auto_init = true, shared_ptr bind_info = nullptr); TableFunctionRelation(const shared_ptr &context, string name, vector parameters, - shared_ptr input_relation_p = nullptr, bool auto_init = true); + shared_ptr input_relation_p = nullptr, bool auto_init = true, + shared_ptr bind_info = nullptr); ~TableFunctionRelation() override { } @@ -30,6 +32,7 @@ class TableFunctionRelation : public Relation { named_parameter_map_t named_parameters; vector columns; shared_ptr input_relation; + shared_ptr bind_info; public: unique_ptr GetQueryNode() override; diff --git a/src/duckdb/src/include/duckdb/main/result_unit.hpp b/src/duckdb/src/include/duckdb/main/result_unit.hpp new file mode 100644 index 000000000..75e380194 --- /dev/null +++ b/src/duckdb/src/include/duckdb/main/result_unit.hpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/result_unit.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/constants.hpp" +#include "duckdb/common/helper.hpp" +#include "duckdb/common/types/data_chunk.hpp" +#include "duckdb/common/unique_ptr.hpp" +#include "duckdb/common/winapi.hpp" + +namespace duckdb { + +//! A piece of query output: what the buffer holds and what the consumer pops. Its concrete type is +//! fixed by the format that produced it, which the consumer checks by name before casting +class ResultUnit { +public: + DUCKDB_API ResultUnit(idx_t row_count, idx_t byte_size); + DUCKDB_API virtual ~ResultUnit(); + +public: + template + TARGET &Cast() { + DynamicCastCheck(this); + return reinterpret_cast(*this); + } + + template + const TARGET &Cast() const { + DynamicCastCheck(this); + return reinterpret_cast(*this); + } + +public: + //! The rows in this unit + const idx_t row_count; + //! The bytes this unit counts against the buffer's cap + const idx_t byte_size; + +private: + ResultUnit(const ResultUnit &) = delete; + ResultUnit &operator=(const ResultUnit &) = delete; +}; + +//! A unit holding a single buffered chunk. +class ChunkUnit : public ResultUnit { +public: + DUCKDB_API explicit ChunkUnit(unique_ptr chunk); + +public: + unique_ptr chunk; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/secret/secret.hpp b/src/duckdb/src/include/duckdb/main/secret/secret.hpp index 3c1782661..6183a6e5c 100644 --- a/src/duckdb/src/include/duckdb/main/secret/secret.hpp +++ b/src/duckdb/src/include/duckdb/main/secret/secret.hpp @@ -213,7 +213,9 @@ class KeyValueSecret : public BaseSecret { // FIXME: use serialization scripts template - static unique_ptr Deserialize(Deserializer &deserializer, BaseSecret base_secret) { + static unique_ptr + Deserialize(Deserializer &deserializer, + BaseSecret base_secret) { // NOLINT(performance-unnecessary-value-param): callback signature. auto result = make_uniq(base_secret); Value secret_map_value; deserializer.ReadProperty(201, "secret_map", secret_map_value); diff --git a/src/duckdb/src/include/duckdb/main/settings.hpp b/src/duckdb/src/include/duckdb/main/settings.hpp index 02b1ffd57..12513510b 100644 --- a/src/duckdb/src/include/duckdb/main/settings.hpp +++ b/src/duckdb/src/include/duckdb/main/settings.hpp @@ -105,22 +105,10 @@ static constexpr idx_t SETTING_INDEX_BASE = __COUNTER__ + 1; // Start of the auto-generated list of settings structures //===----------------------------------------------------------------------===// -struct DeltaOnlyVariantEncodingEnabledSetting { - using RETURN_TYPE = bool; - static constexpr const char *Name = "__delta_only_variant_encoding_enabled"; - static constexpr const char *Description = "Enables the Parquet reader to identify a Variant structurally."; - static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static void ResetGlobal(DatabaseInstance *db, DBConfig &config); - static Value GetSetting(const ClientContext &context); -}; - struct AccessModeSetting { using RETURN_TYPE = AccessMode; static constexpr const char *Name = "access_mode"; - static constexpr const char *Description = "Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE)"; + static constexpr const char *Description = "Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -133,7 +121,7 @@ struct AccessModeSetting { struct ActiveGrammarExtensionsSetting { using RETURN_TYPE = vector; static constexpr const char *Name = "active_grammar_extensions"; - static constexpr const char *Description = "The grammar extensions used by the parser"; + static constexpr const char *Description = "The grammar extensions used by the parser."; static constexpr const char *InputType = "VARCHAR[]"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -147,7 +135,7 @@ struct ActiveGrammarExtensionsSetting { struct AllocatorBackgroundThreadsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "allocator_background_threads"; - static constexpr const char *Description = "Whether to enable the allocator background thread."; + static constexpr const char *Description = "Whether to enable the allocator background threads."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -187,7 +175,7 @@ struct AllocatorFlushThresholdSetting { struct AllowCommunityExtensionsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "allow_community_extensions"; - static constexpr const char *Description = "Allow to load community built extensions"; + static constexpr const char *Description = "Allow loading extensions build by the community."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -204,7 +192,7 @@ struct AllowExtensionRepositoriesSetting { "Whether custom trusted extension repositories are 'allowed', 'forbidden' (which also distrusts existing " "repositories) or 'undecided' (the default: blocks adding new repositories, but keeps trusting existing ones). " "While the database is running the setting can only move from 'undecided' to 'allowed' or 'forbidden', or from " - "'allowed' to 'forbidden'"; + "'allowed' to 'forbidden'."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -217,7 +205,7 @@ struct AllowExtensionRepositoriesSetting { struct AllowExtensionsMetadataMismatchSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "allow_extensions_metadata_mismatch"; - static constexpr const char *Description = "Allow to load extensions with not compatible metadata"; + static constexpr const char *Description = "Allow to load extensions with no compatible metadata."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -229,7 +217,7 @@ struct AllowExtensionsMetadataMismatchSetting { struct AllowParserOverrideExtensionSetting { using RETURN_TYPE = AllowParserOverride; static constexpr const char *Name = "allow_parser_override_extension"; - static constexpr const char *Description = "Allow extensions to override the current parser"; + static constexpr const char *Description = "Allow extensions to override the current parser."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -243,7 +231,7 @@ struct AllowPersistentSecretsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "allow_persistent_secrets"; static constexpr const char *Description = - "Allow the creation of persistent secrets, that are stored and loaded on restarts"; + "Allow the creation of persistent secrets that are stored and loaded on restarts."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -255,7 +243,7 @@ struct AllowPersistentSecretsSetting { struct AllowUnredactedSecretsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "allow_unredacted_secrets"; - static constexpr const char *Description = "Allow printing unredacted secrets"; + static constexpr const char *Description = "Allow printing unredacted secrets."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -268,7 +256,7 @@ struct AllowUnredactedSecretsSetting { struct AllowUnsignedExtensionsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "allow_unsigned_extensions"; - static constexpr const char *Description = "Allow to load extensions with invalid or missing signatures"; + static constexpr const char *Description = "Allow to load extensions with invalid or missing signatures."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -282,7 +270,7 @@ struct AllowedConfigsSetting { using RETURN_TYPE = vector; static constexpr const char *Name = "allowed_configs"; static constexpr const char *Description = - "List of configuration options that are ALWAYS allowed to be changed - even when lock_configuration is true"; + "List of configuration options that are ALWAYS allowed to be changed, even when lock_configuration is true."; static constexpr const char *InputType = "VARCHAR[]"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -294,8 +282,8 @@ struct AllowedConfigsSetting { struct AllowedDirectoriesSetting { using RETURN_TYPE = vector; static constexpr const char *Name = "allowed_directories"; - static constexpr const char *Description = "List of directories/prefixes that are ALWAYS allowed to be queried - " - "even when enable_external_access is false"; + static constexpr const char *Description = "List of directories, and directory prefixes, that are ALWAYS allowed " + "to be queried, even when enable_external_access is false."; static constexpr const char *InputType = "VARCHAR[]"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -308,7 +296,7 @@ struct AllowedPathsSetting { using RETURN_TYPE = vector; static constexpr const char *Name = "allowed_paths"; static constexpr const char *Description = - "List of files that are ALWAYS allowed to be queried - even when enable_external_access is false"; + "List of files that are ALWAYS allowed to be queried, even when enable_external_access is false."; static constexpr const char *InputType = "VARCHAR[]"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -334,7 +322,7 @@ struct ArrowLargeBufferSizeSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "arrow_large_buffer_size"; static constexpr const char *Description = - "Whether Arrow buffers for strings, blobs, uuids and bits should be exported using large buffers"; + "Whether Arrow buffers for strings, blobs, UUIDs and bits should be exported using large buffers."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -361,7 +349,7 @@ struct ArrowOutputListViewSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "arrow_output_list_view"; static constexpr const char *Description = - "Whether export to Arrow format should use ListView as the physical layout for LIST columns"; + "Whether the export to the Arrow format should use ListView as the physical layout for LIST columns."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -374,7 +362,7 @@ struct ArrowOutputVersionSetting { using RETURN_TYPE = ArrowFormatVersion; static constexpr const char *Name = "arrow_output_version"; static constexpr const char *Description = - "Whether strings should be produced by DuckDB in Utf8View format instead of Utf8"; + "Whether strings should be produced by DuckDB in Utf8View format instead of Utf8."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -388,7 +376,7 @@ struct AsofLoopJoinThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "asof_loop_join_threshold"; static constexpr const char *Description = - "The maximum number of rows we need on the left side of an ASOF join to use a nested loop join"; + "The maximum number of rows we need on the left side of an ASOF join to use a nested loop join."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -428,7 +416,8 @@ struct AutoinstallExtensionRepositorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "autoinstall_extension_repository"; static constexpr const char *Description = - "Overrides the custom endpoint for extension installation on autoloading"; + "Overrides the custom endpoint for extension installation on autoloading. Falls back to " + "custom_extension_repository, if not specified."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -441,7 +430,7 @@ struct AutoinstallKnownExtensionsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "autoinstall_known_extensions"; static constexpr const char *Description = - "Whether known extensions are allowed to be automatically installed when a query depends on them"; + "Whether known extensions are allowed to be automatically installed when a query depends on them."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -458,7 +447,7 @@ struct AutoloadKnownExtensionsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "autoload_known_extensions"; static constexpr const char *Description = - "Whether known extensions are allowed to be automatically loaded when a query depends on them"; + "Whether known extensions are allowed to be automatically loaded when a query depends on them."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -474,8 +463,8 @@ struct AutoloadKnownExtensionsSetting { struct BlockAllocatorMemorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "block_allocator_memory"; - static constexpr const char *Description = "Physical memory that the block allocator is allowed to use (this " - "memory is never freed and cannot be reduced)."; + static constexpr const char *Description = "Physical memory that the block allocator is allowed to use. This " + "memory is allocated once, never freed, and cannot be reduced."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -488,7 +477,7 @@ struct CacheLocalFilesSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "cache_local_files"; static constexpr const char *Description = - "Whether the external file cache also caches local files (remote files are always cached)"; + "Whether the external file cache also caches local files. Remote files are always cached."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -500,8 +489,8 @@ struct CacheLocalFilesSetting { struct CatalogErrorMaxSchemasSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "catalog_error_max_schemas"; - static constexpr const char *Description = - "The maximum number of schemas the system will scan for \"did you mean...\" style errors in the catalog"; + static constexpr const char *Description = "The maximum number of schemas in the catalog that the system will scan " + "to generate the \"did you mean...\" error message."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -530,7 +519,7 @@ struct CheckpointThresholdSetting { using RETURN_TYPE = string; static constexpr const char *Name = "checkpoint_threshold"; static constexpr const char *Description = - "The WAL size threshold at which to automatically trigger a checkpoint (e.g. 1GB)"; + "The WAL size threshold at which to automatically trigger a checkpoint, e.g. 1GB."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -542,7 +531,7 @@ struct CheckpointThresholdSetting { struct CurrentDialectSetting { using RETURN_TYPE = string; static constexpr const char *Name = "current_dialect"; - static constexpr const char *Description = "The SQL dialect used by the parser"; + static constexpr const char *Description = "The SQL dialect used by the parser."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -557,7 +546,7 @@ struct CurrentTransactionInvalidationPolicySetting { using RETURN_TYPE = string; static constexpr const char *Name = "current_transaction_invalidation_policy"; static constexpr const char *Description = - "Which types of exceptions invalidate the database for the current transaction"; + "Which types of exceptions invalidate the database for the current transaction."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -570,7 +559,7 @@ struct CurrentTransactionInvalidationPolicySetting { struct CustomExtensionRepositorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "custom_extension_repository"; - static constexpr const char *Description = "Overrides the custom endpoint for remote extension installation"; + static constexpr const char *Description = "Overrides the custom endpoint for extension installation."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -582,7 +571,8 @@ struct CustomExtensionRepositorySetting { struct CustomUserAgentSetting { using RETURN_TYPE = string; static constexpr const char *Name = "custom_user_agent"; - static constexpr const char *Description = "Metadata from DuckDB callers"; + static constexpr const char *Description = "HTTP request metadata that can be set by callers/wrappers to tag their " + "own traffic when DuckDB makes a request."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -594,9 +584,9 @@ struct CustomUserAgentSetting { struct DebugAsofIejoinSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_asof_iejoin"; - static constexpr const char *Description = "DEBUG SETTING: force use of IEJoin to implement AsOf joins"; + static constexpr const char *Description = "Force the use of an IEJoin to implement ASOF joins."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; @@ -606,10 +596,9 @@ struct DebugAsofIejoinSetting { struct DebugCheckpointAbortSetting { using RETURN_TYPE = CheckpointAbort; static constexpr const char *Name = "debug_checkpoint_abort"; - static constexpr const char *Description = - "DEBUG SETTING: trigger an abort while checkpointing for testing purposes"; + static constexpr const char *Description = "Trigger an abort while checkpointing."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "NONE"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -617,24 +606,49 @@ struct DebugCheckpointAbortSetting { static void OnSet(SettingCallbackInfo &info, Value &input); }; +struct DebugCheckpointScanSleepMsSetting { + using RETURN_TYPE = idx_t; + static constexpr const char *Name = "debug_checkpoint_scan_sleep_ms"; + static constexpr const char *Description = + "DEBUG SETTING: time to sleep after a checkpoint has written a table's row groups, before it installs them"; + static constexpr const char *InputType = "UBIGINT"; + static constexpr bool IsDebug = false; + static constexpr bool IsDeprecated = false; + static constexpr const char *DefaultValue = "0"; + static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; + static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); +}; + struct DebugCheckpointSleepMsSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "debug_checkpoint_sleep_ms"; - static constexpr const char *Description = "DEBUG SETTING: time to sleep before a checkpoint"; + static constexpr const char *Description = "Time to sleep before a checkpoint is invoked."; static constexpr const char *InputType = "UBIGINT"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); }; +struct DebugDeltaOnlyVariantEncodingEnabledSetting { + using RETURN_TYPE = bool; + static constexpr const char *Name = "debug_delta_only_variant_encoding_enabled"; + static constexpr const char *Description = "Enables the Parquet reader to identify a Variant structurally."; + static constexpr const char *InputType = "BOOLEAN"; + static constexpr bool IsDebug = true; + static constexpr bool IsDeprecated = false; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(const ClientContext &context); +}; + struct DebugDisableOptimizerSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_disable_optimizer"; - static constexpr const char *Description = "DEBUG SETTING: disable optimizer for most queries"; + static constexpr const char *Description = "Disable running the optimizer."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; @@ -644,7 +658,7 @@ struct DebugDisableOptimizerSetting { struct EnableCachingOperatorsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_enable_caching_operators"; - static constexpr const char *Description = "Enables caching operators that cache intermediate results"; + static constexpr const char *Description = "Enables caching operators that cache intermediate results."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; @@ -657,9 +671,9 @@ struct DebugEvictionQueueSleepMicroSecondsSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "debug_eviction_queue_sleep_micro_seconds"; static constexpr const char *Description = - "DEBUG SETTING: time for the eviction queue to sleep before acquiring shared ownership of block memory"; + "Set a time for the eviction queue to sleep before acquiring the shared ownership of some block memory."; static constexpr const char *InputType = "UBIGINT"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; @@ -669,7 +683,7 @@ struct DebugEvictionQueueSleepMicroSecondsSetting { struct ForceBitpackingModeSetting { using RETURN_TYPE = BitpackingMode; static constexpr const char *Name = "debug_force_bitpacking_mode"; - static constexpr const char *Description = "DEBUG SETTING: forces a specific bitpacking mode"; + static constexpr const char *Description = "Forces a specific bitpacking mode."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; @@ -682,10 +696,10 @@ struct ForceBitpackingModeSetting { struct DebugForceCommitFailureSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_commit_failure"; - static constexpr const char *Description = "DEBUG SETTING: force transaction commit to fail after the undo buffer " - "has been committed, used for testing commit error recovery"; + static constexpr const char *Description = "Force transaction commit to fail after the undo buffer has been " + "committed. Can be used for testing commit error recovery."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -695,10 +709,9 @@ struct DebugForceCommitFailureSetting { struct DebugForceCommitRevertFailureSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_commit_revert_failure"; - static constexpr const char *Description = - "DEBUG SETTING: force RevertCommit to fail while recovering from a commit failure, used for testing"; + static constexpr const char *Description = "Force RevertCommit to fail while recovering from a commit failure."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -708,10 +721,9 @@ struct DebugForceCommitRevertFailureSetting { struct DebugForceExternalSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_external"; - static constexpr const char *Description = - "DEBUG SETTING: force out-of-core computation for operators that support it, used for testing"; + static constexpr const char *Description = "Force out-of-core computation for operators that support it."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; @@ -721,9 +733,9 @@ struct DebugForceExternalSetting { struct DebugForceFetchRowSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_fetch_row"; - static constexpr const char *Description = "DEBUG SETTING: force per-row fetching during scans, used for testing"; + static constexpr const char *Description = "Force per-row fetching during scans."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; @@ -733,7 +745,7 @@ struct DebugForceFetchRowSetting { struct ForceMbedtlsUnsafeSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_mbedtls_unsafe"; - static constexpr const char *Description = "Enable mbedtls for encryption (WARNING: unsafe to use)"; + static constexpr const char *Description = "Enable mbedtls for encryption. Unsafe to use."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; @@ -746,9 +758,9 @@ struct DebugForceNoCrossProductSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_no_cross_product"; static constexpr const char *Description = - "DEBUG SETTING: Force disable cross product generation when hyper graph isn't connected, used for testing"; + "Force disable cross product generation when the hyper graph isn't connected."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; @@ -759,7 +771,7 @@ struct ForceUpdateToDelAndInsertSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_force_update_to_del_and_insert"; static constexpr const char *Description = - "DEBUG SETTING: forces all updates to use the delete + insert code path instead of in-place updates"; + "Forces all updates to use the DELETE + INSERT code path instead of in-place updates."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; @@ -772,7 +784,7 @@ struct ForceVariantShredding { using RETURN_TYPE = string; static constexpr const char *Name = "debug_force_variant_shredding"; static constexpr const char *Description = - "Forces the VARIANT shredding that happens at checkpoint to use the provided schema for the shredding."; + "Forces the VARIANT shredding that happens during checkpointing to use the provided schema for the shredding."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; @@ -784,10 +796,9 @@ struct ForceVariantShredding { struct DebugLocalFileSystemDelayMsSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "debug_local_file_system_delay_ms"; - static constexpr const char *Description = - "DEBUG SETTING: time to sleep before local file system open/read/write operations"; + static constexpr const char *Description = "Time to sleep before local file system open/read/write operations."; static constexpr const char *InputType = "UBIGINT"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; @@ -798,9 +809,9 @@ struct DebugOrderVerificationSetting { using RETURN_TYPE = DebugOrderVerification; static constexpr const char *Name = "debug_order_verification"; static constexpr const char *Description = - "DEBUG SETTING: verify ORDER BY results by rewriting the ordering (NONE, CREATE_SORT_KEY or VARIANT)"; + "Verify ORDER BY results by rewriting the ordering (NONE, CREATE_SORT_KEY or VARIANT)."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); static void ResetGlobal(DatabaseInstance *db, DBConfig &config); @@ -810,10 +821,9 @@ struct DebugOrderVerificationSetting { struct DebugPhysicalTableScanExecutionStrategySetting { using RETURN_TYPE = PhysicalTableScanExecutionStrategy; static constexpr const char *Name = "debug_physical_table_scan_execution_strategy"; - static constexpr const char *Description = - "DEBUG SETTING: force use of given strategy for executing physical table scans"; + static constexpr const char *Description = "Force the use of a given strategy for executing physical table scans."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "DEFAULT"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -824,33 +834,21 @@ struct DebugPhysicalTableScanExecutionStrategySetting { struct DebugSkipCheckpointOnCommitSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_skip_checkpoint_on_commit"; - static constexpr const char *Description = "DEBUG SETTING: skip checkpointing on commit"; + static constexpr const char *Description = "Skip checkpointing on commit."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); }; -struct DebugTransformerTrampolineStyleSetting { - using RETURN_TYPE = bool; - static constexpr const char *Name = "debug_transformer_trampoline_style"; - static constexpr const char *Description = "Use the experimental trampoline-style parser transformer"; - static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; - static constexpr const char *DefaultValue = "false"; - static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); -}; - struct DebugVerificationModeSetting { using RETURN_TYPE = string; static constexpr const char *Name = "debug_verification_mode"; - static constexpr const char *Description = "DEBUG SETTING: toggle the verification mode."; + static constexpr const char *Description = "Toggle the verification mode."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); static void ResetGlobal(DatabaseInstance *db, DBConfig &config); @@ -860,10 +858,9 @@ struct DebugVerificationModeSetting { struct DebugVerificationProjectionSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_verification_projection"; - static constexpr const char *Description = - "DEBUG SETTING: add internal verification projections to stress optimizers"; + static constexpr const char *Description = "Add internal verification projections to stress-test optimizers."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -873,9 +870,9 @@ struct DebugVerificationProjectionSetting { struct DebugVerifyAggregateStateExportSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_verify_aggregate_state_export"; - static constexpr const char *Description = "DEBUG SETTING: enable verification of aggregate state export"; + static constexpr const char *Description = "Enable verification of aggregate state export."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -885,9 +882,9 @@ struct DebugVerifyAggregateStateExportSetting { struct DebugVerifyBlocksSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_verify_blocks"; - static constexpr const char *Description = "DEBUG SETTING: verify block metadata during checkpointing"; + static constexpr const char *Description = "Verify block metadata during checkpointing."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -897,21 +894,48 @@ struct DebugVerifyBlocksSetting { struct DebugVerifyColumnBindingsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_verify_column_bindings"; - static constexpr const char *Description = "DEBUG SETTING: run extra internal verification of column bindings"; + static constexpr const char *Description = "Run extra internal verification of column bindings."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); }; +struct DebugVerifyProgressSetting { + using RETURN_TYPE = DebugProgressVerification; + static constexpr const char *Name = "debug_verify_progress"; + static constexpr const char *Description = "Verify that operators report well-formed, monotonic and complete " + "progress during execution (NONE, LOG or ERROR)."; + static constexpr const char *InputType = "VARCHAR"; + static constexpr bool IsDebug = true; + static constexpr bool IsDeprecated = false; + static constexpr const char *DefaultValue = "NONE"; + static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; + static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); + static void OnSet(SettingCallbackInfo &info, Value &input); +}; + +struct DebugVerifyProgressIgnoreSetting { + using RETURN_TYPE = string; + static constexpr const char *Name = "debug_verify_progress_ignore"; + static constexpr const char *Description = "Comma-separated list of progress violations to ignore, as INVARIANT or " + "INVARIANT:OPERATOR (e.g. UNSUPPORTED_SOURCE:WINDOW)."; + static constexpr const char *InputType = "VARCHAR"; + static constexpr bool IsDebug = true; + static constexpr bool IsDeprecated = false; + static constexpr const char *DefaultValue = ""; + static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; + static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); +}; + struct DebugVerifySerializerSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_verify_serializer"; - static constexpr const char *Description = "DEBUG SETTING: verify logical plan serializer"; + static constexpr const char *Description = "Verify the logical plan serializer."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -921,9 +945,9 @@ struct DebugVerifySerializerSetting { struct DebugVerifyStatementSetting { using RETURN_TYPE = DebugStatementVerification; static constexpr const char *Name = "debug_verify_statement"; - static constexpr const char *Description = "DEBUG SETTING: the type of statement verification to perform"; + static constexpr const char *Description = "Specify the type of statement verification to perform."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "NONE"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -934,10 +958,9 @@ struct DebugVerifyStatementSetting { struct DebugVerifyStatsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "debug_verify_stats"; - static constexpr const char *Description = - "DEBUG SETTING: verify statistics are correct during execution, instead of assuming"; + static constexpr const char *Description = "Verify that statistics are correct during execution."; static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -947,9 +970,9 @@ struct DebugVerifyStatsSetting { struct DebugVerifyVectorSetting { using RETURN_TYPE = DebugVectorVerification; static constexpr const char *Name = "debug_verify_vector"; - static constexpr const char *Description = "DEBUG SETTING: enable vector verification"; + static constexpr const char *Description = "Enable a specific type of vector verification."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "NONE"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -960,9 +983,9 @@ struct DebugVerifyVectorSetting { struct DebugWindowModeSetting { using RETURN_TYPE = WindowAggregationMode; static constexpr const char *Name = "debug_window_mode"; - static constexpr const char *Description = "DEBUG SETTING: switch window mode to use"; + static constexpr const char *Description = "Switch the window mode being used."; static constexpr const char *InputType = "VARCHAR"; - static constexpr bool IsDebug = false; + static constexpr bool IsDebug = true; static constexpr bool IsDeprecated = false; static constexpr const char *DefaultValue = "WINDOW"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; @@ -973,8 +996,8 @@ struct DebugWindowModeSetting { struct DefaultBlockSizeSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "default_block_size"; - static constexpr const char *Description = - "The default block size for new duckdb database files (new as-in, they do not yet exist)."; + static constexpr const char *Description = "The default block size for new duckdb database files. New means that " + "the file is being created and does not yet exist."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -987,7 +1010,7 @@ struct DefaultBlockSizeSetting { struct DefaultCollationSetting { using RETURN_TYPE = string; static constexpr const char *Name = "default_collation"; - static constexpr const char *Description = "The collation setting used when none is specified"; + static constexpr const char *Description = "The collation setting used when none is specified."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1000,7 +1023,8 @@ struct DefaultCollationSetting { struct DefaultNullOrderSetting { using RETURN_TYPE = DefaultOrderByNullType; static constexpr const char *Name = "default_null_order"; - static constexpr const char *Description = "NULL ordering used when none is specified (NULLS_FIRST or NULLS_LAST)"; + static constexpr const char *Description = + "The NULL ordering used when none is specified (NULLS_FIRST or NULLS_LAST)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1013,7 +1037,7 @@ struct DefaultNullOrderSetting { struct DefaultOrderSetting { using RETURN_TYPE = OrderType; static constexpr const char *Name = "default_order"; - static constexpr const char *Description = "The order type used when none is specified (ASC or DESC)"; + static constexpr const char *Description = "The order type used when none is specified (ASC or DESC)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1026,7 +1050,7 @@ struct DefaultOrderSetting { struct DefaultSecretStorageSetting { using RETURN_TYPE = string; static constexpr const char *Name = "default_secret_storage"; - static constexpr const char *Description = "Allows switching the default storage for secrets"; + static constexpr const char *Description = "Allows switching the default storage for secrets."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1039,8 +1063,9 @@ struct DefaultTransactionInvalidationPolicySetting { using RETURN_TYPE = TransactionInvalidationPolicy; static constexpr const char *Name = "default_transaction_invalidation_policy"; static constexpr const char *Description = - "When to invalidate transactions when errors occur (SYNTACTIC_ERRORS_DO_NOT_INVALIDATE, i.e. parser and binder " - "exceptions do not invalidate, or ALL_ERRORS_INVALIDATE_TRANSACTION)"; + "When to invalidate transactions when errors occur. SYNTACTIC_ERRORS_DO_NOT_INVALIDATE means that parser and " + "binder exceptions do not invalidate. ALL_ERRORS_INVALIDATE_TRANSACTION means all errors invalidate a " + "transaction."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1054,7 +1079,7 @@ struct DelimJoinAsCteSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "delim_join_as_cte"; static constexpr const char *Description = - "Rewrite delim joins to materialized CTEs during dependent join flattening"; + "Rewrite delim joins to materialized CTEs during dependent join flattening."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1068,7 +1093,7 @@ struct DialectCompatibilityModeSetting { using RETURN_TYPE = DialectCompatibilityMode; static constexpr const char *Name = "dialect_compatibility_mode"; static constexpr const char *Description = - "Enable SQL dialect compatibility for a certain engine (e.g. `SET dialect_compatibility_mode='spark'`)"; + "Enable SQL dialect compatibility for a certain engine, e.g. `SET dialect_compatibility_mode='spark'`."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1096,7 +1121,7 @@ struct DisableDatabaseInvalidationSetting { struct DisableTimestamptzCastsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "disable_timestamptz_casts"; - static constexpr const char *Description = "Disable casting from timestamp to timestamptz "; + static constexpr const char *Description = "Disable casting from timestamp to timestamptz."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1108,7 +1133,7 @@ struct DisableTimestamptzCastsSetting { struct DisabledCompressionMethodsSetting { using RETURN_TYPE = string; static constexpr const char *Name = "disabled_compression_methods"; - static constexpr const char *Description = "Disable a specific set of compression methods (comma separated)"; + static constexpr const char *Description = "Disable a specific, comma-separated set of compression methods."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1120,7 +1145,8 @@ struct DisabledCompressionMethodsSetting { struct DisabledFilesystemsSetting { using RETURN_TYPE = string; static constexpr const char *Name = "disabled_filesystems"; - static constexpr const char *Description = "Disable specific file systems preventing access (e.g. LocalFileSystem)"; + static constexpr const char *Description = + "Disable specific file systems, thereby preventing their access, e.g. LocalFileSystem."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1132,7 +1158,7 @@ struct DisabledFilesystemsSetting { struct DisabledLogTypes { using RETURN_TYPE = string; static constexpr const char *Name = "disabled_log_types"; - static constexpr const char *Description = "Sets the list of disabled loggers"; + static constexpr const char *Description = "Sets the list of disabled log types."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1144,7 +1170,7 @@ struct DisabledLogTypes { struct DisabledOptimizersSetting { using RETURN_TYPE = string; static constexpr const char *Name = "disabled_optimizers"; - static constexpr const char *Description = "DEBUG SETTING: disable a specific set of optimizers (comma separated)"; + static constexpr const char *Description = "Disable a specific, comma-separated set of optimizers."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1156,7 +1182,9 @@ struct DisabledOptimizersSetting { struct DuckDBAPISetting { using RETURN_TYPE = string; static constexpr const char *Name = "duckdb_api"; - static constexpr const char *Description = "DuckDB API surface"; + static constexpr const char *Description = + "Specifies which client API/binding opened the database connection, e.g. cpp, capi, cli. The value gets folded " + "into the HTTP User-Agent string DuckDB sends on any HTTP request."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1170,7 +1198,7 @@ struct DynamicOrFilterThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "dynamic_or_filter_threshold"; static constexpr const char *Description = - "The maximum amount of OR filters we generate dynamically from a hash join"; + "The maximum amount of OR filters that are generated dynamically from a hash join."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1183,8 +1211,8 @@ struct EnableExternalAccessSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_external_access"; static constexpr const char *Description = - "Allow the database to access external state (through e.g. loading/installing modules, COPY TO/FROM, CSV " - "readers, pandas replacement scans, etc)"; + "Allow the database to access external state, e.g. through loading/installing modules, COPY TO/FROM, CSV " + "readers, pandas replacement scans, etc."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1197,7 +1225,7 @@ struct EnableExternalAccessSetting { struct EnableExternalFileCacheSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_external_file_cache"; - static constexpr const char *Description = "Allow the database to cache external files (e.g., Parquet) in memory."; + static constexpr const char *Description = "Allow the database to cache external files like Parquet in memory."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1211,7 +1239,7 @@ struct EnableFSSTVectorsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_fsst_vectors"; static constexpr const char *Description = - "Allow scans on FSST compressed segments to emit compressed vectors to utilize late decompression"; + "Allow scans on FSST compressed segments to emit compressed vectors to utilize late decompression."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1223,7 +1251,8 @@ struct EnableFSSTVectorsSetting { struct EnableHTTPMetadataCacheSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_http_metadata_cache"; - static constexpr const char *Description = "Whether or not the global http metadata is used to cache HTTP metadata"; + static constexpr const char *Description = + "Whether or not the global http metadata is used to cache HTTP metadata."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1235,7 +1264,7 @@ struct EnableHTTPMetadataCacheSetting { struct EnableLogging { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_logging"; - static constexpr const char *Description = "Enables the logger"; + static constexpr const char *Description = "Enables the logger."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1248,7 +1277,7 @@ struct EnableMacroDependenciesSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_macro_dependencies"; static constexpr const char *Description = - "Enable created MACROs to create dependencies on the referenced objects (such as tables)"; + "Enables created MACROs to create dependencies on the referenced objects, such as tables."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1260,10 +1289,10 @@ struct EnableMacroDependenciesSetting { struct EnableObjectCacheSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_object_cache"; - static constexpr const char *Description = "[PLACEHOLDER] Legacy setting - does nothing"; + static constexpr const char *Description = "Deprecated legacy setting, does nothing."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; + static constexpr bool IsDeprecated = true; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); @@ -1275,7 +1304,7 @@ struct EnableOptimisticWriteSetting { static constexpr const char *Name = "enable_optimistic_write"; static constexpr const char *Description = "Whether or not to optimistically write large appends to disk before committing. Disable this to keep bulk " - "appends in memory (e.g. for in-memory benchmarks)."; + "appends in memory, e.g. for in-memory benchmarks."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1287,7 +1316,7 @@ struct EnableOptimisticWriteSetting { struct EnableOptimizerSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_optimizer"; - static constexpr const char *Description = "Whether or not query optimization is enabled"; + static constexpr const char *Description = "Whether the query optimizer is enabled."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1300,7 +1329,7 @@ struct EnableProfilingSetting { using RETURN_TYPE = string; static constexpr const char *Name = "enable_profiling"; static constexpr const char *Description = - "Enables profiling, and sets the output format (JSON, QUERY_TREE, QUERY_TREE_OPTIMIZER)"; + "Enables profiling and sets the output format, which can be JSON, QUERY_TREE, or QUERY_TREE_OPTIMIZER."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1313,7 +1342,7 @@ struct EnableProgressBarSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_progress_bar"; static constexpr const char *Description = - "Enables the progress bar, printing progress to the terminal for long queries"; + "Enables the progress bar, which prints progress to the terminal during long queries."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1328,7 +1357,7 @@ struct EnableProgressBarPrintSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_progress_bar_print"; static constexpr const char *Description = - "Controls the printing of the progress bar, when 'enable_progress_bar' is true"; + "Controls the printing of the progress bar and requires 'enable_progress_bar' to be true."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1341,7 +1370,7 @@ struct EnableViewDependenciesSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "enable_view_dependencies"; static constexpr const char *Description = - "Enable created VIEWs to create dependencies on the referenced objects (such as tables)"; + "Enable created VIEWs to create dependencies on the referenced objects, such as tables."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1353,7 +1382,7 @@ struct EnableViewDependenciesSetting { struct EnabledLogTypes { using RETURN_TYPE = string; static constexpr const char *Name = "enabled_log_types"; - static constexpr const char *Description = "Sets the list of enabled loggers"; + static constexpr const char *Description = "Sets the list of enabled log types."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1362,10 +1391,23 @@ struct EnabledLogTypes { static Value GetSetting(const ClientContext &context); }; +struct ErrorOnDivisionByZeroSetting { + using RETURN_TYPE = bool; + static constexpr const char *Name = "error_on_division_by_zero"; + static constexpr const char *Description = "Throw an error instead of returning NULL when dividing by zero."; + static constexpr const char *InputType = "BOOLEAN"; + static constexpr bool IsDebug = false; + static constexpr bool IsDeprecated = false; + static constexpr const char *DefaultValue = "true"; + static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; + static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); + static void OnSet(SettingCallbackInfo &info, Value &input); +}; + struct ErrorsAsJSONSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "errors_as_json"; - static constexpr const char *Description = "Output error messages as structured JSON instead of as a raw string"; + static constexpr const char *Description = "Output error messages as structured JSON instead of as a raw string."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1390,7 +1432,8 @@ struct ExperimentalMetadataReuseSetting { struct ExplainOutputSetting { using RETURN_TYPE = ExplainOutputType; static constexpr const char *Name = "explain_output"; - static constexpr const char *Description = "Output of EXPLAIN statements (ALL, OPTIMIZED_ONLY, PHYSICAL_ONLY)"; + static constexpr const char *Description = + "Configure the output of EXPLAIN statements (ALL, OPTIMIZED_ONLY, PHYSICAL_ONLY)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1403,7 +1446,7 @@ struct ExplainOutputSetting { struct ExtensionDirectoriesSetting { using RETURN_TYPE = vector; static constexpr const char *Name = "extension_directories"; - static constexpr const char *Description = "Set the directories to store extensions in"; + static constexpr const char *Description = "Set the directories to store extensions in."; static constexpr const char *InputType = "VARCHAR[]"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1415,7 +1458,7 @@ struct ExtensionDirectoriesSetting { struct ExtensionDirectorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "extension_directory"; - static constexpr const char *Description = "DEPRECATED: Use extension_directories instead"; + static constexpr const char *Description = "Deprecated setting. Use extension_directories instead"; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = true; @@ -1431,7 +1474,7 @@ struct ExtensionRepositoryDirectorySetting { static constexpr const char *Description = "Set the directory in which trusted extension repositories are stored. This is the trust anchor for " "user-provided repositories, so while signature checking is enabled (allow_unsigned_extensions=false) it can " - "only be set at startup, not while the database is running"; + "only be set at startup, not while the database is running."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1474,7 +1517,7 @@ struct ExternalFileCacheSpillSetting { static constexpr const char *Name = "external_file_cache_spill"; static constexpr const char *Description = "Whether evicted external file cache blocks of remote files spill to the temporary directory instead of being " - "dropped, so that they are re-read from there rather than re-fetched from the source"; + "dropped, so that they are re-read from there rather than re-fetched from the source."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1499,7 +1542,7 @@ struct ExternalThreadsSetting { struct FileSearchPathSetting { using RETURN_TYPE = string; static constexpr const char *Name = "file_search_path"; - static constexpr const char *Description = "A comma separated list of directories to search for input files"; + static constexpr const char *Description = "A comma separated list of directories to search for input files."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1526,7 +1569,7 @@ struct ForceColumnMetadataReuseSetting { struct ForceCompressionSetting { using RETURN_TYPE = CompressionType; static constexpr const char *Name = "force_compression"; - static constexpr const char *Description = "DEBUG SETTING: forces a specific compression method to be used"; + static constexpr const char *Description = "Forces the usage of a specific compression method."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1536,35 +1579,38 @@ struct ForceCompressionSetting { static void OnSet(SettingCallbackInfo &info, Value &input); }; -struct GeometryMinimumShreddingSize { - using RETURN_TYPE = int64_t; - static constexpr const char *Name = "geometry_minimum_shredding_size"; - static constexpr const char *Description = "Minimum size of a rowgroup to enable GEOMETRY shredding, or set to -1 " - "to disable entirely. Defaults to 1/4th of a rowgroup"; - static constexpr const char *InputType = "BIGINT"; +struct FsyncModeSetting { + using RETURN_TYPE = FileSyncMode; + static constexpr const char *Name = "fsync_mode"; + static constexpr const char *Description = + "How to synchronize database file changes to stable storage (STANDARD, NONE or FULL). NONE may cause database " + "corruption after an operating system or hardware crash. FULL uses fullfsync on macOS."; + static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; - static constexpr const char *DefaultValue = "30000"; + static constexpr const char *DefaultValue = "STANDARD"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); + static void OnSet(SettingCallbackInfo &info, Value &input); }; -struct HeapBasedParserSetting { - using RETURN_TYPE = bool; - static constexpr const char *Name = "heap_based_parser"; - static constexpr const char *Description = "Use the heap-based PEG parser"; - static constexpr const char *InputType = "BOOLEAN"; +struct GeometryMinimumShreddingSize { + using RETURN_TYPE = int64_t; + static constexpr const char *Name = "geometry_minimum_shredding_size"; + static constexpr const char *Description = "Minimum size of a row group to enable GEOMETRY shredding. Set to -1 to " + "disable shredding entirely. Defaults to 1/4th of a row group."; + static constexpr const char *InputType = "BIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; - static constexpr const char *DefaultValue = "true"; - static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; + static constexpr const char *DefaultValue = "30000"; + static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_ONLY; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); }; struct HomeDirectorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "home_directory"; - static constexpr const char *Description = "Sets the home directory used by the system"; + static constexpr const char *Description = "Sets the home directory of the database instance."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1574,11 +1620,23 @@ struct HomeDirectorySetting { static void OnSet(SettingCallbackInfo &info, Value &input); }; +struct HTTPClientPoolCapacitySetting { + using RETURN_TYPE = int64_t; + static constexpr const char *Name = "http_client_pool_capacity"; + static constexpr const char *Description = + "HTTP client pool capacity derived from CPU and async thread counts unless explicitly set"; + static constexpr const char *InputType = "BIGINT"; + static constexpr bool IsDebug = false; + static constexpr bool IsDeprecated = false; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(const ClientContext &context); +}; + struct HTTPProxySetting { using RETURN_TYPE = string; static constexpr const char *Name = "http_proxy"; - static constexpr const char *Description = - "HTTP proxy host (defaults to the HTTP_PROXY environment variable when unset)"; + static constexpr const char *Description = "The HTTP proxy host. Defaults to the HTTP_PROXY environment variable."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1590,7 +1648,7 @@ struct HTTPProxySetting { struct HTTPProxyPasswordSetting { using RETURN_TYPE = string; static constexpr const char *Name = "http_proxy_password"; - static constexpr const char *Description = "Password for HTTP proxy"; + static constexpr const char *Description = "The password for the HTTP proxy."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1602,7 +1660,7 @@ struct HTTPProxyPasswordSetting { struct HTTPProxyUsernameSetting { using RETURN_TYPE = string; static constexpr const char *Name = "http_proxy_username"; - static constexpr const char *Description = "Username for HTTP proxy"; + static constexpr const char *Description = "The username for the HTTP proxy."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1641,7 +1699,7 @@ struct ImmediateTransactionModeSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "immediate_transaction_mode"; static constexpr const char *Description = - "Whether transactions should be started lazily when needed, or immediately when BEGIN TRANSACTION is called"; + "Whether transactions should be started lazily when needed, or immediately when BEGIN TRANSACTION is called."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1699,7 +1757,7 @@ struct IntegerDivisionSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "integer_division"; static constexpr const char *Description = - "Whether or not the / operator defaults to integer division, or to floating point division"; + "Whether or not the / operator defaults to integer division, or to floating point division."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1712,10 +1770,10 @@ struct LambdaSyntaxSetting { using RETURN_TYPE = LambdaSyntax; static constexpr const char *Name = "lambda_syntax"; static constexpr const char *Description = - "Configures the use of the deprecated single arrow operator (->) for lambda functions."; + "Deprecated setting. Configures the use of the deprecated single arrow operator (->) for lambda functions."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; + static constexpr bool IsDeprecated = true; static constexpr const char *DefaultValue = "DEFAULT"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); @@ -1726,7 +1784,7 @@ struct LateMaterializationMaxRowsSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "late_materialization_max_rows"; static constexpr const char *Description = - "The maximum amount of rows in the LIMIT/SAMPLE for which we trigger late materialization"; + "The maximum amount of rows in the LIMIT/SAMPLE operator for which we trigger late materialization."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1738,8 +1796,8 @@ struct LateMaterializationMaxRowsSetting { struct LegacyDisableNullTypeSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "legacy_disable_null_type"; - static constexpr const char *Description = - "When enabled, prevent the NULL type from leaving the binder (< v2.0 default behavior)"; + static constexpr const char *Description = "When enabled, prevent the NULL type from leaving the binder. This was " + "the default behavior prior to DuckDB v2.0."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1752,11 +1810,11 @@ struct LegacyDisableNullTypeSetting { struct LegacyMetricsFormatSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "legacy_metrics_format"; - static constexpr const char *Description = - "When enabled, profiling output uses the legacy flat format instead of the current grouped format"; + static constexpr const char *Description = "Deprecated setting. When enabled, profiling output uses the legacy " + "flat format instead of the current grouped format."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; + static constexpr bool IsDeprecated = true; static constexpr const char *DefaultValue = "false"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); @@ -1766,7 +1824,7 @@ struct LegacyMetricsFormatSetting { struct LockConfigurationSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "lock_configuration"; - static constexpr const char *Description = "Whether or not configurations can be altered"; + static constexpr const char *Description = "Whether configurations can be altered."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1779,7 +1837,7 @@ struct LogQueryPathSetting { using RETURN_TYPE = string; static constexpr const char *Name = "log_query_path"; static constexpr const char *Description = - "Specifies the path to which queries should be logged (default: NULL, queries are not logged)"; + "Specifies the path to which queries should be logged. The default is NULL, meaning queries are not logged."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1792,7 +1850,7 @@ struct LogQueryPathSetting { struct LoggingLevel { using RETURN_TYPE = string; static constexpr const char *Name = "logging_level"; - static constexpr const char *Description = "The log level which will be recorded in the log"; + static constexpr const char *Description = "Determines which 'severity' of log messages will be logged."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1804,7 +1862,7 @@ struct LoggingLevel { struct LoggingMode { using RETURN_TYPE = string; static constexpr const char *Name = "logging_mode"; - static constexpr const char *Description = "Determines which types of log messages are logged"; + static constexpr const char *Description = "Determines which types of log messages are logged."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1816,7 +1874,8 @@ struct LoggingMode { struct LoggingStorage { using RETURN_TYPE = string; static constexpr const char *Name = "logging_storage"; - static constexpr const char *Description = "Set the logging storage (memory/stdout/file/)"; + static constexpr const char *Description = + "Set the logging storage, options are 'memory', 'stdout', 'file', ''."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1828,7 +1887,7 @@ struct LoggingStorage { struct MaxExecutionTimeSetting { using RETURN_TYPE = int64_t; static constexpr const char *Name = "max_execution_time"; - static constexpr const char *Description = "The maximum execution time per query in milliseconds (0 = no limit)"; + static constexpr const char *Description = "The maximum execution time per query in milliseconds (0 = no limit)."; static constexpr const char *InputType = "BIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1854,7 +1913,7 @@ struct MaxExpressionDepthSetting { struct MaxMemorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "max_memory"; - static constexpr const char *Description = "The maximum memory of the system (e.g. 1GB)"; + static constexpr const char *Description = "The maximum memory of the system (e.g. 1GB)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1868,7 +1927,7 @@ struct MaxStreamingBufferSizeSetting { static constexpr const char *Name = "max_streaming_buffer_size"; static constexpr const char *Description = "The maximum number of bytes a streaming query result buffers (e.g. 1GB). Buffered bytes stay under this cap " - "plus at most one chunk: an oversized chunk is only admitted into an empty queue"; + "plus at most one chunk. An oversized chunk is only admitted into an empty queue."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1881,7 +1940,7 @@ struct MaxTempDirectorySizeSetting { using RETURN_TYPE = string; static constexpr const char *Name = "max_temp_directory_size"; static constexpr const char *Description = - "The maximum amount of data stored inside the 'temp_directory' (when set) (e.g. 1GB)"; + "The maximum amount of data stored inside the 'temp_directory' (when set) (e.g. 1GB)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1893,7 +1952,7 @@ struct MaxTempDirectorySizeSetting { struct MaxVacuumTasksSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "max_vacuum_tasks"; - static constexpr const char *Description = "The maximum vacuum tasks to schedule during a checkpoint."; + static constexpr const char *Description = "The maximum number of vacuum tasks to schedule during a checkpoint."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1905,7 +1964,7 @@ struct MaxVacuumTasksSetting { struct MergeJoinThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "merge_join_threshold"; - static constexpr const char *Description = "The maximum number of rows on either table to choose a merge join"; + static constexpr const char *Description = "The maximum number of rows on either table to choose a merge join."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1918,7 +1977,7 @@ struct NestedLoopJoinThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "nested_loop_join_threshold"; static constexpr const char *Description = - "The maximum number of rows on either table to choose a nested loop join"; + "The maximum number of rows on either table to choose a nested loop join."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1927,24 +1986,11 @@ struct NestedLoopJoinThresholdSetting { static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); }; -struct NullOnDivisionByZeroSetting { - using RETURN_TYPE = bool; - static constexpr const char *Name = "null_on_division_by_zero"; - static constexpr const char *Description = "Return NULL instead of throwing an error when dividing by zero."; - static constexpr const char *InputType = "BOOLEAN"; - static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; - static constexpr const char *DefaultValue = "false"; - static constexpr SettingScopeTarget Scope = SettingScopeTarget::LOCAL_DEFAULT; - static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); - static void OnSet(SettingCallbackInfo &info, Value &input); -}; - struct OldImplicitCastingSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "old_implicit_casting"; static constexpr const char *Description = - "DEPRECATED: Compatibility setting for the pre-0.10 implicit VARCHAR casting behavior; will be removed"; + "Deprecated setting. Used for compatibility for the pre-0.10 implicit VARCHAR casting behavior."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = true; @@ -1958,7 +2004,7 @@ struct OperatorMemoryLimitSetting { using RETURN_TYPE = string; static constexpr const char *Name = "operator_memory_limit"; static constexpr const char *Description = - "The maximum memory for query intermediates (sorts, hash tables) per connection (e.g. 256MB)"; + "The maximum memory available for query intermediates (sorts, hash tables) per connection (e.g. 256MB)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1971,7 +2017,8 @@ struct OrderByNonIntegerLiteralSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "order_by_non_integer_literal"; static constexpr const char *Description = - "Allow ordering by non-integer literals - ordering by such literals has no effect."; + "Allow ordering by non-integer literals. Ordering by such literals has no effect. Enabling this relaxes the " + "check to a silent no-op instead of a binder error."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1983,7 +2030,7 @@ struct OrderByNonIntegerLiteralSetting { struct OrderedAggregateThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "ordered_aggregate_threshold"; - static constexpr const char *Description = "The number of rows to accumulate before sorting, used for tuning"; + static constexpr const char *Description = "The number of rows to accumulate before sorting."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -1997,7 +2044,7 @@ struct PartitionedWriteFlushThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "partitioned_write_flush_threshold"; static constexpr const char *Description = - "The threshold in number of rows after which we flush a thread state when writing using PARTITION_BY"; + "The number of rows threshold after which a thread state is flushed when writing using PARTITION_BY."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2010,7 +2057,7 @@ struct PartitionedWriteMaxOpenFilesSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "partitioned_write_max_open_files"; static constexpr const char *Description = - "The maximum amount of files the system can keep open before flushing to disk when writing using PARTITION_BY"; + "The maximum amount of files the system can keep open before flushing to disk when writing using PARTITION_BY."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2022,7 +2069,7 @@ struct PartitionedWriteMaxOpenFilesSetting { struct PasswordSetting { using RETURN_TYPE = string; static constexpr const char *Name = "password"; - static constexpr const char *Description = "The password to use. Ignored for legacy compatibility."; + static constexpr const char *Description = "The password to use. Kept for legacy compatibility."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2034,7 +2081,7 @@ struct PasswordSetting { struct PerfectHtThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "perfect_ht_threshold"; - static constexpr const char *Description = "Threshold in bytes for when to use a perfect hash table"; + static constexpr const char *Description = "Threshold in bytes for when to use a perfect hash table."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2047,8 +2094,8 @@ struct PerfectHtThresholdSetting { struct PinThreadsSetting { using RETURN_TYPE = ThreadPinMode; static constexpr const char *Name = "pin_threads"; - static constexpr const char *Description = - "Whether to pin threads to cores (Linux only, default AUTO: on when there are more than 64 cores)"; + static constexpr const char *Description = "Whether to pin threads to cores. Linux only, and the default is AUTO. " + "AUTO means the setting is on when there are more than 64 cores."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2062,7 +2109,7 @@ struct PivotFilterThresholdSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "pivot_filter_threshold"; static constexpr const char *Description = - "The threshold to switch from using filtered aggregates to LIST with a dedicated pivot operator"; + "The threshold determining when a dedicated pivot operator switches from using filtered aggregates to LIST."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2074,7 +2121,7 @@ struct PivotFilterThresholdSetting { struct PivotLimitSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "pivot_limit"; - static constexpr const char *Description = "The maximum number of pivot columns in a pivot statement"; + static constexpr const char *Description = "The maximum number of pivot columns in a pivot statement."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2086,7 +2133,7 @@ struct PivotLimitSetting { struct PreferRangeJoinsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "prefer_range_joins"; - static constexpr const char *Description = "Force use of range joins with mixed predicates"; + static constexpr const char *Description = "Force the use of range joins with mixed predicates."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2098,8 +2145,8 @@ struct PreferRangeJoinsSetting { struct PreserveIdentifierCaseSetting { using RETURN_TYPE = IdentifierCaseMode; static constexpr const char *Name = "preserve_identifier_case"; - static constexpr const char *Description = "How to fold non-quoted identifiers: 'preserve_case' keeps the case as " - "written, 'lowercase' lowercases them, 'uppercase' uppercases them"; + static constexpr const char *Description = "How to fold non-quoted identifiers. 'preserve_case' keeps the case as " + "written, 'lowercase' lowercases them, 'uppercase' uppercases them."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2113,8 +2160,8 @@ struct PreserveInsertionOrderSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "preserve_insertion_order"; static constexpr const char *Description = - "Whether or not to preserve insertion order. If set to false the system is allowed to re-order any results " - "that do not contain ORDER BY clauses."; + "Whether or not to preserve insertion order. If set to false, then the system is allowed to re-order any " + "results that do not contain ORDER BY clauses."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2126,7 +2173,7 @@ struct PreserveInsertionOrderSetting { struct ProduceArrowStringViewSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "produce_arrow_string_view"; - static constexpr const char *Description = "DEPRECATED: Already controlled by enable_arrow_string_view"; + static constexpr const char *Description = "Deprecated setting. Controlled via enable_arrow_string_view."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = true; @@ -2139,7 +2186,8 @@ struct ProduceArrowStringViewSetting { struct ProfilingCoverageSetting { using RETURN_TYPE = string; static constexpr const char *Name = "profiling_coverage"; - static constexpr const char *Description = "The profiling coverage (SELECT or ALL)"; + static constexpr const char *Description = + "The profiling coverage, either SELECT (only SELECT queries) or ALL (all queries are profiled)."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2151,7 +2199,8 @@ struct ProfilingCoverageSetting { struct ProfilingModeSetting { using RETURN_TYPE = string; static constexpr const char *Name = "profiling_mode"; - static constexpr const char *Description = "DEPRECATED: Use enable_profiling and profiling_coverage instead"; + static constexpr const char *Description = + "Deprecated setting. Use enable_profiling and profiling_coverage instead."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = true; @@ -2164,7 +2213,7 @@ struct ProfilingOutputSetting { using RETURN_TYPE = string; static constexpr const char *Name = "profiling_output"; static constexpr const char *Description = - "The file to which profile output should be saved, or empty to print to the terminal"; + "The file to which profiler output is written. When empty, the output is printed to the terminal."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2177,8 +2226,8 @@ struct ProfilingRendererSettingsSetting { using RETURN_TYPE = unordered_map; static constexpr const char *Name = "profiling_renderer_settings"; static constexpr const char *Description = - "A map of settings passed to the renderer of the profiler output (e.g. {'max_extra_lines': 100}) - settings " - "not recognized by the active renderer are ignored"; + "A map of settings passed to the renderer of the profiler output, e.g. {'max_extra_lines': 100}. Settings not " + "recognized by the active renderer are ignored."; static constexpr const char *InputType = "MAP(VARCHAR, VARCHAR)"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2191,7 +2240,7 @@ struct ProgressBarTimeSetting { using RETURN_TYPE = int64_t; static constexpr const char *Name = "progress_bar_time"; static constexpr const char *Description = - "Sets the time (in milliseconds) how long a query needs to take before we start printing a progress bar"; + "Configures how long (in milliseconds) a query needs to take before we start printing a progress bar."; static constexpr const char *InputType = "BIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2203,8 +2252,8 @@ struct ProgressBarTimeSetting { struct ReadAheadDepthSetting { using RETURN_TYPE = int64_t; static constexpr const char *Name = "read_ahead_depth"; - static constexpr const char *Description = "Number of scan jobs prefetched ahead of decoding. -1 = automatic " - "(backlog bounded by a memory budget), 0 = disabled."; + static constexpr const char *Description = "The number of scan jobs prefetched ahead of decoding. -1 = automatic, " + "with the backlog being bound by a memory budget, 0 = disabled."; static constexpr const char *InputType = "BIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2218,7 +2267,7 @@ struct RegexMatchOperatorSemanticsSetting { using RETURN_TYPE = RegexMatchOperatorSemantics; static constexpr const char *Name = "regex_match_operator_semantics"; static constexpr const char *Description = - "Configures whether regex match operators use partial or full string matching"; + "Configures whether regex match operators use partial or full string matching."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2231,8 +2280,9 @@ struct RegexMatchOperatorSemanticsSetting { struct ScalarSubqueryErrorOnMultipleRowsSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "scalar_subquery_error_on_multiple_rows"; - static constexpr const char *Description = "Throw an error when a scalar subquery returns more than one row. When " - "disabled, an arbitrary row is returned instead."; + static constexpr const char *Description = + "Deprecated setting. Throw an error when a scalar subquery returns more than one row. This will become the " + "default behavior. When disabled, an arbitrary row is returned instead."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2244,8 +2294,8 @@ struct ScalarSubqueryErrorOnMultipleRowsSetting { struct SchedulerProcessPartialSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "scheduler_process_partial"; - static constexpr const char *Description = - "Partially process tasks before rescheduling - allows for more scheduler fairness between separate queries"; + static constexpr const char *Description = "Partially process tasks before rescheduling. Enabling this allows for " + "more scheduler fairness between separate queries."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2275,7 +2325,7 @@ struct SearchPathSetting { using RETURN_TYPE = string; static constexpr const char *Name = "search_path"; static constexpr const char *Description = - "Sets the default catalog search path as a comma-separated list of values"; + "Sets the default catalog search path as a comma-separated list of values."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2287,7 +2337,7 @@ struct SearchPathSetting { struct SecretDirectorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "secret_directory"; - static constexpr const char *Description = "Set the directory to which persistent secrets are stored"; + static constexpr const char *Description = "Set the directory in which persistent secrets are stored."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2300,8 +2350,8 @@ struct ShowBehaviorSetting { using RETURN_TYPE = ShowBehaviorType; static constexpr const char *Name = "show_behavior"; static constexpr const char *Description = - "How SHOW resolves a bare identifier: 'auto' (describe a table if one exists, else a setting; deprecated), " - "'table' (always a table), or 'setting' (always a setting)"; + "Configures how SHOW resolves a bare identifier. 'auto' describes a table if one exists, else it describes a " + "setting (deprecated). 'table' always describes a table, and 'setting' always describes a setting."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2314,7 +2364,7 @@ struct ShowBehaviorSetting { struct StandardVectorSizeSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "standard_vector_size"; - static constexpr const char *Description = "The compiled-in STANDARD_VECTOR_SIZE (read-only)"; + static constexpr const char *Description = "The compiled-in STANDARD_VECTOR_SIZE (read-only)."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2326,7 +2376,7 @@ struct StandardVectorSizeSetting { struct StorageBlockPrefetchSetting { using RETURN_TYPE = StorageBlockPrefetch; static constexpr const char *Name = "storage_block_prefetch"; - static constexpr const char *Description = "In which scenarios to use storage block prefetching"; + static constexpr const char *Description = "Configures the scenario in which to use storage block prefetching."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2339,7 +2389,9 @@ struct StorageBlockPrefetchSetting { struct StorageCompatibilityVersionSetting { using RETURN_TYPE = string; static constexpr const char *Name = "storage_compatibility_version"; - static constexpr const char *Description = "Serialize on checkpoint with compatibility for a given duckdb version"; + static constexpr const char *Description = + "Sets the DuckDB version for which data is serialized to the DuckDB file during checkpointing. Can differ from " + "the version of the DuckDB instance."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2365,7 +2417,7 @@ struct TableFunctionIdentifierConversionSetting { struct TempDirectorySetting { using RETURN_TYPE = string; static constexpr const char *Name = "temp_directory"; - static constexpr const char *Description = "Set the directory to which to write temp files"; + static constexpr const char *Description = "Set the directory to which temporary files are written."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2377,7 +2429,7 @@ struct TempDirectorySetting { struct TempFileEncryptionSetting { using RETURN_TYPE = bool; static constexpr const char *Name = "temp_file_encryption"; - static constexpr const char *Description = "Encrypt all temporary files if database is encrypted"; + static constexpr const char *Description = "Encrypt all temporary files, if the database is encrypted."; static constexpr const char *InputType = "BOOLEAN"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2390,7 +2442,7 @@ struct TempFileEncryptionSetting { struct ThreadsSetting { using RETURN_TYPE = int64_t; static constexpr const char *Name = "threads"; - static constexpr const char *Description = "The number of total threads used by the system."; + static constexpr const char *Description = "The number of total background threads used by the system."; static constexpr const char *InputType = "BIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2403,7 +2455,7 @@ struct TrackedMetricsSetting { using RETURN_TYPE = vector; static constexpr const char *Name = "tracked_metrics"; static constexpr const char *Description = - "A list of metric glob patterns to enable for collection (e.g. ['query.*', 'optimizer.*'])"; + "A list of metric glob patterns to enable for collection, e.g. ['query.*', 'optimizer.*']."; static constexpr const char *InputType = "VARCHAR[]"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2415,7 +2467,7 @@ struct TrackedMetricsSetting { struct UsernameSetting { using RETURN_TYPE = string; static constexpr const char *Name = "username"; - static constexpr const char *Description = "The username to use. Ignored for legacy compatibility."; + static constexpr const char *Description = "The username to use. Kept for legacy compatibility."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2444,8 +2496,8 @@ struct ValidateExternalFileCacheSetting { using RETURN_TYPE = CacheValidationMode; static constexpr const char *Name = "validate_external_file_cache"; static constexpr const char *Description = - "Cache validation mode: VALIDATE_ALL (default, validate all cache entries), VALIDATE_REMOTE (validate only " - "remote cache entries), or NO_VALIDATION (disable cache validation)."; + "The cache validation mode. VALIDATE_ALL is the default, it validates all cache entries., VALIDATE_REMOTE only " + "validates remote cache entries. NO_VALIDATION disables cache validation."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2458,8 +2510,9 @@ struct ValidateExternalFileCacheSetting { struct VariantMinimumShreddingSizeSetting { using RETURN_TYPE = int64_t; static constexpr const char *Name = "variant_minimum_shredding_size"; - static constexpr const char *Description = "Minimum size of a rowgroup to enable VARIANT shredding, or set to -1 " - "to disable entirely. Defaults to 1/4th of a rowgroup"; + static constexpr const char *Description = + "Minimum size of a row group to have VARIANT shredding enabled. Set to -1 to disable shredding entirely. " + "Defaults to 1/4th of the row group size."; static constexpr const char *InputType = "BIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2472,7 +2525,7 @@ struct WalAutocheckpointEntriesSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "wal_autocheckpoint_entries"; static constexpr const char *Description = - "Trigger automatic checkpoint when WAL entry count reaches or exceeds N (0 = disabled)"; + "Trigger automatic checkpoint when WAL entry count reaches or exceeds N (0 = disabled)."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2513,7 +2566,7 @@ struct WriteBufferRowGroupMemoryLimitSetting { static constexpr const char *Description = "The maximum data to buffer in row groups (in bytes) to buffer prior to flushing them together. When either " "this limit is reached, or write_buffer_row_group_count is reached, we flush the data to disk. Defaults to 20% " - "of memory limit divided by thread count."; + "of the memory limit divided by the thread count."; static constexpr const char *InputType = "VARCHAR"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; @@ -2526,7 +2579,7 @@ struct ZstdMinStringLengthSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "zstd_min_string_length"; static constexpr const char *Description = - "The (average) length at which to enable ZSTD compression, defaults to 4096"; + "The (average) minimum length at which to enable ZSTD compression, defaults to 4096."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; static constexpr bool IsDeprecated = false; diff --git a/src/duckdb/src/include/duckdb/main/stream_query_result.hpp b/src/duckdb/src/include/duckdb/main/stream_query_result.hpp deleted file mode 100644 index d8e10185c..000000000 --- a/src/duckdb/src/include/duckdb/main/stream_query_result.hpp +++ /dev/null @@ -1,86 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/stream_query_result.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/winapi.hpp" -#include "duckdb/main/query_result.hpp" -#include "duckdb/parallel/interrupt.hpp" -#include "duckdb/common/queue.hpp" -#include "duckdb/common/enums/stream_execution_result.hpp" -#include "duckdb/main/buffered_data/simple_buffered_data.hpp" - -namespace duckdb { - -class ClientContext; -class ClientContextLock; -class Executor; -class MaterializedQueryResult; -class PreparedStatementData; - -class StreamQueryResult : public QueryResult { - friend class ClientContext; - -public: - static constexpr const QueryResultType TYPE = QueryResultType::STREAM_RESULT; - -public: - //! Create a successful StreamQueryResult. StreamQueryResults should always be successful initially (it makes no - //! sense to stream an error). - DUCKDB_API StreamQueryResult(StatementType statement_type, StatementProperties properties, - vector types, vector names, - ClientProperties client_properties, shared_ptr buffered_data); - DUCKDB_API explicit StreamQueryResult(ErrorData error); - DUCKDB_API ~StreamQueryResult() override; - -public: - static bool IsChunkReady(StreamExecutionResult result); - //! Reschedules the tasks that work on producing a result chunk, returning when at least one task can be executed - DUCKDB_API void WaitForTask(); - //! Executes a single task within the final pipeline, returning whether or not a chunk is ready to be fetched - DUCKDB_API StreamExecutionResult ExecuteTask(); - //! Converts the QueryResult to a string - DUCKDB_API string ToString() override; - //! Materializes the query result and turns it into a materialized query result - DUCKDB_API unique_ptr Materialize(); - - DUCKDB_API bool IsOpen(); - - //! The buffer backing this stream result - BufferedData &GetBufferedData() { - D_ASSERT(buffered_data); - return *buffered_data; - } - //! False for an error result, which never had a buffer - bool HasBufferedData() const { - return buffered_data != nullptr; - } - - //! Closes the StreamQueryResult - DUCKDB_API void Close(); - - //! The client context this StreamQueryResult belongs to - shared_ptr context; - -protected: - DUCKDB_API unique_ptr FetchInternal() override; - -private: - StreamExecutionResult ExecuteTaskInternal(ClientContextLock &lock); - unique_ptr FetchNextInternal(ClientContextLock &lock); - //! The materialize of a stream a fetch already chose: the remainder is copied out under the cap - unique_ptr MaterializeByDraining(); - unique_ptr LockContext(); - void CheckExecutableInternal(ClientContextLock &lock); - bool IsOpenInternal(ClientContextLock &lock); - -private: - shared_ptr buffered_data; -}; - -} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/optimizer/aggregate_rewrite_helper.hpp b/src/duckdb/src/include/duckdb/optimizer/aggregate_rewrite_helper.hpp index a06e424dd..34c92d73b 100644 --- a/src/duckdb/src/include/duckdb/optimizer/aggregate_rewrite_helper.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/aggregate_rewrite_helper.hpp @@ -27,6 +27,10 @@ struct AggregateRewriteHelper { const vector &input_names, const vector &input_bindings, column_binding_map_t &replacement_map); + //! Projects the definition onto the given bindings so CTE references can rely on a stable column layout + static unique_ptr PinColumnOrder(Optimizer &optimizer, unique_ptr definition, + const vector &types, + const vector &bindings); }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/optimizer/cte_filter_pusher.hpp b/src/duckdb/src/include/duckdb/optimizer/cte_filter_pusher.hpp index 4923dd5da..2785879d2 100644 --- a/src/duckdb/src/include/duckdb/optimizer/cte_filter_pusher.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/cte_filter_pusher.hpp @@ -13,6 +13,7 @@ namespace duckdb { class LogicalOperator; +class LogicalCTERef; class Optimizer; class CTEFilterPusher { @@ -20,6 +21,8 @@ class CTEFilterPusher { explicit CTEFilterPusher(Optimizer &optimizer); //! Finds all materialized CTEs and pushes OR filters into them (if applicable) unique_ptr Optimize(unique_ptr op); + //! Discard planner guarantees before transformations that do not preserve consumer identity. + static void ClearDependencies(LogicalOperator &op); private: //! CTE info needed for creating OR filters that can be pushed down @@ -27,12 +30,15 @@ class CTEFilterPusher { explicit MaterializedCTEInfo(LogicalOperator &materialized_cte); LogicalOperator &materialized_cte; vector> filters; + vector> references; bool all_cte_refs_are_filtered; + bool has_filter_dependency; }; private: //! Find all materialized CTEs and their refs void FindCandidates(LogicalOperator &op); + bool CanPushFilter(const MaterializedCTEInfo &info); //! Creates an OR filter and pushes it into a materialized CTE void PushFilterIntoCTE(MaterializedCTEInfo &info); diff --git a/src/duckdb/src/include/duckdb/optimizer/remote_pushdown_optimizer.hpp b/src/duckdb/src/include/duckdb/optimizer/remote_pushdown_optimizer.hpp index 6a70d9a9c..772681d60 100644 --- a/src/duckdb/src/include/duckdb/optimizer/remote_pushdown_optimizer.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/remote_pushdown_optimizer.hpp @@ -90,6 +90,17 @@ class RemotePushdownOptimizer { void Rewrite(unique_ptr &statement); + //! Drop the given catalog qualifier from every name in the tree. A two-part name (e.g. "db1.t") parses as + //! schema.name, so the catalog can sit in either slot + static void StripCatalogName(SQLStatement &statement, const Identifier &catalog_name); + static void StripCatalogName(QueryNode &node, const Identifier &catalog_name); + static void StripCatalogName(TableRef &ref, const Identifier &catalog_name); + static void StripCatalogName(CreateInfo &info, const Identifier &catalog_name); + static void StripCatalogName(AlterInfo &info, const Identifier &catalog_name); + //! Strip catalog prefix from expression column refs. When strip_subquery_bodies=false, leaves subquery + //! bodies untouched (used for partial pushdown where inner subqueries are not being pushed). + static void StripCatalogName(ParsedExpression &expr, const Identifier &catalog_name); + private: void FindRemoteCatalogsInSearchPath(); CatalogPushdownResult Rewrite(QueryNode &node); @@ -183,14 +194,6 @@ class RemotePushdownOptimizer { static CatalogPushdownResult Merge(CatalogPushdownResult a, CatalogPushdownResult b); unique_ptr CreateRemoteFunctionRef(CatalogPushdownResult &result, unique_ptr node); - static void StripCatalogName(SQLStatement &statement, const Identifier &catalog_name); - static void StripCatalogName(QueryNode &node, const Identifier &catalog_name); - static void StripCatalogName(TableRef &ref, const Identifier &catalog_name); - static void StripCatalogName(CreateInfo &info, const Identifier &catalog_name); - static void StripCatalogName(AlterInfo &info, const Identifier &catalog_name); - //! Strip catalog prefix from expression column refs. When strip_subquery_bodies=false, leaves subquery - //! bodies untouched (used for partial pushdown where inner subqueries are not being pushed). - static void StripCatalogName(ParsedExpression &expr, const Identifier &catalog_name); bool RefersToLocalTable(const ColumnRefExpression &col_ref) const; bool RefersToCTE(const Identifier &cte_name, CatalogPushdownResult &result) const; diff --git a/src/duckdb/src/include/duckdb/optimizer/remove_unused_columns.hpp b/src/duckdb/src/include/duckdb/optimizer/remove_unused_columns.hpp index 82073c32f..716dc2f72 100644 --- a/src/duckdb/src/include/duckdb/optimizer/remove_unused_columns.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/remove_unused_columns.hpp @@ -24,6 +24,7 @@ class BoundColumnRefExpression; class ClientContext; class LogicalColumnDataGet; class LogicalRecursiveCTE; +class LogicalSecureView; class Optimizer; struct ReferencedExtractComponent { @@ -151,12 +152,23 @@ class RemoveUnusedColumns : public BaseColumnPruner { RemoveUnusedColumns &root; unique_ptr> root_cte_map; column_binding_map_t> projection_map_replacements; + struct PrunedViewColumn { + ColumnBinding binding; + //! Expression over the previous binding; nullptr for a rename. + unique_ptr expression; + }; + vector> active_secure_views; + column_binding_map_t> secure_view_replacements; private: template void ClearUnusedExpressions(vector &list, TableIndex table_idx, bool replace = true); + void RecordSecureViewReplacement(ColumnBinding old_binding, ColumnBinding new_binding, + unique_ptr expression = nullptr); + void ApplySecureViewReplacements(); void RemoveColumnsFromLogicalColumnDataGet(LogicalColumnDataGet &get); void RemoveColumnsFromLogicalGet(LogicalGet &get, unique_ptr &op_ref); + void VisitSecureView(LogicalSecureView &view); void CheckPushdownExtract(LogicalOperator &op); void RewriteExpressions(LogicalProjection &proj, idx_t expression_count); void GatherRecursiveDependencies(unique_ptr &bottom, TableIndex cte_index, diff --git a/src/duckdb/src/include/duckdb/optimizer/type_pushdown.hpp b/src/duckdb/src/include/duckdb/optimizer/type_pushdown.hpp index a25dd46e4..4a37be3d6 100644 --- a/src/duckdb/src/include/duckdb/optimizer/type_pushdown.hpp +++ b/src/duckdb/src/include/duckdb/optimizer/type_pushdown.hpp @@ -88,9 +88,13 @@ void FindGetsAndProjections(LogicalOperator &op, Analyses &analyses, Projections struct GetBinding { GetAnalysis &analysis; + // Column index within LogicalGet ProjectionIndex column_index; // If column binding was part of a projection, this is non-nullptr LogicalProjection *projection; + // If column binding was part of projection, column index within + // LogicalProjection wrapping a LogicalGet + ProjectionIndex projection_column_index; }; /* diff --git a/src/duckdb/src/include/duckdb/parallel/pipeline.hpp b/src/duckdb/src/include/duckdb/parallel/pipeline.hpp index edad24075..47965464a 100644 --- a/src/duckdb/src/include/duckdb/parallel/pipeline.hpp +++ b/src/duckdb/src/include/duckdb/parallel/pipeline.hpp @@ -99,6 +99,14 @@ class PipelineBuildState { unique_ptr data; }; +//! Progress of a pipeline, split into the source and the (sink-adjusted) pipeline progress +struct PipelineProgress { + //! Progress as reported by the source, before normalization + ProgressData source; + //! Progress of the pipeline: the normalized source progress, adjusted by the sink + ProgressData pipeline; +}; + //! The Pipeline class represents an execution pipeline starting at a class Pipeline : public enable_shared_from_this { friend class Executor; @@ -154,6 +162,8 @@ class Pipeline : public enable_shared_from_this { //! Returns query progress bool GetProgress(ProgressData &progress_data); + //! Returns the progress of the source and of the pipeline separately + void GetDetailedProgress(PipelineProgress &progress); //! Returns a list of all operators (including source and sink) involved in this pipeline vector> GetOperators(); @@ -195,6 +205,10 @@ class Pipeline : public enable_shared_from_this { //! Updates the batch index of a pipeline (and returns the new minimum batch index) idx_t UpdateBatchIndex(idx_t old_index, idx_t new_index); +private: + //! Tells the progress verifier (if any) that a new run of this pipeline starts + void NotifyProgressReset(); + private: //! Whether or not the pipeline has been readied bool ready; diff --git a/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp b/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp index 4377e68dc..14bc31b9d 100644 --- a/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +++ b/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp @@ -173,6 +173,8 @@ class PipelineExecutor { bool has_executed = false; //! Whether an externally-fed sink has observed its initial batch bool external_batch_initialized = false; + //! Rows of the last source chunk that have not been reported to the progress verifier yet + idx_t unsampled_progress_rows = 0; private: void StartOperator(PhysicalOperator &op); @@ -181,6 +183,8 @@ class PipelineExecutor { //! Reset the operator index to the first operator void GoToSource(idx_t ¤t_idx, idx_t initial_idx); SourceFetchResult FetchFromSource(DataChunk &result); + //! Reports the last source chunk to the progress verifier (if any), once it has been fully processed + void SampleProgress(); void FinishProcessing(int32_t operator_idx = -1); void NotifySourceFinished(); diff --git a/src/duckdb/src/include/duckdb/parallel/progress_verifier.hpp b/src/duckdb/src/include/duckdb/parallel/progress_verifier.hpp new file mode 100644 index 000000000..26af45182 --- /dev/null +++ b/src/duckdb/src/include/duckdb/parallel/progress_verifier.hpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parallel/progress_verifier.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/common.hpp" +#include "duckdb/common/enums/debug_progress_verification.hpp" +#include "duckdb/common/mutex.hpp" +#include "duckdb/common/optional_idx.hpp" +#include "duckdb/common/unordered_map.hpp" +#include "duckdb/common/unordered_set.hpp" + +namespace duckdb { +class ClientContext; +class PhysicalOperator; +class Pipeline; +struct PipelineProgress; + +enum class ProgressInvariant : uint8_t { + //! The source reported invalid progress while it was producing data + UNSUPPORTED_SOURCE, + //! The sink turned valid source progress into invalid progress + UNSUPPORTED_SINK, + //! The source reported progress that is not finite or outside of [0, total] + MALFORMED_SOURCE, + //! The sink reported progress that is not finite or outside of [0, total] + MALFORMED_SINK, + //! The progress of the pipeline decreased + NON_MONOTONIC, + //! The pipeline ran to completion but did not report 100% progress + INCOMPLETE, + //! The progress of the pipeline did not change while it produced many chunks + STALLED, + //! The source progress deviates strongly from the fraction of rows produced (log-only) + INACCURATE +}; + +//! The ProgressVerifier samples the progress of every pipeline after each source chunk and at the end of the query, +//! and verifies that the reported progress is well-formed, monotonic, moving and complete +class ProgressVerifier { +public: + ProgressVerifier(ClientContext &context, DebugProgressVerification mode, const string &ignore_list); + +public: + //! Samples the progress of a pipeline after a non-empty source chunk was pushed through the pipeline + void OnSourceChunk(Pipeline &pipeline, idx_t count); + //! Called when a pipeline executor finished without exhausting its source (e.g. because of a LIMIT) + void OnEarlyExit(Pipeline &pipeline); + //! Called when the source or sink state of a pipeline is reset - this starts a new run of the pipeline + void OnReset(Pipeline &pipeline); + //! Takes a final sample of the given (completed) pipelines and verifies all traces + //! Returns an error message if any violation that fails the query was found + string Finalize(const vector> &pipelines); + + //! The name that is used to attribute a violation to an operator + static string OperatorName(const PhysicalOperator &op); + +private: + struct ProgressSample { + //! Progress fraction reported by the source - or NaN if the source progress was invalid + double source_fraction; + //! Progress fraction of the pipeline - or NaN if the pipeline progress was invalid + double fraction; + //! Rows produced by the source at the time of the sample + idx_t rows; + }; + struct PipelineRun { + vector samples; + idx_t rows = 0; + idx_t chunks = 0; + bool early_exit = false; + bool has_final_sample = false; + optional_idx first_unsupported_source; + optional_idx first_unsupported_sink; + }; + struct PipelineTrace { + //! Held while sampling, so samples are recorded in the order in which they were taken + mutex lock; + string source_name; + string sink_name; + PipelineRun run; + }; + struct Violation { + ProgressInvariant invariant; + string operator_name; + string pipeline; + string detail; + }; + +private: + PipelineTrace &GetTrace(Pipeline &pipeline); + void Sample(Pipeline &pipeline, PipelineTrace &trace, bool is_final); + void VerifyRun(PipelineTrace &trace); + void AddViolation(const PipelineTrace &trace, ProgressInvariant invariant, const string &operator_name, + const string &detail); + bool IsIgnored(const Violation &violation) const; + static bool FailsQuery(ProgressInvariant invariant); + +private: + ClientContext &context; + DebugProgressVerification mode; + unordered_set ignore_list; + + //! Protects the traces map and the violations + mutex lock; + unordered_map> traces; + vector violations; + unordered_set reported; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parallel/scan_read_ahead.hpp b/src/duckdb/src/include/duckdb/parallel/scan_read_ahead.hpp index 6f1e8885c..aafb6afc8 100644 --- a/src/duckdb/src/include/duckdb/parallel/scan_read_ahead.hpp +++ b/src/duckdb/src/include/duckdb/parallel/scan_read_ahead.hpp @@ -162,6 +162,9 @@ class ScanReadAhead { bool TryRunPendingTask(); //! Throw the first error recorded on the async executor, if there is one void ThrowIfError(); + //! Cancel the tasks that have not started yet and wait for the ones that are running. The scheduled closures + //! reference the scan they were scheduled for, so they must not outlive it + void CancelAndDrain(); private: //! Settles the reservation taken by TryReserveSlot diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp index bdf58e13a..d2654cb4d 100644 --- a/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp @@ -180,17 +180,23 @@ struct RenameTableInfo : public AlterTableInfo { //===--------------------------------------------------------------------===// // AddColumnInfo //===--------------------------------------------------------------------===// + +struct AddColumnConstraints { + bool add_not_null = false; + bool add_unique = false; +}; + struct AddColumnInfo : public AlterTableInfo { - AddColumnInfo(const AlterEntryData &data, ColumnDefinition new_column, bool if_column_not_exists, - bool add_not_null); + AddColumnInfo(const AlterEntryData &data, ColumnDefinition new_column_p, bool if_column_not_exists_p, + AddColumnConstraints add_column_constraints_p); ~AddColumnInfo() override; //! New column ColumnDefinition new_column; //! Whether or not an error should be thrown if the column exist bool if_column_not_exists; - //! Whether to add a NOT NULL constraint after adding the column - bool add_not_null = false; + //! Constraints applied via extra ALTER statements after the column is added + AddColumnConstraints add_column_constraints; public: unique_ptr Copy() const override; diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/attach_info.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/attach_info.hpp index e0b8b55d6..c531943ed 100644 --- a/src/duckdb/src/include/duckdb/parser/parsed_data/attach_info.hpp +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/attach_info.hpp @@ -10,6 +10,7 @@ #include "duckdb/common/identifier.hpp" #include "duckdb/parser/parsed_data/parse_info.hpp" +#include "duckdb/parser/parsed_data/external_resource_options.hpp" #include "duckdb/common/unordered_map.hpp" #include "duckdb/common/types/value.hpp" #include "duckdb/common/enums/on_create_conflict.hpp" @@ -37,6 +38,8 @@ struct AttachInfo : public ParseInfo { unordered_map options; //! What to do on create conflict OnCreateConflict on_conflict = OnCreateConflict::ERROR_ON_CONFLICT; + //! Set iff parsed as `ATTACH TO [NEW TEMPORARY] EXTERNAL RESOURCE ...`: the resource to attach. + unique_ptr external_resource; public: //! Copies this AttachInfo and returns an unique pointer to the new AttachInfo. diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/connect_info.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/connect_info.hpp index ce5af3826..0d272c2bb 100644 --- a/src/duckdb/src/include/duckdb/parser/parsed_data/connect_info.hpp +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/connect_info.hpp @@ -13,6 +13,7 @@ #include "duckdb/common/types/value.hpp" #include "duckdb/common/unordered_map.hpp" #include "duckdb/parser/parsed_data/parse_info.hpp" +#include "duckdb/parser/parsed_data/external_resource_options.hpp" #include "duckdb/parser/parsed_expression.hpp" namespace duckdb { @@ -41,6 +42,8 @@ struct ConnectInfo : public ParseInfo { case_insensitive_map_t> parsed_options; //! Set of bound (key, value) options forwarded to the implicit ATTACH. unordered_map options; + //! Set iff parsed as `CONNECT TO [NEW TEMPORARY] EXTERNAL RESOURCE ...`: the resource to connect to. + unique_ptr external_resource; public: unique_ptr Copy() const; diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/external_resource_options.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/external_resource_options.hpp new file mode 100644 index 000000000..7a7b7cdae --- /dev/null +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/external_resource_options.hpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/external_resource_options.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/case_insensitive_map.hpp" +#include "duckdb/common/identifier.hpp" +#include "duckdb/common/types/value.hpp" +#include "duckdb/common/unordered_map.hpp" +#include "duckdb/parser/parsed_expression.hpp" + +namespace duckdb { +class Serializer; +class Deserializer; + +//! The `[NEW TEMPORARY] EXTERNAL RESOURCE '' [(params)]` clause, owned by AttachInfo/ConnectInfo. +//! provider is its own field rather than a magic key in params: the TYPE is the registry key, not a param. +struct ExternalResourceOptions { + //! Create params (key -> expression); transient — consumed at bind, then `params` holds them. + case_insensitive_map_t> parsed_params; + //! The resource type (provider) — the registered external-resource-type name to provision. A string + //! literal, so it is fixed at parse time. + string provider; + //! Bound create params forwarded to the type's create function as a MAP(VARCHAR, VARCHAR). + unordered_map params; + //! Reference form: a bare identifier naming a registered resource to BORROW rather than provision, + //! so no teardown is owned. Mutually exclusive with `provider`. + string reference_name; + + unique_ptr Copy() const; + //! Renders `NEW TEMPORARY EXTERNAL RESOURCE '' [(k v, ...)]`, or the reference form. + string ToString() const; + + void Serialize(Serializer &serializer) const; + static unique_ptr Deserialize(Deserializer &deserializer); +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp b/src/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp index 9b32d2dc0..ede19422b 100644 --- a/src/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp +++ b/src/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp @@ -10,9 +10,19 @@ #include "duckdb/common/common.hpp" #include "duckdb/common/enums/catalog_type.hpp" +#include "duckdb/common/case_insensitive_map.hpp" #include "duckdb/common/identifier.hpp" +#include "duckdb/common/types/value.hpp" +#include "duckdb/common/unordered_map.hpp" namespace duckdb { +class ParsedExpression; +class Value; + +//! Render a statement's `(k v, ...)` option list, quoting each name, from the unbound and bound maps +//! alike. Empty string when there is nothing to render, so callers can append it unconditionally. +string RenderOptionList(const case_insensitive_map_t> &parsed_options, + const unordered_map &options); enum class CatalogType : uint8_t; diff --git a/src/duckdb/src/include/duckdb/parser/parser_options.hpp b/src/duckdb/src/include/duckdb/parser/parser_options.hpp index 467880ae0..63c81afb5 100644 --- a/src/duckdb/src/include/duckdb/parser/parser_options.hpp +++ b/src/duckdb/src/include/duckdb/parser/parser_options.hpp @@ -22,7 +22,6 @@ struct CompiledGrammar; struct ParserOptions { IdentifierCaseMode identifier_case_mode = IdentifierCaseMode::PRESERVE_CASE; bool integer_division = false; - bool heap_based_parser = true; RegexMatchOperatorSemantics regex_match_operator_semantics = RegexMatchOperatorSemantics::PARTIAL; idx_t max_expression_depth = 1000; optional_ptr extensions; diff --git a/src/duckdb/src/include/duckdb/parser/peg/ast/add_column_entry.hpp b/src/duckdb/src/include/duckdb/parser/peg/ast/add_column_entry.hpp index 88bcdeb6e..0f819849e 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/ast/add_column_entry.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/ast/add_column_entry.hpp @@ -3,6 +3,7 @@ #include "duckdb/common/types/value.hpp" #include "duckdb/parser/column_definition.hpp" #include "duckdb/parser/constraint.hpp" +#include "duckdb/parser/parsed_data/alter_table_info.hpp" #include "duckdb/common/identifier.hpp" namespace duckdb { @@ -11,8 +12,9 @@ struct AddColumnEntry { LogicalType type; vector column_path; unique_ptr default_value; + //! Constraints applied via extra ALTER statements after the column is added + AddColumnConstraints add_column_constraints; CompressionType compression_type = CompressionType::COMPRESSION_AUTO; - bool is_not_null = false; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/autocomplete_catalog_provider.hpp b/src/duckdb/src/include/duckdb/parser/peg/autocomplete_catalog_provider.hpp index 6581fcc85..bf99fb89e 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/autocomplete_catalog_provider.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/autocomplete_catalog_provider.hpp @@ -18,7 +18,6 @@ struct AutoCompleteParameters { idx_t max_file_suggestion_count = 1; idx_t max_exact_suggestion_count = 100; bool suggestion_contains_files = false; - bool use_heap_based_parser = false; }; //! Abstract interface for providing catalog-aware autocomplete suggestions. diff --git a/src/duckdb/src/include/duckdb/parser/peg/compiled_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/compiled_grammar.hpp index 3ecf9b6cf..20d7d1ef5 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/compiled_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/compiled_grammar.hpp @@ -17,8 +17,7 @@ struct CompiledGrammar { CompiledGrammar(MatcherAllocator &&allocator, unique_ptr &&keyword_helper, unique_ptr &&tokenizer, compiled_rules_map_t &&rules, const Matcher &program_matcher, const Matcher &top_level_statement_matcher); - static shared_ptr - Create(const case_insensitive_map_t> &grammar_extensions); + static shared_ptr Create(const vector> &grammar_extensions); public: const Matcher &ProgramMatcher() const { @@ -40,8 +39,7 @@ struct CompiledGrammar { //! Compile the base DuckDB grammar. static shared_ptr Create(); //! Compile a grammar for the selected extensions without changing the client configuration. - static shared_ptr Create(const ClientContext &context, - const case_insensitive_set_t &active_extensions); + static shared_ptr Create(const ClientContext &context, const vector &active_extensions); private: MatcherAllocator allocator; diff --git a/src/duckdb/src/include/duckdb/parser/peg/dialect_extension.hpp b/src/duckdb/src/include/duckdb/parser/peg/dialect_extension.hpp index 8c0e6070a..ceb6c6b90 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/dialect_extension.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/dialect_extension.hpp @@ -55,7 +55,7 @@ struct GrammarChangesInput { class DialectExtension { public: explicit DialectExtension(string name_p, optional compatibility_mode = std::nullopt) - : name(std::move(name_p)), compatibility_mode(std::move(compatibility_mode)) { + : name(std::move(name_p)), compatibility_mode(compatibility_mode) { } virtual ~DialectExtension() = default; diff --git a/src/duckdb/src/include/duckdb/parser/peg/grammar_literal_table.hpp b/src/duckdb/src/include/duckdb/parser/peg/grammar_literal_table.hpp new file mode 100644 index 000000000..71989138d --- /dev/null +++ b/src/duckdb/src/include/duckdb/parser/peg/grammar_literal_table.hpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/peg/grammar_literal_table.hpp +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/case_insensitive_map.hpp" +#include "duckdb/parser/peg/literal_info.hpp" + +namespace duckdb { + +class ParsedGrammar; + +//! Immutable after construction, including literals only present in keyword-category rules. +class GrammarLiteralTable { +public: + DUCKDB_API GrammarLiteralTable(const ParsedGrammar &grammar, const case_insensitive_map_t &keywords); + GrammarLiteralTable(const GrammarLiteralTable &) = delete; + GrammarLiteralTable &operator=(const GrammarLiteralTable &) = delete; + + uint64_t CacheId() const { + return cache_id; + } + + LiteralInfo Lookup(const string &text) const { + auto entry = literals.find(text); + return entry == literals.end() ? LiteralInfo() : entry->second; + } + +private: + void Register(const string &text, keyword_categories_t categories = keyword_categories_t()); + +private: + const uint64_t cache_id; + case_insensitive_map_t literals; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp index 52c472fa1..e63de5e5d 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp @@ -655,2718 +655,2771 @@ const unsigned char INLINED_PEG_GRAMMAR[] = { 101, 118, 101, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 68, 114, 111, 112, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 39, 67, 79, 78, 83, 84, 82, 65, 73, 78, 84, 39, 32, 73, 102, 69, 120, 105, 115, 116, - 115, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 68, 114, 111, 112, 66, 101, - 104, 97, 118, 105, 111, 114, 63, 10, 65, 100, 100, 67, 111, 108, 117, 109, 110, 32, 60, 45, - 32, 39, 65, 68, 68, 39, 32, 39, 67, 79, 76, 85, 77, 78, 39, 63, 32, 73, 102, 78, - 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 65, 100, 100, 67, 111, 108, 117, 109, 110, 69, - 110, 116, 114, 121, 10, 65, 100, 100, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 32, + 115, 63, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, 32, 68, 114, + 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 63, 10, 65, 100, 100, 67, 111, 108, 117, 109, + 110, 32, 60, 45, 32, 39, 65, 68, 68, 39, 32, 39, 67, 79, 76, 85, 77, 78, 39, 63, + 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 65, 100, 100, 67, 111, 108, + 117, 109, 110, 69, 110, 116, 114, 121, 10, 65, 100, 100, 67, 111, 108, 117, 109, 110, 69, 110, + 116, 114, 121, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 84, 121, 112, 101, 63, 32, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, + 111, 108, 117, 109, 110, 63, 32, 67, 111, 108, 117, 109, 110, 67, 111, 110, 115, 116, 114, 97, + 105, 110, 116, 42, 10, 68, 114, 111, 112, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, + 68, 82, 79, 80, 39, 32, 39, 67, 79, 76, 85, 77, 78, 39, 63, 32, 73, 102, 69, 120, + 105, 115, 116, 115, 63, 32, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, + 109, 101, 32, 68, 114, 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 63, 10, 65, 108, 116, + 101, 114, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 65, 76, 84, 69, 82, 39, 32, + 39, 67, 79, 76, 85, 77, 78, 39, 63, 32, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, + 109, 110, 78, 97, 109, 101, 32, 65, 108, 116, 101, 114, 67, 111, 108, 117, 109, 110, 69, 110, + 116, 114, 121, 10, 82, 101, 110, 97, 109, 101, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, + 39, 82, 69, 78, 65, 77, 69, 39, 32, 39, 67, 79, 76, 85, 77, 78, 39, 63, 32, 78, + 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 39, 84, 79, 39, + 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 78, 101, 115, 116, 101, + 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 68, 111, 116, 42, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, + 10, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 68, 111, 116, 32, 60, 45, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 46, 39, 10, 82, 101, 110, 97, 109, 101, 65, + 108, 116, 101, 114, 32, 60, 45, 32, 39, 82, 69, 78, 65, 77, 69, 39, 32, 39, 84, 79, + 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 83, 101, 116, 80, + 97, 114, 116, 105, 116, 105, 111, 110, 101, 100, 66, 121, 32, 60, 45, 32, 39, 83, 69, 84, + 39, 32, 39, 80, 65, 82, 84, 73, 84, 73, 79, 78, 69, 68, 39, 32, 39, 66, 89, 39, + 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 41, 41, 10, 82, 101, 115, 101, 116, 80, 97, 114, 116, 105, 116, 105, 111, 110, + 101, 100, 66, 121, 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, 39, 32, 39, 80, 65, 82, + 84, 73, 84, 73, 79, 78, 69, 68, 39, 32, 39, 66, 89, 39, 10, 83, 101, 116, 83, 111, + 114, 116, 101, 100, 66, 121, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 83, 79, 82, + 84, 69, 68, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 114, 100, + 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 41, 10, 82, 101, 115, + 101, 116, 83, 111, 114, 116, 101, 100, 66, 121, 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, + 39, 32, 39, 83, 79, 82, 84, 69, 68, 39, 32, 39, 66, 89, 39, 10, 83, 101, 116, 79, + 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 82, 101, 108, 79, + 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 82, 101, 115, 101, 116, 79, 112, 116, 105, 111, + 110, 115, 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, 39, 32, 82, 101, 108, 79, 112, 116, + 105, 111, 110, 76, 105, 115, 116, 10, 65, 108, 116, 101, 114, 67, 111, 108, 117, 109, 110, 69, + 110, 116, 114, 121, 32, 60, 45, 32, 65, 100, 100, 79, 114, 68, 114, 111, 112, 68, 101, 102, + 97, 117, 108, 116, 32, 47, 32, 67, 104, 97, 110, 103, 101, 78, 117, 108, 108, 97, 98, 105, + 108, 105, 116, 121, 32, 47, 32, 65, 108, 116, 101, 114, 84, 121, 112, 101, 10, 65, 100, 100, + 79, 114, 68, 114, 111, 112, 68, 101, 102, 97, 117, 108, 116, 32, 60, 45, 32, 65, 100, 100, + 68, 101, 102, 97, 117, 108, 116, 32, 47, 32, 68, 114, 111, 112, 68, 101, 102, 97, 117, 108, + 116, 10, 65, 100, 100, 68, 101, 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 83, 69, 84, + 39, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 68, 114, 111, 112, 68, 101, 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, + 82, 79, 80, 39, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 10, 67, 104, 97, 110, 103, + 101, 78, 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, 32, 60, 45, 32, 68, 114, 111, 112, + 79, 114, 83, 101, 116, 32, 39, 78, 79, 84, 39, 32, 39, 78, 85, 76, 76, 39, 10, 68, + 114, 111, 112, 79, 114, 83, 101, 116, 32, 60, 45, 32, 68, 114, 111, 112, 78, 117, 108, 108, + 97, 98, 105, 108, 105, 116, 121, 32, 47, 32, 83, 101, 116, 78, 117, 108, 108, 97, 98, 105, + 108, 105, 116, 121, 10, 68, 114, 111, 112, 78, 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, + 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 10, 83, 101, 116, 78, 117, 108, 108, 97, 98, + 105, 108, 105, 116, 121, 32, 60, 45, 32, 39, 83, 69, 84, 39, 10, 65, 108, 116, 101, 114, + 84, 121, 112, 101, 32, 60, 45, 32, 83, 101, 116, 68, 97, 116, 97, 63, 32, 39, 84, 89, + 80, 69, 39, 32, 84, 121, 112, 101, 63, 32, 85, 115, 105, 110, 103, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 63, 10, 83, 101, 116, 68, 97, 116, 97, 32, 60, 45, 32, 39, 83, + 69, 84, 39, 32, 39, 68, 65, 84, 65, 39, 63, 10, 85, 115, 105, 110, 103, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 108, 116, 101, 114, 86, 105, 101, 119, 83, + 116, 109, 116, 32, 60, 45, 32, 39, 86, 73, 69, 87, 39, 32, 73, 102, 69, 120, 105, 115, + 116, 115, 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 82, 101, + 110, 97, 109, 101, 65, 108, 116, 101, 114, 10, 65, 108, 116, 101, 114, 83, 101, 113, 117, 101, + 110, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 69, 81, 85, 69, 78, 67, 69, + 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, + 100, 83, 101, 113, 117, 101, 110, 99, 101, 78, 97, 109, 101, 32, 65, 108, 116, 101, 114, 83, + 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 115, 10, 81, 117, 97, 108, 105, + 102, 105, 101, 100, 83, 101, 113, 117, 101, 110, 99, 101, 78, 97, 109, 101, 32, 60, 45, 32, + 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, + 63, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, + 110, 63, 32, 83, 101, 113, 117, 101, 110, 99, 101, 78, 97, 109, 101, 10, 65, 108, 116, 101, + 114, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, + 82, 101, 110, 97, 109, 101, 65, 108, 116, 101, 114, 83, 101, 113, 117, 101, 110, 99, 101, 79, + 112, 116, 105, 111, 110, 115, 32, 47, 32, 83, 101, 116, 83, 101, 113, 117, 101, 110, 99, 101, + 79, 112, 116, 105, 111, 110, 10, 82, 101, 110, 97, 109, 101, 65, 108, 116, 101, 114, 83, 101, + 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 82, 101, 110, + 97, 109, 101, 65, 108, 116, 101, 114, 10, 83, 101, 116, 83, 101, 113, 117, 101, 110, 99, 101, + 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, + 116, 105, 111, 110, 43, 10, 65, 108, 116, 101, 114, 68, 97, 116, 97, 98, 97, 115, 101, 83, + 116, 109, 116, 32, 60, 45, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 39, 32, 73, 102, + 69, 120, 105, 115, 116, 115, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, + 83, 69, 84, 39, 32, 39, 65, 76, 73, 65, 83, 39, 32, 39, 84, 79, 39, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 10, 65, 110, 97, 108, 121, 122, 101, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, + 111, 114, 100, 32, 65, 110, 97, 108, 121, 122, 101, 86, 101, 114, 98, 111, 115, 101, 63, 32, + 65, 110, 97, 108, 121, 122, 101, 84, 97, 114, 103, 101, 116, 63, 10, 65, 110, 97, 108, 121, + 122, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, + 101, 78, 97, 109, 101, 32, 78, 97, 109, 101, 76, 105, 115, 116, 63, 10, 65, 110, 97, 108, + 121, 122, 101, 86, 101, 114, 98, 111, 115, 101, 32, 60, 45, 32, 39, 86, 69, 82, 66, 79, + 83, 69, 39, 10, 65, 116, 116, 97, 99, 104, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 60, 45, 32, 39, 65, 84, 84, 65, 67, 72, 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, + 101, 63, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 68, 97, 116, 97, + 98, 97, 115, 101, 63, 32, 68, 97, 116, 97, 98, 97, 115, 101, 80, 97, 116, 104, 32, 65, + 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 65, 116, 116, 97, 99, 104, 79, 112, + 116, 105, 111, 110, 115, 63, 10, 68, 97, 116, 97, 98, 97, 115, 101, 32, 60, 45, 32, 39, + 68, 65, 84, 65, 66, 65, 83, 69, 39, 10, 68, 97, 116, 97, 98, 97, 115, 101, 80, 97, + 116, 104, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 116, + 97, 99, 104, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 67, 111, 108, + 73, 100, 10, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, + 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, + 116, 10, 67, 97, 108, 108, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, + 67, 65, 76, 76, 39, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, + 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 10, 67, 104, 101, 99, 107, 112, 111, 105, + 110, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 104, 101, 99, 107, + 112, 111, 105, 110, 116, 70, 111, 114, 99, 101, 63, 32, 39, 67, 72, 69, 67, 75, 80, 79, + 73, 78, 84, 39, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 63, 10, 67, 104, + 101, 99, 107, 112, 111, 105, 110, 116, 70, 111, 114, 99, 101, 32, 60, 45, 32, 39, 70, 79, + 82, 67, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 67, 79, 77, 77, 69, 78, 84, 39, 32, 39, 79, 78, 39, 32, + 67, 111, 109, 109, 101, 110, 116, 79, 110, 84, 121, 112, 101, 32, 67, 111, 109, 109, 101, 110, + 116, 84, 97, 114, 103, 101, 116, 32, 39, 73, 83, 39, 32, 67, 111, 109, 109, 101, 110, 116, + 86, 97, 108, 117, 101, 10, 67, 111, 109, 109, 101, 110, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, - 84, 121, 112, 101, 63, 32, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, - 110, 63, 32, 67, 111, 108, 117, 109, 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 42, - 10, 68, 114, 111, 112, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 68, 82, 79, 80, - 39, 32, 39, 67, 79, 76, 85, 77, 78, 39, 63, 32, 73, 102, 69, 120, 105, 115, 116, 115, - 63, 32, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 68, - 114, 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 63, 10, 65, 108, 116, 101, 114, 67, 111, - 108, 117, 109, 110, 32, 60, 45, 32, 39, 65, 76, 84, 69, 82, 39, 32, 39, 67, 79, 76, - 85, 77, 78, 39, 63, 32, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, - 109, 101, 32, 65, 108, 116, 101, 114, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 10, - 82, 101, 110, 97, 109, 101, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 82, 69, 78, - 65, 77, 69, 39, 32, 39, 67, 79, 76, 85, 77, 78, 39, 63, 32, 78, 101, 115, 116, 101, - 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 39, 84, 79, 39, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 10, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, - 78, 97, 109, 101, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 68, 111, - 116, 42, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 10, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 68, 111, 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, - 114, 32, 39, 46, 39, 10, 82, 101, 110, 97, 109, 101, 65, 108, 116, 101, 114, 32, 60, 45, - 32, 39, 82, 69, 78, 65, 77, 69, 39, 32, 39, 84, 79, 39, 32, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 10, 83, 101, 116, 80, 97, 114, 116, 105, 116, 105, 111, 110, 101, 100, - 66, 121, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 80, 65, 82, 84, 73, 84, 73, - 79, 78, 69, 68, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, - 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 82, 101, 115, 101, - 116, 80, 97, 114, 116, 105, 116, 105, 111, 110, 101, 100, 66, 121, 32, 60, 45, 32, 39, 82, - 69, 83, 69, 84, 39, 32, 39, 80, 65, 82, 84, 73, 84, 73, 79, 78, 69, 68, 39, 32, - 39, 66, 89, 39, 10, 83, 101, 116, 83, 111, 114, 116, 101, 100, 66, 121, 32, 60, 45, 32, - 39, 83, 69, 84, 39, 32, 39, 83, 79, 82, 84, 69, 68, 39, 32, 39, 66, 89, 39, 32, - 80, 97, 114, 101, 110, 115, 40, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 115, 41, 10, 82, 101, 115, 101, 116, 83, 111, 114, 116, 101, 100, 66, 121, - 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, 39, 32, 39, 83, 79, 82, 84, 69, 68, 39, - 32, 39, 66, 89, 39, 10, 83, 101, 116, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, - 39, 83, 69, 84, 39, 32, 82, 101, 108, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, - 82, 101, 115, 101, 116, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 82, 69, 83, - 69, 84, 39, 32, 82, 101, 108, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 65, 108, - 116, 101, 114, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 32, 60, 45, 32, 65, 100, - 100, 79, 114, 68, 114, 111, 112, 68, 101, 102, 97, 117, 108, 116, 32, 47, 32, 67, 104, 97, - 110, 103, 101, 78, 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, 32, 47, 32, 65, 108, 116, - 101, 114, 84, 121, 112, 101, 10, 65, 100, 100, 79, 114, 68, 114, 111, 112, 68, 101, 102, 97, - 117, 108, 116, 32, 60, 45, 32, 65, 100, 100, 68, 101, 102, 97, 117, 108, 116, 32, 47, 32, - 68, 114, 111, 112, 68, 101, 102, 97, 117, 108, 116, 10, 65, 100, 100, 68, 101, 102, 97, 117, - 108, 116, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 68, 69, 70, 65, 85, 76, 84, - 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 114, 111, 112, 68, 101, 102, - 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 39, 68, 69, 70, 65, - 85, 76, 84, 39, 10, 67, 104, 97, 110, 103, 101, 78, 117, 108, 108, 97, 98, 105, 108, 105, - 116, 121, 32, 60, 45, 32, 68, 114, 111, 112, 79, 114, 83, 101, 116, 32, 39, 78, 79, 84, - 39, 32, 39, 78, 85, 76, 76, 39, 10, 68, 114, 111, 112, 79, 114, 83, 101, 116, 32, 60, - 45, 32, 68, 114, 111, 112, 78, 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, 32, 47, 32, - 83, 101, 116, 78, 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, 10, 68, 114, 111, 112, 78, - 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, - 10, 83, 101, 116, 78, 117, 108, 108, 97, 98, 105, 108, 105, 116, 121, 32, 60, 45, 32, 39, - 83, 69, 84, 39, 10, 65, 108, 116, 101, 114, 84, 121, 112, 101, 32, 60, 45, 32, 83, 101, - 116, 68, 97, 116, 97, 63, 32, 39, 84, 89, 80, 69, 39, 32, 84, 121, 112, 101, 63, 32, - 85, 115, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 83, 101, 116, - 68, 97, 116, 97, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 68, 65, 84, 65, 39, - 63, 10, 85, 115, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, - 32, 39, 85, 83, 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, - 65, 108, 116, 101, 114, 86, 105, 101, 119, 83, 116, 109, 116, 32, 60, 45, 32, 39, 86, 73, - 69, 87, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 66, 97, 115, 101, 84, 97, - 98, 108, 101, 78, 97, 109, 101, 32, 82, 101, 110, 97, 109, 101, 65, 108, 116, 101, 114, 10, - 65, 108, 116, 101, 114, 83, 101, 113, 117, 101, 110, 99, 101, 83, 116, 109, 116, 32, 60, 45, - 32, 39, 83, 69, 81, 85, 69, 78, 67, 69, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, - 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 83, 101, 113, 117, 101, 110, 99, 101, 78, - 97, 109, 101, 32, 65, 108, 116, 101, 114, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, - 105, 111, 110, 115, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 83, 101, 113, 117, 101, 110, - 99, 101, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, - 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, 32, 83, 99, 104, 101, 109, 97, 81, 117, - 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, 32, 83, 101, 113, 117, 101, 110, 99, - 101, 78, 97, 109, 101, 10, 65, 108, 116, 101, 114, 83, 101, 113, 117, 101, 110, 99, 101, 79, - 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 82, 101, 110, 97, 109, 101, 65, 108, 116, 101, - 114, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 115, 32, 47, 32, 83, - 101, 116, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 10, 82, 101, 110, - 97, 109, 101, 65, 108, 116, 101, 114, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, - 111, 110, 115, 32, 60, 45, 32, 82, 101, 110, 97, 109, 101, 65, 108, 116, 101, 114, 10, 83, - 101, 116, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, - 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 43, 10, 65, 108, 116, 101, - 114, 68, 97, 116, 97, 98, 97, 115, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 65, - 84, 65, 66, 65, 83, 69, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 83, 69, 84, 39, 32, 39, 65, 76, 73, 65, - 83, 39, 32, 39, 84, 79, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 65, - 110, 97, 108, 121, 122, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 65, - 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 32, 65, 110, 97, 108, 121, 122, - 101, 86, 101, 114, 98, 111, 115, 101, 63, 32, 65, 110, 97, 108, 121, 122, 101, 84, 97, 114, - 103, 101, 116, 63, 10, 65, 110, 97, 108, 121, 122, 101, 84, 97, 114, 103, 101, 116, 32, 60, - 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 78, 97, 109, 101, - 76, 105, 115, 116, 63, 10, 65, 110, 97, 108, 121, 122, 101, 86, 101, 114, 98, 111, 115, 101, - 32, 60, 45, 32, 39, 86, 69, 82, 66, 79, 83, 69, 39, 10, 65, 116, 116, 97, 99, 104, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 65, 84, 84, 65, 67, 72, - 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, 101, 63, 32, 73, 102, 78, 111, 116, 69, 120, - 105, 115, 116, 115, 63, 32, 68, 97, 116, 97, 98, 97, 115, 101, 63, 32, 68, 97, 116, 97, - 98, 97, 115, 101, 80, 97, 116, 104, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, - 63, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 68, 97, 116, - 97, 98, 97, 115, 101, 32, 60, 45, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 39, 10, - 68, 97, 116, 97, 98, 97, 115, 101, 80, 97, 116, 104, 32, 60, 45, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 32, 60, - 45, 32, 39, 65, 83, 39, 32, 67, 111, 108, 73, 100, 10, 65, 116, 116, 97, 99, 104, 79, - 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, - 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 67, 97, 108, 108, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 67, 65, 76, 76, 39, 32, 81, 117, 97, 108, - 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, - 115, 10, 67, 104, 101, 99, 107, 112, 111, 105, 110, 116, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 67, 104, 101, 99, 107, 112, 111, 105, 110, 116, 70, 111, 114, 99, 101, - 63, 32, 39, 67, 72, 69, 67, 75, 80, 79, 73, 78, 84, 39, 32, 67, 97, 116, 97, 108, - 111, 103, 78, 97, 109, 101, 63, 10, 67, 104, 101, 99, 107, 112, 111, 105, 110, 116, 70, 111, - 114, 99, 101, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 10, 67, 111, 109, 109, 101, - 110, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 67, 79, 77, 77, - 69, 78, 84, 39, 32, 39, 79, 78, 39, 32, 67, 111, 109, 109, 101, 110, 116, 79, 110, 84, - 121, 112, 101, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 32, 39, 73, 83, 39, 32, 67, 111, 109, 109, 101, 110, 116, 86, 97, 108, 117, 101, 10, 67, - 111, 109, 109, 101, 110, 116, 79, 110, 84, 121, 112, 101, 32, 60, 45, 32, 32, 32, 32, 67, - 111, 109, 109, 101, 110, 116, 84, 97, 98, 108, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, - 116, 83, 101, 113, 117, 101, 110, 99, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 70, - 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, - 114, 111, 84, 97, 98, 108, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, - 114, 111, 32, 47, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 67, 111, 109, 109, 101, 110, 116, 86, 105, 101, 119, 32, 47, 32, 67, - 111, 109, 109, 101, 110, 116, 68, 97, 116, 97, 98, 97, 115, 101, 32, 47, 32, 67, 111, 109, - 109, 101, 110, 116, 73, 110, 100, 101, 120, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 83, - 99, 104, 101, 109, 97, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 84, 121, 112, 101, 32, - 47, 32, 67, 111, 109, 109, 101, 110, 116, 67, 111, 108, 117, 109, 110, 10, 67, 111, 109, 109, - 101, 110, 116, 84, 97, 98, 108, 101, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 10, - 67, 111, 109, 109, 101, 110, 116, 83, 101, 113, 117, 101, 110, 99, 101, 32, 60, 45, 32, 39, - 83, 69, 81, 85, 69, 78, 67, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, 70, 117, 110, - 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 70, 85, 78, 67, 84, 73, 79, 78, 39, 10, - 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, 114, 111, 84, 97, 98, 108, 101, 32, 60, 45, - 32, 39, 77, 65, 67, 82, 79, 39, 32, 39, 84, 65, 66, 76, 69, 39, 10, 67, 111, 109, - 109, 101, 110, 116, 77, 97, 99, 114, 111, 32, 60, 45, 32, 39, 77, 65, 67, 82, 79, 39, - 10, 67, 111, 109, 109, 101, 110, 116, 86, 105, 101, 119, 32, 60, 45, 32, 39, 86, 73, 69, - 87, 39, 10, 67, 111, 109, 109, 101, 110, 116, 68, 97, 116, 97, 98, 97, 115, 101, 32, 60, - 45, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, - 73, 110, 100, 101, 120, 32, 60, 45, 32, 39, 73, 78, 68, 69, 88, 39, 10, 67, 111, 109, - 109, 101, 110, 116, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, 39, 83, 67, 72, 69, 77, - 65, 39, 10, 67, 111, 109, 109, 101, 110, 116, 84, 121, 112, 101, 32, 60, 45, 32, 39, 84, - 89, 80, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, 67, 111, 108, 117, 109, 110, 32, 60, - 45, 32, 39, 67, 79, 76, 85, 77, 78, 39, 10, 67, 111, 109, 109, 101, 110, 116, 86, 97, - 108, 117, 101, 32, 60, 45, 32, 78, 117, 108, 108, 76, 105, 116, 101, 114, 97, 108, 32, 47, - 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 10, - 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 32, 60, - 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 110, 110, - 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 67, 79, 78, - 78, 69, 67, 84, 39, 32, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 63, - 10, 68, 105, 115, 99, 111, 110, 110, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 60, 45, 32, 39, 68, 73, 83, 67, 79, 78, 78, 69, 67, 84, 39, 10, 83, 101, 115, - 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, - 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 47, 32, 83, 116, 114, 105, 110, - 103, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 47, 32, 67, 97, 116, - 97, 108, 111, 103, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 10, 76, 111, - 99, 97, 108, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, - 39, 76, 79, 67, 65, 76, 39, 10, 83, 116, 114, 105, 110, 103, 83, 101, 115, 115, 105, 111, - 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, - 101, 114, 97, 108, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, - 111, 110, 76, 105, 115, 116, 63, 10, 67, 97, 116, 97, 108, 111, 103, 83, 101, 115, 115, 105, - 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, - 97, 109, 101, 10, 67, 111, 112, 121, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, - 32, 39, 67, 79, 80, 89, 39, 32, 67, 111, 112, 121, 86, 97, 114, 105, 97, 116, 105, 111, - 110, 115, 10, 67, 111, 112, 121, 86, 97, 114, 105, 97, 116, 105, 111, 110, 115, 32, 60, 45, - 32, 67, 111, 112, 121, 84, 97, 98, 108, 101, 32, 47, 32, 67, 111, 112, 121, 83, 101, 108, - 101, 99, 116, 32, 47, 32, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, - 115, 101, 10, 67, 111, 112, 121, 84, 97, 98, 108, 101, 32, 60, 45, 32, 66, 97, 115, 101, - 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, - 109, 110, 76, 105, 115, 116, 63, 32, 70, 114, 111, 109, 79, 114, 84, 111, 32, 67, 111, 112, - 121, 70, 105, 108, 101, 78, 97, 109, 101, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, - 115, 63, 10, 70, 114, 111, 109, 79, 114, 84, 111, 32, 60, 45, 32, 67, 111, 112, 121, 70, - 114, 111, 109, 32, 47, 32, 67, 111, 112, 121, 84, 111, 10, 67, 111, 112, 121, 70, 114, 111, - 109, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 10, 67, 111, 112, 121, 84, 111, 32, 60, - 45, 32, 39, 84, 79, 39, 10, 67, 111, 112, 121, 83, 101, 108, 101, 99, 116, 32, 60, 45, - 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 32, 39, 84, 79, 39, 32, 67, 111, - 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, - 110, 115, 63, 10, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, - 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 47, 32, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 67, 111, 112, 121, 70, 105, 108, - 101, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 67, 111, - 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 67, 111, 108, 73, 100, 10, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 97, 114, 97, 109, 101, 116, 101, - 114, 32, 47, 32, 80, 97, 114, 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 10, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, - 114, 97, 108, 10, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 73, 100, 101, 110, - 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 10, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 67, 111, 108, 73, 100, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 67, 111, 108, 73, 100, 10, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 67, 111, - 108, 73, 100, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 46, - 39, 32, 67, 111, 108, 73, 100, 10, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 115, 32, - 60, 45, 32, 39, 87, 73, 84, 72, 39, 63, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, - 110, 76, 105, 115, 116, 10, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, - 32, 60, 45, 32, 67, 111, 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, 112, 116, 105, 111, - 110, 76, 105, 115, 116, 32, 47, 32, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, - 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, - 100, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 83, 112, 101, 99, 105, - 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, 110, 32, 83, 112, 101, 99, 105, 97, 108, - 105, 122, 101, 100, 79, 112, 116, 105, 111, 110, 84, 97, 105, 108, 42, 10, 83, 112, 101, 99, - 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, - 32, 39, 44, 39, 63, 32, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, - 105, 111, 110, 10, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, - 110, 32, 60, 45, 32, 83, 105, 110, 103, 108, 101, 79, 112, 116, 105, 111, 110, 32, 47, 32, - 78, 117, 108, 108, 65, 115, 79, 112, 116, 105, 111, 110, 32, 47, 32, 68, 101, 108, 105, 109, - 105, 116, 101, 114, 65, 115, 79, 112, 116, 105, 111, 110, 32, 47, 32, 69, 115, 99, 97, 112, - 101, 65, 115, 79, 112, 116, 105, 111, 110, 32, 47, 10, 9, 69, 110, 99, 111, 100, 105, 110, - 103, 79, 112, 116, 105, 111, 110, 32, 47, 32, 81, 117, 111, 116, 101, 65, 115, 79, 112, 116, - 105, 111, 110, 32, 47, 32, 70, 111, 114, 99, 101, 81, 117, 111, 116, 101, 79, 112, 116, 105, - 111, 110, 32, 47, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 79, 112, 116, 105, - 111, 110, 32, 47, 32, 70, 111, 114, 99, 101, 78, 117, 108, 108, 79, 112, 116, 105, 111, 110, - 10, 83, 105, 110, 103, 108, 101, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 66, 105, 110, - 97, 114, 121, 79, 112, 116, 105, 111, 110, 32, 47, 32, 70, 114, 101, 101, 122, 101, 79, 112, - 116, 105, 111, 110, 32, 47, 32, 79, 105, 100, 115, 79, 112, 116, 105, 111, 110, 32, 47, 32, - 67, 115, 118, 79, 112, 116, 105, 111, 110, 32, 47, 32, 72, 101, 97, 100, 101, 114, 79, 112, - 116, 105, 111, 110, 10, 66, 105, 110, 97, 114, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, - 32, 39, 66, 73, 78, 65, 82, 89, 39, 10, 70, 114, 101, 101, 122, 101, 79, 112, 116, 105, - 111, 110, 32, 60, 45, 32, 39, 70, 82, 69, 69, 90, 69, 39, 10, 79, 105, 100, 115, 79, - 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 73, 68, 83, 39, 10, 67, 115, 118, 79, - 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 67, 83, 86, 39, 10, 72, 101, 97, 100, 101, - 114, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 72, 69, 65, 68, 69, 82, 39, 10, - 78, 117, 108, 108, 65, 115, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 78, 85, 76, - 76, 39, 32, 39, 65, 83, 39, 63, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 10, 68, 101, 108, 105, 109, 105, 116, 101, 114, 65, 115, 79, 112, 116, 105, 111, 110, - 32, 60, 45, 32, 39, 68, 69, 76, 73, 77, 73, 84, 69, 82, 39, 32, 39, 65, 83, 39, - 63, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 81, 117, 111, 116, - 101, 65, 115, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 81, 85, 79, 84, 69, 39, - 32, 39, 65, 83, 39, 63, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, - 10, 69, 115, 99, 97, 112, 101, 65, 115, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, - 69, 83, 67, 65, 80, 69, 39, 32, 39, 65, 83, 39, 63, 32, 83, 116, 114, 105, 110, 103, - 76, 105, 116, 101, 114, 97, 108, 10, 69, 110, 99, 111, 100, 105, 110, 103, 79, 112, 116, 105, - 111, 110, 32, 60, 45, 32, 39, 69, 78, 67, 79, 68, 73, 78, 71, 39, 32, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 70, 111, 114, 99, 101, 81, 117, 111, 116, - 101, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 70, 111, 114, 99, 101, 81, 117, 111, 116, - 101, 63, 32, 39, 81, 85, 79, 84, 69, 39, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, - 108, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 83, 116, 97, 114, 83, 121, 109, 98, - 111, 108, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 83, 116, 97, 114, - 83, 121, 109, 98, 111, 108, 32, 47, 32, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, - 70, 111, 114, 99, 101, 81, 117, 111, 116, 101, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, - 39, 10, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 79, 112, 116, 105, 111, 110, 32, - 60, 45, 32, 40, 39, 80, 65, 82, 84, 73, 84, 73, 79, 78, 39, 32, 47, 32, 39, 80, - 65, 82, 84, 73, 84, 73, 79, 78, 69, 68, 39, 41, 32, 39, 66, 89, 39, 32, 80, 97, - 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, + 47, 32, 67, 111, 109, 109, 101, 110, 116, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, + 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 109, 109, 101, 110, 116, + 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 109, 109, 101, 110, 116, 79, 110, + 84, 121, 112, 101, 32, 60, 45, 32, 32, 32, 32, 67, 111, 109, 109, 101, 110, 116, 84, 97, + 98, 108, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 83, 101, 113, 117, 101, 110, 99, + 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 70, 117, 110, 99, 116, 105, 111, 110, 32, + 47, 32, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, 114, 111, 84, 97, 98, 108, 101, 32, + 47, 32, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, 114, 111, 32, 47, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, + 109, 101, 110, 116, 86, 105, 101, 119, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 68, 97, + 116, 97, 98, 97, 115, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 73, 110, 100, 101, + 120, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 83, 99, 104, 101, 109, 97, 32, 47, 32, + 67, 111, 109, 109, 101, 110, 116, 84, 121, 112, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, + 116, 67, 111, 108, 117, 109, 110, 10, 67, 111, 109, 109, 101, 110, 116, 84, 97, 98, 108, 101, + 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, 83, + 101, 113, 117, 101, 110, 99, 101, 32, 60, 45, 32, 39, 83, 69, 81, 85, 69, 78, 67, 69, + 39, 10, 67, 111, 109, 109, 101, 110, 116, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, + 32, 39, 70, 85, 78, 67, 84, 73, 79, 78, 39, 10, 67, 111, 109, 109, 101, 110, 116, 77, + 97, 99, 114, 111, 84, 97, 98, 108, 101, 32, 60, 45, 32, 39, 77, 65, 67, 82, 79, 39, + 32, 39, 84, 65, 66, 76, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, 114, + 111, 32, 60, 45, 32, 39, 77, 65, 67, 82, 79, 39, 10, 67, 111, 109, 109, 101, 110, 116, + 86, 105, 101, 119, 32, 60, 45, 32, 39, 86, 73, 69, 87, 39, 10, 67, 111, 109, 109, 101, + 110, 116, 68, 97, 116, 97, 98, 97, 115, 101, 32, 60, 45, 32, 39, 68, 65, 84, 65, 66, + 65, 83, 69, 39, 10, 67, 111, 109, 109, 101, 110, 116, 73, 110, 100, 101, 120, 32, 60, 45, + 32, 39, 73, 78, 68, 69, 88, 39, 10, 67, 111, 109, 109, 101, 110, 116, 83, 99, 104, 101, + 109, 97, 32, 60, 45, 32, 39, 83, 67, 72, 69, 77, 65, 39, 10, 67, 111, 109, 109, 101, + 110, 116, 84, 121, 112, 101, 32, 60, 45, 32, 39, 84, 89, 80, 69, 39, 10, 67, 111, 109, + 109, 101, 110, 116, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 67, 79, 76, 85, 77, + 78, 39, 10, 67, 111, 109, 109, 101, 110, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 78, + 117, 108, 108, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, + 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 10, 83, 116, 114, 105, 110, 103, 76, 105, + 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, + 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 110, 110, 101, 99, 116, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 32, 60, 45, 32, 39, 67, 79, 78, 78, 69, 67, 84, 39, 32, 83, 101, + 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 63, 10, 68, 105, 115, 99, 111, 110, 110, + 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 68, 73, 83, + 67, 79, 78, 78, 69, 67, 84, 39, 10, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, + 101, 116, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, 101, 115, 115, 105, 111, 110, 84, 97, + 114, 103, 101, 116, 32, 47, 32, 83, 116, 114, 105, 110, 103, 83, 101, 115, 115, 105, 111, 110, + 84, 97, 114, 103, 101, 116, 32, 47, 32, 67, 97, 116, 97, 108, 111, 103, 83, 101, 115, 115, + 105, 111, 110, 84, 97, 114, 103, 101, 116, 10, 76, 111, 99, 97, 108, 83, 101, 115, 115, 105, + 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, + 83, 116, 114, 105, 110, 103, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, + 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 71, 101, 110, + 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, + 67, 97, 116, 97, 108, 111, 103, 83, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, + 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 10, 67, 111, 112, 121, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 67, 79, 80, 89, 39, 32, + 67, 111, 112, 121, 86, 97, 114, 105, 97, 116, 105, 111, 110, 115, 10, 67, 111, 112, 121, 86, + 97, 114, 105, 97, 116, 105, 111, 110, 115, 32, 60, 45, 32, 67, 111, 112, 121, 84, 97, 98, + 108, 101, 32, 47, 32, 67, 111, 112, 121, 83, 101, 108, 101, 99, 116, 32, 47, 32, 67, 111, + 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, 115, 101, 10, 67, 111, 112, 121, 84, + 97, 98, 108, 101, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, + 101, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, + 70, 114, 111, 109, 79, 114, 84, 111, 32, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, + 101, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 115, 63, 10, 70, 114, 111, 109, 79, + 114, 84, 111, 32, 60, 45, 32, 67, 111, 112, 121, 70, 114, 111, 109, 32, 47, 32, 67, 111, + 112, 121, 84, 111, 10, 67, 111, 112, 121, 70, 114, 111, 109, 32, 60, 45, 32, 39, 70, 82, + 79, 77, 39, 10, 67, 111, 112, 121, 84, 111, 32, 60, 45, 32, 39, 84, 79, 39, 10, 67, + 111, 112, 121, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, + 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, + 110, 97, 108, 41, 32, 39, 84, 79, 39, 32, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, + 109, 101, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 115, 63, 10, 67, 111, 112, 121, + 70, 105, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 67, 111, 112, 121, 70, 105, 108, 101, + 78, 97, 109, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 67, 111, 112, + 121, 70, 105, 108, 101, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, + 97, 108, 32, 47, 32, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 67, 111, 108, 73, 100, 32, 47, 32, 67, 111, 112, 121, 70, + 105, 108, 101, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, + 112, 121, 70, 105, 108, 101, 78, 97, 109, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, 80, 97, 114, 101, + 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 112, 121, 70, 105, 108, + 101, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, + 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 112, 121, + 70, 105, 108, 101, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, + 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 112, 121, 70, 105, 108, + 101, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 67, 111, 108, 73, 100, + 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 67, 111, 108, 73, 100, 10, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 67, 111, 108, 73, 100, 32, 60, 45, 32, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, + 109, 101, 83, 117, 102, 102, 105, 120, 43, 10, 67, 111, 112, 121, 70, 105, 108, 101, 78, 97, + 109, 101, 83, 117, 102, 102, 105, 120, 32, 60, 45, 32, 39, 46, 39, 32, 67, 111, 108, 73, + 100, 10, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 87, 73, + 84, 72, 39, 63, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, + 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 67, 111, + 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, + 47, 32, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, 110, 76, + 105, 115, 116, 10, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, + 110, 76, 105, 115, 116, 32, 60, 45, 32, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, + 79, 112, 116, 105, 111, 110, 32, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, + 116, 105, 111, 110, 84, 97, 105, 108, 42, 10, 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, + 100, 79, 112, 116, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 39, 44, 39, 63, 32, + 83, 112, 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, 110, 10, 83, 112, + 101, 99, 105, 97, 108, 105, 122, 101, 100, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 83, + 105, 110, 103, 108, 101, 79, 112, 116, 105, 111, 110, 32, 47, 32, 78, 117, 108, 108, 65, 115, + 79, 112, 116, 105, 111, 110, 32, 47, 32, 68, 101, 108, 105, 109, 105, 116, 101, 114, 65, 115, + 79, 112, 116, 105, 111, 110, 32, 47, 32, 69, 115, 99, 97, 112, 101, 65, 115, 79, 112, 116, + 105, 111, 110, 32, 47, 10, 9, 69, 110, 99, 111, 100, 105, 110, 103, 79, 112, 116, 105, 111, + 110, 32, 47, 32, 81, 117, 111, 116, 101, 65, 115, 79, 112, 116, 105, 111, 110, 32, 47, 32, + 70, 111, 114, 99, 101, 81, 117, 111, 116, 101, 79, 112, 116, 105, 111, 110, 32, 47, 32, 80, + 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 79, 112, 116, 105, 111, 110, 32, 47, 32, 70, + 111, 114, 99, 101, 78, 117, 108, 108, 79, 112, 116, 105, 111, 110, 10, 83, 105, 110, 103, 108, + 101, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 66, 105, 110, 97, 114, 121, 79, 112, 116, + 105, 111, 110, 32, 47, 32, 70, 114, 101, 101, 122, 101, 79, 112, 116, 105, 111, 110, 32, 47, + 32, 79, 105, 100, 115, 79, 112, 116, 105, 111, 110, 32, 47, 32, 67, 115, 118, 79, 112, 116, + 105, 111, 110, 32, 47, 32, 72, 101, 97, 100, 101, 114, 79, 112, 116, 105, 111, 110, 10, 66, + 105, 110, 97, 114, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 66, 73, 78, 65, + 82, 89, 39, 10, 70, 114, 101, 101, 122, 101, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, + 39, 70, 82, 69, 69, 90, 69, 39, 10, 79, 105, 100, 115, 79, 112, 116, 105, 111, 110, 32, + 60, 45, 32, 39, 79, 73, 68, 83, 39, 10, 67, 115, 118, 79, 112, 116, 105, 111, 110, 32, + 60, 45, 32, 39, 67, 83, 86, 39, 10, 72, 101, 97, 100, 101, 114, 79, 112, 116, 105, 111, + 110, 32, 60, 45, 32, 39, 72, 69, 65, 68, 69, 82, 39, 10, 78, 117, 108, 108, 65, 115, + 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 78, 85, 76, 76, 39, 32, 39, 65, 83, + 39, 63, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 68, 101, 108, + 105, 109, 105, 116, 101, 114, 65, 115, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 68, + 69, 76, 73, 77, 73, 84, 69, 82, 39, 32, 39, 65, 83, 39, 63, 32, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 81, 117, 111, 116, 101, 65, 115, 79, 112, 116, + 105, 111, 110, 32, 60, 45, 32, 39, 81, 85, 79, 84, 69, 39, 32, 39, 65, 83, 39, 63, + 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 115, 99, 97, 112, + 101, 65, 115, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 69, 83, 67, 65, 80, 69, + 39, 32, 39, 65, 83, 39, 63, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, + 108, 10, 69, 110, 99, 111, 100, 105, 110, 103, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, + 39, 69, 78, 67, 79, 68, 73, 78, 71, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, + 101, 114, 97, 108, 10, 70, 111, 114, 99, 101, 81, 117, 111, 116, 101, 79, 112, 116, 105, 111, + 110, 32, 60, 45, 32, 70, 111, 114, 99, 101, 81, 117, 111, 116, 101, 63, 32, 39, 81, 85, + 79, 84, 69, 39, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 67, 111, 108, 117, 109, + 110, 76, 105, 115, 116, 10, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 67, 111, 108, 117, + 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, + 32, 47, 32, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 70, 111, 114, 99, 101, 81, + 117, 111, 116, 101, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 10, 80, 97, 114, 116, + 105, 116, 105, 111, 110, 66, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 40, 39, 80, + 65, 82, 84, 73, 84, 73, 79, 78, 39, 32, 47, 32, 39, 80, 65, 82, 84, 73, 84, 73, + 79, 78, 69, 68, 39, 41, 32, 39, 66, 89, 39, 32, 80, 97, 114, 116, 105, 116, 105, 111, + 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 80, 97, 114, 116, 105, 116, + 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 83, + 116, 97, 114, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, + 76, 105, 115, 116, 32, 47, 32, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, - 116, 32, 60, 45, 32, 83, 116, 97, 114, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, - 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 47, 32, 80, 97, 114, 101, 110, 116, 104, - 101, 115, 105, 122, 101, 100, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, - 117, 109, 110, 76, 105, 115, 116, 32, 47, 32, 83, 105, 110, 103, 108, 101, 80, 97, 114, 116, - 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 83, 116, - 97, 114, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, - 105, 115, 116, 32, 60, 45, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 10, 80, 97, - 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 80, 97, 114, 116, 105, 116, 105, 111, 110, - 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, 10, 83, 105, 110, 103, 108, - 101, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, - 115, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 70, 111, 114, 99, 101, 78, 117, 108, - 108, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 32, 70, - 111, 114, 99, 101, 78, 111, 116, 78, 117, 108, 108, 63, 32, 39, 78, 85, 76, 76, 39, 32, - 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 70, 111, 114, 99, 101, 78, 111, 116, 78, - 117, 108, 108, 32, 60, 45, 32, 39, 78, 79, 84, 39, 10, 83, 116, 97, 114, 83, 121, 109, - 98, 111, 108, 32, 60, 45, 32, 39, 42, 39, 10, 67, 111, 112, 121, 71, 101, 110, 101, 114, - 105, 99, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, - 112, 116, 105, 111, 110, 41, 41, 10, 67, 111, 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, - 112, 116, 105, 111, 110, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 67, 111, 112, 121, - 79, 112, 116, 105, 111, 110, 32, 47, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 101, 100, - 66, 121, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 32, 47, 32, 71, 101, 110, 101, 114, - 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 10, 79, 114, 100, 101, 114, 66, 121, - 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 82, 68, 69, 82, - 39, 32, 39, 66, 89, 39, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, - 116, 105, 111, 110, 86, 97, 108, 117, 101, 63, 10, 80, 97, 114, 116, 105, 116, 105, 111, 110, - 101, 100, 66, 121, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 40, 39, - 80, 65, 82, 84, 73, 84, 73, 79, 78, 39, 32, 47, 32, 39, 80, 65, 82, 84, 73, 84, - 73, 79, 78, 69, 68, 39, 41, 32, 39, 66, 89, 39, 32, 71, 101, 110, 101, 114, 105, 99, - 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 86, 97, 108, 117, 101, 63, 10, 71, 101, 110, - 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 71, 101, 110, 101, 114, 105, - 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 41, 41, 10, 71, 101, 110, 101, 114, 105, - 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 67, 111, 112, 121, 79, - 112, 116, 105, 111, 110, 78, 97, 109, 101, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, - 121, 79, 112, 116, 105, 111, 110, 86, 97, 108, 117, 101, 63, 10, 71, 101, 110, 101, 114, 105, - 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 86, 97, 108, 117, 101, 32, 60, 45, 32, - 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 79, 114, 100, - 101, 114, 76, 105, 115, 116, 32, 47, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, - 79, 112, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 101, 110, - 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 79, 114, 100, 101, 114, 76, - 105, 115, 116, 32, 60, 45, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, - 116, 105, 111, 110, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 71, 101, 110, 101, 114, 105, 99, 67, - 111, 112, 121, 79, 112, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 101, 110, 101, 114, 105, - 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 80, 97, 114, 101, 110, 116, 104, 101, 115, - 105, 122, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 41, 10, 67, 111, 112, 121, 70, 114, 111, 109, - 68, 97, 116, 97, 98, 97, 115, 101, 32, 60, 45, 32, 67, 111, 112, 121, 70, 114, 111, 109, - 68, 97, 116, 97, 98, 97, 115, 101, 87, 105, 116, 104, 70, 108, 97, 103, 32, 47, 32, 67, - 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, 115, 101, 87, 105, 116, 104, 111, - 117, 116, 70, 108, 97, 103, 10, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, - 97, 115, 101, 87, 105, 116, 104, 70, 108, 97, 103, 32, 60, 45, 32, 39, 70, 82, 79, 77, - 39, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 39, 32, 67, 111, 108, 73, 100, 32, 39, - 84, 79, 39, 32, 67, 111, 108, 73, 100, 32, 67, 111, 112, 121, 68, 97, 116, 97, 98, 97, - 115, 101, 70, 108, 97, 103, 10, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, - 97, 115, 101, 87, 105, 116, 104, 111, 117, 116, 70, 108, 97, 103, 32, 60, 45, 32, 39, 70, - 82, 79, 77, 39, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 39, 32, 67, 111, 108, 73, - 100, 32, 39, 84, 79, 39, 32, 67, 111, 108, 73, 100, 10, 67, 111, 112, 121, 68, 97, 116, - 97, 98, 97, 115, 101, 70, 108, 97, 103, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, - 83, 99, 104, 101, 109, 97, 79, 114, 68, 97, 116, 97, 41, 10, 83, 99, 104, 101, 109, 97, - 79, 114, 68, 97, 116, 97, 32, 60, 45, 32, 67, 111, 112, 121, 83, 99, 104, 101, 109, 97, - 32, 47, 32, 67, 111, 112, 121, 68, 97, 116, 97, 10, 67, 111, 112, 121, 83, 99, 104, 101, - 109, 97, 32, 60, 45, 32, 39, 83, 67, 72, 69, 77, 65, 39, 10, 67, 111, 112, 121, 68, - 97, 116, 97, 32, 60, 45, 32, 39, 68, 65, 84, 65, 39, 10, 67, 114, 101, 97, 116, 101, - 73, 110, 100, 101, 120, 83, 116, 109, 116, 32, 60, 45, 32, 85, 110, 105, 113, 117, 101, 73, - 110, 100, 101, 120, 63, 32, 39, 73, 78, 68, 69, 88, 39, 32, 73, 102, 78, 111, 116, 69, - 120, 105, 115, 116, 115, 63, 32, 73, 110, 100, 101, 120, 78, 97, 109, 101, 63, 32, 39, 79, - 78, 39, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, - 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 73, 110, 100, 101, 120, - 84, 121, 112, 101, 63, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, 110, - 100, 101, 120, 69, 108, 101, 109, 101, 110, 116, 41, 41, 63, 32, 87, 105, 116, 104, 76, 105, - 115, 116, 63, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, - 104, 76, 105, 115, 116, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 108, 79, - 112, 116, 105, 111, 110, 79, 114, 79, 105, 100, 115, 10, 82, 101, 108, 79, 112, 116, 105, 111, - 110, 79, 114, 79, 105, 100, 115, 32, 60, 45, 32, 82, 101, 108, 79, 112, 116, 105, 111, 110, - 76, 105, 115, 116, 32, 47, 32, 79, 105, 100, 115, 10, 82, 101, 108, 79, 112, 116, 105, 111, - 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, - 40, 82, 101, 108, 79, 112, 116, 105, 111, 110, 41, 41, 10, 79, 105, 100, 115, 32, 60, 45, - 32, 87, 105, 116, 104, 79, 114, 87, 105, 116, 104, 111, 117, 116, 79, 105, 100, 115, 32, 39, - 79, 73, 68, 83, 39, 10, 87, 105, 116, 104, 79, 114, 87, 105, 116, 104, 111, 117, 116, 79, - 105, 100, 115, 32, 60, 45, 32, 87, 105, 116, 104, 79, 105, 100, 115, 32, 47, 32, 87, 105, - 116, 104, 111, 117, 116, 79, 105, 100, 115, 10, 87, 105, 116, 104, 79, 105, 100, 115, 32, 60, - 45, 32, 39, 87, 73, 84, 72, 39, 10, 87, 105, 116, 104, 111, 117, 116, 79, 105, 100, 115, - 32, 60, 45, 32, 39, 87, 73, 84, 72, 79, 85, 84, 39, 10, 73, 110, 100, 101, 120, 69, - 108, 101, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, - 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 85, 110, 105, 113, 117, 101, 73, 110, 100, 101, - 120, 32, 60, 45, 32, 39, 85, 78, 73, 81, 85, 69, 39, 10, 73, 110, 100, 101, 120, 84, - 121, 112, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 10, 82, 101, 108, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 82, - 101, 108, 79, 112, 116, 105, 111, 110, 78, 97, 109, 101, 32, 82, 101, 108, 79, 112, 116, 105, - 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 79, 112, 116, 63, 10, 82, 101, 108, 79, 112, - 116, 105, 111, 110, 78, 97, 109, 101, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 83, 116, 114, 105, 110, 103, 32, 47, 32, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 68, 111, 116, 116, 101, 100, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 83, 116, 114, 105, 110, 103, 32, 60, 45, 32, 68, 111, 116, - 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 82, 101, 108, 79, 112, 116, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 79, 112, 116, 32, 60, 45, 32, 39, 61, - 39, 32, 68, 101, 102, 65, 114, 103, 10, 68, 101, 102, 65, 114, 103, 32, 60, 45, 32, 68, - 101, 102, 65, 114, 103, 78, 117, 108, 108, 32, 47, 32, 68, 101, 102, 65, 114, 103, 83, 116, - 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 78, 117, 109, 98, 101, 114, - 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 78, 111, 110, 101, 76, 105, 116, 101, 114, 97, - 108, 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 68, 101, 102, - 65, 114, 103, 75, 101, 121, 119, 111, 114, 100, 10, 68, 101, 102, 65, 114, 103, 78, 117, 108, - 108, 32, 60, 45, 32, 78, 117, 108, 108, 76, 105, 116, 101, 114, 97, 108, 10, 68, 101, 102, - 65, 114, 103, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 82, 101, 115, 101, 114, 118, - 101, 100, 75, 101, 121, 119, 111, 114, 100, 10, 68, 101, 102, 65, 114, 103, 83, 116, 114, 105, - 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 10, 78, 111, 110, 101, 76, 105, 116, 101, 114, 97, 108, 32, 60, - 45, 32, 39, 78, 79, 78, 69, 39, 10, 67, 114, 101, 97, 116, 101, 77, 97, 99, 114, 111, - 83, 116, 109, 116, 32, 60, 45, 32, 77, 97, 99, 114, 111, 79, 114, 70, 117, 110, 99, 116, - 105, 111, 110, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, - 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 32, 76, 105, 115, 116, 40, 77, 97, 99, 114, - 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 41, 10, 77, 97, 99, 114, 111, 79, 114, - 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 77, 97, 99, 114, 111, 75, 101, 121, - 119, 111, 114, 100, 32, 47, 32, 70, 117, 110, 99, 116, 105, 111, 110, 75, 101, 121, 119, 111, - 114, 100, 10, 77, 97, 99, 114, 111, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, - 77, 65, 67, 82, 79, 39, 10, 70, 117, 110, 99, 116, 105, 111, 110, 75, 101, 121, 119, 111, - 114, 100, 32, 60, 45, 32, 39, 70, 85, 78, 67, 84, 73, 79, 78, 39, 10, 77, 97, 99, - 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 77, 97, 99, 114, 111, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 63, 41, - 32, 39, 65, 83, 39, 32, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, - 110, 66, 111, 100, 121, 10, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, - 110, 66, 111, 100, 121, 32, 60, 45, 32, 84, 97, 98, 108, 101, 77, 97, 99, 114, 111, 68, - 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 47, 32, 83, 99, 97, 108, 97, 114, 77, 97, - 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 10, 77, 97, 99, 114, 111, 80, - 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 76, 105, 115, 116, 40, 77, 97, - 99, 114, 111, 80, 97, 114, 97, 109, 101, 116, 101, 114, 41, 10, 77, 97, 99, 114, 111, 80, - 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, 97, 114, - 97, 109, 101, 116, 101, 114, 32, 47, 32, 83, 105, 109, 112, 108, 101, 80, 97, 114, 97, 109, - 101, 116, 101, 114, 10, 83, 105, 109, 112, 108, 101, 80, 97, 114, 97, 109, 101, 116, 101, 114, - 32, 60, 45, 32, 84, 121, 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, 32, 84, 121, 112, - 101, 63, 10, 83, 99, 97, 108, 97, 114, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, - 116, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, - 97, 98, 108, 101, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, - 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, - 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 67, 114, 101, 97, 116, - 101, 83, 99, 104, 101, 109, 97, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 67, 72, 69, - 77, 65, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, - 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 10, 67, 114, 101, 97, 116, 101, 83, 101, 99, - 114, 101, 116, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 69, 67, 82, 69, 84, 39, 32, - 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 83, 101, 99, 114, 101, 116, 78, - 97, 109, 101, 63, 32, 83, 101, 99, 114, 101, 116, 83, 116, 111, 114, 97, 103, 101, 83, 112, - 101, 99, 105, 102, 105, 101, 114, 63, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, - 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 83, 101, 99, 114, 101, 116, 83, 116, 111, - 114, 97, 103, 101, 83, 112, 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 73, 78, - 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 83, 101, 99, 114, 101, 116, 78, - 97, 109, 101, 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 67, 114, 101, 97, 116, 101, 83, - 101, 113, 117, 101, 110, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 69, 81, 85, - 69, 78, 67, 69, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, - 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 32, 83, 101, 113, 117, 101, 110, 99, - 101, 79, 112, 116, 105, 111, 110, 42, 10, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, - 105, 111, 110, 32, 60, 45, 10, 9, 83, 101, 113, 83, 101, 116, 67, 121, 99, 108, 101, 32, - 47, 10, 9, 83, 101, 113, 83, 101, 116, 73, 110, 99, 114, 101, 109, 101, 110, 116, 32, 47, - 10, 9, 83, 101, 113, 83, 101, 116, 77, 105, 110, 77, 97, 120, 32, 47, 10, 9, 83, 101, - 113, 78, 111, 77, 105, 110, 77, 97, 120, 32, 47, 10, 9, 83, 101, 113, 83, 116, 97, 114, - 116, 87, 105, 116, 104, 32, 47, 10, 9, 83, 101, 113, 79, 119, 110, 101, 100, 66, 121, 10, - 83, 101, 113, 83, 101, 116, 67, 121, 99, 108, 101, 32, 60, 45, 32, 83, 101, 113, 67, 121, - 99, 108, 101, 32, 47, 32, 83, 101, 113, 78, 111, 67, 121, 99, 108, 101, 10, 83, 101, 113, - 67, 121, 99, 108, 101, 32, 60, 45, 32, 39, 67, 89, 67, 76, 69, 39, 10, 83, 101, 113, - 78, 111, 67, 121, 99, 108, 101, 32, 60, 45, 32, 39, 78, 79, 39, 32, 39, 67, 89, 67, - 76, 69, 39, 10, 83, 101, 113, 83, 101, 116, 73, 110, 99, 114, 101, 109, 101, 110, 116, 32, - 60, 45, 32, 39, 73, 78, 67, 82, 69, 77, 69, 78, 84, 39, 32, 39, 66, 89, 39, 63, - 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 101, 113, 83, 101, 116, 77, 105, - 110, 77, 97, 120, 32, 60, 45, 32, 83, 101, 113, 77, 105, 110, 79, 114, 77, 97, 120, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 101, 113, 78, 111, 77, 105, 110, 77, - 97, 120, 32, 60, 45, 32, 39, 78, 79, 39, 32, 83, 101, 113, 77, 105, 110, 79, 114, 77, - 97, 120, 10, 83, 101, 113, 83, 116, 97, 114, 116, 87, 105, 116, 104, 32, 60, 45, 32, 39, - 83, 84, 65, 82, 84, 39, 32, 39, 87, 73, 84, 72, 39, 63, 32, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 83, 101, 113, 79, 119, 110, 101, 100, 66, 121, 32, 60, 45, 32, - 39, 79, 87, 78, 69, 68, 39, 32, 39, 66, 89, 39, 32, 81, 117, 97, 108, 105, 102, 105, - 101, 100, 78, 97, 109, 101, 10, 83, 101, 113, 77, 105, 110, 79, 114, 77, 97, 120, 32, 60, - 45, 32, 77, 105, 110, 86, 97, 108, 117, 101, 32, 47, 32, 77, 97, 120, 86, 97, 108, 117, - 101, 10, 77, 105, 110, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 77, 73, 78, 86, 65, - 76, 85, 69, 39, 10, 77, 97, 120, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 77, 65, - 88, 86, 65, 76, 85, 69, 39, 10, 67, 114, 101, 97, 116, 101, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, 101, - 112, 108, 97, 99, 101, 63, 32, 84, 101, 109, 112, 111, 114, 97, 114, 121, 63, 32, 67, 114, - 101, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 86, 97, 114, 105, 97, 116, 105, - 111, 110, 10, 67, 114, 101, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 86, 97, - 114, 105, 97, 116, 105, 111, 110, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, - 108, 101, 83, 116, 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 77, 97, 99, 114, 111, - 83, 116, 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 83, 101, 113, 117, 101, 110, 99, - 101, 83, 116, 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 84, 121, 112, 101, 83, 116, - 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 83, 99, 104, 101, 109, 97, 83, 116, 109, - 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 86, 105, 101, 119, 83, 116, 109, 116, 32, 47, - 32, 67, 114, 101, 97, 116, 101, 73, 110, 100, 101, 120, 83, 116, 109, 116, 32, 47, 32, 67, - 114, 101, 97, 116, 101, 83, 101, 99, 114, 101, 116, 83, 116, 109, 116, 32, 47, 32, 67, 114, - 101, 97, 116, 101, 84, 114, 105, 103, 103, 101, 114, 83, 116, 109, 116, 10, 79, 114, 82, 101, - 112, 108, 97, 99, 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 82, 69, 80, 76, 65, - 67, 69, 39, 10, 84, 101, 109, 112, 111, 114, 97, 114, 121, 32, 60, 45, 32, 80, 101, 114, - 115, 105, 115, 116, 101, 110, 116, 32, 47, 32, 84, 101, 109, 112, 80, 101, 114, 115, 105, 115, - 116, 101, 110, 116, 32, 47, 32, 84, 101, 109, 112, 111, 114, 97, 114, 121, 80, 101, 114, 115, - 105, 115, 116, 101, 110, 116, 10, 80, 101, 114, 115, 105, 115, 116, 101, 110, 116, 32, 60, 45, - 32, 39, 80, 69, 82, 83, 73, 83, 84, 69, 78, 84, 39, 10, 84, 101, 109, 112, 80, 101, - 114, 115, 105, 115, 116, 101, 110, 116, 32, 60, 45, 32, 39, 84, 69, 77, 80, 39, 10, 84, - 101, 109, 112, 111, 114, 97, 114, 121, 80, 101, 114, 115, 105, 115, 116, 101, 110, 116, 32, 60, - 45, 32, 39, 84, 69, 77, 80, 79, 82, 65, 82, 89, 39, 10, 67, 114, 101, 97, 116, 101, - 84, 97, 98, 108, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, - 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, - 105, 101, 100, 78, 97, 109, 101, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 68, - 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 67, 111, 109, 109, 105, 116, 65, 99, 116, 105, - 111, 110, 63, 10, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 68, 101, 102, 105, 110, - 105, 116, 105, 111, 110, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, - 65, 115, 32, 47, 32, 67, 114, 101, 97, 116, 101, 67, 111, 108, 117, 109, 110, 76, 105, 115, - 116, 10, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 65, 115, 32, 60, 45, 32, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 76, 105, 115, 116, 63, 32, 80, 97, 114, 116, 105, - 116, 105, 111, 110, 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 63, 32, 87, - 105, 116, 104, 76, 105, 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 87, 105, 116, 104, 68, 97, 116, 97, 63, 10, 80, 97, 114, 116, 105, 116, - 105, 111, 110, 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, - 80, 97, 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, 83, 111, 114, 116, 101, 100, 79, 112, - 116, 105, 111, 110, 115, 32, 47, 32, 83, 111, 114, 116, 101, 100, 79, 112, 116, 80, 97, 114, - 116, 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 10, 80, 97, 114, 116, 105, 116, + 116, 32, 47, 32, 83, 105, 110, 103, 108, 101, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, + 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 83, 116, 97, 114, 80, 97, 114, 116, + 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, + 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 10, 80, 97, 114, 101, 110, 116, 104, 101, + 115, 105, 122, 101, 100, 80, 97, 114, 116, 105, 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, + 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 67, 111, 108, + 117, 109, 110, 76, 105, 115, 116, 41, 10, 83, 105, 110, 103, 108, 101, 80, 97, 114, 116, 105, + 116, 105, 111, 110, 66, 121, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, + 67, 111, 108, 73, 100, 10, 70, 111, 114, 99, 101, 78, 117, 108, 108, 79, 112, 116, 105, 111, + 110, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 32, 70, 111, 114, 99, 101, 78, 111, + 116, 78, 117, 108, 108, 63, 32, 39, 78, 85, 76, 76, 39, 32, 67, 111, 108, 117, 109, 110, + 76, 105, 115, 116, 10, 70, 111, 114, 99, 101, 78, 111, 116, 78, 117, 108, 108, 32, 60, 45, + 32, 39, 78, 79, 84, 39, 10, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 32, 60, 45, + 32, 39, 42, 39, 10, 67, 111, 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, 112, 116, 105, + 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, + 116, 40, 67, 111, 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, 112, 116, 105, 111, 110, 41, + 41, 10, 67, 111, 112, 121, 71, 101, 110, 101, 114, 105, 99, 79, 112, 116, 105, 111, 110, 32, + 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, + 32, 47, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 101, 100, 66, 121, 67, 111, 112, 121, + 79, 112, 116, 105, 111, 110, 32, 47, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, + 79, 112, 116, 105, 111, 110, 10, 79, 114, 100, 101, 114, 66, 121, 67, 111, 112, 121, 79, 112, + 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 82, 68, 69, 82, 39, 32, 39, 66, 89, 39, + 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 86, 97, + 108, 117, 101, 63, 10, 80, 97, 114, 116, 105, 116, 105, 111, 110, 101, 100, 66, 121, 67, 111, + 112, 121, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 40, 39, 80, 65, 82, 84, 73, 84, + 73, 79, 78, 39, 32, 47, 32, 39, 80, 65, 82, 84, 73, 84, 73, 79, 78, 69, 68, 39, + 41, 32, 39, 66, 89, 39, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, + 116, 105, 111, 110, 86, 97, 108, 117, 101, 63, 10, 71, 101, 110, 101, 114, 105, 99, 67, 111, + 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, + 110, 115, 40, 76, 105, 115, 116, 40, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, + 112, 116, 105, 111, 110, 41, 41, 10, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, + 112, 116, 105, 111, 110, 32, 60, 45, 32, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 78, + 97, 109, 101, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, + 110, 86, 97, 108, 117, 101, 63, 10, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, + 112, 116, 105, 111, 110, 86, 97, 108, 117, 101, 32, 60, 45, 32, 71, 101, 110, 101, 114, 105, + 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 79, 114, 100, 101, 114, 76, 105, 115, 116, + 32, 47, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 101, 110, 101, 114, 105, 99, 67, 111, + 112, 121, 79, 112, 116, 105, 111, 110, 79, 114, 100, 101, 114, 76, 105, 115, 116, 32, 60, 45, + 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 80, 97, + 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 76, 105, 115, 116, 10, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, + 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, + 112, 116, 105, 111, 110, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, + 110, 115, 40, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 76, 105, 115, 116, 41, 10, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, + 115, 101, 32, 60, 45, 32, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, + 115, 101, 87, 105, 116, 104, 70, 108, 97, 103, 32, 47, 32, 67, 111, 112, 121, 70, 114, 111, + 109, 68, 97, 116, 97, 98, 97, 115, 101, 87, 105, 116, 104, 111, 117, 116, 70, 108, 97, 103, + 10, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, 115, 101, 87, 105, 116, + 104, 70, 108, 97, 103, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 39, 68, 65, 84, + 65, 66, 65, 83, 69, 39, 32, 67, 111, 108, 73, 100, 32, 39, 84, 79, 39, 32, 67, 111, + 108, 73, 100, 32, 67, 111, 112, 121, 68, 97, 116, 97, 98, 97, 115, 101, 70, 108, 97, 103, + 10, 67, 111, 112, 121, 70, 114, 111, 109, 68, 97, 116, 97, 98, 97, 115, 101, 87, 105, 116, + 104, 111, 117, 116, 70, 108, 97, 103, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 39, + 68, 65, 84, 65, 66, 65, 83, 69, 39, 32, 67, 111, 108, 73, 100, 32, 39, 84, 79, 39, + 32, 67, 111, 108, 73, 100, 10, 67, 111, 112, 121, 68, 97, 116, 97, 98, 97, 115, 101, 70, + 108, 97, 103, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 99, 104, 101, 109, 97, + 79, 114, 68, 97, 116, 97, 41, 10, 83, 99, 104, 101, 109, 97, 79, 114, 68, 97, 116, 97, + 32, 60, 45, 32, 67, 111, 112, 121, 83, 99, 104, 101, 109, 97, 32, 47, 32, 67, 111, 112, + 121, 68, 97, 116, 97, 10, 67, 111, 112, 121, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, + 39, 83, 67, 72, 69, 77, 65, 39, 10, 67, 111, 112, 121, 68, 97, 116, 97, 32, 60, 45, + 32, 39, 68, 65, 84, 65, 39, 10, 67, 114, 101, 97, 116, 101, 73, 110, 100, 101, 120, 83, + 116, 109, 116, 32, 60, 45, 32, 85, 110, 105, 113, 117, 101, 73, 110, 100, 101, 120, 63, 32, + 39, 73, 78, 68, 69, 88, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, + 32, 73, 110, 100, 101, 120, 78, 97, 109, 101, 63, 32, 39, 79, 78, 39, 32, 66, 97, 115, + 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, + 117, 109, 110, 76, 105, 115, 116, 63, 32, 73, 110, 100, 101, 120, 84, 121, 112, 101, 63, 32, + 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, 110, 100, 101, 120, 69, 108, 101, + 109, 101, 110, 116, 41, 41, 63, 32, 87, 105, 116, 104, 76, 105, 115, 116, 63, 32, 87, 104, + 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 76, 105, 115, 116, 32, + 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 108, 79, 112, 116, 105, 111, 110, 79, + 114, 79, 105, 100, 115, 10, 82, 101, 108, 79, 112, 116, 105, 111, 110, 79, 114, 79, 105, 100, + 115, 32, 60, 45, 32, 82, 101, 108, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 47, + 32, 79, 105, 100, 115, 10, 82, 101, 108, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, + 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 82, 101, 108, 79, 112, + 116, 105, 111, 110, 41, 41, 10, 79, 105, 100, 115, 32, 60, 45, 32, 87, 105, 116, 104, 79, + 114, 87, 105, 116, 104, 111, 117, 116, 79, 105, 100, 115, 32, 39, 79, 73, 68, 83, 39, 10, + 87, 105, 116, 104, 79, 114, 87, 105, 116, 104, 111, 117, 116, 79, 105, 100, 115, 32, 60, 45, + 32, 87, 105, 116, 104, 79, 105, 100, 115, 32, 47, 32, 87, 105, 116, 104, 111, 117, 116, 79, + 105, 100, 115, 10, 87, 105, 116, 104, 79, 105, 100, 115, 32, 60, 45, 32, 39, 87, 73, 84, + 72, 39, 10, 87, 105, 116, 104, 111, 117, 116, 79, 105, 100, 115, 32, 60, 45, 32, 39, 87, + 73, 84, 72, 79, 85, 84, 39, 10, 73, 110, 100, 101, 120, 69, 108, 101, 109, 101, 110, 116, + 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 68, 101, 115, 99, 79, + 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, + 115, 116, 63, 10, 85, 110, 105, 113, 117, 101, 73, 110, 100, 101, 120, 32, 60, 45, 32, 39, + 85, 78, 73, 81, 85, 69, 39, 10, 73, 110, 100, 101, 120, 84, 121, 112, 101, 32, 60, 45, + 32, 39, 85, 83, 73, 78, 71, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, + 82, 101, 108, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 82, 101, 108, 79, 112, 116, 105, + 111, 110, 78, 97, 109, 101, 32, 82, 101, 108, 79, 112, 116, 105, 111, 110, 65, 114, 103, 117, + 109, 101, 110, 116, 79, 112, 116, 63, 10, 82, 101, 108, 79, 112, 116, 105, 111, 110, 78, 97, + 109, 101, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 83, 116, 114, 105, 110, 103, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, + 101, 114, 97, 108, 10, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 83, 116, 114, 105, 110, 103, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 10, 82, 101, 108, 79, 112, 116, 105, 111, 110, 65, 114, 103, + 117, 109, 101, 110, 116, 79, 112, 116, 32, 60, 45, 32, 39, 61, 39, 32, 68, 101, 102, 65, + 114, 103, 10, 68, 101, 102, 65, 114, 103, 32, 60, 45, 32, 68, 101, 102, 65, 114, 103, 78, + 117, 108, 108, 32, 47, 32, 68, 101, 102, 65, 114, 103, 83, 116, 114, 105, 110, 103, 76, 105, + 116, 101, 114, 97, 108, 32, 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, + 108, 32, 47, 32, 78, 111, 110, 101, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 68, 101, 102, 65, 114, 103, 75, 101, 121, + 119, 111, 114, 100, 10, 68, 101, 102, 65, 114, 103, 78, 117, 108, 108, 32, 60, 45, 32, 78, + 117, 108, 108, 76, 105, 116, 101, 114, 97, 108, 10, 68, 101, 102, 65, 114, 103, 75, 101, 121, + 119, 111, 114, 100, 32, 60, 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, + 111, 114, 100, 10, 68, 101, 102, 65, 114, 103, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, + 114, 97, 108, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 10, 78, 111, 110, 101, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 78, 79, 78, + 69, 39, 10, 67, 114, 101, 97, 116, 101, 77, 97, 99, 114, 111, 83, 116, 109, 116, 32, 60, + 45, 32, 77, 97, 99, 114, 111, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 32, 73, 102, + 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, + 78, 97, 109, 101, 32, 76, 105, 115, 116, 40, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, + 105, 116, 105, 111, 110, 41, 10, 77, 97, 99, 114, 111, 79, 114, 70, 117, 110, 99, 116, 105, + 111, 110, 32, 60, 45, 32, 77, 97, 99, 114, 111, 75, 101, 121, 119, 111, 114, 100, 32, 47, + 32, 70, 117, 110, 99, 116, 105, 111, 110, 75, 101, 121, 119, 111, 114, 100, 10, 77, 97, 99, + 114, 111, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 77, 65, 67, 82, 79, 39, + 10, 70, 117, 110, 99, 116, 105, 111, 110, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, + 39, 70, 85, 78, 67, 84, 73, 79, 78, 39, 10, 77, 97, 99, 114, 111, 68, 101, 102, 105, + 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 77, 97, 99, + 114, 111, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 63, 41, 32, 39, 65, 83, 39, 32, + 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 66, 111, 100, 121, 10, + 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 66, 111, 100, 121, 32, + 60, 45, 32, 84, 97, 98, 108, 101, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, + 105, 111, 110, 32, 47, 32, 83, 99, 97, 108, 97, 114, 77, 97, 99, 114, 111, 68, 101, 102, + 105, 110, 105, 116, 105, 111, 110, 10, 77, 97, 99, 114, 111, 80, 97, 114, 97, 109, 101, 116, + 101, 114, 115, 32, 60, 45, 32, 76, 105, 115, 116, 40, 77, 97, 99, 114, 111, 80, 97, 114, + 97, 109, 101, 116, 101, 114, 41, 10, 77, 97, 99, 114, 111, 80, 97, 114, 97, 109, 101, 116, + 101, 114, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, + 32, 47, 32, 83, 105, 109, 112, 108, 101, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 83, + 105, 109, 112, 108, 101, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 84, 121, + 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, 32, 84, 121, 112, 101, 63, 10, 83, 99, 97, + 108, 97, 114, 77, 97, 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, + 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 97, 98, 108, 101, 77, 97, + 99, 114, 111, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 39, 84, 65, + 66, 76, 69, 39, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 73, 110, 116, 101, 114, 110, 97, 108, 10, 67, 114, 101, 97, 116, 101, 83, 99, 104, 101, 109, + 97, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 67, 72, 69, 77, 65, 39, 32, 73, 102, + 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, + 78, 97, 109, 101, 10, 67, 114, 101, 97, 116, 101, 83, 101, 99, 114, 101, 116, 83, 116, 109, + 116, 32, 60, 45, 32, 39, 83, 69, 67, 82, 69, 84, 39, 32, 73, 102, 78, 111, 116, 69, + 120, 105, 115, 116, 115, 63, 32, 83, 101, 99, 114, 101, 116, 78, 97, 109, 101, 63, 32, 83, + 101, 99, 114, 101, 116, 83, 116, 111, 114, 97, 103, 101, 83, 112, 101, 99, 105, 102, 105, 101, + 114, 63, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, + 76, 105, 115, 116, 10, 83, 101, 99, 114, 101, 116, 83, 116, 111, 114, 97, 103, 101, 83, 112, + 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 73, 78, 39, 32, 73, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 10, 83, 101, 99, 114, 101, 116, 78, 97, 109, 101, 32, 60, 45, + 32, 67, 111, 108, 73, 100, 10, 67, 114, 101, 97, 116, 101, 83, 101, 113, 117, 101, 110, 99, + 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 69, 81, 85, 69, 78, 67, 69, 39, 32, + 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, + 101, 100, 78, 97, 109, 101, 32, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, + 110, 42, 10, 83, 101, 113, 117, 101, 110, 99, 101, 79, 112, 116, 105, 111, 110, 32, 60, 45, + 10, 9, 83, 101, 113, 83, 101, 116, 67, 121, 99, 108, 101, 32, 47, 10, 9, 83, 101, 113, + 83, 101, 116, 73, 110, 99, 114, 101, 109, 101, 110, 116, 32, 47, 10, 9, 83, 101, 113, 83, + 101, 116, 77, 105, 110, 77, 97, 120, 32, 47, 10, 9, 83, 101, 113, 78, 111, 77, 105, 110, + 77, 97, 120, 32, 47, 10, 9, 83, 101, 113, 83, 116, 97, 114, 116, 87, 105, 116, 104, 32, + 47, 10, 9, 83, 101, 113, 79, 119, 110, 101, 100, 66, 121, 10, 83, 101, 113, 83, 101, 116, + 67, 121, 99, 108, 101, 32, 60, 45, 32, 83, 101, 113, 67, 121, 99, 108, 101, 32, 47, 32, + 83, 101, 113, 78, 111, 67, 121, 99, 108, 101, 10, 83, 101, 113, 67, 121, 99, 108, 101, 32, + 60, 45, 32, 39, 67, 89, 67, 76, 69, 39, 10, 83, 101, 113, 78, 111, 67, 121, 99, 108, + 101, 32, 60, 45, 32, 39, 78, 79, 39, 32, 39, 67, 89, 67, 76, 69, 39, 10, 83, 101, + 113, 83, 101, 116, 73, 110, 99, 114, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 73, 78, + 67, 82, 69, 77, 69, 78, 84, 39, 32, 39, 66, 89, 39, 63, 32, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 10, 83, 101, 113, 83, 101, 116, 77, 105, 110, 77, 97, 120, 32, 60, + 45, 32, 83, 101, 113, 77, 105, 110, 79, 114, 77, 97, 120, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 10, 83, 101, 113, 78, 111, 77, 105, 110, 77, 97, 120, 32, 60, 45, 32, + 39, 78, 79, 39, 32, 83, 101, 113, 77, 105, 110, 79, 114, 77, 97, 120, 10, 83, 101, 113, + 83, 116, 97, 114, 116, 87, 105, 116, 104, 32, 60, 45, 32, 39, 83, 84, 65, 82, 84, 39, + 32, 39, 87, 73, 84, 72, 39, 63, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 83, 101, 113, 79, 119, 110, 101, 100, 66, 121, 32, 60, 45, 32, 39, 79, 87, 78, 69, 68, + 39, 32, 39, 66, 89, 39, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, + 10, 83, 101, 113, 77, 105, 110, 79, 114, 77, 97, 120, 32, 60, 45, 32, 77, 105, 110, 86, + 97, 108, 117, 101, 32, 47, 32, 77, 97, 120, 86, 97, 108, 117, 101, 10, 77, 105, 110, 86, + 97, 108, 117, 101, 32, 60, 45, 32, 39, 77, 73, 78, 86, 65, 76, 85, 69, 39, 10, 77, + 97, 120, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 77, 65, 88, 86, 65, 76, 85, 69, + 39, 10, 67, 114, 101, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, 101, 63, + 32, 84, 101, 109, 112, 111, 114, 97, 114, 121, 63, 32, 67, 114, 101, 97, 116, 101, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 86, 97, 114, 105, 97, 116, 105, 111, 110, 10, 67, 114, 101, + 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 86, 97, 114, 105, 97, 116, 105, 111, + 110, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 83, 116, 109, 116, + 32, 47, 32, 67, 114, 101, 97, 116, 101, 77, 97, 99, 114, 111, 83, 116, 109, 116, 32, 47, + 32, 67, 114, 101, 97, 116, 101, 83, 101, 113, 117, 101, 110, 99, 101, 83, 116, 109, 116, 32, + 47, 32, 67, 114, 101, 97, 116, 101, 84, 121, 112, 101, 83, 116, 109, 116, 32, 47, 32, 67, + 114, 101, 97, 116, 101, 83, 99, 104, 101, 109, 97, 83, 116, 109, 116, 32, 47, 32, 67, 114, + 101, 97, 116, 101, 86, 105, 101, 119, 83, 116, 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, + 101, 73, 110, 100, 101, 120, 83, 116, 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 83, + 101, 99, 114, 101, 116, 83, 116, 109, 116, 32, 47, 32, 67, 114, 101, 97, 116, 101, 84, 114, + 105, 103, 103, 101, 114, 83, 116, 109, 116, 10, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, + 60, 45, 32, 39, 79, 82, 39, 32, 39, 82, 69, 80, 76, 65, 67, 69, 39, 10, 84, 101, + 109, 112, 111, 114, 97, 114, 121, 32, 60, 45, 32, 80, 101, 114, 115, 105, 115, 116, 101, 110, + 116, 32, 47, 32, 84, 101, 109, 112, 80, 101, 114, 115, 105, 115, 116, 101, 110, 116, 32, 47, + 32, 84, 101, 109, 112, 111, 114, 97, 114, 121, 80, 101, 114, 115, 105, 115, 116, 101, 110, 116, + 10, 80, 101, 114, 115, 105, 115, 116, 101, 110, 116, 32, 60, 45, 32, 39, 80, 69, 82, 83, + 73, 83, 84, 69, 78, 84, 39, 10, 84, 101, 109, 112, 80, 101, 114, 115, 105, 115, 116, 101, + 110, 116, 32, 60, 45, 32, 39, 84, 69, 77, 80, 39, 10, 84, 101, 109, 112, 111, 114, 97, + 114, 121, 80, 101, 114, 115, 105, 115, 116, 101, 110, 116, 32, 60, 45, 32, 39, 84, 69, 77, + 80, 79, 82, 65, 82, 89, 39, 10, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 83, + 116, 109, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 73, 102, 78, 111, 116, + 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, + 101, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 68, 101, 102, 105, 110, 105, 116, + 105, 111, 110, 32, 67, 111, 109, 109, 105, 116, 65, 99, 116, 105, 111, 110, 63, 10, 67, 114, + 101, 97, 116, 101, 84, 97, 98, 108, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, + 60, 45, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 65, 115, 32, 47, 32, 67, + 114, 101, 97, 116, 101, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 67, 114, 101, 97, + 116, 101, 84, 97, 98, 108, 101, 65, 115, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 76, 105, 115, 116, 63, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 83, 111, + 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 63, 32, 87, 105, 116, 104, 76, 105, 115, + 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 87, 105, + 116, 104, 68, 97, 116, 97, 63, 10, 80, 97, 114, 116, 105, 116, 105, 111, 110, 83, 111, 114, + 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, - 60, 45, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, - 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 63, 10, 83, 111, 114, 116, 101, - 100, 79, 112, 116, 80, 97, 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, - 32, 60, 45, 32, 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, 80, 97, - 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 80, 97, 114, 116, - 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 80, 65, 82, - 84, 73, 84, 73, 79, 78, 69, 68, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, - 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 83, 79, - 82, 84, 69, 68, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, - 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 87, 105, 116, 104, - 68, 97, 116, 97, 32, 60, 45, 32, 87, 105, 116, 104, 68, 97, 116, 97, 79, 110, 108, 121, - 32, 47, 32, 87, 105, 116, 104, 78, 111, 68, 97, 116, 97, 10, 87, 105, 116, 104, 68, 97, - 116, 97, 79, 110, 108, 121, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, 68, 65, - 84, 65, 39, 10, 87, 105, 116, 104, 78, 111, 68, 97, 116, 97, 32, 60, 45, 32, 39, 87, - 73, 84, 72, 39, 32, 39, 78, 79, 39, 32, 39, 68, 65, 84, 65, 39, 10, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 41, 41, 10, - 67, 114, 101, 97, 116, 101, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, - 80, 97, 114, 101, 110, 115, 40, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, - 108, 117, 109, 110, 76, 105, 115, 116, 63, 41, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, - 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 63, 32, 87, 105, 116, 104, 76, - 105, 115, 116, 63, 10, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 32, 60, 45, 32, - 39, 73, 70, 39, 32, 39, 78, 79, 84, 39, 32, 39, 69, 88, 73, 83, 84, 83, 39, 10, - 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, - 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, - 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, - 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, - 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, - 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 67, 97, 116, 97, - 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, - 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, - 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, - 32, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, - 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, - 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 82, 101, 115, 101, 114, 118, 101, 100, 73, + 47, 32, 83, 111, 114, 116, 101, 100, 79, 112, 116, 80, 97, 114, 116, 105, 116, 105, 111, 110, + 79, 112, 116, 105, 111, 110, 115, 10, 80, 97, 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, + 83, 111, 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, + 116, 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, 83, 111, 114, 116, 101, 100, + 79, 112, 116, 105, 111, 110, 115, 63, 10, 83, 111, 114, 116, 101, 100, 79, 112, 116, 80, 97, + 114, 116, 105, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 83, 111, + 114, 116, 101, 100, 79, 112, 116, 105, 111, 110, 115, 32, 80, 97, 114, 116, 105, 116, 105, 111, + 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 80, 97, 114, 116, 105, 116, 105, 111, 110, 79, + 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 80, 65, 82, 84, 73, 84, 73, 79, 78, + 69, 68, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, + 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 111, 114, 116, 101, 100, + 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 39, 83, 79, 82, 84, 69, 68, 39, 32, + 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 87, 105, 116, 104, 68, 97, 116, 97, 32, 60, + 45, 32, 87, 105, 116, 104, 68, 97, 116, 97, 79, 110, 108, 121, 32, 47, 32, 87, 105, 116, + 104, 78, 111, 68, 97, 116, 97, 10, 87, 105, 116, 104, 68, 97, 116, 97, 79, 110, 108, 121, + 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, 68, 65, 84, 65, 39, 10, 87, 105, + 116, 104, 78, 111, 68, 97, 116, 97, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, + 78, 79, 39, 32, 39, 68, 65, 84, 65, 39, 10, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, + 40, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 41, 41, 10, 67, 114, 101, 97, 116, 101, + 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, + 40, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 76, 105, + 115, 116, 63, 41, 32, 80, 97, 114, 116, 105, 116, 105, 111, 110, 83, 111, 114, 116, 101, 100, + 79, 112, 116, 105, 111, 110, 115, 63, 32, 87, 105, 116, 104, 76, 105, 115, 116, 63, 10, 73, + 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 32, 60, 45, 32, 39, 73, 70, 39, 32, 39, + 78, 79, 84, 39, 32, 39, 69, 88, 73, 83, 84, 83, 39, 10, 81, 117, 97, 108, 105, 102, + 105, 101, 100, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, + 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, - 101, 114, 97, 108, 32, 60, 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, - 116, 105, 102, 105, 101, 114, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 10, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, - 105, 111, 110, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, - 46, 39, 10, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, - 111, 110, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 32, 39, 46, 39, - 10, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, - 102, 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, - 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 32, 39, 46, 39, 10, 84, 97, 98, 108, 101, - 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, - 108, 101, 78, 97, 109, 101, 32, 39, 46, 39, 10, 82, 101, 115, 101, 114, 118, 101, 100, 84, - 97, 98, 108, 101, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, - 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 39, - 46, 39, 10, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, - 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 114, 101, 97, 116, 101, 84, - 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 69, 108, 101, 109, 101, 110, 116, 41, 10, 67, - 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 69, 108, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, - 108, 117, 109, 110, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 47, 32, 67, 114, 101, - 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 67, - 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 68, 101, 102, 105, - 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 68, 101, 102, 105, - 110, 105, 116, 105, 111, 110, 10, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, - 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 84, 111, 112, 76, 101, 118, 101, 108, - 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 67, 111, 108, 117, 109, 110, 68, 101, 102, - 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 84, 121, 112, 101, 63, 32, 71, 101, 110, 101, 114, 97, - 116, 101, 100, 67, 111, 108, 117, 109, 110, 63, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, - 116, 78, 97, 109, 101, 67, 108, 97, 117, 115, 101, 63, 32, 67, 111, 108, 117, 109, 110, 67, - 111, 110, 115, 116, 114, 97, 105, 110, 116, 42, 10, 67, 111, 108, 117, 109, 110, 67, 111, 110, - 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 78, 111, 116, 78, 117, 108, 108, 67, 111, - 110, 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, 85, 110, 105, 113, 117, 101, 67, 111, 110, - 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, 80, 114, 105, 109, 97, 114, 121, 75, 101, 121, - 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, 68, 101, 102, 97, 117, 108, 116, - 86, 97, 108, 117, 101, 32, 47, 32, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, - 105, 110, 116, 32, 47, 32, 70, 111, 114, 101, 105, 103, 110, 75, 101, 121, 67, 111, 110, 115, - 116, 114, 97, 105, 110, 116, 32, 47, 32, 67, 111, 108, 117, 109, 110, 67, 111, 108, 108, 97, - 116, 105, 111, 110, 32, 47, 32, 67, 111, 108, 117, 109, 110, 67, 111, 109, 112, 114, 101, 115, - 115, 105, 111, 110, 10, 78, 111, 116, 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, - 110, 116, 32, 60, 45, 32, 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, - 32, 47, 32, 78, 111, 116, 78, 117, 108, 108, 67, 111, 108, 117, 109, 110, 67, 111, 110, 115, - 116, 114, 97, 105, 110, 116, 10, 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, - 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, 39, 10, 78, 111, 116, 78, 117, 108, 108, 67, - 111, 108, 117, 109, 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, - 78, 79, 84, 39, 32, 39, 78, 85, 76, 76, 39, 10, 85, 110, 105, 113, 117, 101, 67, 111, - 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 85, 78, 73, 81, 85, 69, 39, - 10, 80, 114, 105, 109, 97, 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, - 116, 32, 60, 45, 32, 39, 80, 82, 73, 77, 65, 82, 89, 39, 32, 39, 75, 69, 89, 39, - 10, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 68, 69, - 70, 65, 85, 76, 84, 39, 32, 67, 111, 108, 117, 109, 110, 68, 101, 102, 97, 117, 108, 116, - 69, 120, 112, 114, 10, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, - 32, 60, 45, 32, 39, 67, 72, 69, 67, 75, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 70, 111, 114, 101, 105, 103, 110, 75, 101, - 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 82, 69, 70, 69, - 82, 69, 78, 67, 69, 83, 39, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, - 101, 32, 80, 97, 114, 101, 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, - 63, 32, 75, 101, 121, 65, 99, 116, 105, 111, 110, 115, 10, 67, 111, 108, 117, 109, 110, 67, - 111, 108, 108, 97, 116, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, - 39, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, - 111, 108, 117, 109, 110, 67, 111, 109, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, - 39, 85, 83, 73, 78, 71, 39, 32, 39, 67, 79, 77, 80, 82, 69, 83, 83, 73, 79, 78, - 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 75, 101, 121, 65, - 99, 116, 105, 111, 110, 115, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 65, 99, 116, 105, - 111, 110, 63, 32, 68, 101, 108, 101, 116, 101, 65, 99, 116, 105, 111, 110, 63, 10, 85, 112, - 100, 97, 116, 101, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, - 85, 80, 68, 65, 84, 69, 39, 32, 75, 101, 121, 65, 99, 116, 105, 111, 110, 10, 68, 101, - 108, 101, 116, 101, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, - 68, 69, 76, 69, 84, 69, 39, 32, 75, 101, 121, 65, 99, 116, 105, 111, 110, 10, 75, 101, - 121, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 78, 111, 75, 101, 121, 65, 99, 116, 105, - 111, 110, 32, 47, 32, 82, 101, 115, 116, 114, 105, 99, 116, 75, 101, 121, 65, 99, 116, 105, - 111, 110, 32, 47, 32, 67, 97, 115, 99, 97, 100, 101, 75, 101, 121, 65, 99, 116, 105, 111, - 110, 32, 47, 32, 83, 101, 116, 78, 117, 108, 108, 75, 101, 121, 65, 99, 116, 105, 111, 110, - 32, 47, 32, 83, 101, 116, 68, 101, 102, 97, 117, 108, 116, 75, 101, 121, 65, 99, 116, 105, - 111, 110, 10, 78, 111, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 78, - 79, 39, 32, 39, 65, 67, 84, 73, 79, 78, 39, 10, 82, 101, 115, 116, 114, 105, 99, 116, - 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 82, 69, 83, 84, 82, 73, - 67, 84, 39, 10, 67, 97, 115, 99, 97, 100, 101, 75, 101, 121, 65, 99, 116, 105, 111, 110, - 32, 60, 45, 32, 39, 67, 65, 83, 67, 65, 68, 69, 39, 10, 83, 101, 116, 78, 117, 108, - 108, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, - 39, 78, 85, 76, 76, 39, 10, 83, 101, 116, 68, 101, 102, 97, 117, 108, 116, 75, 101, 121, - 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 68, 69, 70, - 65, 85, 76, 84, 39, 10, 84, 111, 112, 76, 101, 118, 101, 108, 67, 111, 110, 115, 116, 114, - 97, 105, 110, 116, 32, 60, 45, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, - 109, 101, 67, 108, 97, 117, 115, 101, 63, 32, 84, 111, 112, 76, 101, 118, 101, 108, 67, 111, - 110, 115, 116, 114, 97, 105, 110, 116, 76, 105, 115, 116, 10, 84, 111, 112, 76, 101, 118, 101, - 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 84, - 111, 112, 80, 114, 105, 109, 97, 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, - 110, 116, 32, 47, 32, 84, 111, 112, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, - 105, 110, 116, 32, 47, 32, 84, 111, 112, 85, 110, 105, 113, 117, 101, 67, 111, 110, 115, 116, - 114, 97, 105, 110, 116, 32, 47, 32, 84, 111, 112, 70, 111, 114, 101, 105, 103, 110, 75, 101, - 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 67, 111, 110, 115, 116, 114, 97, 105, - 110, 116, 78, 97, 109, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 67, 79, 78, - 83, 84, 82, 65, 73, 78, 84, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, - 84, 111, 112, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, - 45, 32, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 84, 111, - 112, 80, 114, 105, 109, 97, 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, - 116, 32, 60, 45, 32, 39, 80, 82, 73, 77, 65, 82, 89, 39, 32, 39, 75, 69, 89, 39, - 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 10, 84, 111, 112, 85, 110, 105, - 113, 117, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 85, 78, - 73, 81, 85, 69, 39, 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 10, 84, - 111, 112, 70, 111, 114, 101, 105, 103, 110, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, - 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 69, 73, 71, 78, 39, 32, 39, 75, 69, 89, - 39, 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 32, 70, 111, 114, 101, 105, - 103, 110, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 67, 111, 108, 117, - 109, 110, 73, 100, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, - 105, 115, 116, 40, 67, 111, 108, 73, 100, 41, 41, 10, 80, 108, 97, 105, 110, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 33, 82, 101, 115, 101, 114, 118, 101, 100, - 75, 101, 121, 119, 111, 114, 100, 32, 60, 91, 97, 45, 122, 95, 93, 105, 91, 97, 45, 122, - 48, 45, 57, 95, 93, 105, 42, 62, 10, 81, 117, 111, 116, 101, 100, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 34, 39, 32, 91, 94, 34, 93, 42, 32, 39, - 34, 39, 10, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, - 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 68, 111, 116, 67, 111, 108, - 76, 97, 98, 101, 108, 42, 10, 68, 111, 116, 67, 111, 108, 76, 97, 98, 101, 108, 32, 60, - 45, 32, 39, 46, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 10, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 32, 60, 45, 32, 81, 117, 111, 116, 101, 100, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 32, 47, 32, 80, 108, 97, 105, 110, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 10, 67, 111, 108, 73, 100, 32, 60, 45, 32, 85, 110, 114, 101, 115, 101, 114, - 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 67, 111, 108, 117, 109, 110, 78, - 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 10, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 60, 45, - 32, 67, 111, 108, 73, 100, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 84, 121, 112, 101, 70, 117, 110, - 99, 78, 97, 109, 101, 32, 60, 45, 32, 85, 110, 114, 101, 115, 101, 114, 118, 101, 100, 75, - 101, 121, 119, 111, 114, 100, 32, 47, 32, 84, 121, 112, 101, 70, 117, 110, 99, 75, 101, 121, - 119, 111, 114, 100, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 84, 121, - 112, 101, 70, 117, 110, 99, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 84, 121, 112, - 101, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 70, 117, 110, 99, 78, - 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 10, 84, 121, 112, 101, 78, 97, 109, 101, 32, - 60, 45, 32, 85, 110, 114, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, - 32, 47, 32, 84, 121, 112, 101, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, - 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 76, 97, 98, 101, 108, - 32, 60, 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 85, 110, 114, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 70, 117, 110, 99, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, - 84, 121, 112, 101, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, - 116, 114, 105, 110, 103, 32, 60, 45, 32, 67, 111, 108, 76, 97, 98, 101, 108, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, - 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 76, 97, 98, - 101, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 67, 111, 108, 76, - 97, 98, 101, 108, 10, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, - 116, 101, 114, 97, 108, 10, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, - 110, 32, 60, 45, 32, 71, 101, 110, 101, 114, 97, 116, 101, 100, 63, 32, 39, 65, 83, 39, - 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 32, - 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 84, 121, 112, 101, 63, - 10, 71, 101, 110, 101, 114, 97, 116, 101, 100, 32, 60, 45, 32, 39, 71, 69, 78, 69, 82, - 65, 84, 69, 68, 39, 32, 65, 108, 119, 97, 121, 115, 79, 114, 66, 121, 68, 101, 102, 97, - 117, 108, 116, 63, 10, 65, 108, 119, 97, 121, 115, 79, 114, 66, 121, 68, 101, 102, 97, 117, - 108, 116, 32, 60, 45, 32, 39, 65, 76, 87, 65, 89, 83, 39, 32, 47, 32, 40, 39, 66, - 89, 39, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 41, 10, 71, 101, 110, 101, 114, 97, - 116, 101, 100, 67, 111, 108, 117, 109, 110, 84, 121, 112, 101, 32, 60, 45, 32, 86, 105, 114, - 116, 117, 97, 108, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, - 47, 32, 83, 116, 111, 114, 101, 100, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, - 117, 109, 110, 10, 67, 111, 109, 109, 105, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, - 39, 79, 78, 39, 32, 39, 67, 79, 77, 77, 73, 84, 39, 32, 80, 114, 101, 115, 101, 114, - 118, 101, 79, 114, 68, 101, 108, 101, 116, 101, 32, 39, 82, 79, 87, 83, 39, 10, 80, 114, - 101, 115, 101, 114, 118, 101, 79, 114, 68, 101, 108, 101, 116, 101, 32, 60, 45, 32, 80, 114, - 101, 115, 101, 114, 118, 101, 82, 111, 119, 115, 32, 47, 32, 68, 101, 108, 101, 116, 101, 82, - 111, 119, 115, 10, 80, 114, 101, 115, 101, 114, 118, 101, 82, 111, 119, 115, 32, 60, 45, 32, - 39, 80, 82, 69, 83, 69, 82, 86, 69, 39, 10, 68, 101, 108, 101, 116, 101, 82, 111, 119, - 115, 32, 60, 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 86, 105, 114, 116, 117, 97, - 108, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, - 39, 86, 73, 82, 84, 85, 65, 76, 39, 10, 83, 116, 111, 114, 101, 100, 71, 101, 110, 101, - 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 83, 84, 79, 82, - 69, 68, 39, 10, 67, 114, 101, 97, 116, 101, 84, 114, 105, 103, 103, 101, 114, 83, 116, 109, - 116, 32, 60, 45, 32, 39, 84, 82, 73, 71, 71, 69, 82, 39, 32, 73, 102, 78, 111, 116, - 69, 120, 105, 115, 116, 115, 63, 32, 84, 114, 105, 103, 103, 101, 114, 78, 97, 109, 101, 32, - 84, 114, 105, 103, 103, 101, 114, 84, 105, 109, 105, 110, 103, 32, 84, 114, 105, 103, 103, 101, - 114, 69, 118, 101, 110, 116, 32, 39, 79, 78, 39, 32, 66, 97, 115, 101, 84, 97, 98, 108, - 101, 78, 97, 109, 101, 32, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 67, 108, 97, - 117, 115, 101, 63, 32, 70, 111, 114, 69, 97, 99, 104, 67, 108, 97, 117, 115, 101, 63, 32, - 84, 114, 105, 103, 103, 101, 114, 66, 111, 100, 121, 10, 84, 114, 105, 103, 103, 101, 114, 66, - 111, 100, 121, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 47, 32, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 47, 32, 68, 101, 108, 101, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, - 32, 77, 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, - 84, 114, 105, 103, 103, 101, 114, 78, 97, 109, 101, 32, 60, 45, 32, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 10, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 39, 82, 69, 70, 69, 82, 69, 78, 67, 73, 78, 71, 39, - 32, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 73, 116, 101, 109, 32, 82, 101, 102, - 101, 114, 101, 110, 99, 105, 110, 103, 73, 116, 101, 109, 63, 10, 82, 101, 102, 101, 114, 101, - 110, 99, 105, 110, 103, 73, 116, 101, 109, 32, 60, 45, 32, 82, 101, 102, 101, 114, 101, 110, - 99, 105, 110, 103, 78, 101, 119, 84, 97, 98, 108, 101, 65, 115, 32, 47, 32, 82, 101, 102, - 101, 114, 101, 110, 99, 105, 110, 103, 79, 108, 100, 84, 97, 98, 108, 101, 65, 115, 10, 82, - 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 78, 101, 119, 84, 97, 98, 108, 101, 65, 115, - 32, 60, 45, 32, 39, 78, 69, 87, 39, 32, 39, 84, 65, 66, 76, 69, 39, 32, 39, 65, - 83, 39, 32, 67, 111, 108, 73, 100, 10, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, - 79, 108, 100, 84, 97, 98, 108, 101, 65, 115, 32, 60, 45, 32, 39, 79, 76, 68, 39, 32, - 39, 84, 65, 66, 76, 69, 39, 32, 39, 65, 83, 39, 32, 67, 111, 108, 73, 100, 10, 84, - 114, 105, 103, 103, 101, 114, 84, 105, 109, 105, 110, 103, 32, 60, 45, 32, 84, 114, 105, 103, - 103, 101, 114, 66, 101, 102, 111, 114, 101, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 65, - 102, 116, 101, 114, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 73, 110, 115, 116, 101, 97, - 100, 79, 102, 10, 84, 114, 105, 103, 103, 101, 114, 66, 101, 102, 111, 114, 101, 32, 60, 45, - 32, 39, 66, 69, 70, 79, 82, 69, 39, 10, 84, 114, 105, 103, 103, 101, 114, 65, 102, 116, - 101, 114, 32, 60, 45, 32, 39, 65, 70, 84, 69, 82, 39, 10, 84, 114, 105, 103, 103, 101, - 114, 73, 110, 115, 116, 101, 97, 100, 79, 102, 32, 60, 45, 32, 39, 73, 78, 83, 84, 69, - 65, 68, 39, 32, 39, 79, 70, 39, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, - 116, 32, 60, 45, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 85, 112, 100, - 97, 116, 101, 79, 102, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, - 73, 110, 115, 101, 114, 116, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, - 116, 68, 101, 108, 101, 116, 101, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, - 110, 116, 85, 112, 100, 97, 116, 101, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, - 116, 73, 110, 115, 101, 114, 116, 32, 60, 45, 32, 39, 73, 78, 83, 69, 82, 84, 39, 10, - 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 68, 101, 108, 101, 116, 101, 32, 60, - 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, - 101, 110, 116, 85, 112, 100, 97, 116, 101, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, - 39, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 85, 112, 100, 97, 116, 101, - 79, 102, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 79, 70, 39, 32, - 84, 114, 105, 103, 103, 101, 114, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 84, 114, - 105, 103, 103, 101, 114, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, - 105, 115, 116, 40, 67, 111, 108, 73, 100, 41, 10, 70, 111, 114, 69, 97, 99, 104, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 70, 111, 114, 69, 97, 99, 104, 82, 111, 119, 32, 47, - 32, 70, 111, 114, 69, 97, 99, 104, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 70, 111, - 114, 69, 97, 99, 104, 82, 111, 119, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 39, 69, - 65, 67, 72, 39, 32, 39, 82, 79, 87, 39, 10, 70, 111, 114, 69, 97, 99, 104, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 39, 69, 65, - 67, 72, 39, 32, 39, 83, 84, 65, 84, 69, 77, 69, 78, 84, 39, 10, 67, 114, 101, 97, - 116, 101, 84, 121, 112, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 84, 89, 80, 69, 39, - 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, - 105, 101, 100, 78, 97, 109, 101, 32, 39, 65, 83, 39, 32, 67, 114, 101, 97, 116, 101, 84, - 121, 112, 101, 10, 67, 114, 101, 97, 116, 101, 84, 121, 112, 101, 32, 60, 45, 32, 69, 110, - 117, 109, 83, 101, 108, 101, 99, 116, 84, 121, 112, 101, 32, 47, 32, 69, 110, 117, 109, 83, - 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 76, 105, 115, 116, 32, 47, 32, 67, - 114, 101, 97, 116, 101, 84, 121, 112, 101, 70, 114, 111, 109, 84, 121, 112, 101, 10, 67, 114, - 101, 97, 116, 101, 84, 121, 112, 101, 70, 114, 111, 109, 84, 121, 112, 101, 32, 60, 45, 32, - 84, 121, 112, 101, 10, 69, 110, 117, 109, 83, 101, 108, 101, 99, 116, 84, 121, 112, 101, 32, - 60, 45, 32, 39, 69, 78, 85, 77, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, - 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, - 41, 10, 69, 110, 117, 109, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 76, - 105, 115, 116, 32, 60, 45, 32, 39, 69, 78, 85, 77, 39, 32, 80, 97, 114, 101, 110, 115, - 40, 76, 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 41, - 63, 41, 10, 67, 114, 101, 97, 116, 101, 86, 105, 101, 119, 83, 116, 109, 116, 32, 60, 45, - 32, 67, 114, 101, 97, 116, 101, 83, 101, 99, 117, 114, 101, 63, 32, 67, 114, 101, 97, 116, - 101, 82, 101, 99, 117, 114, 115, 105, 118, 101, 63, 32, 39, 86, 73, 69, 87, 39, 32, 73, + 101, 114, 97, 108, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, + 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 99, 104, 101, 109, 97, 82, + 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, + 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 83, 99, 104, 101, + 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, + 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, + 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, + 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, + 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, 82, 101, 115, 101, 114, + 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, + 103, 76, 105, 116, 101, 114, 97, 108, 10, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, + 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, + 101, 114, 97, 108, 10, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, + 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 67, 97, 116, + 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, + 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 46, 39, 10, 83, 99, 104, + 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, 32, + 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 32, 39, 46, 39, 10, 82, 101, 115, 101, 114, + 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 60, 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, + 78, 97, 109, 101, 32, 39, 46, 39, 10, 84, 97, 98, 108, 101, 81, 117, 97, 108, 105, 102, + 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, 101, 78, 97, 109, 101, + 32, 39, 46, 39, 10, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 81, 117, + 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 60, 45, 32, 82, 101, 115, 101, 114, + 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 39, 46, 39, 10, 67, 114, 101, + 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, + 45, 32, 76, 105, 115, 116, 40, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, + 108, 117, 109, 110, 69, 108, 101, 109, 101, 110, 116, 41, 10, 67, 114, 101, 97, 116, 101, 84, + 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 68, 101, + 102, 105, 110, 105, 116, 105, 111, 110, 32, 47, 32, 67, 114, 101, 97, 116, 101, 84, 97, 98, + 108, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 67, 114, 101, 97, 116, 101, 84, + 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, + 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, + 10, 67, 114, 101, 97, 116, 101, 84, 97, 98, 108, 101, 67, 111, 110, 115, 116, 114, 97, 105, + 110, 116, 32, 60, 45, 32, 84, 111, 112, 76, 101, 118, 101, 108, 67, 111, 110, 115, 116, 114, + 97, 105, 110, 116, 10, 67, 111, 108, 117, 109, 110, 68, 101, 102, 105, 110, 105, 116, 105, 111, + 110, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 32, 84, 121, 112, 101, 63, 32, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, + 117, 109, 110, 63, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, 67, + 108, 97, 117, 115, 101, 63, 32, 67, 111, 108, 117, 109, 110, 67, 111, 110, 115, 116, 114, 97, + 105, 110, 116, 42, 10, 67, 111, 108, 117, 109, 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, + 116, 32, 60, 45, 32, 78, 111, 116, 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, + 110, 116, 32, 47, 32, 85, 110, 105, 113, 117, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, + 116, 32, 47, 32, 80, 114, 105, 109, 97, 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, + 97, 105, 110, 116, 32, 47, 32, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 32, + 47, 32, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, + 70, 111, 114, 101, 105, 103, 110, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 32, 47, 32, 67, 111, 108, 117, 109, 110, 67, 111, 108, 108, 97, 116, 105, 111, 110, 32, 47, + 32, 67, 111, 108, 117, 109, 110, 67, 111, 109, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, + 111, 116, 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, + 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, 78, 111, 116, + 78, 117, 108, 108, 67, 111, 108, 117, 109, 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 10, 78, 117, 108, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, + 78, 85, 76, 76, 39, 10, 78, 111, 116, 78, 117, 108, 108, 67, 111, 108, 117, 109, 110, 67, + 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 78, 79, 84, 39, 32, 39, + 78, 85, 76, 76, 39, 10, 85, 110, 105, 113, 117, 101, 67, 111, 110, 115, 116, 114, 97, 105, + 110, 116, 32, 60, 45, 32, 39, 85, 78, 73, 81, 85, 69, 39, 10, 80, 114, 105, 109, 97, + 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, + 80, 82, 73, 77, 65, 82, 89, 39, 32, 39, 75, 69, 89, 39, 10, 68, 101, 102, 97, 117, + 108, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, + 32, 67, 111, 108, 117, 109, 110, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, 114, 10, 67, + 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 67, + 72, 69, 67, 75, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 41, 10, 70, 111, 114, 101, 105, 103, 110, 75, 101, 121, 67, 111, 110, 115, 116, + 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 82, 69, 70, 69, 82, 69, 78, 67, 69, 83, + 39, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 80, 97, 114, 101, + 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, 63, 32, 75, 101, 121, 65, + 99, 116, 105, 111, 110, 115, 10, 67, 111, 108, 117, 109, 110, 67, 111, 108, 108, 97, 116, 105, + 111, 110, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, 39, 32, 68, 111, 116, 116, + 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 117, 109, 110, 67, + 111, 109, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, + 39, 32, 39, 67, 79, 77, 80, 82, 69, 83, 83, 73, 79, 78, 39, 32, 67, 111, 108, 73, + 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 75, 101, 121, 65, 99, 116, 105, 111, 110, 115, + 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 65, 99, 116, 105, 111, 110, 63, 32, 68, 101, + 108, 101, 116, 101, 65, 99, 116, 105, 111, 110, 63, 10, 85, 112, 100, 97, 116, 101, 65, 99, + 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 85, 80, 68, 65, 84, 69, + 39, 32, 75, 101, 121, 65, 99, 116, 105, 111, 110, 10, 68, 101, 108, 101, 116, 101, 65, 99, + 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 68, 69, 76, 69, 84, 69, + 39, 32, 75, 101, 121, 65, 99, 116, 105, 111, 110, 10, 75, 101, 121, 65, 99, 116, 105, 111, + 110, 32, 60, 45, 32, 78, 111, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 47, 32, 82, + 101, 115, 116, 114, 105, 99, 116, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 47, 32, 67, + 97, 115, 99, 97, 100, 101, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 47, 32, 83, 101, + 116, 78, 117, 108, 108, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 47, 32, 83, 101, 116, + 68, 101, 102, 97, 117, 108, 116, 75, 101, 121, 65, 99, 116, 105, 111, 110, 10, 78, 111, 75, + 101, 121, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 78, 79, 39, 32, 39, 65, 67, + 84, 73, 79, 78, 39, 10, 82, 101, 115, 116, 114, 105, 99, 116, 75, 101, 121, 65, 99, 116, + 105, 111, 110, 32, 60, 45, 32, 39, 82, 69, 83, 84, 82, 73, 67, 84, 39, 10, 67, 97, + 115, 99, 97, 100, 101, 75, 101, 121, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 67, + 65, 83, 67, 65, 68, 69, 39, 10, 83, 101, 116, 78, 117, 108, 108, 75, 101, 121, 65, 99, + 116, 105, 111, 110, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 78, 85, 76, 76, 39, + 10, 83, 101, 116, 68, 101, 102, 97, 117, 108, 116, 75, 101, 121, 65, 99, 116, 105, 111, 110, + 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 10, + 84, 111, 112, 76, 101, 118, 101, 108, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, + 45, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, 67, 108, 97, 117, + 115, 101, 63, 32, 84, 111, 112, 76, 101, 118, 101, 108, 67, 111, 110, 115, 116, 114, 97, 105, + 110, 116, 76, 105, 115, 116, 10, 84, 111, 112, 76, 101, 118, 101, 108, 67, 111, 110, 115, 116, + 114, 97, 105, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 84, 111, 112, 80, 114, 105, 109, + 97, 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, 84, + 111, 112, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 47, 32, + 84, 111, 112, 85, 110, 105, 113, 117, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, + 47, 32, 84, 111, 112, 70, 111, 114, 101, 105, 103, 110, 75, 101, 121, 67, 111, 110, 115, 116, + 114, 97, 105, 110, 116, 10, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 67, 79, 78, 83, 84, 82, 65, 73, 78, + 84, 39, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, 10, 84, 111, + 112, 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, + 67, 104, 101, 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 84, 111, 112, 80, + 114, 105, 109, 97, 114, 121, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, + 60, 45, 32, 39, 80, 82, 73, 77, 65, 82, 89, 39, 32, 39, 75, 69, 89, 39, 32, 67, + 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 10, 84, 111, 112, 85, 110, 105, 113, 117, + 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 32, 60, 45, 32, 39, 85, 78, 73, 81, + 85, 69, 39, 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 10, 84, 111, 112, + 70, 111, 114, 101, 105, 103, 110, 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 32, 60, 45, 32, 39, 70, 79, 82, 69, 73, 71, 78, 39, 32, 39, 75, 69, 89, 39, 32, + 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 32, 70, 111, 114, 101, 105, 103, 110, + 75, 101, 121, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 10, 67, 111, 108, 117, 109, 110, + 73, 100, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, + 116, 40, 67, 111, 108, 73, 100, 41, 41, 10, 80, 108, 97, 105, 110, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 32, 60, 45, 32, 33, 82, 101, 115, 101, 114, 118, 101, 100, 75, 101, + 121, 119, 111, 114, 100, 32, 60, 91, 97, 45, 122, 95, 93, 105, 91, 97, 45, 122, 48, 45, + 57, 95, 93, 105, 42, 62, 10, 81, 117, 111, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 60, 45, 32, 39, 34, 39, 32, 91, 94, 34, 93, 42, 32, 39, 34, 39, + 10, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, + 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 68, 111, 116, 67, 111, 108, 76, 97, + 98, 101, 108, 42, 10, 68, 111, 116, 67, 111, 108, 76, 97, 98, 101, 108, 32, 60, 45, 32, + 39, 46, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 10, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 60, 45, 32, 81, 117, 111, 116, 101, 100, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 47, 32, 80, 108, 97, 105, 110, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 10, 67, 111, 108, 73, 100, 32, 60, 45, 32, 85, 110, 114, 101, 115, 101, 114, 118, 101, + 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, + 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 10, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 60, 45, 32, 67, + 111, 108, 73, 100, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 84, 121, 112, 101, 70, 117, 110, 99, 78, + 97, 109, 101, 32, 60, 45, 32, 85, 110, 114, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, + 119, 111, 114, 100, 32, 47, 32, 84, 121, 112, 101, 70, 117, 110, 99, 75, 101, 121, 119, 111, + 114, 100, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 84, 121, 112, 101, + 70, 117, 110, 99, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 84, 121, 112, 101, 78, + 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 70, 117, 110, 99, 78, 97, 109, + 101, 75, 101, 121, 119, 111, 114, 100, 10, 84, 121, 112, 101, 78, 97, 109, 101, 32, 60, 45, + 32, 85, 110, 114, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, + 32, 84, 121, 112, 101, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 76, 97, 98, 101, 108, 32, 60, + 45, 32, 82, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, + 85, 110, 114, 101, 115, 101, 114, 118, 101, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, + 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, + 70, 117, 110, 99, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 84, 121, + 112, 101, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 73, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, 116, 114, + 105, 110, 103, 32, 60, 45, 32, 67, 111, 108, 76, 97, 98, 101, 108, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 32, 47, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, + 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 76, 97, 98, 101, 108, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 67, 111, 108, 76, 97, 98, + 101, 108, 10, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, + 114, 97, 108, 10, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, + 60, 45, 32, 71, 101, 110, 101, 114, 97, 116, 101, 100, 63, 32, 39, 65, 83, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 32, 71, 101, + 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 84, 121, 112, 101, 63, 10, 71, + 101, 110, 101, 114, 97, 116, 101, 100, 32, 60, 45, 32, 39, 71, 69, 78, 69, 82, 65, 84, + 69, 68, 39, 32, 65, 108, 119, 97, 121, 115, 79, 114, 66, 121, 68, 101, 102, 97, 117, 108, + 116, 63, 10, 65, 108, 119, 97, 121, 115, 79, 114, 66, 121, 68, 101, 102, 97, 117, 108, 116, + 32, 60, 45, 32, 39, 65, 76, 87, 65, 89, 83, 39, 32, 47, 32, 40, 39, 66, 89, 39, + 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 41, 10, 71, 101, 110, 101, 114, 97, 116, 101, + 100, 67, 111, 108, 117, 109, 110, 84, 121, 112, 101, 32, 60, 45, 32, 86, 105, 114, 116, 117, + 97, 108, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, 47, 32, + 83, 116, 111, 114, 101, 100, 71, 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, + 110, 10, 67, 111, 109, 109, 105, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 79, + 78, 39, 32, 39, 67, 79, 77, 77, 73, 84, 39, 32, 80, 114, 101, 115, 101, 114, 118, 101, + 79, 114, 68, 101, 108, 101, 116, 101, 32, 39, 82, 79, 87, 83, 39, 10, 80, 114, 101, 115, + 101, 114, 118, 101, 79, 114, 68, 101, 108, 101, 116, 101, 32, 60, 45, 32, 80, 114, 101, 115, + 101, 114, 118, 101, 82, 111, 119, 115, 32, 47, 32, 68, 101, 108, 101, 116, 101, 82, 111, 119, + 115, 10, 80, 114, 101, 115, 101, 114, 118, 101, 82, 111, 119, 115, 32, 60, 45, 32, 39, 80, + 82, 69, 83, 69, 82, 86, 69, 39, 10, 68, 101, 108, 101, 116, 101, 82, 111, 119, 115, 32, + 60, 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 86, 105, 114, 116, 117, 97, 108, 71, + 101, 110, 101, 114, 97, 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 86, + 73, 82, 84, 85, 65, 76, 39, 10, 83, 116, 111, 114, 101, 100, 71, 101, 110, 101, 114, 97, + 116, 101, 100, 67, 111, 108, 117, 109, 110, 32, 60, 45, 32, 39, 83, 84, 79, 82, 69, 68, + 39, 10, 67, 114, 101, 97, 116, 101, 84, 114, 105, 103, 103, 101, 114, 83, 116, 109, 116, 32, + 60, 45, 32, 39, 84, 82, 73, 71, 71, 69, 82, 39, 32, 73, 102, 78, 111, 116, 69, 120, + 105, 115, 116, 115, 63, 32, 84, 114, 105, 103, 103, 101, 114, 78, 97, 109, 101, 32, 84, 114, + 105, 103, 103, 101, 114, 84, 105, 109, 105, 110, 103, 32, 84, 114, 105, 103, 103, 101, 114, 69, + 118, 101, 110, 116, 32, 39, 79, 78, 39, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, + 97, 109, 101, 32, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 67, 108, 97, 117, 115, + 101, 63, 32, 70, 111, 114, 69, 97, 99, 104, 67, 108, 97, 117, 115, 101, 63, 32, 84, 114, + 105, 103, 103, 101, 114, 66, 111, 100, 121, 10, 84, 114, 105, 103, 103, 101, 114, 66, 111, 100, + 121, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 32, 47, 32, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, + 32, 68, 101, 108, 101, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 77, + 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 84, 114, + 105, 103, 103, 101, 114, 78, 97, 109, 101, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 10, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 82, 69, 70, 69, 82, 69, 78, 67, 73, 78, 71, 39, 32, 82, + 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 73, 116, 101, 109, 32, 82, 101, 102, 101, 114, + 101, 110, 99, 105, 110, 103, 73, 116, 101, 109, 63, 10, 82, 101, 102, 101, 114, 101, 110, 99, + 105, 110, 103, 73, 116, 101, 109, 32, 60, 45, 32, 82, 101, 102, 101, 114, 101, 110, 99, 105, + 110, 103, 78, 101, 119, 84, 97, 98, 108, 101, 65, 115, 32, 47, 32, 82, 101, 102, 101, 114, + 101, 110, 99, 105, 110, 103, 79, 108, 100, 84, 97, 98, 108, 101, 65, 115, 10, 82, 101, 102, + 101, 114, 101, 110, 99, 105, 110, 103, 78, 101, 119, 84, 97, 98, 108, 101, 65, 115, 32, 60, + 45, 32, 39, 78, 69, 87, 39, 32, 39, 84, 65, 66, 76, 69, 39, 32, 39, 65, 83, 39, + 32, 67, 111, 108, 73, 100, 10, 82, 101, 102, 101, 114, 101, 110, 99, 105, 110, 103, 79, 108, + 100, 84, 97, 98, 108, 101, 65, 115, 32, 60, 45, 32, 39, 79, 76, 68, 39, 32, 39, 84, + 65, 66, 76, 69, 39, 32, 39, 65, 83, 39, 32, 67, 111, 108, 73, 100, 10, 84, 114, 105, + 103, 103, 101, 114, 84, 105, 109, 105, 110, 103, 32, 60, 45, 32, 84, 114, 105, 103, 103, 101, + 114, 66, 101, 102, 111, 114, 101, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 65, 102, 116, + 101, 114, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 73, 110, 115, 116, 101, 97, 100, 79, + 102, 10, 84, 114, 105, 103, 103, 101, 114, 66, 101, 102, 111, 114, 101, 32, 60, 45, 32, 39, + 66, 69, 70, 79, 82, 69, 39, 10, 84, 114, 105, 103, 103, 101, 114, 65, 102, 116, 101, 114, + 32, 60, 45, 32, 39, 65, 70, 84, 69, 82, 39, 10, 84, 114, 105, 103, 103, 101, 114, 73, + 110, 115, 116, 101, 97, 100, 79, 102, 32, 60, 45, 32, 39, 73, 78, 83, 84, 69, 65, 68, + 39, 32, 39, 79, 70, 39, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 32, + 60, 45, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 85, 112, 100, 97, 116, + 101, 79, 102, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 73, 110, + 115, 101, 114, 116, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 68, + 101, 108, 101, 116, 101, 32, 47, 32, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, + 85, 112, 100, 97, 116, 101, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 73, + 110, 115, 101, 114, 116, 32, 60, 45, 32, 39, 73, 78, 83, 69, 82, 84, 39, 10, 84, 114, + 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 68, 101, 108, 101, 116, 101, 32, 60, 45, 32, + 39, 68, 69, 76, 69, 84, 69, 39, 10, 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, + 116, 85, 112, 100, 97, 116, 101, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 10, + 84, 114, 105, 103, 103, 101, 114, 69, 118, 101, 110, 116, 85, 112, 100, 97, 116, 101, 79, 102, + 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 79, 70, 39, 32, 84, 114, + 105, 103, 103, 101, 114, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 84, 114, 105, 103, + 103, 101, 114, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, + 116, 40, 67, 111, 108, 73, 100, 41, 10, 70, 111, 114, 69, 97, 99, 104, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 70, 111, 114, 69, 97, 99, 104, 82, 111, 119, 32, 47, 32, 70, + 111, 114, 69, 97, 99, 104, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 70, 111, 114, 69, + 97, 99, 104, 82, 111, 119, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 39, 69, 65, 67, + 72, 39, 32, 39, 82, 79, 87, 39, 10, 70, 111, 114, 69, 97, 99, 104, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 39, 69, 65, 67, 72, + 39, 32, 39, 83, 84, 65, 84, 69, 77, 69, 78, 84, 39, 10, 67, 114, 101, 97, 116, 101, + 84, 121, 112, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 84, 89, 80, 69, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, - 100, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, - 115, 116, 63, 32, 87, 105, 116, 104, 76, 105, 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, - 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, - 97, 108, 10, 67, 114, 101, 97, 116, 101, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, - 45, 32, 39, 82, 69, 67, 85, 82, 83, 73, 86, 69, 39, 10, 67, 114, 101, 97, 116, 101, - 83, 101, 99, 117, 114, 101, 32, 60, 45, 32, 39, 83, 69, 67, 85, 82, 69, 39, 10, 68, - 101, 97, 108, 108, 111, 99, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, - 45, 32, 39, 68, 69, 65, 76, 76, 79, 67, 65, 84, 69, 39, 32, 68, 101, 97, 108, 108, - 111, 99, 97, 116, 101, 80, 114, 101, 112, 97, 114, 101, 63, 32, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 10, 68, 101, 97, 108, 108, 111, 99, 97, 116, 101, 80, 114, 101, 112, 97, - 114, 101, 32, 60, 45, 32, 39, 80, 82, 69, 80, 65, 82, 69, 39, 10, 68, 101, 108, 101, - 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, - 108, 97, 117, 115, 101, 63, 32, 39, 68, 69, 76, 69, 84, 69, 39, 32, 39, 70, 82, 79, - 77, 39, 32, 84, 97, 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 68, 101, - 108, 101, 116, 101, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 32, 87, 104, 101, - 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, - 108, 97, 117, 115, 101, 63, 10, 84, 114, 117, 110, 99, 97, 116, 101, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 32, 60, 45, 32, 39, 84, 82, 85, 78, 67, 65, 84, 69, 39, 32, 39, - 84, 65, 66, 76, 69, 39, 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, - 101, 10, 84, 97, 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 60, 45, 32, - 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 39, 65, 83, 39, 63, 32, - 67, 111, 108, 73, 100, 63, 10, 68, 101, 108, 101, 116, 101, 85, 115, 105, 110, 103, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 76, 105, 115, 116, - 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, 68, 101, 115, 99, 114, 105, 98, 101, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 104, 111, 119, 84, 97, 98, 108, - 101, 115, 32, 47, 32, 83, 104, 111, 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, 83, - 101, 108, 101, 99, 116, 32, 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 101, 108, 101, - 99, 116, 32, 47, 32, 83, 104, 111, 119, 65, 108, 108, 84, 97, 98, 108, 101, 115, 32, 47, - 32, 83, 104, 111, 119, 66, 121, 78, 97, 109, 101, 32, 47, 32, 68, 101, 115, 99, 114, 105, - 98, 101, 66, 121, 78, 97, 109, 101, 10, 35, 32, 34, 68, 69, 83, 67, 82, 73, 66, 69, - 32, 40, 113, 117, 101, 114, 121, 41, 34, 32, 97, 110, 100, 32, 34, 83, 85, 77, 77, 65, - 82, 73, 90, 69, 32, 40, 113, 117, 101, 114, 121, 41, 34, 32, 100, 101, 115, 99, 114, 105, - 98, 101, 32, 116, 104, 101, 32, 113, 117, 101, 114, 121, 39, 115, 32, 99, 111, 108, 117, 109, - 110, 115, 46, 32, 34, 83, 72, 79, 87, 32, 40, 113, 117, 101, 114, 121, 41, 34, 32, 100, - 111, 101, 115, 32, 116, 111, 111, 32, 98, 117, 116, 32, 105, 115, 32, 100, 101, 112, 114, 101, - 99, 97, 116, 101, 100, 44, 10, 35, 32, 115, 111, 32, 83, 104, 111, 119, 68, 101, 112, 114, - 101, 99, 97, 116, 101, 100, 83, 101, 108, 101, 99, 116, 32, 105, 115, 32, 112, 97, 114, 115, - 101, 100, 32, 121, 101, 116, 32, 115, 117, 112, 112, 114, 101, 115, 115, 101, 100, 32, 102, 114, - 111, 109, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, 101, 116, 101, 32, 40, 109, 97, 116, - 99, 104, 101, 114, 95, 102, 97, 99, 116, 111, 114, 121, 46, 99, 112, 112, 41, 32, 45, 32, - 83, 72, 79, 87, 32, 119, 111, 110, 39, 116, 32, 111, 102, 102, 101, 114, 32, 116, 111, 32, - 99, 111, 109, 112, 108, 101, 116, 101, 32, 97, 32, 113, 117, 101, 114, 121, 46, 10, 83, 104, - 111, 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, 83, 101, 108, 101, 99, 116, 32, 60, - 45, 32, 83, 104, 111, 119, 82, 117, 108, 101, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, - 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 68, 101, 115, 99, 114, - 105, 98, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, 98, - 101, 79, 114, 83, 117, 109, 109, 97, 114, 105, 122, 101, 32, 83, 101, 108, 101, 99, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 83, 104, 111, - 119, 65, 108, 108, 84, 97, 98, 108, 101, 115, 32, 60, 45, 32, 83, 104, 111, 119, 79, 114, - 68, 101, 115, 99, 114, 105, 98, 101, 32, 39, 65, 76, 76, 39, 32, 39, 84, 65, 66, 76, - 69, 83, 39, 63, 10, 83, 104, 111, 119, 84, 97, 98, 108, 101, 115, 32, 60, 45, 32, 83, - 104, 111, 119, 79, 114, 68, 101, 115, 99, 114, 105, 98, 101, 32, 39, 84, 65, 66, 76, 69, - 83, 39, 32, 39, 70, 82, 79, 77, 39, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, - 97, 109, 101, 10, 35, 32, 34, 83, 72, 79, 87, 32, 110, 97, 109, 101, 34, 32, 105, 115, - 32, 115, 101, 116, 116, 105, 110, 103, 115, 45, 102, 105, 114, 115, 116, 44, 32, 115, 111, 32, - 105, 116, 115, 32, 116, 97, 114, 103, 101, 116, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, - 101, 116, 101, 115, 32, 115, 101, 116, 116, 105, 110, 103, 32, 110, 97, 109, 101, 115, 32, 40, - 97, 110, 100, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, 77, 121, 83, 81, - 76, 32, 102, 111, 114, 109, 115, 41, 44, 32, 110, 111, 116, 10, 35, 32, 97, 114, 98, 105, - 116, 114, 97, 114, 121, 32, 116, 97, 98, 108, 101, 115, 46, 32, 34, 68, 69, 83, 67, 82, - 73, 66, 69, 34, 47, 34, 83, 85, 77, 77, 65, 82, 73, 90, 69, 34, 32, 100, 101, 115, - 99, 114, 105, 98, 101, 32, 97, 32, 114, 101, 108, 97, 116, 105, 111, 110, 44, 32, 115, 111, - 32, 116, 104, 101, 105, 114, 32, 116, 97, 114, 103, 101, 116, 32, 97, 117, 116, 111, 99, 111, - 109, 112, 108, 101, 116, 101, 115, 32, 116, 97, 98, 108, 101, 32, 110, 97, 109, 101, 115, 46, - 10, 83, 104, 111, 119, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 83, 104, 111, 119, 82, - 117, 108, 101, 32, 83, 104, 111, 119, 84, 97, 114, 103, 101, 116, 63, 10, 68, 101, 115, 99, - 114, 105, 98, 101, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, - 98, 101, 79, 114, 83, 117, 109, 109, 97, 114, 105, 122, 101, 32, 68, 101, 115, 99, 114, 105, - 98, 101, 84, 97, 114, 103, 101, 116, 63, 10, 68, 101, 115, 99, 114, 105, 98, 101, 79, 114, - 83, 117, 109, 109, 97, 114, 105, 122, 101, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, 98, - 101, 82, 117, 108, 101, 32, 47, 32, 83, 117, 109, 109, 97, 114, 105, 122, 101, 10, 35, 32, - 83, 72, 79, 87, 39, 115, 32, 111, 119, 110, 32, 102, 111, 114, 109, 115, 32, 40, 97, 32, - 115, 101, 116, 116, 105, 110, 103, 115, 45, 102, 105, 114, 115, 116, 32, 110, 97, 109, 101, 32, - 97, 110, 100, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, 77, 121, 83, 81, - 76, 32, 102, 111, 114, 109, 115, 41, 32, 112, 108, 117, 115, 32, 116, 104, 101, 32, 100, 101, - 115, 99, 114, 105, 98, 101, 45, 115, 116, 121, 108, 101, 32, 116, 97, 114, 103, 101, 116, 115, - 32, 105, 116, 32, 115, 116, 105, 108, 108, 10, 35, 32, 116, 111, 108, 101, 114, 97, 116, 101, - 115, 32, 102, 111, 114, 32, 116, 104, 101, 32, 100, 101, 112, 114, 101, 99, 97, 116, 101, 100, - 32, 34, 100, 101, 115, 99, 114, 105, 98, 101, 32, 118, 105, 97, 32, 83, 72, 79, 87, 34, - 46, 32, 79, 110, 108, 121, 32, 115, 101, 116, 116, 105, 110, 103, 115, 32, 97, 110, 100, 32, - 116, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, 102, 111, 114, 109, 115, 32, 97, 114, - 101, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, 101, 116, 101, 100, 32, 97, 102, 116, 101, - 114, 32, 83, 72, 79, 87, 59, 10, 35, 32, 97, 32, 113, 117, 97, 108, 105, 102, 105, 101, - 100, 32, 116, 97, 98, 108, 101, 32, 105, 115, 32, 112, 97, 114, 115, 101, 100, 32, 98, 117, - 116, 32, 105, 116, 115, 32, 115, 117, 103, 103, 101, 115, 116, 105, 111, 110, 115, 32, 97, 114, - 101, 32, 115, 117, 112, 112, 114, 101, 115, 115, 101, 100, 32, 40, 115, 101, 101, 32, 109, 97, - 116, 99, 104, 101, 114, 46, 99, 112, 112, 41, 46, 10, 83, 104, 111, 119, 84, 97, 114, 103, - 101, 116, 32, 60, 45, 32, 83, 104, 111, 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, - 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 47, - 32, 83, 104, 111, 119, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 47, 32, 68, + 100, 78, 97, 109, 101, 32, 39, 65, 83, 39, 32, 67, 114, 101, 97, 116, 101, 84, 121, 112, + 101, 10, 67, 114, 101, 97, 116, 101, 84, 121, 112, 101, 32, 60, 45, 32, 69, 110, 117, 109, + 83, 101, 108, 101, 99, 116, 84, 121, 112, 101, 32, 47, 32, 69, 110, 117, 109, 83, 116, 114, + 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 76, 105, 115, 116, 32, 47, 32, 67, 114, 101, + 97, 116, 101, 84, 121, 112, 101, 70, 114, 111, 109, 84, 121, 112, 101, 10, 67, 114, 101, 97, + 116, 101, 84, 121, 112, 101, 70, 114, 111, 109, 84, 121, 112, 101, 32, 60, 45, 32, 84, 121, + 112, 101, 10, 69, 110, 117, 109, 83, 101, 108, 101, 99, 116, 84, 121, 112, 101, 32, 60, 45, + 32, 39, 69, 78, 85, 77, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, + 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, + 69, 110, 117, 109, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 76, 105, 115, + 116, 32, 60, 45, 32, 39, 69, 78, 85, 77, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, + 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 41, 63, 41, + 10, 67, 114, 101, 97, 116, 101, 86, 105, 101, 119, 83, 116, 109, 116, 32, 60, 45, 32, 67, + 114, 101, 97, 116, 101, 83, 101, 99, 117, 114, 101, 63, 32, 67, 114, 101, 97, 116, 101, 82, + 101, 99, 117, 114, 115, 105, 118, 101, 63, 32, 39, 86, 73, 69, 87, 39, 32, 73, 102, 78, + 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, + 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, + 63, 32, 87, 105, 116, 104, 76, 105, 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 101, 108, + 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, + 10, 67, 114, 101, 97, 116, 101, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, 45, 32, + 39, 82, 69, 67, 85, 82, 83, 73, 86, 69, 39, 10, 67, 114, 101, 97, 116, 101, 83, 101, + 99, 117, 114, 101, 32, 60, 45, 32, 39, 83, 69, 67, 85, 82, 69, 39, 10, 68, 101, 97, + 108, 108, 111, 99, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, + 39, 68, 69, 65, 76, 76, 79, 67, 65, 84, 69, 39, 32, 68, 101, 97, 108, 108, 111, 99, + 97, 116, 101, 80, 114, 101, 112, 97, 114, 101, 63, 32, 67, 111, 108, 73, 100, 79, 114, 83, + 116, 114, 105, 110, 103, 10, 68, 101, 97, 108, 108, 111, 99, 97, 116, 101, 80, 114, 101, 112, + 97, 114, 101, 32, 60, 45, 32, 39, 80, 82, 69, 80, 65, 82, 69, 39, 10, 68, 101, 108, + 101, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, + 67, 108, 97, 117, 115, 101, 63, 32, 39, 68, 69, 76, 69, 84, 69, 39, 32, 39, 70, 82, + 79, 77, 39, 32, 84, 97, 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 68, + 101, 108, 101, 116, 101, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 32, 87, 104, + 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, + 67, 108, 97, 117, 115, 101, 63, 10, 84, 114, 117, 110, 99, 97, 116, 101, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 84, 82, 85, 78, 67, 65, 84, 69, 39, 32, + 39, 84, 65, 66, 76, 69, 39, 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, + 109, 101, 10, 84, 97, 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 60, 45, + 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 39, 65, 83, 39, 63, + 32, 67, 111, 108, 73, 100, 63, 10, 68, 101, 108, 101, 116, 101, 85, 115, 105, 110, 103, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 76, 105, 115, + 116, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, 68, 101, 115, 99, 114, 105, 98, 101, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 104, 111, 119, 84, 97, 98, + 108, 101, 115, 32, 47, 32, 83, 104, 111, 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, + 83, 101, 108, 101, 99, 116, 32, 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 101, 108, + 101, 99, 116, 32, 47, 32, 83, 104, 111, 119, 65, 108, 108, 84, 97, 98, 108, 101, 115, 32, + 47, 32, 83, 104, 111, 119, 66, 121, 78, 97, 109, 101, 32, 47, 32, 68, 101, 115, 99, 114, + 105, 98, 101, 66, 121, 78, 97, 109, 101, 10, 35, 32, 34, 68, 69, 83, 67, 82, 73, 66, + 69, 32, 40, 113, 117, 101, 114, 121, 41, 34, 32, 97, 110, 100, 32, 34, 83, 85, 77, 77, + 65, 82, 73, 90, 69, 32, 40, 113, 117, 101, 114, 121, 41, 34, 32, 100, 101, 115, 99, 114, + 105, 98, 101, 32, 116, 104, 101, 32, 113, 117, 101, 114, 121, 39, 115, 32, 99, 111, 108, 117, + 109, 110, 115, 46, 32, 34, 83, 72, 79, 87, 32, 40, 113, 117, 101, 114, 121, 41, 34, 32, + 100, 111, 101, 115, 32, 116, 111, 111, 32, 98, 117, 116, 32, 105, 115, 32, 100, 101, 112, 114, + 101, 99, 97, 116, 101, 100, 44, 10, 35, 32, 115, 111, 32, 83, 104, 111, 119, 68, 101, 112, + 114, 101, 99, 97, 116, 101, 100, 83, 101, 108, 101, 99, 116, 32, 105, 115, 32, 112, 97, 114, + 115, 101, 100, 32, 121, 101, 116, 32, 115, 117, 112, 112, 114, 101, 115, 115, 101, 100, 32, 102, + 114, 111, 109, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, 101, 116, 101, 32, 40, 109, 97, + 116, 99, 104, 101, 114, 95, 102, 97, 99, 116, 111, 114, 121, 46, 99, 112, 112, 41, 32, 45, + 32, 83, 72, 79, 87, 32, 119, 111, 110, 39, 116, 32, 111, 102, 102, 101, 114, 32, 116, 111, + 32, 99, 111, 109, 112, 108, 101, 116, 101, 32, 97, 32, 113, 117, 101, 114, 121, 46, 10, 83, + 104, 111, 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, 83, 101, 108, 101, 99, 116, 32, + 60, 45, 32, 83, 104, 111, 119, 82, 117, 108, 101, 32, 83, 101, 108, 101, 99, 116, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 68, 101, 115, 99, + 114, 105, 98, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, + 98, 101, 79, 114, 83, 117, 109, 109, 97, 114, 105, 122, 101, 32, 83, 101, 108, 101, 99, 116, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 83, 104, + 111, 119, 65, 108, 108, 84, 97, 98, 108, 101, 115, 32, 60, 45, 32, 83, 104, 111, 119, 79, + 114, 68, 101, 115, 99, 114, 105, 98, 101, 32, 39, 65, 76, 76, 39, 32, 39, 84, 65, 66, + 76, 69, 83, 39, 63, 10, 83, 104, 111, 119, 84, 97, 98, 108, 101, 115, 32, 60, 45, 32, + 83, 104, 111, 119, 79, 114, 68, 101, 115, 99, 114, 105, 98, 101, 32, 39, 84, 65, 66, 76, + 69, 83, 39, 32, 39, 70, 82, 79, 77, 39, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, + 78, 97, 109, 101, 10, 35, 32, 34, 83, 72, 79, 87, 32, 110, 97, 109, 101, 34, 32, 105, + 115, 32, 115, 101, 116, 116, 105, 110, 103, 115, 45, 102, 105, 114, 115, 116, 44, 32, 115, 111, + 32, 105, 116, 115, 32, 116, 97, 114, 103, 101, 116, 32, 97, 117, 116, 111, 99, 111, 109, 112, + 108, 101, 116, 101, 115, 32, 115, 101, 116, 116, 105, 110, 103, 32, 110, 97, 109, 101, 115, 32, + 40, 97, 110, 100, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, 77, 121, 83, + 81, 76, 32, 102, 111, 114, 109, 115, 41, 44, 32, 110, 111, 116, 10, 35, 32, 97, 114, 98, + 105, 116, 114, 97, 114, 121, 32, 116, 97, 98, 108, 101, 115, 46, 32, 34, 68, 69, 83, 67, + 82, 73, 66, 69, 34, 47, 34, 83, 85, 77, 77, 65, 82, 73, 90, 69, 34, 32, 100, 101, + 115, 99, 114, 105, 98, 101, 32, 97, 32, 114, 101, 108, 97, 116, 105, 111, 110, 44, 32, 115, + 111, 32, 116, 104, 101, 105, 114, 32, 116, 97, 114, 103, 101, 116, 32, 97, 117, 116, 111, 99, + 111, 109, 112, 108, 101, 116, 101, 115, 32, 116, 97, 98, 108, 101, 32, 110, 97, 109, 101, 115, + 46, 10, 83, 104, 111, 119, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 83, 104, 111, 119, + 82, 117, 108, 101, 32, 83, 104, 111, 119, 84, 97, 114, 103, 101, 116, 63, 10, 68, 101, 115, + 99, 114, 105, 98, 101, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 68, 101, 115, 99, 114, + 105, 98, 101, 79, 114, 83, 117, 109, 109, 97, 114, 105, 122, 101, 32, 68, 101, 115, 99, 114, + 105, 98, 101, 84, 97, 114, 103, 101, 116, 63, 10, 68, 101, 115, 99, 114, 105, 98, 101, 79, + 114, 83, 117, 109, 109, 97, 114, 105, 122, 101, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, + 98, 101, 82, 117, 108, 101, 32, 47, 32, 83, 117, 109, 109, 97, 114, 105, 122, 101, 10, 35, + 32, 83, 72, 79, 87, 39, 115, 32, 111, 119, 110, 32, 102, 111, 114, 109, 115, 32, 40, 97, + 32, 115, 101, 116, 116, 105, 110, 103, 115, 45, 102, 105, 114, 115, 116, 32, 110, 97, 109, 101, + 32, 97, 110, 100, 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, 77, 121, 83, + 81, 76, 32, 102, 111, 114, 109, 115, 41, 32, 112, 108, 117, 115, 32, 116, 104, 101, 32, 100, + 101, 115, 99, 114, 105, 98, 101, 45, 115, 116, 121, 108, 101, 32, 116, 97, 114, 103, 101, 116, + 115, 32, 105, 116, 32, 115, 116, 105, 108, 108, 10, 35, 32, 116, 111, 108, 101, 114, 97, 116, + 101, 115, 32, 102, 111, 114, 32, 116, 104, 101, 32, 100, 101, 112, 114, 101, 99, 97, 116, 101, + 100, 32, 34, 100, 101, 115, 99, 114, 105, 98, 101, 32, 118, 105, 97, 32, 83, 72, 79, 87, + 34, 46, 32, 79, 110, 108, 121, 32, 115, 101, 116, 116, 105, 110, 103, 115, 32, 97, 110, 100, + 32, 116, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, 102, 111, 114, 109, 115, 32, 97, + 114, 101, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, 101, 116, 101, 100, 32, 97, 102, 116, + 101, 114, 32, 83, 72, 79, 87, 59, 10, 35, 32, 97, 32, 113, 117, 97, 108, 105, 102, 105, + 101, 100, 32, 116, 97, 98, 108, 101, 32, 105, 115, 32, 112, 97, 114, 115, 101, 100, 32, 98, + 117, 116, 32, 105, 116, 115, 32, 115, 117, 103, 103, 101, 115, 116, 105, 111, 110, 115, 32, 97, + 114, 101, 32, 115, 117, 112, 112, 114, 101, 115, 115, 101, 100, 32, 40, 115, 101, 101, 32, 109, + 97, 116, 99, 104, 101, 114, 46, 99, 112, 112, 41, 46, 10, 83, 104, 111, 119, 84, 97, 114, + 103, 101, 116, 32, 60, 45, 32, 83, 104, 111, 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, + 100, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, + 47, 32, 83, 104, 111, 119, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 47, 32, + 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, + 108, 32, 47, 32, 83, 104, 111, 119, 83, 112, 101, 99, 105, 97, 108, 70, 111, 114, 109, 10, + 35, 32, 34, 83, 72, 79, 87, 32, 99, 97, 116, 46, 116, 98, 108, 34, 32, 115, 116, 105, + 108, 108, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 116, 97, 98, 108, 101, + 32, 40, 100, 101, 112, 114, 101, 99, 97, 116, 101, 100, 41, 44, 32, 98, 117, 116, 32, 105, + 115, 32, 115, 117, 112, 112, 114, 101, 115, 115, 101, 100, 32, 102, 114, 111, 109, 32, 97, 117, + 116, 111, 99, 111, 109, 112, 108, 101, 116, 101, 32, 40, 115, 101, 101, 32, 109, 97, 116, 99, + 104, 101, 114, 46, 99, 112, 112, 41, 32, 115, 111, 32, 83, 72, 79, 87, 10, 35, 32, 100, + 111, 101, 115, 32, 110, 111, 116, 32, 99, 111, 109, 112, 108, 101, 116, 101, 32, 113, 117, 97, + 108, 105, 102, 105, 101, 100, 32, 116, 97, 98, 108, 101, 115, 32, 40, 117, 110, 108, 105, 107, + 101, 32, 68, 69, 83, 67, 82, 73, 66, 69, 44, 32, 119, 104, 105, 99, 104, 32, 100, 111, + 101, 115, 41, 46, 32, 87, 114, 97, 112, 115, 32, 116, 104, 101, 32, 103, 101, 110, 101, 114, + 105, 99, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, + 101, 32, 40, 115, 101, 108, 101, 99, 116, 46, 103, 114, 97, 109, 41, 46, 10, 83, 104, 111, + 119, 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, 81, 117, 97, 108, 105, 102, 105, 101, 100, + 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, + 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 35, 32, 65, 32, 98, 97, 114, 101, + 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 105, 115, 32, 115, 117, 103, 103, 101, + 115, 116, 101, 100, 32, 97, 115, 32, 97, 32, 115, 101, 116, 116, 105, 110, 103, 32, 110, 97, + 109, 101, 32, 40, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 105, 115, 32, 111, + 118, 101, 114, 114, 105, 100, 100, 101, 110, 32, 116, 111, 32, 83, 85, 71, 71, 69, 83, 84, + 95, 83, 69, 84, 84, 73, 78, 71, 95, 78, 65, 77, 69, 41, 46, 10, 83, 104, 111, 119, + 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 60, 45, 32, 83, 101, 116, 116, 105, + 110, 103, 78, 97, 109, 101, 10, 35, 32, 84, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, + 32, 77, 121, 83, 81, 76, 32, 102, 111, 114, 109, 115, 32, 97, 114, 101, 32, 111, 110, 108, + 121, 32, 104, 101, 114, 101, 32, 115, 111, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, 101, + 116, 101, 32, 115, 117, 103, 103, 101, 115, 116, 115, 32, 116, 104, 101, 115, 101, 32, 107, 101, + 121, 119, 111, 114, 100, 115, 32, 97, 102, 116, 101, 114, 32, 83, 72, 79, 87, 59, 32, 112, + 97, 114, 115, 105, 110, 103, 32, 111, 102, 32, 101, 46, 103, 46, 10, 35, 32, 34, 83, 72, + 79, 87, 32, 100, 97, 116, 97, 98, 97, 115, 101, 115, 34, 32, 114, 101, 115, 111, 108, 118, + 101, 115, 32, 116, 104, 114, 111, 117, 103, 104, 32, 83, 104, 111, 119, 83, 101, 116, 116, 105, + 110, 103, 78, 97, 109, 101, 32, 40, 116, 104, 101, 32, 105, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 41, 32, 97, 98, 111, 118, 101, 44, 32, 119, 104, 105, 99, 104, 32, 116, 104, 101, + 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 101, 114, 32, 115, 112, 101, 99, 105, 97, 108, + 45, 99, 97, 115, 101, 115, 46, 10, 83, 104, 111, 119, 83, 112, 101, 99, 105, 97, 108, 70, + 111, 114, 109, 32, 60, 45, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 83, 39, 32, 47, + 32, 39, 83, 67, 72, 69, 77, 65, 83, 39, 32, 47, 32, 39, 84, 65, 66, 76, 69, 83, + 39, 32, 47, 32, 39, 86, 65, 82, 73, 65, 66, 76, 69, 83, 39, 10, 68, 101, 115, 99, + 114, 105, 98, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, + 98, 101, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 47, 32, 68, 101, + 115, 99, 114, 105, 98, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, + 68, 101, 115, 99, 114, 105, 98, 101, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, + 101, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, - 32, 47, 32, 83, 104, 111, 119, 83, 112, 101, 99, 105, 97, 108, 70, 111, 114, 109, 10, 35, - 32, 34, 83, 72, 79, 87, 32, 99, 97, 116, 46, 116, 98, 108, 34, 32, 115, 116, 105, 108, - 108, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 116, 97, 98, 108, 101, 32, - 40, 100, 101, 112, 114, 101, 99, 97, 116, 101, 100, 41, 44, 32, 98, 117, 116, 32, 105, 115, - 32, 115, 117, 112, 112, 114, 101, 115, 115, 101, 100, 32, 102, 114, 111, 109, 32, 97, 117, 116, - 111, 99, 111, 109, 112, 108, 101, 116, 101, 32, 40, 115, 101, 101, 32, 109, 97, 116, 99, 104, - 101, 114, 46, 99, 112, 112, 41, 32, 115, 111, 32, 83, 72, 79, 87, 10, 35, 32, 100, 111, - 101, 115, 32, 110, 111, 116, 32, 99, 111, 109, 112, 108, 101, 116, 101, 32, 113, 117, 97, 108, - 105, 102, 105, 101, 100, 32, 116, 97, 98, 108, 101, 115, 32, 40, 117, 110, 108, 105, 107, 101, - 32, 68, 69, 83, 67, 82, 73, 66, 69, 44, 32, 119, 104, 105, 99, 104, 32, 100, 111, 101, - 115, 41, 46, 32, 87, 114, 97, 112, 115, 32, 116, 104, 101, 32, 103, 101, 110, 101, 114, 105, - 99, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, - 32, 40, 115, 101, 108, 101, 99, 116, 46, 103, 114, 97, 109, 41, 46, 10, 83, 104, 111, 119, - 68, 101, 112, 114, 101, 99, 97, 116, 101, 100, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, - 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, - 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 35, 32, 65, 32, 98, 97, 114, 101, 32, - 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 105, 115, 32, 115, 117, 103, 103, 101, 115, - 116, 101, 100, 32, 97, 115, 32, 97, 32, 115, 101, 116, 116, 105, 110, 103, 32, 110, 97, 109, - 101, 32, 40, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 105, 115, 32, 111, 118, - 101, 114, 114, 105, 100, 100, 101, 110, 32, 116, 111, 32, 83, 85, 71, 71, 69, 83, 84, 95, - 83, 69, 84, 84, 73, 78, 71, 95, 78, 65, 77, 69, 41, 46, 10, 83, 104, 111, 119, 83, - 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 60, 45, 32, 83, 101, 116, 116, 105, 110, - 103, 78, 97, 109, 101, 10, 35, 32, 84, 104, 101, 32, 115, 112, 101, 99, 105, 97, 108, 32, - 77, 121, 83, 81, 76, 32, 102, 111, 114, 109, 115, 32, 97, 114, 101, 32, 111, 110, 108, 121, - 32, 104, 101, 114, 101, 32, 115, 111, 32, 97, 117, 116, 111, 99, 111, 109, 112, 108, 101, 116, - 101, 32, 115, 117, 103, 103, 101, 115, 116, 115, 32, 116, 104, 101, 115, 101, 32, 107, 101, 121, - 119, 111, 114, 100, 115, 32, 97, 102, 116, 101, 114, 32, 83, 72, 79, 87, 59, 32, 112, 97, - 114, 115, 105, 110, 103, 32, 111, 102, 32, 101, 46, 103, 46, 10, 35, 32, 34, 83, 72, 79, - 87, 32, 100, 97, 116, 97, 98, 97, 115, 101, 115, 34, 32, 114, 101, 115, 111, 108, 118, 101, - 115, 32, 116, 104, 114, 111, 117, 103, 104, 32, 83, 104, 111, 119, 83, 101, 116, 116, 105, 110, - 103, 78, 97, 109, 101, 32, 40, 116, 104, 101, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, - 114, 41, 32, 97, 98, 111, 118, 101, 44, 32, 119, 104, 105, 99, 104, 32, 116, 104, 101, 32, - 116, 114, 97, 110, 115, 102, 111, 114, 109, 101, 114, 32, 115, 112, 101, 99, 105, 97, 108, 45, - 99, 97, 115, 101, 115, 46, 10, 83, 104, 111, 119, 83, 112, 101, 99, 105, 97, 108, 70, 111, - 114, 109, 32, 60, 45, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 83, 39, 32, 47, 32, - 39, 83, 67, 72, 69, 77, 65, 83, 39, 32, 47, 32, 39, 84, 65, 66, 76, 69, 83, 39, - 32, 47, 32, 39, 86, 65, 82, 73, 65, 66, 76, 69, 83, 39, 10, 68, 101, 115, 99, 114, - 105, 98, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, 98, - 101, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 47, 32, 68, 101, 115, - 99, 114, 105, 98, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 68, - 101, 115, 99, 114, 105, 98, 101, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, - 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 68, 101, - 115, 99, 114, 105, 98, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, - 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 117, 109, - 109, 97, 114, 105, 122, 101, 32, 60, 45, 32, 83, 117, 109, 109, 97, 114, 105, 122, 101, 82, - 117, 108, 101, 10, 83, 117, 109, 109, 97, 114, 105, 122, 101, 82, 117, 108, 101, 32, 60, 45, - 32, 39, 83, 85, 77, 77, 65, 82, 73, 90, 69, 39, 10, 83, 104, 111, 119, 79, 114, 68, - 101, 115, 99, 114, 105, 98, 101, 32, 60, 45, 32, 83, 104, 111, 119, 82, 117, 108, 101, 32, - 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 82, 117, 108, 101, 10, 83, 104, 111, 119, 82, - 117, 108, 101, 32, 60, 45, 32, 39, 83, 72, 79, 87, 39, 10, 68, 101, 115, 99, 114, 105, - 98, 101, 82, 117, 108, 101, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, 98, 101, 76, 111, - 110, 103, 82, 117, 108, 101, 32, 47, 32, 68, 101, 115, 99, 82, 117, 108, 101, 10, 68, 101, - 115, 99, 114, 105, 98, 101, 76, 111, 110, 103, 82, 117, 108, 101, 32, 60, 45, 32, 39, 68, - 69, 83, 67, 82, 73, 66, 69, 39, 10, 68, 101, 115, 99, 82, 117, 108, 101, 32, 60, 45, - 32, 39, 68, 69, 83, 67, 39, 10, 68, 101, 116, 97, 99, 104, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 39, 68, 69, 84, 65, 67, 72, 39, 32, 68, 97, 116, 97, - 98, 97, 115, 101, 63, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 67, 97, 116, 97, - 108, 111, 103, 78, 97, 109, 101, 10, 68, 114, 111, 112, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 68, 114, 111, 112, 69, 110, 116, 114, - 105, 101, 115, 32, 68, 114, 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 63, 10, 68, 114, - 111, 112, 69, 110, 116, 114, 105, 101, 115, 32, 60, 45, 10, 9, 68, 114, 111, 112, 84, 97, - 98, 108, 101, 32, 47, 10, 9, 68, 114, 111, 112, 84, 97, 98, 108, 101, 70, 117, 110, 99, - 116, 105, 111, 110, 32, 47, 10, 9, 68, 114, 111, 112, 70, 117, 110, 99, 116, 105, 111, 110, - 32, 47, 10, 9, 68, 114, 111, 112, 83, 99, 104, 101, 109, 97, 32, 47, 10, 9, 68, 114, - 111, 112, 73, 110, 100, 101, 120, 32, 47, 10, 9, 68, 114, 111, 112, 83, 101, 113, 117, 101, - 110, 99, 101, 32, 47, 10, 9, 68, 114, 111, 112, 67, 111, 108, 108, 97, 116, 105, 111, 110, - 32, 47, 10, 9, 68, 114, 111, 112, 84, 121, 112, 101, 32, 47, 10, 9, 68, 114, 111, 112, - 83, 101, 99, 114, 101, 116, 32, 47, 10, 9, 68, 114, 111, 112, 84, 114, 105, 103, 103, 101, - 114, 10, 68, 114, 111, 112, 84, 114, 105, 103, 103, 101, 114, 32, 60, 45, 32, 39, 84, 82, - 73, 71, 71, 69, 82, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 84, 114, 105, - 103, 103, 101, 114, 78, 97, 109, 101, 32, 39, 79, 78, 39, 32, 66, 97, 115, 101, 84, 97, - 98, 108, 101, 78, 97, 109, 101, 10, 68, 114, 111, 112, 84, 97, 98, 108, 101, 32, 60, 45, - 32, 84, 97, 98, 108, 101, 79, 114, 86, 105, 101, 119, 32, 73, 102, 69, 120, 105, 115, 116, - 115, 63, 32, 76, 105, 115, 116, 40, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, - 101, 41, 10, 68, 114, 111, 112, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, - 32, 60, 45, 32, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, 114, 111, 84, 97, 98, 108, - 101, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 84, 97, 98, - 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 41, 10, 68, 114, 111, 112, - 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, 111, 110, - 84, 121, 112, 101, 77, 97, 99, 114, 111, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, - 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 41, 10, 68, 114, 111, 112, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, 39, - 83, 67, 72, 69, 77, 65, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, - 115, 116, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 41, 10, 68, 114, - 111, 112, 73, 110, 100, 101, 120, 32, 60, 45, 32, 39, 73, 78, 68, 69, 88, 39, 32, 73, - 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 81, 117, 97, 108, 105, 102, - 105, 101, 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 41, 10, 81, 117, 97, 108, 105, 102, - 105, 101, 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, - 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 110, 100, - 101, 120, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 73, - 110, 100, 101, 120, 32, 47, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 73, 110, 100, 101, - 120, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 10, 81, 117, 97, 108, 105, 102, 105, 101, - 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 32, 60, 45, 32, - 73, 110, 100, 101, 120, 78, 97, 109, 101, 10, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, - 114, 118, 101, 100, 73, 110, 100, 101, 120, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 81, - 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, - 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, - 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 110, 100, 101, 120, 32, 60, 45, - 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, - 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, - 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 73, 110, - 100, 101, 120, 78, 97, 109, 101, 10, 68, 114, 111, 112, 83, 101, 113, 117, 101, 110, 99, 101, - 32, 60, 45, 32, 39, 83, 69, 81, 85, 69, 78, 67, 69, 39, 32, 73, 102, 69, 120, 105, - 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 83, - 101, 113, 117, 101, 110, 99, 101, 78, 97, 109, 101, 41, 10, 68, 114, 111, 112, 67, 111, 108, - 108, 97, 116, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 73, 79, 78, - 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 67, 111, 108, - 108, 97, 116, 105, 111, 110, 78, 97, 109, 101, 41, 10, 68, 114, 111, 112, 84, 121, 112, 101, - 32, 60, 45, 32, 39, 84, 89, 80, 69, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, - 32, 76, 105, 115, 116, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 121, 112, 101, 78, - 97, 109, 101, 41, 10, 68, 114, 111, 112, 83, 101, 99, 114, 101, 116, 32, 60, 45, 32, 84, - 101, 109, 112, 111, 114, 97, 114, 121, 63, 32, 39, 83, 69, 67, 82, 69, 84, 39, 32, 73, - 102, 69, 120, 105, 115, 116, 115, 63, 32, 83, 101, 99, 114, 101, 116, 78, 97, 109, 101, 32, - 68, 114, 111, 112, 83, 101, 99, 114, 101, 116, 83, 116, 111, 114, 97, 103, 101, 63, 10, 84, - 97, 98, 108, 101, 79, 114, 86, 105, 101, 119, 32, 60, 45, 32, 67, 111, 109, 109, 101, 110, - 116, 84, 97, 98, 108, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 86, 105, 101, 119, - 32, 47, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, 86, 105, 101, 119, 69, - 110, 116, 114, 121, 10, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, 86, 105, 101, - 119, 69, 110, 116, 114, 121, 32, 60, 45, 32, 39, 77, 65, 84, 69, 82, 73, 65, 76, 73, - 90, 69, 68, 39, 32, 39, 86, 73, 69, 87, 39, 10, 70, 117, 110, 99, 116, 105, 111, 110, - 84, 121, 112, 101, 77, 97, 99, 114, 111, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, 111, - 110, 84, 121, 112, 101, 77, 97, 99, 114, 111, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, - 70, 117, 110, 99, 116, 105, 111, 110, 84, 121, 112, 101, 70, 117, 110, 99, 116, 105, 111, 110, - 10, 70, 117, 110, 99, 116, 105, 111, 110, 84, 121, 112, 101, 77, 97, 99, 114, 111, 75, 101, - 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 77, 65, 67, 82, 79, 39, 10, 70, 117, 110, - 99, 116, 105, 111, 110, 84, 121, 112, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, - 32, 39, 70, 85, 78, 67, 84, 73, 79, 78, 39, 10, 68, 114, 111, 112, 66, 101, 104, 97, - 118, 105, 111, 114, 32, 60, 45, 32, 67, 97, 115, 99, 97, 100, 101, 68, 114, 111, 112, 66, - 101, 104, 97, 118, 105, 111, 114, 32, 47, 32, 82, 101, 115, 116, 114, 105, 99, 116, 68, 114, - 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 10, 67, 97, 115, 99, 97, 100, 101, 68, 114, - 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 32, 60, 45, 32, 39, 67, 65, 83, 67, 65, - 68, 69, 39, 10, 82, 101, 115, 116, 114, 105, 99, 116, 68, 114, 111, 112, 66, 101, 104, 97, - 118, 105, 111, 114, 32, 60, 45, 32, 39, 82, 69, 83, 84, 82, 73, 67, 84, 39, 10, 73, - 102, 69, 120, 105, 115, 116, 115, 32, 60, 45, 32, 39, 73, 70, 39, 32, 39, 69, 88, 73, - 83, 84, 83, 39, 10, 68, 114, 111, 112, 83, 101, 99, 114, 101, 116, 83, 116, 111, 114, 97, - 103, 101, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 10, 69, 120, 101, 99, 117, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 60, 45, 32, 39, 69, 88, 69, 67, 85, 84, 69, 39, 32, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, - 103, 117, 109, 101, 110, 116, 115, 63, 10, 69, 120, 112, 108, 97, 105, 110, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 69, 88, 80, 76, 65, 73, 78, 39, 32, 65, - 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 63, 32, 69, 120, 112, 108, 97, - 105, 110, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 63, 32, 69, 120, 112, 108, 97, 105, - 110, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 115, 10, 69, 120, 112, 108, - 97, 105, 110, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, - 111, 110, 41, 41, 10, 69, 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, 111, 110, 32, 60, - 45, 32, 69, 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, 111, 110, 78, 97, 109, 101, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 69, 120, 112, 108, 97, 105, 110, 79, - 112, 116, 105, 111, 110, 78, 97, 109, 101, 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, - 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 67, 111, 108, 73, 100, 32, 47, 32, 70, 117, - 110, 99, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 84, 121, 112, 101, - 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 10, 69, 120, 112, 108, 97, 105, 110, 83, - 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, - 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, - 108, 10, 69, 120, 112, 108, 97, 105, 110, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 115, 32, 60, 45, 10, 32, 32, 32, 32, 65, 108, 116, 101, 114, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 65, 110, 97, 108, 121, 122, 101, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 67, 97, 108, 108, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 67, 104, 101, 99, 107, - 112, 111, 105, 110, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, - 32, 67, 111, 112, 121, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, - 32, 67, 114, 101, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, - 32, 32, 32, 68, 101, 97, 108, 108, 111, 99, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 47, 10, 32, 32, 32, 32, 68, 101, 108, 101, 116, 101, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 68, 114, 111, 112, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 69, 120, 101, 99, 117, 116, 101, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 73, 110, 115, 101, 114, 116, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 76, 111, 97, 100, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 77, 101, 114, 103, - 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, - 32, 80, 114, 97, 103, 109, 97, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, - 32, 32, 32, 80, 114, 101, 112, 97, 114, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 47, 10, 32, 32, 32, 32, 69, 120, 112, 108, 97, 105, 110, 83, 101, 108, 101, 99, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 84, 114, 97, 110, 115, - 97, 99, 116, 105, 111, 110, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, - 32, 32, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, - 32, 32, 32, 32, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 47, 10, 32, 32, 32, 32, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, - 10, 32, 32, 32, 32, 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, - 69, 120, 112, 111, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, - 69, 88, 80, 79, 82, 84, 39, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, 39, 32, 69, - 120, 112, 111, 114, 116, 83, 111, 117, 114, 99, 101, 63, 32, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, - 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 69, 120, 112, 111, 114, 116, 83, 111, 117, 114, - 99, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 84, - 79, 39, 10, 73, 109, 112, 111, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, - 45, 32, 39, 73, 77, 80, 79, 82, 84, 39, 32, 39, 68, 65, 84, 65, 66, 65, 83, 69, - 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 108, 117, - 109, 110, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, 78, 101, 115, 116, 101, - 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, - 109, 101, 32, 47, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, - 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, 109, - 101, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, - 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, 84, 97, 98, 108, - 101, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, - 47, 32, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 10, 35, - 32, 97, 32, 99, 111, 108, 117, 109, 110, 32, 111, 102, 32, 97, 32, 116, 97, 98, 108, 101, - 32, 105, 110, 32, 97, 32, 110, 101, 115, 116, 101, 100, 32, 115, 99, 104, 101, 109, 97, 32, - 99, 104, 97, 105, 110, 32, 45, 32, 102, 105, 118, 101, 32, 111, 114, 32, 109, 111, 114, 101, - 32, 99, 111, 109, 112, 111, 110, 101, 110, 116, 115, 44, 32, 119, 104, 101, 114, 101, 32, 116, - 104, 101, 32, 113, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 105, 115, 32, - 100, 101, 101, 112, 101, 114, 32, 116, 104, 97, 110, 10, 35, 32, 99, 97, 116, 97, 108, 111, - 103, 32, 43, 32, 115, 99, 104, 101, 109, 97, 32, 97, 110, 100, 32, 105, 116, 32, 105, 115, - 32, 110, 111, 32, 108, 111, 110, 103, 101, 114, 32, 112, 111, 115, 105, 116, 105, 111, 110, 97, - 108, 32, 119, 104, 105, 99, 104, 32, 99, 111, 109, 112, 111, 110, 101, 110, 116, 115, 32, 97, - 114, 101, 32, 115, 99, 104, 101, 109, 97, 115, 32, 97, 110, 100, 32, 119, 104, 105, 99, 104, - 32, 105, 115, 32, 116, 104, 101, 32, 116, 97, 98, 108, 101, 10, 78, 101, 115, 116, 101, 100, - 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, 109, - 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, - 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, + 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 117, + 109, 109, 97, 114, 105, 122, 101, 32, 60, 45, 32, 83, 117, 109, 109, 97, 114, 105, 122, 101, + 82, 117, 108, 101, 10, 83, 117, 109, 109, 97, 114, 105, 122, 101, 82, 117, 108, 101, 32, 60, + 45, 32, 39, 83, 85, 77, 77, 65, 82, 73, 90, 69, 39, 10, 83, 104, 111, 119, 79, 114, + 68, 101, 115, 99, 114, 105, 98, 101, 32, 60, 45, 32, 83, 104, 111, 119, 82, 117, 108, 101, + 32, 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 82, 117, 108, 101, 10, 83, 104, 111, 119, + 82, 117, 108, 101, 32, 60, 45, 32, 39, 83, 72, 79, 87, 39, 10, 68, 101, 115, 99, 114, + 105, 98, 101, 82, 117, 108, 101, 32, 60, 45, 32, 68, 101, 115, 99, 114, 105, 98, 101, 76, + 111, 110, 103, 82, 117, 108, 101, 32, 47, 32, 68, 101, 115, 99, 82, 117, 108, 101, 10, 68, + 101, 115, 99, 114, 105, 98, 101, 76, 111, 110, 103, 82, 117, 108, 101, 32, 60, 45, 32, 39, + 68, 69, 83, 67, 82, 73, 66, 69, 39, 10, 68, 101, 115, 99, 82, 117, 108, 101, 32, 60, + 45, 32, 39, 68, 69, 83, 67, 39, 10, 68, 101, 116, 97, 99, 104, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 32, 60, 45, 32, 39, 68, 69, 84, 65, 67, 72, 39, 32, 68, 97, 116, + 97, 98, 97, 115, 101, 63, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 67, 97, 116, + 97, 108, 111, 103, 78, 97, 109, 101, 10, 68, 114, 111, 112, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 68, 114, 111, 112, 69, 110, 116, + 114, 105, 101, 115, 32, 68, 114, 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 63, 10, 68, + 114, 111, 112, 69, 110, 116, 114, 105, 101, 115, 32, 60, 45, 10, 9, 68, 114, 111, 112, 84, + 97, 98, 108, 101, 32, 47, 10, 9, 68, 114, 111, 112, 84, 97, 98, 108, 101, 70, 117, 110, + 99, 116, 105, 111, 110, 32, 47, 10, 9, 68, 114, 111, 112, 70, 117, 110, 99, 116, 105, 111, + 110, 32, 47, 10, 9, 68, 114, 111, 112, 83, 99, 104, 101, 109, 97, 32, 47, 10, 9, 68, + 114, 111, 112, 73, 110, 100, 101, 120, 32, 47, 10, 9, 68, 114, 111, 112, 83, 101, 113, 117, + 101, 110, 99, 101, 32, 47, 10, 9, 68, 114, 111, 112, 67, 111, 108, 108, 97, 116, 105, 111, + 110, 32, 47, 10, 9, 68, 114, 111, 112, 84, 121, 112, 101, 32, 47, 10, 9, 68, 114, 111, + 112, 83, 101, 99, 114, 101, 116, 32, 47, 10, 9, 68, 114, 111, 112, 84, 114, 105, 103, 103, + 101, 114, 10, 68, 114, 111, 112, 84, 114, 105, 103, 103, 101, 114, 32, 60, 45, 32, 39, 84, + 82, 73, 71, 71, 69, 82, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 84, 114, + 105, 103, 103, 101, 114, 78, 97, 109, 101, 32, 39, 79, 78, 39, 32, 66, 97, 115, 101, 84, + 97, 98, 108, 101, 78, 97, 109, 101, 10, 68, 114, 111, 112, 84, 97, 98, 108, 101, 32, 60, + 45, 32, 84, 97, 98, 108, 101, 79, 114, 86, 105, 101, 119, 32, 73, 102, 69, 120, 105, 115, + 116, 115, 63, 32, 76, 105, 115, 116, 40, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, + 109, 101, 41, 10, 68, 114, 111, 112, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, + 110, 32, 60, 45, 32, 67, 111, 109, 109, 101, 110, 116, 77, 97, 99, 114, 111, 84, 97, 98, + 108, 101, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 84, 97, + 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 41, 10, 68, 114, 111, + 112, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, 111, + 110, 84, 121, 112, 101, 77, 97, 99, 114, 111, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, + 32, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 73, 100, 101, 110, 116, 105, + 102, 105, 101, 114, 41, 10, 68, 114, 111, 112, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, + 39, 83, 67, 72, 69, 77, 65, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, + 105, 115, 116, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 41, 10, 68, + 114, 111, 112, 73, 110, 100, 101, 120, 32, 60, 45, 32, 39, 73, 78, 68, 69, 88, 39, 32, + 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 81, 117, 97, 108, 105, + 102, 105, 101, 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 41, 10, 81, 117, 97, 108, 105, + 102, 105, 101, 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, + 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 110, + 100, 101, 120, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, + 73, 110, 100, 101, 120, 32, 47, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 73, 110, 100, + 101, 120, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 10, 81, 117, 97, 108, 105, 102, 105, + 101, 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 83, 116, 114, 105, 110, 103, 32, 60, 45, + 32, 73, 110, 100, 101, 120, 78, 97, 109, 101, 10, 83, 99, 104, 101, 109, 97, 82, 101, 115, + 101, 114, 118, 101, 100, 73, 110, 100, 101, 120, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, - 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, - 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, - 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, 82, 101, 115, 101, 114, 118, 101, 100, 67, - 111, 108, 117, 109, 110, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, - 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, - 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, - 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, - 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, - 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 81, 117, 97, 108, 105, 102, 105, 99, - 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, 108, 117, 109, 110, - 78, 97, 109, 101, 10, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, - 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 83, 99, + 101, 100, 73, 110, 100, 101, 120, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, 103, 82, + 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 73, 110, 100, 101, 120, 32, 60, + 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, + 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 73, + 110, 100, 101, 120, 78, 97, 109, 101, 10, 68, 114, 111, 112, 83, 101, 113, 117, 101, 110, 99, + 101, 32, 60, 45, 32, 39, 83, 69, 81, 85, 69, 78, 67, 69, 39, 32, 73, 102, 69, 120, + 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, + 83, 101, 113, 117, 101, 110, 99, 101, 78, 97, 109, 101, 41, 10, 68, 114, 111, 112, 67, 111, + 108, 108, 97, 116, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 73, 79, + 78, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 76, 105, 115, 116, 40, 67, 111, + 108, 108, 97, 116, 105, 111, 110, 78, 97, 109, 101, 41, 10, 68, 114, 111, 112, 84, 121, 112, + 101, 32, 60, 45, 32, 39, 84, 89, 80, 69, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, + 63, 32, 76, 105, 115, 116, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 121, 112, 101, + 78, 97, 109, 101, 41, 10, 68, 114, 111, 112, 83, 101, 99, 114, 101, 116, 32, 60, 45, 32, + 84, 101, 109, 112, 111, 114, 97, 114, 121, 63, 32, 39, 83, 69, 67, 82, 69, 84, 39, 32, + 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 83, 101, 99, 114, 101, 116, 78, 97, 109, 101, + 32, 68, 114, 111, 112, 83, 101, 99, 114, 101, 116, 83, 116, 111, 114, 97, 103, 101, 63, 10, + 84, 97, 98, 108, 101, 79, 114, 86, 105, 101, 119, 32, 60, 45, 32, 67, 111, 109, 109, 101, + 110, 116, 84, 97, 98, 108, 101, 32, 47, 32, 67, 111, 109, 109, 101, 110, 116, 86, 105, 101, + 119, 32, 47, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, 86, 105, 101, 119, + 69, 110, 116, 114, 121, 10, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, 86, 105, + 101, 119, 69, 110, 116, 114, 121, 32, 60, 45, 32, 39, 77, 65, 84, 69, 82, 73, 65, 76, + 73, 90, 69, 68, 39, 32, 39, 86, 73, 69, 87, 39, 10, 70, 117, 110, 99, 116, 105, 111, + 110, 84, 121, 112, 101, 77, 97, 99, 114, 111, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, + 111, 110, 84, 121, 112, 101, 77, 97, 99, 114, 111, 75, 101, 121, 119, 111, 114, 100, 32, 47, + 32, 70, 117, 110, 99, 116, 105, 111, 110, 84, 121, 112, 101, 70, 117, 110, 99, 116, 105, 111, + 110, 10, 70, 117, 110, 99, 116, 105, 111, 110, 84, 121, 112, 101, 77, 97, 99, 114, 111, 75, + 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 77, 65, 67, 82, 79, 39, 10, 70, 117, + 110, 99, 116, 105, 111, 110, 84, 121, 112, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, + 45, 32, 39, 70, 85, 78, 67, 84, 73, 79, 78, 39, 10, 68, 114, 111, 112, 66, 101, 104, + 97, 118, 105, 111, 114, 32, 60, 45, 32, 67, 97, 115, 99, 97, 100, 101, 68, 114, 111, 112, + 66, 101, 104, 97, 118, 105, 111, 114, 32, 47, 32, 82, 101, 115, 116, 114, 105, 99, 116, 68, + 114, 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 10, 67, 97, 115, 99, 97, 100, 101, 68, + 114, 111, 112, 66, 101, 104, 97, 118, 105, 111, 114, 32, 60, 45, 32, 39, 67, 65, 83, 67, + 65, 68, 69, 39, 10, 82, 101, 115, 116, 114, 105, 99, 116, 68, 114, 111, 112, 66, 101, 104, + 97, 118, 105, 111, 114, 32, 60, 45, 32, 39, 82, 69, 83, 84, 82, 73, 67, 84, 39, 10, + 73, 102, 69, 120, 105, 115, 116, 115, 32, 60, 45, 32, 39, 73, 70, 39, 32, 39, 69, 88, + 73, 83, 84, 83, 39, 10, 68, 114, 111, 112, 83, 101, 99, 114, 101, 116, 83, 116, 111, 114, + 97, 103, 101, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, 101, 110, 116, 105, + 102, 105, 101, 114, 10, 69, 120, 101, 99, 117, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 69, 88, 69, 67, 85, 84, 69, 39, 32, 67, 111, 108, 73, 100, + 79, 114, 83, 116, 114, 105, 110, 103, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, + 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 63, 10, 69, 120, 112, 108, 97, 105, 110, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 69, 88, 80, 76, 65, 73, + 78, 39, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 63, 32, 69, + 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 63, 32, 69, 120, + 112, 108, 97, 105, 110, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 115, 10, + 69, 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, + 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 108, 97, 105, 110, + 79, 112, 116, 105, 111, 110, 41, 41, 10, 69, 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, + 111, 110, 32, 60, 45, 32, 69, 120, 112, 108, 97, 105, 110, 79, 112, 116, 105, 111, 110, 78, + 97, 109, 101, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 69, 120, 112, 108, + 97, 105, 110, 79, 112, 116, 105, 111, 110, 78, 97, 109, 101, 32, 60, 45, 32, 65, 110, 97, + 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 67, 111, 108, 73, 100, 32, + 47, 32, 70, 117, 110, 99, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, + 84, 121, 112, 101, 78, 97, 109, 101, 75, 101, 121, 119, 111, 114, 100, 10, 69, 120, 112, 108, + 97, 105, 110, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, + 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, + 101, 114, 110, 97, 108, 10, 69, 120, 112, 108, 97, 105, 110, 97, 98, 108, 101, 83, 116, 97, + 116, 101, 109, 101, 110, 116, 115, 32, 60, 45, 10, 32, 32, 32, 32, 65, 108, 116, 101, 114, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 65, 110, 97, 108, + 121, 122, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 67, + 97, 108, 108, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 67, + 104, 101, 99, 107, 112, 111, 105, 110, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, + 10, 32, 32, 32, 32, 67, 111, 112, 121, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, + 10, 32, 32, 32, 32, 67, 114, 101, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 32, 47, 10, 32, 32, 32, 32, 68, 101, 97, 108, 108, 111, 99, 97, 116, 101, 83, 116, 97, + 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 68, 101, 108, 101, 116, 101, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 68, 114, 111, 112, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 69, 120, 101, 99, 117, + 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 73, 110, + 115, 101, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, + 76, 111, 97, 100, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, + 77, 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, + 10, 32, 32, 32, 32, 80, 114, 97, 103, 109, 97, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 32, 47, 10, 32, 32, 32, 32, 80, 114, 101, 112, 97, 114, 101, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 69, 120, 112, 108, 97, 105, 110, 83, 101, 108, + 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 84, + 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 47, 10, 32, 32, 32, 32, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 47, 10, 32, 32, 32, 32, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 32, 47, 10, 32, 32, 32, 32, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 47, 10, 32, 32, 32, 32, 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 10, 69, 120, 112, 111, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 60, 45, 32, 39, 69, 88, 80, 79, 82, 84, 39, 32, 39, 68, 65, 84, 65, 66, 65, 83, + 69, 39, 32, 69, 120, 112, 111, 114, 116, 83, 111, 117, 114, 99, 101, 63, 32, 83, 116, 114, + 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, + 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 69, 120, 112, 111, 114, 116, + 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, + 101, 32, 39, 84, 79, 39, 10, 73, 109, 112, 111, 114, 116, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 60, 45, 32, 39, 73, 77, 80, 79, 82, 84, 39, 32, 39, 68, 65, 84, 65, + 66, 65, 83, 69, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, + 67, 111, 108, 117, 109, 110, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, 78, + 101, 115, 116, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, + 109, 110, 78, 97, 109, 101, 32, 47, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, + 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, + 110, 78, 97, 109, 101, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, + 101, 100, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, + 84, 97, 98, 108, 101, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, 108, 117, 109, 110, 78, + 97, 109, 101, 32, 47, 32, 78, 101, 115, 116, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, + 109, 101, 10, 35, 32, 97, 32, 99, 111, 108, 117, 109, 110, 32, 111, 102, 32, 97, 32, 116, + 97, 98, 108, 101, 32, 105, 110, 32, 97, 32, 110, 101, 115, 116, 101, 100, 32, 115, 99, 104, + 101, 109, 97, 32, 99, 104, 97, 105, 110, 32, 45, 32, 102, 105, 118, 101, 32, 111, 114, 32, + 109, 111, 114, 101, 32, 99, 111, 109, 112, 111, 110, 101, 110, 116, 115, 44, 32, 119, 104, 101, + 114, 101, 32, 116, 104, 101, 32, 113, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, + 32, 105, 115, 32, 100, 101, 101, 112, 101, 114, 32, 116, 104, 97, 110, 10, 35, 32, 99, 97, + 116, 97, 108, 111, 103, 32, 43, 32, 115, 99, 104, 101, 109, 97, 32, 97, 110, 100, 32, 105, + 116, 32, 105, 115, 32, 110, 111, 32, 108, 111, 110, 103, 101, 114, 32, 112, 111, 115, 105, 116, + 105, 111, 110, 97, 108, 32, 119, 104, 105, 99, 104, 32, 99, 111, 109, 112, 111, 110, 101, 110, + 116, 115, 32, 97, 114, 101, 32, 115, 99, 104, 101, 109, 97, 115, 32, 97, 110, 100, 32, 119, + 104, 105, 99, 104, 32, 105, 115, 32, 116, 104, 101, 32, 116, 97, 98, 108, 101, 10, 78, 101, + 115, 116, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, + 110, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, + 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, - 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 81, 117, 97, 108, 105, 102, 105, 99, 97, - 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, 108, 117, 109, 110, 78, - 97, 109, 101, 10, 84, 97, 98, 108, 101, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, 108, - 117, 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 84, 97, 98, 108, 101, 81, 117, 97, 108, + 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, + 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, + 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, 82, 101, 115, 101, 114, + 118, 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, + 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, + 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, + 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, + 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, - 108, 117, 109, 110, 78, 97, 109, 101, 10, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, 111, 110, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, - 116, 104, 105, 110, 71, 114, 111, 117, 112, 67, 108, 97, 117, 115, 101, 63, 32, 70, 105, 108, - 116, 101, 114, 67, 108, 97, 117, 115, 101, 63, 32, 69, 120, 112, 111, 114, 116, 67, 108, 97, - 117, 115, 101, 63, 32, 79, 118, 101, 114, 67, 108, 97, 117, 115, 101, 63, 10, 70, 117, 110, - 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, - 101, 110, 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 70, 117, 110, 99, 116, - 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, - 116, 76, 105, 115, 116, 41, 10, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, - 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 32, 70, 117, 110, 99, - 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 63, 32, 79, 114, - 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 73, 103, 110, 111, 114, 101, 79, - 114, 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 63, 10, 70, 117, 110, 99, 116, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, - 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, - 41, 10, 70, 117, 110, 99, 116, 105, 111, 110, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, - 99, 104, 101, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 32, 47, 32, - 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 70, 117, 110, 99, 116, 105, - 111, 110, 78, 97, 109, 101, 32, 47, 32, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, - 101, 65, 115, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 10, 70, 117, 110, - 99, 116, 105, 111, 110, 78, 97, 109, 101, 65, 115, 81, 117, 97, 108, 105, 102, 105, 101, 100, - 78, 97, 109, 101, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, - 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, - 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, - 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, - 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, - 99, 97, 116, 105, 111, 110, 42, 32, 82, 101, 115, 101, 114, 118, 101, 100, 70, 117, 110, 99, - 116, 105, 111, 110, 78, 97, 109, 101, 10, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, - 118, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 32, 60, 45, 32, 83, - 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, - 101, 115, 101, 114, 118, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, - 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 32, 60, 45, 32, 68, 105, 115, - 116, 105, 110, 99, 116, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 65, 108, 108, 75, 101, - 121, 119, 111, 114, 100, 10, 68, 105, 115, 116, 105, 110, 99, 116, 75, 101, 121, 119, 111, 114, - 100, 32, 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 10, 65, 108, 108, 75, - 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 69, 120, 112, 111, - 114, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 69, 88, 80, 79, 82, 84, 95, - 83, 84, 65, 84, 69, 39, 10, 87, 105, 116, 104, 105, 110, 71, 114, 111, 117, 112, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 73, 78, 39, 32, 39, 71, 82, - 79, 85, 80, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 114, 100, 101, 114, 66, 121, 67, - 108, 97, 117, 115, 101, 41, 10, 70, 105, 108, 116, 101, 114, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 70, 73, 76, 84, 69, 82, 39, 32, 70, 105, 108, 116, 101, 114, 67, 108, - 97, 117, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 105, 108, 116, 101, - 114, 67, 108, 97, 117, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, - 32, 80, 97, 114, 101, 110, 115, 40, 70, 105, 108, 116, 101, 114, 67, 108, 97, 117, 115, 101, - 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 70, 105, 108, 116, 101, 114, 67, 108, 97, 117, - 115, 101, 67, 111, 110, 116, 101, 110, 116, 115, 32, 60, 45, 32, 39, 87, 72, 69, 82, 69, - 39, 63, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, 103, 110, 111, 114, 101, - 79, 114, 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 32, 60, 45, 32, 73, 103, - 110, 111, 114, 101, 78, 117, 108, 108, 115, 32, 47, 32, 82, 101, 115, 112, 101, 99, 116, 78, - 117, 108, 108, 115, 10, 73, 103, 110, 111, 114, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, - 39, 73, 71, 78, 79, 82, 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 82, 101, 115, - 112, 101, 99, 116, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 82, 69, 83, 80, 69, 67, - 84, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 80, 97, 114, 101, 110, 116, 104, 101, 115, - 105, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, - 41, 10, 76, 105, 116, 101, 114, 97, 108, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 78, - 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 67, 111, 110, 115, 116, - 97, 110, 116, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 110, 115, 116, 97, 110, 116, 76, - 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 78, 117, 108, 108, 76, 105, 116, 101, 114, 97, - 108, 32, 47, 32, 84, 114, 117, 101, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 70, 97, - 108, 115, 101, 76, 105, 116, 101, 114, 97, 108, 10, 78, 117, 108, 108, 76, 105, 116, 101, 114, - 97, 108, 32, 60, 45, 32, 39, 78, 85, 76, 76, 39, 10, 84, 114, 117, 101, 76, 105, 116, - 101, 114, 97, 108, 32, 60, 45, 32, 39, 84, 82, 85, 69, 39, 10, 70, 97, 108, 115, 101, - 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 70, 65, 76, 83, 69, 39, 10, 67, - 97, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 97, 115, - 116, 79, 114, 84, 114, 121, 67, 97, 115, 116, 32, 80, 97, 114, 101, 110, 115, 40, 67, 97, - 115, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 67, 97, 115, 116, 65, 114, 103, - 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 39, 65, 83, 39, 32, 84, 121, 112, 101, 10, 67, 97, 115, 116, 79, 114, 84, 114, 121, - 67, 97, 115, 116, 32, 60, 45, 32, 67, 97, 115, 116, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 84, 114, 121, 67, 97, 115, 116, 75, 101, 121, 119, 111, 114, 100, 10, 67, 97, 115, - 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 65, 83, 84, 39, 10, 84, - 114, 121, 67, 97, 115, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 84, 82, - 89, 95, 67, 65, 83, 84, 39, 10, 67, 111, 108, 73, 100, 68, 111, 116, 32, 60, 45, 32, - 67, 111, 108, 73, 100, 32, 39, 46, 39, 10, 83, 116, 97, 114, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 81, 117, 97, 108, 105, 102, 105, 101, - 114, 76, 105, 115, 116, 63, 32, 39, 42, 39, 32, 69, 120, 99, 108, 117, 100, 101, 76, 105, - 115, 116, 63, 32, 82, 101, 112, 108, 97, 99, 101, 76, 105, 115, 116, 63, 32, 82, 101, 110, - 97, 109, 101, 76, 105, 115, 116, 63, 10, 83, 116, 97, 114, 81, 117, 97, 108, 105, 102, 105, - 101, 114, 76, 105, 115, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 68, 111, 116, 43, 10, - 69, 120, 99, 108, 117, 100, 101, 76, 105, 115, 116, 32, 60, 45, 32, 69, 120, 99, 108, 117, - 100, 101, 79, 114, 69, 120, 99, 101, 112, 116, 32, 69, 120, 99, 108, 117, 100, 101, 78, 97, - 109, 101, 115, 10, 69, 120, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 101, 112, 116, 32, - 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 47, 32, 39, 69, 88, 67, 69, - 80, 84, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 115, 32, 60, 45, 32, - 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, 47, 32, 69, 120, - 99, 108, 117, 100, 101, 78, 97, 109, 101, 83, 105, 110, 103, 108, 101, 10, 69, 120, 99, 108, - 117, 100, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 41, 41, - 10, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 83, 105, 110, 103, 108, 101, 32, 60, - 45, 32, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 10, 69, 120, 99, 108, 117, 100, - 101, 78, 97, 109, 101, 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, 68, 111, 116, 116, - 101, 100, 78, 97, 109, 101, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, 67, 111, 108, 117, - 109, 110, 78, 97, 109, 101, 10, 69, 120, 99, 108, 117, 100, 101, 68, 111, 116, 116, 101, 100, - 78, 97, 109, 101, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 10, 69, 120, 99, 108, 117, 100, 101, 67, 111, 108, 117, 109, 110, 78, 97, - 109, 101, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, - 82, 101, 112, 108, 97, 99, 101, 76, 105, 115, 116, 32, 60, 45, 32, 39, 82, 69, 80, 76, - 65, 67, 69, 39, 32, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 105, 101, 115, 10, - 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 105, 101, 115, 32, 60, 45, 32, 82, 101, - 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 83, 105, 110, 103, 108, 101, 32, 47, 32, 82, - 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 10, 82, 101, 112, 108, - 97, 99, 101, 69, 110, 116, 114, 121, 83, 105, 110, 103, 108, 101, 32, 60, 45, 32, 82, 101, - 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 10, 82, 101, 112, 108, 97, 99, 101, 69, 110, - 116, 114, 121, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, - 115, 116, 40, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 41, 41, 10, 82, 101, - 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 39, 65, 83, 39, 32, 67, 111, 108, 117, 109, 110, 82, 101, 102, 101, - 114, 101, 110, 99, 101, 10, 82, 101, 110, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, - 39, 82, 69, 78, 65, 77, 69, 39, 32, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 105, - 101, 115, 10, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 105, 101, 115, 32, 60, 45, 32, - 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 32, 47, 32, 83, 105, - 110, 103, 108, 101, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 10, 82, 101, 110, 97, - 109, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 41, 41, - 10, 83, 105, 110, 103, 108, 101, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 32, 60, - 45, 32, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 10, 82, 101, 110, 97, 109, 101, - 69, 110, 116, 114, 121, 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, - 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 83, 117, 98, - 113, 117, 101, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, - 117, 98, 113, 117, 101, 114, 121, 78, 111, 116, 63, 32, 83, 117, 98, 113, 117, 101, 114, 121, - 69, 120, 105, 115, 116, 115, 63, 32, 83, 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, - 114, 101, 110, 99, 101, 10, 83, 117, 98, 113, 117, 101, 114, 121, 78, 111, 116, 32, 60, 45, - 32, 39, 78, 79, 84, 39, 10, 83, 117, 98, 113, 117, 101, 114, 121, 69, 120, 105, 115, 116, - 115, 32, 60, 45, 32, 39, 69, 88, 73, 83, 84, 83, 39, 10, 67, 97, 115, 101, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 65, 83, 69, 39, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 67, 97, 115, 101, 87, 104, 101, 110, 84, - 104, 101, 110, 43, 32, 67, 97, 115, 101, 69, 108, 115, 101, 63, 32, 39, 69, 78, 68, 39, - 10, 67, 97, 115, 101, 87, 104, 101, 110, 84, 104, 101, 110, 32, 60, 45, 32, 39, 87, 72, - 69, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 84, 72, 69, 78, - 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 97, 115, 101, 69, 108, 115, - 101, 32, 60, 45, 32, 39, 69, 76, 83, 69, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 10, 84, 121, 112, 101, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 84, 121, - 112, 101, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 73, 110, 116, - 101, 114, 118, 97, 108, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 73, 78, 84, - 69, 82, 86, 65, 76, 39, 32, 73, 110, 116, 101, 114, 118, 97, 108, 80, 97, 114, 97, 109, - 101, 116, 101, 114, 32, 73, 110, 116, 101, 114, 118, 97, 108, 63, 10, 73, 110, 116, 101, 114, - 118, 97, 108, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 73, 110, 116, 101, - 114, 118, 97, 108, 83, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, - 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 80, 97, - 114, 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, 110, 116, 101, 114, - 118, 97, 108, 83, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, - 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 70, 114, 97, 109, - 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 114, 97, 109, 105, 110, 103, 32, 70, - 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 87, 105, 110, 100, 111, 119, 69, 120, 99, - 108, 117, 100, 101, 67, 108, 97, 117, 115, 101, 63, 10, 70, 114, 97, 109, 105, 110, 103, 32, - 60, 45, 32, 82, 111, 119, 115, 70, 114, 97, 109, 105, 110, 103, 32, 47, 32, 82, 97, 110, - 103, 101, 70, 114, 97, 109, 105, 110, 103, 32, 47, 32, 71, 114, 111, 117, 112, 115, 70, 114, - 97, 109, 105, 110, 103, 10, 82, 111, 119, 115, 70, 114, 97, 109, 105, 110, 103, 32, 60, 45, - 32, 39, 82, 79, 87, 83, 39, 10, 82, 97, 110, 103, 101, 70, 114, 97, 109, 105, 110, 103, - 32, 60, 45, 32, 39, 82, 65, 78, 71, 69, 39, 10, 71, 114, 111, 117, 112, 115, 70, 114, - 97, 109, 105, 110, 103, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 83, 39, 10, 70, 114, - 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 60, 45, 32, 66, 101, 116, 119, 101, 101, 110, - 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 47, 32, 83, 105, 110, 103, 108, 101, - 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 10, 83, 105, 110, 103, 108, 101, 70, 114, - 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 60, 45, 32, 70, 114, 97, 109, 101, 66, 111, - 117, 110, 100, 10, 66, 101, 116, 119, 101, 101, 110, 70, 114, 97, 109, 101, 69, 120, 116, 101, - 110, 116, 32, 60, 45, 32, 39, 66, 69, 84, 87, 69, 69, 78, 39, 32, 70, 114, 97, 109, - 101, 66, 111, 117, 110, 100, 32, 39, 65, 78, 68, 39, 32, 70, 114, 97, 109, 101, 66, 111, - 117, 110, 100, 10, 70, 114, 97, 109, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 70, 114, - 97, 109, 101, 85, 110, 98, 111, 117, 110, 100, 101, 100, 32, 47, 32, 70, 114, 97, 109, 101, - 67, 117, 114, 114, 101, 110, 116, 82, 111, 119, 32, 47, 32, 70, 114, 97, 109, 101, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 114, 97, 109, 101, 85, 110, 98, 111, 117, 110, - 100, 101, 100, 32, 60, 45, 32, 39, 85, 78, 66, 79, 85, 78, 68, 69, 68, 39, 32, 80, - 114, 101, 99, 101, 100, 105, 110, 103, 79, 114, 70, 111, 108, 108, 111, 119, 105, 110, 103, 10, - 70, 114, 97, 109, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 80, 114, 101, 99, 101, 100, 105, 110, 103, 79, - 114, 70, 111, 108, 108, 111, 119, 105, 110, 103, 10, 70, 114, 97, 109, 101, 67, 117, 114, 114, - 101, 110, 116, 82, 111, 119, 32, 60, 45, 32, 39, 67, 85, 82, 82, 69, 78, 84, 39, 32, - 39, 82, 79, 87, 39, 10, 80, 114, 101, 99, 101, 100, 105, 110, 103, 79, 114, 70, 111, 108, - 108, 111, 119, 105, 110, 103, 32, 60, 45, 32, 80, 114, 101, 99, 101, 100, 105, 110, 103, 70, - 114, 97, 109, 101, 32, 47, 32, 70, 111, 108, 108, 111, 119, 105, 110, 103, 70, 114, 97, 109, - 101, 10, 80, 114, 101, 99, 101, 100, 105, 110, 103, 70, 114, 97, 109, 101, 32, 60, 45, 32, - 39, 80, 82, 69, 67, 69, 68, 73, 78, 71, 39, 10, 70, 111, 108, 108, 111, 119, 105, 110, - 103, 70, 114, 97, 109, 101, 32, 60, 45, 32, 39, 70, 79, 76, 76, 79, 87, 73, 78, 71, - 39, 10, 87, 105, 110, 100, 111, 119, 69, 120, 99, 108, 117, 100, 101, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 87, 105, 110, 100, 111, - 119, 69, 120, 99, 108, 117, 100, 101, 69, 108, 101, 109, 101, 110, 116, 10, 87, 105, 110, 100, - 111, 119, 69, 120, 99, 108, 117, 100, 101, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, 32, - 69, 120, 99, 108, 117, 100, 101, 67, 117, 114, 114, 101, 110, 116, 82, 111, 119, 32, 47, 32, - 69, 120, 99, 108, 117, 100, 101, 71, 114, 111, 117, 112, 32, 47, 32, 69, 120, 99, 108, 117, - 100, 101, 84, 105, 101, 115, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 111, 79, 116, - 104, 101, 114, 115, 10, 69, 120, 99, 108, 117, 100, 101, 67, 117, 114, 114, 101, 110, 116, 82, - 111, 119, 32, 60, 45, 32, 39, 67, 85, 82, 82, 69, 78, 84, 39, 32, 39, 82, 79, 87, - 39, 10, 69, 120, 99, 108, 117, 100, 101, 71, 114, 111, 117, 112, 32, 60, 45, 32, 39, 71, - 82, 79, 85, 80, 39, 10, 69, 120, 99, 108, 117, 100, 101, 84, 105, 101, 115, 32, 60, 45, - 32, 39, 84, 73, 69, 83, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, 111, 79, 116, 104, - 101, 114, 115, 32, 60, 45, 32, 39, 78, 79, 39, 32, 39, 79, 84, 72, 69, 82, 83, 39, - 10, 79, 118, 101, 114, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 86, 69, 82, - 39, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 10, 87, 105, 110, 100, 111, 119, - 70, 114, 97, 109, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 32, 47, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 68, - 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 10, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 32, 60, 45, 32, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 97, 114, 101, 110, 115, 73, 100, 101, 110, - 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 41, 10, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, - 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 87, 105, 110, 100, 111, 119, - 70, 114, 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 80, 97, 114, - 101, 110, 115, 32, 47, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, - 116, 101, 110, 116, 115, 80, 97, 114, 101, 110, 115, 10, 87, 105, 110, 100, 111, 119, 70, 114, - 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 80, 97, 114, 101, 110, - 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 87, 105, 110, 100, 111, 119, 70, 114, - 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 87, 105, 110, - 100, 111, 119, 70, 114, 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, - 32, 60, 45, 32, 66, 97, 115, 101, 87, 105, 110, 100, 111, 119, 78, 97, 109, 101, 63, 32, - 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 10, - 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 80, - 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 87, 105, 110, 100, - 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 87, 105, 110, - 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 32, 60, 45, 32, - 87, 105, 110, 100, 111, 119, 80, 97, 114, 116, 105, 116, 105, 111, 110, 63, 32, 79, 114, 100, - 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 70, 114, 97, 109, 101, 67, 108, 97, - 117, 115, 101, 63, 10, 66, 97, 115, 101, 87, 105, 110, 100, 111, 119, 78, 97, 109, 101, 32, - 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 87, 105, 110, 100, 111, 119, - 80, 97, 114, 116, 105, 116, 105, 111, 110, 32, 60, 45, 32, 39, 80, 65, 82, 84, 73, 84, - 73, 79, 78, 39, 32, 39, 66, 89, 39, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 41, 10, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 65, 114, 114, 97, 121, 66, 111, 117, 110, 100, 101, 100, 76, 105, 115, - 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 65, 114, 114, 97, 121, 80, - 97, 114, 101, 110, 115, 83, 101, 108, 101, 99, 116, 10, 65, 114, 114, 97, 121, 66, 111, 117, - 110, 100, 101, 100, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 39, 65, 82, 82, 65, 89, 39, 63, 32, 66, 111, 117, 110, 100, 101, 100, 76, 105, - 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 114, 114, 97, 121, 80, 97, - 114, 101, 110, 115, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 39, 65, 82, 82, 65, 89, - 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 66, 111, 117, 110, 100, 101, - 100, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, - 91, 39, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, - 32, 39, 93, 39, 10, 83, 116, 114, 117, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 39, 123, 39, 32, 76, 105, 115, 116, 40, 83, 116, 114, 117, 99, 116, - 70, 105, 101, 108, 100, 41, 63, 32, 39, 125, 39, 10, 83, 116, 114, 117, 99, 116, 70, 105, - 101, 108, 100, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, - 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 77, 97, 112, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 77, 65, 80, 39, 32, 77, - 97, 112, 83, 116, 114, 117, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 77, - 97, 112, 83, 116, 114, 117, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 39, 123, 39, 32, 76, 105, 115, 116, 40, 77, 97, 112, 83, 116, 114, 117, 99, 116, - 70, 105, 101, 108, 100, 41, 63, 32, 39, 125, 39, 10, 77, 97, 112, 83, 116, 114, 117, 99, - 116, 70, 105, 101, 108, 100, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, - 112, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 71, 114, - 111, 117, 112, 105, 110, 103, 79, 114, 71, 114, 111, 117, 112, 105, 110, 103, 73, 100, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 41, 63, 41, 10, 71, 114, 111, 117, 112, 105, 110, 103, 79, 114, 71, 114, 111, 117, 112, - 105, 110, 103, 73, 100, 32, 60, 45, 32, 71, 114, 111, 117, 112, 105, 110, 103, 75, 101, 121, - 119, 111, 114, 100, 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 73, 100, 75, 101, 121, - 119, 111, 114, 100, 10, 71, 114, 111, 117, 112, 105, 110, 103, 75, 101, 121, 119, 111, 114, 100, - 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 10, 71, 114, 111, 117, 112, - 105, 110, 103, 73, 100, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 71, 82, 79, - 85, 80, 73, 78, 71, 95, 73, 68, 39, 10, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, - 60, 45, 32, 81, 117, 101, 115, 116, 105, 111, 110, 77, 97, 114, 107, 78, 117, 109, 98, 101, - 114, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, 65, 110, 111, 110, 121, - 109, 111, 117, 115, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, 78, 117, 109, 98, - 101, 114, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, 67, 111, 108, 76, - 97, 98, 101, 108, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 81, 117, 101, 115, 116, 105, - 111, 110, 77, 97, 114, 107, 78, 117, 109, 98, 101, 114, 101, 100, 80, 97, 114, 97, 109, 101, - 116, 101, 114, 32, 60, 45, 32, 39, 63, 39, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, - 101, 114, 97, 108, 10, 65, 110, 111, 110, 121, 109, 111, 117, 115, 80, 97, 114, 97, 109, 101, - 116, 101, 114, 32, 60, 45, 32, 39, 63, 39, 10, 78, 117, 109, 98, 101, 114, 101, 100, 80, - 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 39, 36, 39, 32, 78, 117, 109, 98, - 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 108, 76, 97, 98, 101, 108, 80, 97, - 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 39, 36, 39, 32, 67, 111, 108, 76, 97, - 98, 101, 108, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 39, 35, 39, 32, 78, 117, 109, 98, 101, 114, 76, 105, - 116, 101, 114, 97, 108, 10, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 10, 76, 105, 115, - 116, 67, 111, 109, 112, 114, 101, 104, 101, 110, 115, 105, 111, 110, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 39, 91, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 39, 70, 79, 82, 39, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, - 114, 83, 116, 114, 105, 110, 103, 41, 32, 39, 73, 78, 39, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 76, 105, 115, 116, 67, 111, 109, 112, 114, 101, 104, 101, 110, 115, 105, - 111, 110, 70, 105, 108, 116, 101, 114, 63, 32, 39, 93, 39, 10, 76, 105, 115, 116, 67, 111, - 109, 112, 114, 101, 104, 101, 110, 115, 105, 111, 110, 70, 105, 108, 116, 101, 114, 32, 60, 45, - 32, 39, 73, 70, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 97, 114, - 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 83, 105, 110, 103, - 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 10, 32, 32, 32, 32, - 80, 97, 114, 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 9, - 76, 105, 116, 101, 114, 97, 108, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, - 9, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 10, 32, 32, 32, 32, 83, 117, 98, - 113, 117, 101, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, - 32, 32, 83, 112, 101, 99, 105, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 80, 97, 114, 101, 110, 116, - 104, 101, 115, 105, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, - 32, 32, 73, 110, 116, 101, 114, 118, 97, 108, 76, 105, 116, 101, 114, 97, 108, 32, 47, 10, - 32, 32, 32, 32, 84, 121, 112, 101, 76, 105, 116, 101, 114, 97, 108, 32, 47, 10, 32, 32, - 32, 32, 67, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, - 32, 32, 32, 83, 116, 97, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, - 32, 32, 32, 32, 67, 97, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, - 10, 32, 32, 32, 32, 71, 114, 111, 117, 112, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 77, 97, 112, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 67, 111, 108, 117, 109, - 110, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 47, 10, 32, 32, 32, 32, 76, 105, 115, - 116, 67, 111, 109, 112, 114, 101, 104, 101, 110, 115, 105, 111, 110, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 76, 105, 115, 116, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 83, 116, 114, 117, 99, 116, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 80, 111, 115, 105, 116, - 105, 111, 110, 97, 108, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, - 32, 32, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, - 35, 32, 76, 69, 86, 69, 76, 32, 49, 32, 40, 76, 111, 119, 101, 115, 116, 41, 10, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 76, 97, 109, 98, 100, 97, 65, - 114, 114, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 117, 109, - 110, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, 114, 32, 60, 45, 32, 67, 111, 108, 68, - 101, 102, 79, 114, 69, 120, 112, 114, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 46, 53, - 10, 76, 97, 109, 98, 100, 97, 65, 114, 114, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 76, 111, 103, 105, 99, 97, 108, 79, 114, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 83, 105, 110, 103, 108, 101, 65, 114, 114, 111, 119, 80, 97, 105, - 114, 42, 10, 83, 105, 110, 103, 108, 101, 65, 114, 114, 111, 119, 80, 97, 105, 114, 32, 60, - 45, 32, 39, 45, 62, 39, 32, 76, 111, 103, 105, 99, 97, 108, 79, 114, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 76, 111, 103, 105, 99, 97, 108, 79, 114, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 76, 111, 103, 105, 99, 97, 108, 65, 110, 100, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 76, 111, 103, 105, 99, 97, 108, 79, 114, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 76, 111, 103, 105, - 99, 97, 108, 79, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, - 60, 45, 32, 39, 79, 82, 39, 32, 76, 111, 103, 105, 99, 97, 108, 65, 110, 100, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 68, 101, 102, 79, 114, 69, 120, 112, - 114, 32, 60, 45, 32, 67, 111, 108, 68, 101, 102, 65, 110, 100, 69, 120, 112, 114, 32, 67, - 111, 108, 68, 101, 102, 79, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, - 108, 42, 10, 67, 111, 108, 68, 101, 102, 79, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 84, 97, 105, 108, 32, 60, 45, 32, 39, 79, 82, 39, 32, 67, 111, 108, 68, 101, 102, - 65, 110, 100, 69, 120, 112, 114, 10, 35, 32, 76, 69, 86, 69, 76, 32, 50, 10, 76, 111, - 103, 105, 99, 97, 108, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 76, 111, 103, 105, 99, 97, 108, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 76, 111, 103, 105, 99, 97, 108, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 84, 97, 105, 108, 42, 10, 76, 111, 103, 105, 99, 97, 108, 65, 110, 100, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 39, 65, 78, - 68, 39, 32, 76, 111, 103, 105, 99, 97, 108, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 10, 67, 111, 108, 68, 101, 102, 65, 110, 100, 69, 120, 112, 114, 32, 60, 45, - 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 67, 111, 108, 68, 101, 102, 65, 110, 100, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 67, 111, 108, 68, 101, 102, 65, 110, 100, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 39, 65, - 78, 68, 39, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 35, 32, 76, 69, 86, 69, 76, 32, 51, 10, 76, - 111, 103, 105, 99, 97, 108, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 73, 115, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 111, 116, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 78, 111, 116, 75, 101, 121, 119, 111, 114, 100, 43, 10, - 78, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 10, - 35, 32, 76, 69, 86, 69, 76, 32, 52, 10, 73, 115, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 115, 84, 101, 115, 116, 42, 10, 73, - 115, 84, 101, 115, 116, 32, 60, 45, 32, 73, 115, 76, 105, 116, 101, 114, 97, 108, 32, 47, - 32, 78, 111, 116, 78, 117, 108, 108, 32, 47, 32, 73, 115, 78, 117, 108, 108, 10, 73, 115, - 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 73, 83, 39, 32, 39, 78, 79, 84, - 39, 63, 32, 73, 115, 76, 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 10, 73, 115, - 76, 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 32, 60, 45, 32, 84, 114, 117, 101, - 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 70, 97, 108, 115, 101, 76, 105, 116, 101, 114, - 97, 108, 32, 47, 32, 78, 117, 108, 108, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 85, - 110, 107, 110, 111, 119, 110, 76, 105, 116, 101, 114, 97, 108, 10, 85, 110, 107, 110, 111, 119, - 110, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 85, 78, 75, 78, 79, 87, 78, - 39, 10, 78, 111, 116, 78, 117, 108, 108, 32, 60, 45, 32, 78, 111, 116, 78, 117, 108, 108, - 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 78, 111, 116, 78, 117, 108, 108, 79, 112, 101, - 114, 97, 116, 111, 114, 10, 78, 111, 116, 78, 117, 108, 108, 75, 101, 121, 119, 111, 114, 100, - 32, 60, 45, 32, 39, 78, 79, 84, 39, 32, 39, 78, 85, 76, 76, 39, 10, 78, 111, 116, - 78, 117, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 78, 79, 84, - 78, 85, 76, 76, 39, 10, 73, 115, 78, 117, 108, 108, 32, 60, 45, 32, 73, 115, 78, 117, - 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 73, 115, 78, 117, 108, 108, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 73, 83, 78, 85, 76, 76, 39, 10, 35, 32, - 76, 69, 86, 69, 76, 32, 53, 32, 40, 83, 112, 108, 105, 116, 32, 98, 101, 99, 97, 117, - 115, 101, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 97, 108, 108, 111, 119, 115, 32, 112, 111, 115, 116, 32, - 101, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 119, 104, 105, 108, 101, 32, 73, 115, 79, - 112, 101, 114, 97, 116, 111, 114, 32, 100, 111, 101, 115, 32, 110, 111, 116, 41, 10, 73, 115, - 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, - 109, 84, 97, 105, 108, 42, 10, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, - 109, 84, 97, 105, 108, 32, 60, 45, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, - 114, 111, 109, 79, 112, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, - 109, 79, 112, 32, 60, 45, 32, 39, 73, 83, 39, 32, 39, 78, 79, 84, 39, 63, 32, 39, - 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 39, 70, 82, 79, 77, 39, 10, 35, 32, 76, - 69, 86, 69, 76, 32, 54, 10, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 66, 101, 116, 119, 101, 101, 110, 73, 110, - 76, 105, 107, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 67, 111, 109, 112, 97, - 114, 105, 115, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, - 10, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 84, 97, 105, 108, 32, 60, 45, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 79, - 112, 101, 114, 97, 116, 111, 114, 32, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 63, 32, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, 79, 112, 101, 114, 97, 116, 111, - 114, 69, 113, 117, 97, 108, 32, 47, 10, 32, 32, 32, 32, 79, 112, 101, 114, 97, 116, 111, - 114, 78, 111, 116, 69, 113, 117, 97, 108, 32, 47, 10, 32, 32, 32, 32, 79, 112, 101, 114, - 97, 116, 111, 114, 76, 101, 115, 115, 84, 104, 97, 110, 32, 47, 10, 32, 32, 32, 32, 79, - 112, 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, 116, 101, 114, 84, 104, 97, 110, 32, 47, - 10, 32, 32, 32, 32, 79, 112, 101, 114, 97, 116, 111, 114, 76, 101, 115, 115, 84, 104, 97, - 110, 69, 113, 117, 97, 108, 115, 32, 47, 10, 32, 32, 32, 32, 79, 112, 101, 114, 97, 116, - 111, 114, 71, 114, 101, 97, 116, 101, 114, 84, 104, 97, 110, 69, 113, 117, 97, 108, 115, 10, - 79, 112, 101, 114, 97, 116, 111, 114, 69, 113, 117, 97, 108, 32, 60, 45, 32, 39, 61, 39, - 32, 47, 32, 39, 61, 61, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 78, 111, 116, 69, - 113, 117, 97, 108, 32, 60, 45, 32, 39, 33, 61, 39, 32, 47, 32, 39, 60, 62, 39, 10, - 79, 112, 101, 114, 97, 116, 111, 114, 76, 101, 115, 115, 84, 104, 97, 110, 32, 60, 45, 32, - 39, 60, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, 116, 101, 114, 84, - 104, 97, 110, 32, 60, 45, 32, 39, 62, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 76, - 101, 115, 115, 84, 104, 97, 110, 69, 113, 117, 97, 108, 115, 32, 60, 45, 32, 39, 60, 61, - 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, 116, 101, 114, 84, 104, 97, - 110, 69, 113, 117, 97, 108, 115, 32, 60, 45, 32, 39, 62, 61, 39, 10, 35, 32, 76, 69, - 86, 69, 76, 32, 55, 10, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, - 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 66, 101, 116, - 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 79, 112, 63, 10, 66, 101, 116, 119, 101, 101, - 110, 73, 110, 76, 105, 107, 101, 79, 112, 32, 60, 45, 32, 39, 78, 79, 84, 39, 63, 32, - 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 79, 112, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 79, - 112, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 66, 101, 116, 119, 101, - 101, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 73, 110, 67, 108, 97, 117, 115, 101, 32, - 47, 32, 76, 105, 107, 101, 67, 108, 97, 117, 115, 101, 10, 76, 105, 107, 101, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 76, 105, 107, 101, 86, 97, 114, 105, 97, 116, 105, 111, 110, - 115, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 69, 115, 99, 97, 112, 101, 67, 108, 97, 117, 115, 101, 63, 10, - 69, 115, 99, 97, 112, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 69, 83, 67, - 65, 80, 69, 39, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 76, 105, 107, 101, 86, 97, 114, 105, 97, 116, 105, 111, 110, 115, - 32, 60, 45, 32, 83, 105, 109, 105, 108, 97, 114, 84, 111, 84, 111, 107, 101, 110, 32, 47, - 32, 82, 101, 103, 101, 120, 73, 110, 115, 101, 110, 115, 105, 116, 105, 118, 101, 77, 97, 116, - 99, 104, 84, 111, 107, 101, 110, 32, 47, 32, 82, 101, 103, 101, 120, 77, 97, 116, 99, 104, - 84, 111, 107, 101, 110, 32, 47, 32, 73, 76, 105, 107, 101, 84, 111, 107, 101, 110, 32, 47, - 32, 76, 105, 107, 101, 84, 111, 107, 101, 110, 32, 47, 32, 71, 108, 111, 98, 84, 111, 107, - 101, 110, 32, 47, 32, 78, 111, 116, 73, 76, 105, 107, 101, 79, 112, 32, 47, 32, 78, 111, - 116, 76, 105, 107, 101, 79, 112, 32, 47, 32, 78, 111, 116, 82, 101, 103, 101, 120, 73, 110, - 115, 101, 110, 115, 105, 116, 105, 118, 101, 77, 97, 116, 99, 104, 79, 112, 32, 47, 32, 78, - 111, 116, 83, 105, 109, 105, 108, 97, 114, 84, 111, 79, 112, 10, 76, 105, 107, 101, 84, 111, - 107, 101, 110, 32, 32, 32, 32, 32, 32, 60, 45, 32, 39, 76, 73, 75, 69, 39, 32, 47, - 32, 39, 126, 126, 39, 10, 73, 76, 105, 107, 101, 84, 111, 107, 101, 110, 32, 32, 32, 32, - 32, 60, 45, 32, 39, 73, 76, 73, 75, 69, 39, 32, 47, 32, 39, 126, 126, 42, 39, 10, - 71, 108, 111, 98, 84, 111, 107, 101, 110, 32, 32, 32, 32, 32, 32, 60, 45, 32, 39, 71, - 76, 79, 66, 39, 32, 47, 32, 39, 126, 126, 126, 39, 10, 83, 105, 109, 105, 108, 97, 114, - 84, 111, 84, 111, 107, 101, 110, 32, 60, 45, 32, 39, 83, 73, 77, 73, 76, 65, 82, 39, - 32, 39, 84, 79, 39, 10, 82, 101, 103, 101, 120, 77, 97, 116, 99, 104, 84, 111, 107, 101, - 110, 32, 60, 45, 32, 39, 126, 39, 10, 82, 101, 103, 101, 120, 73, 110, 115, 101, 110, 115, - 105, 116, 105, 118, 101, 77, 97, 116, 99, 104, 84, 111, 107, 101, 110, 32, 60, 45, 32, 39, - 126, 42, 39, 10, 78, 111, 116, 73, 76, 105, 107, 101, 79, 112, 32, 32, 32, 32, 32, 60, - 45, 32, 39, 33, 126, 126, 42, 39, 10, 78, 111, 116, 76, 105, 107, 101, 79, 112, 32, 32, - 32, 32, 32, 32, 60, 45, 32, 39, 33, 126, 126, 39, 10, 78, 111, 116, 82, 101, 103, 101, - 120, 73, 110, 115, 101, 110, 115, 105, 116, 105, 118, 101, 77, 97, 116, 99, 104, 79, 112, 32, - 60, 45, 32, 39, 33, 126, 42, 39, 10, 78, 111, 116, 83, 105, 109, 105, 108, 97, 114, 84, - 111, 79, 112, 32, 60, 45, 32, 39, 33, 126, 39, 10, 73, 110, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 39, 73, 78, 39, 32, 73, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 73, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 73, 110, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 47, 32, 73, 110, 83, - 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 73, 110, 67, - 111, 110, 116, 97, 105, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, 110, - 67, 111, 110, 116, 97, 105, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 73, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, - 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 73, 110, 83, 101, 108, 101, 99, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, - 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, - 97, 108, 41, 10, 66, 101, 116, 119, 101, 101, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, - 32, 39, 66, 69, 84, 87, 69, 69, 78, 39, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, - 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 65, 78, 68, 39, - 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 10, 35, 32, 76, 69, 86, 69, 76, 32, 56, 10, 79, 116, 104, 101, 114, - 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, 108, 42, 10, 79, - 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, 108, 32, 60, 45, 32, - 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 66, 105, 116, 119, 105, 115, - 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 116, 104, 101, 114, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, 65, 110, 121, 65, 108, 108, 80, - 97, 114, 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 78, 97, 109, 101, - 100, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 10, 65, 110, 121, 65, 108, - 108, 80, 97, 114, 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 65, - 110, 121, 65, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 78, 97, 109, 101, 100, 79, - 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, - 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, - 73, 110, 101, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 74, 115, 111, 110, 79, - 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 76, 105, 115, 116, 79, 112, 101, 114, 97, 116, - 111, 114, 32, 47, 32, 83, 116, 114, 105, 110, 103, 79, 112, 101, 114, 97, 116, 111, 114, 32, - 47, 32, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, 79, 112, - 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 10, 65, 110, 121, 65, 108, 108, 79, 112, 101, 114, 97, 116, - 111, 114, 32, 60, 45, 32, 65, 110, 121, 79, 112, 32, 65, 110, 121, 79, 114, 65, 108, 108, - 10, 65, 110, 121, 79, 114, 65, 108, 108, 32, 60, 45, 32, 83, 117, 98, 113, 117, 101, 114, - 121, 65, 110, 121, 32, 47, 32, 83, 117, 98, 113, 117, 101, 114, 121, 65, 108, 108, 10, 83, - 117, 98, 113, 117, 101, 114, 121, 65, 110, 121, 32, 60, 45, 32, 39, 65, 78, 89, 39, 10, - 83, 117, 98, 113, 117, 101, 114, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, - 10, 73, 110, 101, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 62, 62, - 61, 39, 32, 47, 32, 39, 60, 60, 61, 39, 10, 74, 115, 111, 110, 79, 112, 101, 114, 97, - 116, 111, 114, 32, 60, 45, 32, 39, 45, 62, 62, 39, 10, 76, 105, 115, 116, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 60, 45, 62, 39, 32, 47, 32, 39, 38, 38, - 39, 32, 47, 32, 39, 64, 62, 39, 32, 47, 32, 39, 60, 64, 39, 10, 83, 116, 114, 105, - 110, 103, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 94, 64, 39, 32, 47, - 32, 39, 124, 124, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, - 116, 111, 114, 32, 60, 45, 32, 39, 79, 80, 69, 82, 65, 84, 79, 82, 39, 32, 80, 97, - 114, 101, 110, 115, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, - 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 81, 117, 97, 108, 105, 102, 105, 101, - 100, 79, 112, 101, 114, 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, 32, 60, 45, - 32, 67, 111, 108, 73, 100, 68, 111, 116, 42, 32, 65, 110, 121, 79, 112, 10, 65, 110, 121, - 79, 112, 32, 60, 45, 32, 39, 33, 126, 126, 42, 39, 32, 47, 32, 39, 62, 62, 61, 39, - 32, 47, 32, 39, 60, 60, 61, 39, 32, 47, 32, 39, 60, 45, 62, 39, 32, 47, 32, 39, - 45, 62, 62, 39, 32, 47, 32, 39, 33, 126, 126, 39, 32, 47, 32, 39, 33, 126, 42, 39, - 32, 47, 32, 39, 126, 126, 42, 39, 32, 47, 32, 39, 126, 126, 126, 39, 32, 47, 32, 39, - 126, 42, 39, 32, 47, 32, 39, 33, 126, 39, 32, 47, 32, 39, 94, 64, 39, 32, 47, 32, - 39, 124, 124, 39, 32, 47, 32, 39, 38, 38, 39, 32, 47, 32, 39, 64, 62, 39, 32, 47, - 32, 39, 60, 64, 39, 32, 47, 32, 39, 60, 61, 39, 32, 47, 32, 39, 62, 61, 39, 32, - 47, 32, 39, 60, 62, 39, 32, 47, 32, 39, 33, 61, 39, 32, 47, 32, 39, 61, 61, 39, - 32, 47, 32, 39, 60, 60, 39, 32, 47, 32, 39, 62, 62, 39, 32, 47, 32, 39, 47, 47, - 39, 32, 47, 32, 39, 42, 42, 39, 32, 47, 32, 39, 45, 62, 39, 32, 47, 32, 39, 126, - 126, 39, 32, 47, 32, 39, 43, 39, 32, 47, 32, 39, 45, 39, 32, 47, 32, 39, 42, 39, - 32, 47, 32, 39, 47, 39, 32, 47, 32, 39, 37, 39, 32, 47, 32, 39, 94, 39, 32, 47, - 32, 39, 60, 39, 32, 47, 32, 39, 62, 39, 32, 47, 32, 39, 61, 39, 32, 47, 32, 39, - 38, 39, 32, 47, 32, 39, 124, 39, 32, 47, 32, 39, 126, 39, 32, 47, 32, 39, 33, 39, - 10, 35, 32, 76, 69, 86, 69, 76, 32, 57, 10, 66, 105, 116, 119, 105, 115, 101, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 100, 100, 105, 116, 105, 118, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 66, 105, 116, 119, 105, 115, - 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 66, - 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, - 114, 32, 60, 45, 32, 39, 38, 39, 32, 47, 32, 39, 124, 39, 32, 47, 32, 39, 60, 60, - 39, 32, 47, 32, 39, 62, 62, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 48, 10, - 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 100, 100, 105, 116, 105, 118, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 84, 101, 114, - 109, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 84, 101, 114, 109, 32, 60, 45, 32, 39, 43, 39, 32, 47, - 32, 39, 45, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 49, 10, 77, 117, 108, 116, - 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, - 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 77, - 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 70, 97, 99, 116, 111, 114, 32, 69, 120, - 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 10, 70, 97, 99, 116, 111, 114, 32, 60, 45, 32, 39, 42, 39, 32, 47, 32, 39, - 47, 39, 32, 47, 32, 39, 47, 47, 39, 32, 47, 32, 39, 37, 39, 10, 35, 32, 76, 69, - 86, 69, 76, 32, 49, 50, 10, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, - 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 108, 97, - 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 69, 120, 112, 111, 110, 101, 110, - 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, - 108, 42, 10, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 69, 120, 112, 111, 110, - 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 67, 111, 108, 108, 97, 116, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 111, 110, 101, 110, 116, 79, 112, - 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 94, 39, 32, 47, 32, 39, 42, 42, 39, - 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 51, 10, 67, 111, 108, 108, 97, 116, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 116, 84, 105, 109, 101, 90, - 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 67, 111, 108, 108, 97, 116, - 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 67, 111, 108, - 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, - 45, 32, 67, 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 65, 116, - 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, - 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 67, - 79, 76, 76, 65, 84, 69, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 52, 10, 65, - 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 84, 97, 105, 108, 42, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 65, 116, 84, 105, 109, 101, - 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 80, 114, 101, 102, 105, 120, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, - 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 65, 84, 39, 32, 39, 84, 73, - 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, - 53, 10, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 42, 32, 66, 97, - 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 114, 101, 102, 105, 120, 79, - 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, - 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 77, 105, 110, 117, 115, 80, 114, 101, 102, - 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 80, 108, 117, 115, 80, 114, 101, - 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 84, 105, 108, 100, 101, 80, - 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 10, 77, 105, 110, 117, 115, 80, - 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 45, 39, - 10, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, - 60, 45, 32, 39, 43, 39, 10, 84, 105, 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, - 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 126, 39, 10, 35, 32, 76, 69, 86, 69, - 76, 32, 49, 54, 32, 40, 72, 105, 103, 104, 101, 115, 116, 41, 10, 66, 97, 115, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 105, 110, 103, 108, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, - 110, 76, 105, 115, 116, 63, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 76, 105, - 115, 116, 32, 60, 45, 32, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 43, 10, 73, - 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, 115, 116, 79, 112, - 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, 114, - 32, 47, 32, 83, 108, 105, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, - 32, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 10, 67, 97, 115, - 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 58, 58, 39, 32, 84, 121, - 112, 101, 10, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 68, 111, - 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, - 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, 111, 114, 10, 68, 111, 116, 77, - 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 46, 39, - 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 111, - 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, - 46, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 10, 77, 101, 116, 104, 111, 100, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 76, 97, 98, 101, 108, - 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, - 117, 109, 101, 110, 116, 115, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, - 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 41, 10, 77, 101, 116, 104, 111, 100, 69, + 108, 117, 109, 110, 78, 97, 109, 101, 10, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, + 118, 101, 100, 84, 97, 98, 108, 101, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 60, + 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, + 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 81, 117, 97, 108, 105, + 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 67, 111, 108, + 117, 109, 110, 78, 97, 109, 101, 10, 84, 97, 98, 108, 101, 82, 101, 115, 101, 114, 118, 101, + 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 84, 97, 98, 108, 101, + 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, + 101, 100, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 10, 70, 117, 110, 99, 116, 105, 111, + 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 70, 117, 110, 99, 116, + 105, 111, 110, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 70, 117, 110, 99, 116, 105, + 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, + 115, 32, 87, 105, 116, 104, 105, 110, 71, 114, 111, 117, 112, 67, 108, 97, 117, 115, 101, 63, + 32, 70, 105, 108, 116, 101, 114, 67, 108, 97, 117, 115, 101, 63, 32, 69, 120, 112, 111, 114, + 116, 67, 108, 97, 117, 115, 101, 63, 32, 79, 118, 101, 114, 67, 108, 97, 117, 115, 101, 63, + 10, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, + 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 70, + 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, + 117, 109, 101, 110, 116, 76, 105, 115, 116, 41, 10, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 32, - 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, - 110, 116, 115, 63, 32, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, - 73, 103, 110, 111, 114, 101, 79, 114, 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, - 63, 10, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, - 109, 101, 110, 116, 115, 32, 60, 45, 32, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, - 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 10, 83, 108, 105, 99, 101, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 91, 39, 32, 83, 108, 105, 99, 101, - 66, 111, 117, 110, 100, 32, 39, 93, 39, 10, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, - 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 69, 110, 100, 83, - 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 32, 83, 116, 101, 112, 83, 108, 105, 99, 101, - 66, 111, 117, 110, 100, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, - 32, 60, 45, 32, 39, 58, 39, 32, 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, 108, 117, - 101, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 110, 100, 83, 108, 105, 99, - 101, 77, 105, 110, 117, 115, 10, 69, 110, 100, 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, - 32, 60, 45, 32, 39, 45, 39, 10, 83, 116, 101, 112, 83, 108, 105, 99, 101, 66, 111, 117, - 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 63, 10, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, - 32, 39, 33, 39, 10, 83, 112, 101, 99, 105, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 97, 108, 101, 115, - 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 85, 110, 112, 97, 99, - 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, 114, 121, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 67, 111, 108, 117, 109, 110, 115, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 47, 32, 78, 117, 108, 108, 73, 102, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 47, 32, 82, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 47, 32, 84, 114, 105, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 39, 67, 79, 65, 76, 69, 83, 67, 69, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, - 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, - 39, 85, 78, 80, 65, 67, 75, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 39, 84, 82, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 67, 111, 108, 117, 109, 110, 115, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, - 108, 63, 32, 39, 67, 79, 76, 85, 77, 78, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 69, 88, 84, 82, 65, 67, - 84, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, - 117, 109, 101, 110, 116, 115, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, - 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, - 101, 110, 116, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 39, 76, 65, 77, 66, 68, 65, 39, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, - 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 78, 117, 108, 108, 73, 102, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 39, 78, 85, 76, 76, 73, 70, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 78, - 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 44, 39, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 10, 80, 111, 115, 105, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, 32, 80, 97, 114, - 101, 110, 115, 40, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, - 115, 41, 10, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, - 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 10, 82, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, - 32, 39, 82, 79, 87, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 83, 117, 98, 115, 116, 114, 105, - 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 83, 85, 66, - 83, 84, 82, 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 117, 98, 115, 116, - 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 83, 117, 98, 115, 116, - 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 83, 117, 98, - 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, 32, 83, - 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, - 115, 116, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, - 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, 114, 10, 83, 117, - 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, 114, 32, 60, 45, 32, 83, 117, - 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, 116, 105, 111, 110, 97, 108, 70, - 111, 114, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, 114, 10, 83, 117, - 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, 116, 105, 111, 110, 97, 108, 70, - 111, 114, 32, 60, 45, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 83, 117, 98, 115, - 116, 114, 105, 110, 103, 70, 111, 114, 32, 60, 45, 32, 70, 111, 114, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 84, 114, 105, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 39, 84, 82, 73, 77, 39, 32, 80, 97, 114, 101, 110, 115, 40, 84, 114, - 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 84, 114, 105, 109, 65, 114, 103, - 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 84, 114, 105, 109, 68, 105, 114, 101, 99, 116, - 105, 111, 110, 63, 32, 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 63, 32, 76, 105, 115, - 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 105, 109, 68, 105, - 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 114, 105, 109, 66, 111, 116, 104, 32, - 47, 32, 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, 32, 47, 32, 84, 114, 105, 109, - 84, 114, 97, 105, 108, 105, 110, 103, 10, 84, 114, 105, 109, 66, 111, 116, 104, 32, 60, 45, - 32, 39, 66, 79, 84, 72, 39, 10, 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, 32, - 60, 45, 32, 39, 76, 69, 65, 68, 73, 78, 71, 39, 10, 84, 114, 105, 109, 84, 114, 97, - 105, 108, 105, 110, 103, 32, 60, 45, 32, 39, 84, 82, 65, 73, 76, 73, 78, 71, 39, 10, - 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 63, 32, 39, 70, 82, 79, 77, 39, 10, 79, 118, 101, 114, 108, 97, 121, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 79, 86, 69, 82, 76, - 65, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 118, 101, 114, 108, 97, 121, 65, 114, - 103, 117, 109, 101, 110, 116, 115, 41, 10, 79, 118, 101, 114, 108, 97, 121, 65, 114, 103, 117, - 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 118, 101, 114, 108, 97, 121, 80, 97, 114, 97, - 109, 101, 116, 101, 114, 115, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 79, 118, 101, 114, 108, 97, 121, 80, 97, - 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 39, 80, 76, 65, 67, 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, - 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 70, 114, 111, 109, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 10, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, - 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, - 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, - 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, - 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 65, 114, 103, 117, - 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, - 97, 114, 116, 10, 69, 120, 116, 114, 97, 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, - 114, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 10, 69, 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, 114, 103, - 117, 109, 101, 110, 116, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 32, 60, - 45, 10, 32, 32, 32, 32, 89, 101, 97, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, - 77, 111, 110, 116, 104, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, 97, 121, 75, 101, - 121, 119, 111, 114, 100, 32, 47, 32, 72, 111, 117, 114, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 77, 105, 110, 117, 116, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 83, 101, - 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 77, 105, - 108, 108, 105, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, - 105, 99, 114, 111, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, - 87, 101, 101, 107, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 81, 117, 97, 114, 116, 101, - 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, 101, 99, 97, 100, 101, 75, 101, 121, - 119, 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 67, 101, 110, 116, 117, 114, 121, 75, 101, - 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 108, 108, 101, 110, 110, 105, 117, 109, 75, 101, - 121, 119, 111, 114, 100, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, - 99, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, - 101, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, - 116, 32, 47, 32, 82, 101, 103, 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, - 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 68, 101, 115, 116, 114, - 111, 121, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, - 109, 116, 32, 47, 32, 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, - 111, 117, 114, 99, 101, 115, 83, 116, 109, 116, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, - 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, - 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, - 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 69, - 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, - 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 82, 101, 103, 105, 115, 116, 101, 114, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, - 32, 60, 45, 32, 39, 82, 69, 71, 73, 83, 84, 69, 82, 39, 32, 39, 69, 88, 84, 69, - 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 39, 32, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, - 97, 115, 63, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 68, 101, 115, 116, 114, 111, 121, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, - 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 69, 83, 84, 82, 79, - 89, 39, 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, - 82, 67, 69, 39, 32, 67, 111, 108, 73, 100, 10, 83, 104, 111, 119, 69, 120, 116, 101, 114, - 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 115, 83, 116, 109, 116, 32, 60, 45, 32, - 39, 83, 72, 79, 87, 39, 32, 83, 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, - 101, 114, 63, 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, 79, - 85, 82, 67, 69, 83, 39, 10, 83, 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, - 101, 114, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 35, 32, 84, 104, 101, 32, 114, 101, - 99, 105, 112, 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, - 46, 32, 73, 116, 115, 32, 111, 119, 110, 32, 114, 117, 108, 101, 32, 114, 97, 116, 104, 101, - 114, 32, 116, 104, 97, 110, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, - 58, 32, 116, 104, 101, 32, 116, 119, 111, 32, 111, 112, 116, 105, 111, 110, 32, 98, 97, 103, - 115, 32, 97, 114, 101, 10, 35, 32, 100, 105, 115, 116, 105, 110, 99, 116, 44, 32, 97, 110, - 100, 32, 97, 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 97, 110, 32, 99, 97, - 114, 114, 121, 32, 98, 111, 116, 104, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, - 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, - 115, 32, 60, 45, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, - 111, 110, 76, 105, 115, 116, 10, 73, 110, 115, 101, 114, 116, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 73, - 78, 83, 69, 82, 84, 39, 32, 79, 114, 65, 99, 116, 105, 111, 110, 63, 32, 39, 73, 78, - 84, 79, 39, 32, 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, 66, 121, 78, - 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 63, 32, 73, 110, 115, 101, 114, - 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 73, 110, 115, 101, 114, 116, 86, - 97, 108, 117, 101, 115, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 67, 108, 97, 117, - 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, - 10, 79, 114, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 79, - 114, 82, 101, 112, 108, 97, 99, 101, 32, 47, 32, 73, 110, 115, 101, 114, 116, 79, 114, 73, - 103, 110, 111, 114, 101, 10, 73, 110, 115, 101, 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, - 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 82, 69, 80, 76, 65, 67, 69, 39, 10, - 73, 110, 115, 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, 32, 60, 45, 32, 39, 79, - 82, 39, 32, 39, 73, 71, 78, 79, 82, 69, 39, 10, 66, 121, 78, 97, 109, 101, 79, 114, - 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 66, 121, - 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 47, 32, 73, 110, 115, 101, 114, 116, 66, 121, - 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 10, 73, 110, 115, 101, 114, 116, - 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 66, 89, 39, 32, - 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 10, 73, 110, 115, 101, 114, 116, 66, - 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 66, - 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 10, - 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 39, 78, 65, 77, - 69, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 32, - 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, 10, 73, 110, 115, 101, 114, 116, - 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, - 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 63, 10, 73, 110, 115, - 101, 114, 116, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, - 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 41, 10, 73, 110, 115, 101, 114, 116, - 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, - 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, 10, 73, 110, 115, 101, 114, 116, 86, - 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, 114, - 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, - 117, 101, 115, 10, 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, - 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, - 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, - 76, 85, 69, 83, 39, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, 78, 70, 76, 73, 67, 84, - 39, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, 116, 63, 32, - 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, 111, 110, 10, 79, 110, 67, - 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 79, 110, 67, - 111, 110, 102, 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, - 103, 101, 116, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 73, 110, 100, 101, - 120, 84, 97, 114, 103, 101, 116, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 111, - 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, - 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 73, 110, 100, 101, 120, 84, - 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, 78, 83, 84, - 82, 65, 73, 78, 84, 39, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, - 101, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, 111, 110, 32, 60, - 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, 101, 32, 47, - 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, 116, 104, 105, 110, 103, 10, 79, - 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, 101, 32, 60, 45, 32, 39, - 68, 79, 39, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 83, 69, 84, 39, 32, 85, - 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 87, 104, 101, 114, 101, - 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, - 116, 104, 105, 110, 103, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, 84, 72, 73, - 78, 71, 39, 10, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 82, 69, 84, 85, 82, 78, 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, - 116, 76, 105, 115, 116, 10, 76, 111, 97, 100, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 60, 45, 32, 39, 76, 79, 65, 68, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, - 105, 110, 103, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 63, 32, 69, 120, 116, 101, - 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 63, 10, 69, 120, 116, 101, 110, 115, 105, 111, - 110, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 10, 73, 110, 115, 116, 97, 108, 108, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 63, 32, 39, 73, 78, 83, 84, - 65, 76, 76, 39, 32, 73, 110, 115, 116, 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 63, - 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 63, 32, 86, - 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 63, 10, 73, 110, 115, 116, 97, 108, - 108, 65, 110, 100, 76, 111, 97, 100, 32, 60, 45, 32, 39, 65, 78, 68, 39, 32, 39, 76, - 79, 65, 68, 39, 10, 85, 112, 100, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, - 115, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, - 69, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 83, 39, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 41, 41, - 63, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 70, 114, 111, 109, - 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 70, - 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, 10, 70, 114, 111, 109, - 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, - 39, 70, 82, 79, 77, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 70, 114, - 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, 32, 60, 45, 32, 39, 70, - 82, 79, 77, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 86, - 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 32, 60, 45, 32, 39, 86, 69, 82, - 83, 73, 79, 78, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, - 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 101, 110, 115, 105, 111, - 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, - 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 47, 32, 68, 114, 111, 112, - 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, - 116, 109, 116, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, - 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, 39, 67, 82, - 69, 65, 84, 69, 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, 101, 63, 32, 39, 69, 88, - 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, 83, 73, 84, 79, 82, 89, - 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, - 79, 114, 83, 116, 114, 105, 110, 103, 32, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, - 114, 101, 102, 105, 120, 32, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, - 105, 99, 75, 101, 121, 63, 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 114, 101, - 102, 105, 120, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 63, 32, 39, 80, 82, 69, 70, - 73, 88, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 82, 101, - 112, 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, 105, 99, 75, 101, 121, 32, 60, 45, - 32, 39, 85, 83, 73, 78, 71, 39, 63, 32, 39, 80, 85, 66, 76, 73, 67, 39, 32, 40, - 39, 75, 69, 89, 83, 39, 32, 47, 32, 39, 75, 69, 89, 39, 41, 32, 76, 105, 115, 116, - 40, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 41, 10, 68, 114, 111, 112, - 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, - 116, 109, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 39, 69, 88, 84, 69, 78, - 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, 83, 73, 84, 79, 82, 89, 39, 32, 73, - 102, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, - 110, 103, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 77, 69, - 82, 71, 69, 39, 32, 39, 73, 78, 84, 79, 39, 32, 84, 97, 114, 103, 101, 116, 79, 112, - 116, 65, 108, 105, 97, 115, 32, 77, 101, 114, 103, 101, 73, 110, 116, 111, 85, 115, 105, 110, - 103, 67, 108, 97, 117, 115, 101, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, - 114, 32, 77, 101, 114, 103, 101, 77, 97, 116, 99, 104, 43, 32, 82, 101, 116, 117, 114, 110, - 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, - 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, - 71, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 10, 77, 101, 114, 103, 101, 77, 97, 116, - 99, 104, 32, 60, 45, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, - 47, 32, 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 10, 77, - 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, - 78, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, 65, 110, 100, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, 32, 77, 97, 116, 99, 104, - 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 10, 77, 97, 116, 99, 104, - 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 85, 112, - 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 101, - 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 73, 110, - 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 111, - 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, - 32, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 85, 112, - 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, - 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 73, - 110, 102, 111, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 73, 110, 102, 111, - 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 65, 99, - 116, 105, 111, 110, 32, 47, 32, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, - 114, 80, 111, 115, 105, 116, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, - 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, - 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, 10, 85, 112, 100, 97, 116, - 101, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, - 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 10, 68, 101, - 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, - 68, 69, 76, 69, 84, 69, 39, 10, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, - 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, 83, 69, 82, 84, 39, 32, 73, 110, - 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, 10, 73, 110, 115, 101, 114, - 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, - 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 47, 32, 73, 110, 115, 101, 114, 116, 68, - 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 73, 110, 115, 101, 114, - 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 10, 73, 110, - 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, - 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, - 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, - 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, - 111, 110, 63, 32, 39, 42, 39, 63, 10, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, - 115, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, - 110, 76, 105, 115, 116, 63, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, - 10, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, 84, 72, 73, 78, 71, 39, 10, - 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 39, 69, 82, 82, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, - 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, - 104, 83, 101, 116, 73, 110, 102, 111, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, - 83, 101, 116, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 10, - 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 65, 78, - 68, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 111, 116, 77, 97, 116, - 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 78, 39, - 32, 39, 78, 79, 84, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, 66, 121, 83, - 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 63, 32, 65, 110, 100, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, 32, 77, 97, 116, - 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 10, 66, 121, 83, - 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 121, 83, - 111, 117, 114, 99, 101, 32, 47, 32, 66, 121, 84, 97, 114, 103, 101, 116, 10, 66, 121, 83, - 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 83, 79, 85, 82, 67, - 69, 39, 10, 66, 121, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 66, 89, 39, 32, - 39, 84, 65, 82, 71, 69, 84, 39, 10, 80, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, - 84, 97, 98, 108, 101, 82, 101, 102, 32, 80, 105, 118, 111, 116, 79, 110, 63, 32, 80, 105, - 118, 111, 116, 85, 115, 105, 110, 103, 63, 32, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, - 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 79, 110, 32, 60, 45, 32, 39, - 79, 78, 39, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, - 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, - 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 67, 111, - 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 80, 105, 118, - 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 41, 10, 80, 105, 118, 111, 116, - 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 32, 60, 45, 32, 80, 105, 118, 111, 116, - 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 80, 105, 118, - 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 47, 32, 80, 105, 118, 111, 116, 67, - 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, - 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, - 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, 116, 67, 111, 108, - 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 66, 97, 115, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, - 101, 114, 110, 97, 108, 41, 10, 80, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, - 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 47, 32, 39, 80, 73, 86, 79, 84, 95, - 87, 73, 68, 69, 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, - 100, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, 47, 32, 39, 80, 73, - 86, 79, 84, 95, 76, 79, 78, 71, 69, 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 75, - 101, 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 39, 79, 78, 39, - 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 73, 110, 116, 111, 78, 97, 109, 101, - 86, 97, 108, 117, 101, 115, 63, 10, 73, 110, 116, 111, 78, 97, 109, 101, 86, 97, 108, 117, - 101, 115, 32, 60, 45, 32, 39, 73, 78, 84, 79, 39, 32, 39, 78, 65, 77, 69, 39, 32, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 86, 97, 108, 117, 101, 79, - 114, 86, 97, 108, 117, 101, 115, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, - 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 10, 86, 97, 108, 117, 101, 79, 114, 86, 97, - 108, 117, 101, 115, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, 39, 32, 47, 32, 39, 86, - 65, 76, 85, 69, 83, 39, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, - 115, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 116, 104, - 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 47, 32, 66, 97, 114, - 101, 78, 97, 109, 101, 76, 105, 115, 116, 10, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, - 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, - 41, 41, 10, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 76, - 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 10, 73, - 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, - 32, 60, 45, 32, 73, 110, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 47, 32, 69, - 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 10, 73, 110, 99, 108, 117, 100, 101, 78, - 117, 108, 108, 115, 32, 60, 45, 32, 39, 73, 78, 67, 76, 85, 68, 69, 39, 32, 39, 78, - 85, 76, 76, 83, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, - 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, - 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 60, 45, 32, 85, 110, 112, - 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, 108, 101, 32, 47, 32, 85, - 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 10, 85, 110, 112, - 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, 108, 101, 32, 60, 45, 32, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 85, 110, 112, 105, 118, 111, - 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, - 41, 41, 10, 80, 114, 97, 103, 109, 97, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, - 45, 32, 39, 80, 82, 65, 71, 77, 65, 39, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, - 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, 103, 109, 97, - 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, - 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 32, 47, 32, 80, 114, 97, 103, 109, - 97, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, - 103, 110, 32, 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 32, 39, 61, - 39, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 10, 80, 114, 97, 103, 109, - 97, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 80, 114, 97, 103, 109, 97, 78, - 97, 109, 101, 32, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, - 63, 10, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 41, 41, 10, 80, 114, 101, 112, 97, 114, 101, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 69, 80, 65, 82, 69, 39, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 84, 121, 112, 101, 76, 105, 115, 116, 63, 32, 39, 65, - 83, 39, 32, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 84, 121, 112, 101, 76, 105, 115, - 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 84, 121, 112, - 101, 41, 41, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, - 116, 101, 114, 110, 97, 108, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, - 97, 117, 115, 101, 63, 32, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, - 105, 110, 32, 82, 101, 115, 117, 108, 116, 77, 111, 100, 105, 102, 105, 101, 114, 115, 63, 10, - 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 32, 60, 45, 32, - 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 32, 83, 101, 108, 101, 99, - 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 84, 97, 105, 108, 42, 10, 83, 101, 108, - 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 84, 97, 105, 108, 32, 60, 45, - 32, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, 32, 73, 110, 116, 101, 114, 115, 101, - 99, 116, 67, 104, 97, 105, 110, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, - 105, 110, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 32, 73, 110, 116, - 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 84, 97, 105, 108, 42, 10, 73, 110, 116, - 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 84, 97, 105, 108, 32, 60, 45, 32, 83, - 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 83, 101, - 108, 101, 99, 116, 65, 116, 111, 109, 10, 83, 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, - 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 83, 69, 67, - 84, 39, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 10, 83, 101, - 108, 101, 99, 116, 65, 116, 111, 109, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 80, 97, - 114, 101, 110, 115, 32, 47, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 84, 121, 112, 101, 10, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, - 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 83, 101, 116, 111, 112, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, 101, 116, 111, 112, 84, 121, 112, 101, 32, - 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 32, 66, 121, 78, 97, 109, - 101, 63, 10, 83, 101, 116, 111, 112, 84, 121, 112, 101, 32, 60, 45, 32, 83, 101, 116, 111, - 112, 85, 110, 105, 111, 110, 32, 47, 32, 83, 101, 116, 111, 112, 69, 120, 99, 101, 112, 116, - 10, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, 32, 60, 45, 32, 39, 85, 78, 73, 79, - 78, 39, 10, 83, 101, 116, 111, 112, 69, 120, 99, 101, 112, 116, 32, 60, 45, 32, 39, 69, - 88, 67, 69, 80, 84, 39, 10, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 39, 66, 89, - 39, 32, 39, 78, 65, 77, 69, 39, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 84, 121, 112, 101, 32, 60, 45, 32, 79, 112, 116, 105, 111, 110, 97, 108, - 80, 97, 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 47, - 32, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 101, 115, 99, - 114, 105, 98, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 84, 97, 98, 108, - 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 80, 105, 118, 111, 116, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 85, 110, 112, 105, 118, 111, 116, 83, 116, 97, - 116, 101, 109, 101, 110, 116, 10, 82, 101, 115, 117, 108, 116, 77, 111, 100, 105, 102, 105, 101, - 114, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, - 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 63, 10, 76, 105, 109, 105, 116, 79, - 102, 102, 115, 101, 116, 32, 60, 45, 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, 102, 115, 101, 116, 76, 105, 109, 105, 116, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, - 97, 117, 115, 101, 10, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 79, 102, - 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 76, 105, - 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, 67, - 108, 97, 117, 115, 101, 32, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 63, 10, 79, - 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 70, 101, 116, 99, 104, 67, 108, - 97, 117, 115, 101, 10, 70, 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, - 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, - 39, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 79, 112, 116, 105, - 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, - 99, 116, 32, 60, 45, 32, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, - 114, 101, 110, 115, 32, 47, 32, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 10, - 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, - 116, 41, 10, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, - 101, 108, 101, 99, 116, 70, 114, 111, 109, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, - 101, 63, 32, 71, 114, 111, 117, 112, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 72, 97, - 118, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 32, 87, 105, 110, 100, 111, 119, 67, 108, - 97, 117, 115, 101, 63, 32, 81, 117, 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 63, - 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 83, 101, 108, 101, 99, - 116, 70, 114, 111, 109, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, - 108, 97, 117, 115, 101, 32, 47, 32, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, - 97, 117, 115, 101, 10, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, - 111, 109, 67, 108, 97, 117, 115, 101, 63, 10, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, - 32, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, - 116, 114, 105, 110, 103, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, - 115, 116, 63, 32, 85, 115, 105, 110, 103, 75, 101, 121, 63, 32, 39, 65, 83, 39, 32, 77, - 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, 63, 32, 67, 84, 69, 66, 111, 100, 121, - 10, 67, 84, 69, 66, 111, 100, 121, 32, 60, 45, 32, 67, 84, 69, 83, 101, 108, 101, 99, - 116, 66, 111, 100, 121, 32, 47, 32, 67, 84, 69, 68, 77, 76, 66, 111, 100, 121, 10, 67, - 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, + 63, 32, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 73, 103, 110, + 111, 114, 101, 79, 114, 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 63, 10, 70, + 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 32, + 60, 45, 32, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, + 109, 101, 110, 116, 41, 10, 70, 117, 110, 99, 116, 105, 111, 110, 73, 100, 101, 110, 116, 105, + 102, 105, 101, 114, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, + 118, 101, 100, 83, 99, 104, 101, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, + 101, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 70, 117, + 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 32, 47, 32, 70, 117, 110, 99, 116, 105, 111, + 110, 78, 97, 109, 101, 65, 115, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, + 10, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 65, 115, 81, 117, 97, 108, 105, + 102, 105, 101, 100, 78, 97, 109, 101, 32, 60, 45, 32, 70, 117, 110, 99, 116, 105, 111, 110, + 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, + 83, 99, 104, 101, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 32, 60, + 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, + 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 42, 32, 82, 101, 115, 101, 114, 118, 101, 100, + 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, 83, 99, 104, 101, 109, 97, 82, + 101, 115, 101, 114, 118, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 32, + 60, 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 78, + 97, 109, 101, 10, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 32, 60, 45, + 32, 68, 105, 115, 116, 105, 110, 99, 116, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 65, + 108, 108, 75, 101, 121, 119, 111, 114, 100, 10, 68, 105, 115, 116, 105, 110, 99, 116, 75, 101, + 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 10, + 65, 108, 108, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, + 69, 120, 112, 111, 114, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 69, 88, 80, + 79, 82, 84, 95, 83, 84, 65, 84, 69, 39, 10, 87, 105, 116, 104, 105, 110, 71, 114, 111, + 117, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 73, 78, 39, + 32, 39, 71, 82, 79, 85, 80, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 114, 100, 101, + 114, 66, 121, 67, 108, 97, 117, 115, 101, 41, 10, 70, 105, 108, 116, 101, 114, 67, 108, 97, + 117, 115, 101, 32, 60, 45, 32, 39, 70, 73, 76, 84, 69, 82, 39, 32, 70, 105, 108, 116, + 101, 114, 67, 108, 97, 117, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, + 105, 108, 116, 101, 114, 67, 108, 97, 117, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 70, 105, 108, 116, 101, 114, 67, 108, + 97, 117, 115, 101, 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 70, 105, 108, 116, 101, 114, + 67, 108, 97, 117, 115, 101, 67, 111, 110, 116, 101, 110, 116, 115, 32, 60, 45, 32, 39, 87, + 72, 69, 82, 69, 39, 63, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, 103, + 110, 111, 114, 101, 79, 114, 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 32, 60, + 45, 32, 73, 103, 110, 111, 114, 101, 78, 117, 108, 108, 115, 32, 47, 32, 82, 101, 115, 112, + 101, 99, 116, 78, 117, 108, 108, 115, 10, 73, 103, 110, 111, 114, 101, 78, 117, 108, 108, 115, + 32, 60, 45, 32, 39, 73, 71, 78, 79, 82, 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, + 10, 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 82, 69, + 83, 80, 69, 67, 84, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 80, 97, 114, 101, 110, + 116, 104, 101, 115, 105, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 41, 63, 41, 10, 76, 105, 116, 101, 114, 97, 108, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 32, 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 67, + 111, 110, 115, 116, 97, 110, 116, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 110, 115, 116, + 97, 110, 116, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 78, 117, 108, 108, 76, 105, + 116, 101, 114, 97, 108, 32, 47, 32, 84, 114, 117, 101, 76, 105, 116, 101, 114, 97, 108, 32, + 47, 32, 70, 97, 108, 115, 101, 76, 105, 116, 101, 114, 97, 108, 10, 78, 117, 108, 108, 76, + 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 78, 85, 76, 76, 39, 10, 84, 114, 117, + 101, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 84, 82, 85, 69, 39, 10, 70, + 97, 108, 115, 101, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 70, 65, 76, 83, + 69, 39, 10, 67, 97, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, + 32, 67, 97, 115, 116, 79, 114, 84, 114, 121, 67, 97, 115, 116, 32, 80, 97, 114, 101, 110, + 115, 40, 67, 97, 115, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 67, 97, 115, + 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 39, 65, 83, 39, 32, 84, 121, 112, 101, 10, 67, 97, 115, 116, 79, + 114, 84, 114, 121, 67, 97, 115, 116, 32, 60, 45, 32, 67, 97, 115, 116, 75, 101, 121, 119, + 111, 114, 100, 32, 47, 32, 84, 114, 121, 67, 97, 115, 116, 75, 101, 121, 119, 111, 114, 100, + 10, 67, 97, 115, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 65, 83, + 84, 39, 10, 84, 114, 121, 67, 97, 115, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, + 32, 39, 84, 82, 89, 95, 67, 65, 83, 84, 39, 10, 67, 111, 108, 73, 100, 68, 111, 116, + 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 39, 46, 39, 10, 83, 116, 97, 114, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 81, 117, 97, 108, + 105, 102, 105, 101, 114, 76, 105, 115, 116, 63, 32, 39, 42, 39, 32, 69, 120, 99, 108, 117, + 100, 101, 76, 105, 115, 116, 63, 32, 82, 101, 112, 108, 97, 99, 101, 76, 105, 115, 116, 63, + 32, 82, 101, 110, 97, 109, 101, 76, 105, 115, 116, 63, 10, 83, 116, 97, 114, 81, 117, 97, + 108, 105, 102, 105, 101, 114, 76, 105, 115, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 68, + 111, 116, 43, 10, 69, 120, 99, 108, 117, 100, 101, 76, 105, 115, 116, 32, 60, 45, 32, 69, + 120, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 101, 112, 116, 32, 69, 120, 99, 108, 117, + 100, 101, 78, 97, 109, 101, 115, 10, 69, 120, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, + 101, 112, 116, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 47, 32, 39, + 69, 88, 67, 69, 80, 84, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 115, + 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, + 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 83, 105, 110, 103, 108, 101, 10, + 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 99, 108, 117, 100, 101, 78, 97, + 109, 101, 41, 41, 10, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 83, 105, 110, 103, + 108, 101, 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, 78, 97, 109, 101, 10, 69, 120, + 99, 108, 117, 100, 101, 78, 97, 109, 101, 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, + 68, 111, 116, 116, 101, 100, 78, 97, 109, 101, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, + 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 10, 69, 120, 99, 108, 117, 100, 101, 68, 111, + 116, 116, 101, 100, 78, 97, 109, 101, 32, 60, 45, 32, 68, 111, 116, 116, 101, 100, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 10, 69, 120, 99, 108, 117, 100, 101, 67, 111, 108, 117, + 109, 110, 78, 97, 109, 101, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, + 105, 110, 103, 10, 82, 101, 112, 108, 97, 99, 101, 76, 105, 115, 116, 32, 60, 45, 32, 39, + 82, 69, 80, 76, 65, 67, 69, 39, 32, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, + 105, 101, 115, 10, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 105, 101, 115, 32, 60, + 45, 32, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 83, 105, 110, 103, 108, 101, + 32, 47, 32, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 10, + 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 83, 105, 110, 103, 108, 101, 32, 60, + 45, 32, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 10, 82, 101, 112, 108, 97, + 99, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, + 115, 40, 76, 105, 115, 116, 40, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 41, + 41, 10, 82, 101, 112, 108, 97, 99, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 65, 83, 39, 32, 67, 111, 108, 117, 109, 110, + 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 82, 101, 110, 97, 109, 101, 76, 105, 115, 116, + 32, 60, 45, 32, 39, 82, 69, 78, 65, 77, 69, 39, 32, 82, 101, 110, 97, 109, 101, 69, + 110, 116, 114, 105, 101, 115, 10, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 105, 101, 115, + 32, 60, 45, 32, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 32, + 47, 32, 83, 105, 110, 103, 108, 101, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 10, + 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 76, 105, 115, 116, 32, 60, 45, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 82, 101, 110, 97, 109, 101, 69, 110, 116, + 114, 121, 41, 41, 10, 83, 105, 110, 103, 108, 101, 82, 101, 110, 97, 109, 101, 69, 110, 116, + 114, 121, 32, 60, 45, 32, 82, 101, 110, 97, 109, 101, 69, 110, 116, 114, 121, 10, 82, 101, + 110, 97, 109, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, + 78, 97, 109, 101, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 10, 83, 117, 98, 113, 117, 101, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 83, 117, 98, 113, 117, 101, 114, 121, 78, 111, 116, 63, 32, 83, 117, 98, 113, + 117, 101, 114, 121, 69, 120, 105, 115, 116, 115, 63, 32, 83, 117, 98, 113, 117, 101, 114, 121, + 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 83, 117, 98, 113, 117, 101, 114, 121, 78, 111, + 116, 32, 60, 45, 32, 39, 78, 79, 84, 39, 10, 83, 117, 98, 113, 117, 101, 114, 121, 69, + 120, 105, 115, 116, 115, 32, 60, 45, 32, 39, 69, 88, 73, 83, 84, 83, 39, 10, 67, 97, + 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 65, 83, + 69, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 67, 97, 115, 101, 87, + 104, 101, 110, 84, 104, 101, 110, 43, 32, 67, 97, 115, 101, 69, 108, 115, 101, 63, 32, 39, + 69, 78, 68, 39, 10, 67, 97, 115, 101, 87, 104, 101, 110, 84, 104, 101, 110, 32, 60, 45, + 32, 39, 87, 72, 69, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, + 84, 72, 69, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 97, 115, + 101, 69, 108, 115, 101, 32, 60, 45, 32, 39, 69, 76, 83, 69, 39, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 10, 84, 121, 112, 101, 76, 105, 116, 101, 114, 97, 108, 32, 60, + 45, 32, 84, 121, 112, 101, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 10, 73, 110, 116, 101, 114, 118, 97, 108, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, + 39, 73, 78, 84, 69, 82, 86, 65, 76, 39, 32, 73, 110, 116, 101, 114, 118, 97, 108, 80, + 97, 114, 97, 109, 101, 116, 101, 114, 32, 73, 110, 116, 101, 114, 118, 97, 108, 63, 10, 73, + 110, 116, 101, 114, 118, 97, 108, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, + 73, 110, 116, 101, 114, 118, 97, 108, 83, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, + 116, 101, 114, 32, 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, + 47, 32, 80, 97, 114, 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, + 110, 116, 101, 114, 118, 97, 108, 83, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, + 101, 114, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, + 70, 114, 97, 109, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 114, 97, 109, 105, + 110, 103, 32, 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 87, 105, 110, 100, 111, + 119, 69, 120, 99, 108, 117, 100, 101, 67, 108, 97, 117, 115, 101, 63, 10, 70, 114, 97, 109, + 105, 110, 103, 32, 60, 45, 32, 82, 111, 119, 115, 70, 114, 97, 109, 105, 110, 103, 32, 47, + 32, 82, 97, 110, 103, 101, 70, 114, 97, 109, 105, 110, 103, 32, 47, 32, 71, 114, 111, 117, + 112, 115, 70, 114, 97, 109, 105, 110, 103, 10, 82, 111, 119, 115, 70, 114, 97, 109, 105, 110, + 103, 32, 60, 45, 32, 39, 82, 79, 87, 83, 39, 10, 82, 97, 110, 103, 101, 70, 114, 97, + 109, 105, 110, 103, 32, 60, 45, 32, 39, 82, 65, 78, 71, 69, 39, 10, 71, 114, 111, 117, + 112, 115, 70, 114, 97, 109, 105, 110, 103, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 83, + 39, 10, 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 60, 45, 32, 66, 101, 116, + 119, 101, 101, 110, 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 47, 32, 83, 105, + 110, 103, 108, 101, 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 10, 83, 105, 110, 103, + 108, 101, 70, 114, 97, 109, 101, 69, 120, 116, 101, 110, 116, 32, 60, 45, 32, 70, 114, 97, + 109, 101, 66, 111, 117, 110, 100, 10, 66, 101, 116, 119, 101, 101, 110, 70, 114, 97, 109, 101, + 69, 120, 116, 101, 110, 116, 32, 60, 45, 32, 39, 66, 69, 84, 87, 69, 69, 78, 39, 32, + 70, 114, 97, 109, 101, 66, 111, 117, 110, 100, 32, 39, 65, 78, 68, 39, 32, 70, 114, 97, + 109, 101, 66, 111, 117, 110, 100, 10, 70, 114, 97, 109, 101, 66, 111, 117, 110, 100, 32, 60, + 45, 32, 70, 114, 97, 109, 101, 85, 110, 98, 111, 117, 110, 100, 101, 100, 32, 47, 32, 70, + 114, 97, 109, 101, 67, 117, 114, 114, 101, 110, 116, 82, 111, 119, 32, 47, 32, 70, 114, 97, + 109, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 114, 97, 109, 101, 85, 110, + 98, 111, 117, 110, 100, 101, 100, 32, 60, 45, 32, 39, 85, 78, 66, 79, 85, 78, 68, 69, + 68, 39, 32, 80, 114, 101, 99, 101, 100, 105, 110, 103, 79, 114, 70, 111, 108, 108, 111, 119, + 105, 110, 103, 10, 70, 114, 97, 109, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 80, 114, 101, 99, 101, 100, + 105, 110, 103, 79, 114, 70, 111, 108, 108, 111, 119, 105, 110, 103, 10, 70, 114, 97, 109, 101, + 67, 117, 114, 114, 101, 110, 116, 82, 111, 119, 32, 60, 45, 32, 39, 67, 85, 82, 82, 69, + 78, 84, 39, 32, 39, 82, 79, 87, 39, 10, 80, 114, 101, 99, 101, 100, 105, 110, 103, 79, + 114, 70, 111, 108, 108, 111, 119, 105, 110, 103, 32, 60, 45, 32, 80, 114, 101, 99, 101, 100, + 105, 110, 103, 70, 114, 97, 109, 101, 32, 47, 32, 70, 111, 108, 108, 111, 119, 105, 110, 103, + 70, 114, 97, 109, 101, 10, 80, 114, 101, 99, 101, 100, 105, 110, 103, 70, 114, 97, 109, 101, + 32, 60, 45, 32, 39, 80, 82, 69, 67, 69, 68, 73, 78, 71, 39, 10, 70, 111, 108, 108, + 111, 119, 105, 110, 103, 70, 114, 97, 109, 101, 32, 60, 45, 32, 39, 70, 79, 76, 76, 79, + 87, 73, 78, 71, 39, 10, 87, 105, 110, 100, 111, 119, 69, 120, 99, 108, 117, 100, 101, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 87, + 105, 110, 100, 111, 119, 69, 120, 99, 108, 117, 100, 101, 69, 108, 101, 109, 101, 110, 116, 10, + 87, 105, 110, 100, 111, 119, 69, 120, 99, 108, 117, 100, 101, 69, 108, 101, 109, 101, 110, 116, + 32, 60, 45, 32, 69, 120, 99, 108, 117, 100, 101, 67, 117, 114, 114, 101, 110, 116, 82, 111, + 119, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, 71, 114, 111, 117, 112, 32, 47, 32, 69, + 120, 99, 108, 117, 100, 101, 84, 105, 101, 115, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, + 78, 111, 79, 116, 104, 101, 114, 115, 10, 69, 120, 99, 108, 117, 100, 101, 67, 117, 114, 114, + 101, 110, 116, 82, 111, 119, 32, 60, 45, 32, 39, 67, 85, 82, 82, 69, 78, 84, 39, 32, + 39, 82, 79, 87, 39, 10, 69, 120, 99, 108, 117, 100, 101, 71, 114, 111, 117, 112, 32, 60, + 45, 32, 39, 71, 82, 79, 85, 80, 39, 10, 69, 120, 99, 108, 117, 100, 101, 84, 105, 101, + 115, 32, 60, 45, 32, 39, 84, 73, 69, 83, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, + 111, 79, 116, 104, 101, 114, 115, 32, 60, 45, 32, 39, 78, 79, 39, 32, 39, 79, 84, 72, + 69, 82, 83, 39, 10, 79, 118, 101, 114, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, + 79, 86, 69, 82, 39, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 10, 87, 105, + 110, 100, 111, 119, 70, 114, 97, 109, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 87, 105, 110, 100, 111, 119, 70, 114, + 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 47, 32, 73, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 10, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 32, + 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 97, 114, 101, 110, 115, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, + 40, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 41, 10, 87, 105, 110, 100, 111, 119, 70, + 114, 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 87, 105, + 110, 100, 111, 119, 70, 114, 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, + 115, 80, 97, 114, 101, 110, 115, 32, 47, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, + 101, 67, 111, 110, 116, 101, 110, 116, 115, 80, 97, 114, 101, 110, 115, 10, 87, 105, 110, 100, + 111, 119, 70, 114, 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 80, + 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 87, 105, 110, 100, + 111, 119, 70, 114, 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 41, + 10, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 78, 97, 109, 101, 67, 111, 110, 116, + 101, 110, 116, 115, 32, 60, 45, 32, 66, 97, 115, 101, 87, 105, 110, 100, 111, 119, 78, 97, + 109, 101, 63, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, + 110, 116, 115, 10, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, + 110, 116, 115, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, + 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, 41, + 10, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 67, 111, 110, 116, 101, 110, 116, 115, + 32, 60, 45, 32, 87, 105, 110, 100, 111, 119, 80, 97, 114, 116, 105, 116, 105, 111, 110, 63, + 32, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 70, 114, 97, 109, + 101, 67, 108, 97, 117, 115, 101, 63, 10, 66, 97, 115, 101, 87, 105, 110, 100, 111, 119, 78, + 97, 109, 101, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 87, 105, + 110, 100, 111, 119, 80, 97, 114, 116, 105, 116, 105, 111, 110, 32, 60, 45, 32, 39, 80, 65, + 82, 84, 73, 84, 73, 79, 78, 39, 32, 39, 66, 89, 39, 32, 76, 105, 115, 116, 40, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 76, 105, 115, 116, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 114, 114, 97, 121, 66, 111, 117, 110, 100, 101, + 100, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 65, 114, + 114, 97, 121, 80, 97, 114, 101, 110, 115, 83, 101, 108, 101, 99, 116, 10, 65, 114, 114, 97, + 121, 66, 111, 117, 110, 100, 101, 100, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 39, 65, 82, 82, 65, 89, 39, 63, 32, 66, 111, 117, 110, 100, + 101, 100, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 114, 114, + 97, 121, 80, 97, 114, 101, 110, 115, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 39, 65, + 82, 82, 65, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 66, 111, + 117, 110, 100, 101, 100, 76, 105, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 39, 91, 39, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 41, 63, 32, 39, 93, 39, 10, 83, 116, 114, 117, 99, 116, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 123, 39, 32, 76, 105, 115, 116, 40, 83, 116, + 114, 117, 99, 116, 70, 105, 101, 108, 100, 41, 63, 32, 39, 125, 39, 10, 83, 116, 114, 117, + 99, 116, 70, 105, 101, 108, 100, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, + 114, 105, 110, 103, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 77, 97, 112, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 77, 65, + 80, 39, 32, 77, 97, 112, 83, 116, 114, 117, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 77, 97, 112, 83, 116, 114, 117, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 39, 123, 39, 32, 76, 105, 115, 116, 40, 77, 97, 112, 83, 116, + 114, 117, 99, 116, 70, 105, 101, 108, 100, 41, 63, 32, 39, 125, 39, 10, 77, 97, 112, 83, + 116, 114, 117, 99, 116, 70, 105, 101, 108, 100, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 71, 114, 111, 117, 112, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, + 45, 32, 71, 114, 111, 117, 112, 105, 110, 103, 79, 114, 71, 114, 111, 117, 112, 105, 110, 103, + 73, 100, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 41, 63, 41, 10, 71, 114, 111, 117, 112, 105, 110, 103, 79, 114, 71, + 114, 111, 117, 112, 105, 110, 103, 73, 100, 32, 60, 45, 32, 71, 114, 111, 117, 112, 105, 110, + 103, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 73, + 100, 75, 101, 121, 119, 111, 114, 100, 10, 71, 114, 111, 117, 112, 105, 110, 103, 75, 101, 121, + 119, 111, 114, 100, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 10, 71, + 114, 111, 117, 112, 105, 110, 103, 73, 100, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, + 39, 71, 82, 79, 85, 80, 73, 78, 71, 95, 73, 68, 39, 10, 80, 97, 114, 97, 109, 101, + 116, 101, 114, 32, 60, 45, 32, 81, 117, 101, 115, 116, 105, 111, 110, 77, 97, 114, 107, 78, + 117, 109, 98, 101, 114, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, 65, + 110, 111, 110, 121, 109, 111, 117, 115, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, + 78, 117, 109, 98, 101, 114, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 32, + 67, 111, 108, 76, 97, 98, 101, 108, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 81, 117, + 101, 115, 116, 105, 111, 110, 77, 97, 114, 107, 78, 117, 109, 98, 101, 114, 101, 100, 80, 97, + 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 39, 63, 39, 32, 78, 117, 109, 98, 101, + 114, 76, 105, 116, 101, 114, 97, 108, 10, 65, 110, 111, 110, 121, 109, 111, 117, 115, 80, 97, + 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 39, 63, 39, 10, 78, 117, 109, 98, 101, + 114, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 39, 36, 39, 32, + 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 67, 111, 108, 76, 97, 98, + 101, 108, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 39, 36, 39, 32, 67, + 111, 108, 76, 97, 98, 101, 108, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 35, 39, 32, 78, 117, 109, 98, + 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, + 10, 76, 105, 115, 116, 67, 111, 109, 112, 114, 101, 104, 101, 110, 115, 105, 111, 110, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 91, 39, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 39, 70, 79, 82, 39, 32, 76, 105, 115, 116, 40, 67, 111, + 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 32, 39, 73, 78, 39, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 76, 105, 115, 116, 67, 111, 109, 112, 114, 101, 104, + 101, 110, 115, 105, 111, 110, 70, 105, 108, 116, 101, 114, 63, 32, 39, 93, 39, 10, 76, 105, + 115, 116, 67, 111, 109, 112, 114, 101, 104, 101, 110, 115, 105, 111, 110, 70, 105, 108, 116, 101, + 114, 32, 60, 45, 32, 39, 73, 70, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 10, 80, 97, 114, 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, + 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, + 83, 105, 110, 103, 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 10, + 32, 32, 32, 32, 80, 97, 114, 101, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 47, 10, 9, 76, 105, 116, 101, 114, 97, 108, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 47, 10, 9, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 47, 10, 32, 32, 32, + 32, 83, 117, 98, 113, 117, 101, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 10, 32, 32, 32, 32, 83, 112, 101, 99, 105, 97, 108, 70, 117, 110, 99, 116, 105, 111, + 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 80, 97, + 114, 101, 110, 116, 104, 101, 115, 105, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 10, 32, 32, 32, 32, 73, 110, 116, 101, 114, 118, 97, 108, 76, 105, 116, 101, 114, 97, + 108, 32, 47, 10, 32, 32, 32, 32, 84, 121, 112, 101, 76, 105, 116, 101, 114, 97, 108, 32, + 47, 10, 32, 32, 32, 32, 67, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 47, 10, 32, 32, 32, 32, 83, 116, 97, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 47, 10, 32, 32, 32, 32, 67, 97, 115, 116, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 47, 10, 32, 32, 32, 32, 71, 114, 111, 117, 112, 105, 110, 103, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 77, 97, 112, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 70, 117, 110, 99, 116, 105, + 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 67, + 111, 108, 117, 109, 110, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 47, 10, 32, 32, 32, + 32, 76, 105, 115, 116, 67, 111, 109, 112, 114, 101, 104, 101, 110, 115, 105, 111, 110, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 76, 105, 115, 116, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 83, 116, 114, 117, + 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 10, 32, 32, 32, 32, 80, + 111, 115, 105, 116, 105, 111, 110, 97, 108, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 10, 32, 32, 32, 32, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 32, 40, 76, 111, 119, 101, 115, + 116, 41, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 76, 97, 109, + 98, 100, 97, 65, 114, 114, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, + 111, 108, 117, 109, 110, 68, 101, 102, 97, 117, 108, 116, 69, 120, 112, 114, 32, 60, 45, 32, + 67, 111, 108, 68, 101, 102, 79, 114, 69, 120, 112, 114, 10, 35, 32, 76, 69, 86, 69, 76, + 32, 49, 46, 53, 10, 76, 97, 109, 98, 100, 97, 65, 114, 114, 111, 119, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 76, 111, 103, 105, 99, 97, 108, 79, 114, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 83, 105, 110, 103, 108, 101, 65, 114, 114, 111, + 119, 80, 97, 105, 114, 42, 10, 83, 105, 110, 103, 108, 101, 65, 114, 114, 111, 119, 80, 97, + 105, 114, 32, 60, 45, 32, 39, 45, 62, 39, 32, 76, 111, 103, 105, 99, 97, 108, 79, 114, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, 111, 103, 105, 99, 97, 108, 79, 114, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 76, 111, 103, 105, 99, 97, + 108, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 76, 111, 103, 105, 99, + 97, 108, 79, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, + 76, 111, 103, 105, 99, 97, 108, 79, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, + 97, 105, 108, 32, 60, 45, 32, 39, 79, 82, 39, 32, 76, 111, 103, 105, 99, 97, 108, 65, + 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 68, 101, 102, 79, + 114, 69, 120, 112, 114, 32, 60, 45, 32, 67, 111, 108, 68, 101, 102, 65, 110, 100, 69, 120, + 112, 114, 32, 67, 111, 108, 68, 101, 102, 79, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 84, 97, 105, 108, 42, 10, 67, 111, 108, 68, 101, 102, 79, 114, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 39, 79, 82, 39, 32, 67, 111, + 108, 68, 101, 102, 65, 110, 100, 69, 120, 112, 114, 10, 35, 32, 76, 69, 86, 69, 76, 32, + 50, 10, 76, 111, 103, 105, 99, 97, 108, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 76, 111, 103, 105, 99, 97, 108, 78, 111, 116, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 76, 111, 103, 105, 99, 97, 108, 65, 110, 100, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 76, 111, 103, 105, 99, 97, 108, + 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, + 32, 39, 65, 78, 68, 39, 32, 76, 111, 103, 105, 99, 97, 108, 78, 111, 116, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 68, 101, 102, 65, 110, 100, 69, 120, 112, + 114, 32, 60, 45, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 67, 111, 108, 68, 101, 102, 65, 110, 100, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 67, 111, 108, 68, 101, + 102, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, + 45, 32, 39, 65, 78, 68, 39, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, + 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 35, 32, 76, 69, 86, 69, 76, + 32, 51, 10, 76, 111, 103, 105, 99, 97, 108, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 60, 45, 32, 78, 111, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 63, 32, 73, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 111, 116, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 78, 111, 116, 75, 101, 121, 119, 111, + 114, 100, 43, 10, 78, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 78, + 79, 84, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 52, 10, 73, 115, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, + 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 115, 84, 101, 115, + 116, 42, 10, 73, 115, 84, 101, 115, 116, 32, 60, 45, 32, 73, 115, 76, 105, 116, 101, 114, + 97, 108, 32, 47, 32, 78, 111, 116, 78, 117, 108, 108, 32, 47, 32, 73, 115, 78, 117, 108, + 108, 10, 73, 115, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 73, 83, 39, 32, + 39, 78, 79, 84, 39, 63, 32, 73, 115, 76, 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, + 101, 10, 73, 115, 76, 105, 116, 101, 114, 97, 108, 86, 97, 108, 117, 101, 32, 60, 45, 32, + 84, 114, 117, 101, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 70, 97, 108, 115, 101, 76, + 105, 116, 101, 114, 97, 108, 32, 47, 32, 78, 117, 108, 108, 76, 105, 116, 101, 114, 97, 108, + 32, 47, 32, 85, 110, 107, 110, 111, 119, 110, 76, 105, 116, 101, 114, 97, 108, 10, 85, 110, + 107, 110, 111, 119, 110, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 85, 78, 75, + 78, 79, 87, 78, 39, 10, 78, 111, 116, 78, 117, 108, 108, 32, 60, 45, 32, 78, 111, 116, + 78, 117, 108, 108, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 78, 111, 116, 78, 117, 108, + 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 78, 111, 116, 78, 117, 108, 108, 75, 101, 121, + 119, 111, 114, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 32, 39, 78, 85, 76, 76, 39, + 10, 78, 111, 116, 78, 117, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, + 39, 78, 79, 84, 78, 85, 76, 76, 39, 10, 73, 115, 78, 117, 108, 108, 32, 60, 45, 32, + 73, 115, 78, 117, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 73, 115, 78, 117, 108, + 108, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 73, 83, 78, 85, 76, 76, + 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 53, 32, 40, 83, 112, 108, 105, 116, 32, 98, + 101, 99, 97, 117, 115, 101, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, + 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 97, 108, 108, 111, 119, 115, 32, 112, + 111, 115, 116, 32, 101, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 119, 104, 105, 108, 101, + 32, 73, 115, 79, 112, 101, 114, 97, 116, 111, 114, 32, 100, 111, 101, 115, 32, 110, 111, 116, + 41, 10, 73, 115, 68, 105, 115, 116, 105, 110, 99, 116, 70, 114, 111, 109, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 115, 68, 105, 115, 116, 105, 110, 99, + 116, 70, 114, 111, 109, 84, 97, 105, 108, 42, 10, 73, 115, 68, 105, 115, 116, 105, 110, 99, + 116, 70, 114, 111, 109, 84, 97, 105, 108, 32, 60, 45, 32, 73, 115, 68, 105, 115, 116, 105, + 110, 99, 116, 70, 114, 111, 109, 79, 112, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, 115, 68, 105, 115, 116, 105, 110, 99, + 116, 70, 114, 111, 109, 79, 112, 32, 60, 45, 32, 39, 73, 83, 39, 32, 39, 78, 79, 84, + 39, 63, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 39, 70, 82, 79, 77, 39, + 10, 35, 32, 76, 69, 86, 69, 76, 32, 54, 10, 67, 111, 109, 112, 97, 114, 105, 115, 111, + 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 66, 101, 116, 119, 101, + 101, 110, 73, 110, 76, 105, 107, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 67, + 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, + 97, 105, 108, 42, 10, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 67, 111, 109, 112, 97, 114, 105, + 115, 111, 110, 79, 112, 101, 114, 97, 116, 111, 114, 32, 78, 111, 116, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 63, 32, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 109, 112, 97, 114, 105, 115, 111, + 110, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, 79, 112, 101, + 114, 97, 116, 111, 114, 69, 113, 117, 97, 108, 32, 47, 10, 32, 32, 32, 32, 79, 112, 101, + 114, 97, 116, 111, 114, 78, 111, 116, 69, 113, 117, 97, 108, 32, 47, 10, 32, 32, 32, 32, + 79, 112, 101, 114, 97, 116, 111, 114, 76, 101, 115, 115, 84, 104, 97, 110, 32, 47, 10, 32, + 32, 32, 32, 79, 112, 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, 116, 101, 114, 84, 104, + 97, 110, 32, 47, 10, 32, 32, 32, 32, 79, 112, 101, 114, 97, 116, 111, 114, 76, 101, 115, + 115, 84, 104, 97, 110, 69, 113, 117, 97, 108, 115, 32, 47, 10, 32, 32, 32, 32, 79, 112, + 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, 116, 101, 114, 84, 104, 97, 110, 69, 113, 117, + 97, 108, 115, 10, 79, 112, 101, 114, 97, 116, 111, 114, 69, 113, 117, 97, 108, 32, 60, 45, + 32, 39, 61, 39, 32, 47, 32, 39, 61, 61, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, + 78, 111, 116, 69, 113, 117, 97, 108, 32, 60, 45, 32, 39, 33, 61, 39, 32, 47, 32, 39, + 60, 62, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 76, 101, 115, 115, 84, 104, 97, 110, + 32, 60, 45, 32, 39, 60, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, + 116, 101, 114, 84, 104, 97, 110, 32, 60, 45, 32, 39, 62, 39, 10, 79, 112, 101, 114, 97, + 116, 111, 114, 76, 101, 115, 115, 84, 104, 97, 110, 69, 113, 117, 97, 108, 115, 32, 60, 45, + 32, 39, 60, 61, 39, 10, 79, 112, 101, 114, 97, 116, 111, 114, 71, 114, 101, 97, 116, 101, + 114, 84, 104, 97, 110, 69, 113, 117, 97, 108, 115, 32, 60, 45, 32, 39, 62, 61, 39, 10, + 35, 32, 76, 69, 86, 69, 76, 32, 55, 10, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, + 105, 107, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 79, 116, 104, + 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 79, 112, 63, 10, 66, 101, + 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 79, 112, 32, 60, 45, 32, 39, 78, 79, + 84, 39, 63, 32, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, 105, 107, 101, 79, 112, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 66, 101, 116, 119, 101, 101, 110, 73, 110, 76, + 105, 107, 101, 79, 112, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 66, + 101, 116, 119, 101, 101, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 73, 110, 67, 108, 97, + 117, 115, 101, 32, 47, 32, 76, 105, 107, 101, 67, 108, 97, 117, 115, 101, 10, 76, 105, 107, + 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 76, 105, 107, 101, 86, 97, 114, 105, 97, + 116, 105, 111, 110, 115, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 69, 115, 99, 97, 112, 101, 67, 108, 97, 117, + 115, 101, 63, 10, 69, 115, 99, 97, 112, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 39, 69, 83, 67, 65, 80, 69, 39, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, 105, 107, 101, 86, 97, 114, 105, 97, 116, + 105, 111, 110, 115, 32, 60, 45, 32, 83, 105, 109, 105, 108, 97, 114, 84, 111, 84, 111, 107, + 101, 110, 32, 47, 32, 82, 101, 103, 101, 120, 73, 110, 115, 101, 110, 115, 105, 116, 105, 118, + 101, 77, 97, 116, 99, 104, 84, 111, 107, 101, 110, 32, 47, 32, 82, 101, 103, 101, 120, 77, + 97, 116, 99, 104, 84, 111, 107, 101, 110, 32, 47, 32, 73, 76, 105, 107, 101, 84, 111, 107, + 101, 110, 32, 47, 32, 76, 105, 107, 101, 84, 111, 107, 101, 110, 32, 47, 32, 71, 108, 111, + 98, 84, 111, 107, 101, 110, 32, 47, 32, 78, 111, 116, 73, 76, 105, 107, 101, 79, 112, 32, + 47, 32, 78, 111, 116, 76, 105, 107, 101, 79, 112, 32, 47, 32, 78, 111, 116, 82, 101, 103, + 101, 120, 73, 110, 115, 101, 110, 115, 105, 116, 105, 118, 101, 77, 97, 116, 99, 104, 79, 112, + 32, 47, 32, 78, 111, 116, 83, 105, 109, 105, 108, 97, 114, 84, 111, 79, 112, 10, 76, 105, + 107, 101, 84, 111, 107, 101, 110, 32, 32, 32, 32, 32, 32, 60, 45, 32, 39, 76, 73, 75, + 69, 39, 32, 47, 32, 39, 126, 126, 39, 10, 73, 76, 105, 107, 101, 84, 111, 107, 101, 110, + 32, 32, 32, 32, 32, 60, 45, 32, 39, 73, 76, 73, 75, 69, 39, 32, 47, 32, 39, 126, + 126, 42, 39, 10, 71, 108, 111, 98, 84, 111, 107, 101, 110, 32, 32, 32, 32, 32, 32, 60, + 45, 32, 39, 71, 76, 79, 66, 39, 32, 47, 32, 39, 126, 126, 126, 39, 10, 83, 105, 109, + 105, 108, 97, 114, 84, 111, 84, 111, 107, 101, 110, 32, 60, 45, 32, 39, 83, 73, 77, 73, + 76, 65, 82, 39, 32, 39, 84, 79, 39, 10, 82, 101, 103, 101, 120, 77, 97, 116, 99, 104, + 84, 111, 107, 101, 110, 32, 60, 45, 32, 39, 126, 39, 10, 82, 101, 103, 101, 120, 73, 110, + 115, 101, 110, 115, 105, 116, 105, 118, 101, 77, 97, 116, 99, 104, 84, 111, 107, 101, 110, 32, + 60, 45, 32, 39, 126, 42, 39, 10, 78, 111, 116, 73, 76, 105, 107, 101, 79, 112, 32, 32, + 32, 32, 32, 60, 45, 32, 39, 33, 126, 126, 42, 39, 10, 78, 111, 116, 76, 105, 107, 101, + 79, 112, 32, 32, 32, 32, 32, 32, 60, 45, 32, 39, 33, 126, 126, 39, 10, 78, 111, 116, + 82, 101, 103, 101, 120, 73, 110, 115, 101, 110, 115, 105, 116, 105, 118, 101, 77, 97, 116, 99, + 104, 79, 112, 32, 60, 45, 32, 39, 33, 126, 42, 39, 10, 78, 111, 116, 83, 105, 109, 105, + 108, 97, 114, 84, 111, 79, 112, 32, 60, 45, 32, 39, 33, 126, 39, 10, 73, 110, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, 39, 32, 73, 110, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 10, 73, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, + 45, 32, 73, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 47, + 32, 73, 110, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, + 32, 73, 110, 67, 111, 110, 116, 97, 105, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 73, 110, 67, 111, 110, 116, 97, 105, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 73, 110, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, + 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 73, 110, 83, 101, 108, + 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, - 116, 101, 114, 110, 97, 108, 41, 10, 67, 84, 69, 68, 77, 76, 66, 111, 100, 121, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 116, 97, 116, 101, 109, 101, 110, 116, 41, 10, - 85, 115, 105, 110, 103, 75, 101, 121, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, - 39, 75, 69, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, - 105, 115, 116, 41, 10, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, 32, 60, 45, - 32, 39, 78, 79, 84, 39, 63, 32, 39, 77, 65, 84, 69, 82, 73, 65, 76, 73, 90, 69, - 68, 39, 10, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, - 84, 72, 39, 32, 82, 101, 99, 117, 114, 115, 105, 118, 101, 63, 32, 76, 105, 115, 116, 40, - 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, 110, 116, 41, 10, 82, 101, 99, 117, 114, - 115, 105, 118, 101, 32, 60, 45, 32, 39, 82, 69, 67, 85, 82, 83, 73, 86, 69, 39, 10, - 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 76, - 69, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 63, - 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 63, 10, 84, 97, 114, 103, 101, 116, 76, - 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 65, 108, 105, 97, 115, 101, 100, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 67, 111, 108, 117, 109, 110, 65, 108, 105, - 97, 115, 101, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 68, 105, 115, 116, - 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, - 99, 116, 79, 110, 32, 47, 32, 68, 105, 115, 116, 105, 110, 99, 116, 65, 108, 108, 10, 68, - 105, 115, 116, 105, 110, 99, 116, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, - 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, 60, 45, 32, 39, 68, 73, 83, 84, 73, - 78, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, - 116, 115, 63, 10, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, - 115, 32, 60, 45, 32, 39, 79, 78, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, - 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 73, 110, 110, 101, 114, - 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 86, 97, 108, 117, 101, 115, 82, 101, - 102, 32, 47, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, - 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 66, 97, 115, 101, - 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, 80, 97, 114, 101, 110, 115, 84, 97, 98, - 108, 101, 82, 101, 102, 10, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 73, 110, - 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, 32, 74, 111, 105, 110, 79, 114, 80, 105, - 118, 111, 116, 42, 10, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, - 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 76, - 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, - 114, 101, 110, 99, 101, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 66, 97, - 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, - 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, - 78, 97, 109, 101, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 32, 65, 116, 67, - 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, - 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 39, 58, 39, 10, 86, 97, - 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 67, 111, 108, 111, 110, 63, 32, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, - 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 80, 97, 114, 101, 110, 115, 84, - 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 67, 111, 108, 111, 110, 63, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, - 82, 101, 102, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 32, 83, 97, 109, - 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 74, 111, 105, 110, 79, 114, 80, 105, 118, - 111, 116, 32, 60, 45, 32, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, - 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, - 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, - 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 80, 73, - 86, 79, 84, 39, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 80, 105, 118, + 116, 101, 114, 110, 97, 108, 41, 10, 66, 101, 116, 119, 101, 101, 110, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 66, 69, 84, 87, 69, 69, 78, 39, 32, 79, 116, 104, 101, 114, + 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, + 65, 78, 68, 39, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 10, 35, 32, 76, 69, 86, 69, 76, 32, 56, 10, 79, + 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, + 108, 42, 10, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, 108, + 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 66, 105, + 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 116, 104, 101, + 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, 65, 110, 121, + 65, 108, 108, 80, 97, 114, 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, + 78, 97, 109, 101, 100, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 10, 65, + 110, 121, 65, 108, 108, 80, 97, 114, 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, + 60, 45, 32, 65, 110, 121, 65, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 78, 97, + 109, 101, 100, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, + 32, 32, 32, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 47, 32, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, + 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, + 114, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 10, 65, 110, 121, 65, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, + 32, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, + 65, 110, 121, 79, 114, 65, 108, 108, 10, 65, 110, 121, 79, 114, 65, 108, 108, 32, 60, 45, + 32, 83, 117, 98, 113, 117, 101, 114, 121, 65, 110, 121, 32, 47, 32, 83, 117, 98, 113, 117, + 101, 114, 121, 65, 108, 108, 10, 83, 117, 98, 113, 117, 101, 114, 121, 65, 110, 121, 32, 60, + 45, 32, 39, 65, 78, 89, 39, 10, 83, 117, 98, 113, 117, 101, 114, 121, 65, 108, 108, 32, + 60, 45, 32, 39, 65, 76, 76, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, + 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 79, 80, 69, 82, 65, 84, 79, 82, 39, + 32, 80, 97, 114, 101, 110, 115, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, + 114, 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 81, 117, 97, 108, 105, + 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, + 32, 60, 45, 32, 67, 111, 108, 73, 100, 68, 111, 116, 42, 32, 65, 110, 121, 79, 112, 101, + 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, 35, 32, 76, 69, 86, 69, 76, + 32, 57, 10, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 84, 97, 105, 108, 42, 10, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 66, 105, 116, 79, 112, 101, 114, 97, 116, + 111, 114, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 38, 39, + 32, 47, 32, 39, 124, 39, 32, 47, 32, 39, 60, 60, 39, 32, 47, 32, 39, 62, 62, 39, + 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 48, 10, 65, 100, 100, 105, 116, 105, 118, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 77, 117, 108, 116, 105, 112, + 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, + 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, + 108, 42, 10, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 84, 97, 105, 108, 32, 60, 45, 32, 84, 101, 114, 109, 32, 77, 117, 108, 116, 105, 112, + 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, + 101, 114, 109, 32, 60, 45, 32, 39, 43, 39, 32, 47, 32, 39, 45, 39, 10, 35, 32, 76, + 69, 86, 69, 76, 32, 49, 49, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, + 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 111, + 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, + 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, + 60, 45, 32, 70, 97, 99, 116, 111, 114, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, + 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 97, 99, 116, 111, + 114, 32, 60, 45, 32, 39, 42, 39, 32, 47, 32, 39, 47, 39, 32, 47, 32, 39, 47, 47, + 39, 32, 47, 32, 39, 37, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 50, 10, 69, + 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 69, 120, 112, 111, 110, + 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, + 97, 105, 108, 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, + 116, 111, 114, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 69, 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, + 45, 32, 39, 94, 39, 32, 47, 32, 39, 42, 42, 39, 10, 35, 32, 76, 69, 86, 69, 76, + 32, 49, 51, 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 84, 97, 105, 108, 42, 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, + 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 108, 97, 116, 101, 79, 112, + 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, 39, 10, + 35, 32, 76, 69, 86, 69, 76, 32, 49, 52, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, + 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, + 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, 116, 84, 105, 109, 101, 90, 111, + 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 116, + 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, + 105, 108, 32, 60, 45, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, + 97, 116, 111, 114, 32, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, + 32, 60, 45, 32, 39, 65, 84, 39, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, + 69, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 53, 10, 80, 114, 101, 102, 105, 120, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, + 79, 112, 101, 114, 97, 116, 111, 114, 42, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 10, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, + 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, + 32, 47, 32, 77, 105, 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, + 111, 114, 32, 47, 32, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, + 116, 111, 114, 32, 47, 32, 84, 105, 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, + 114, 97, 116, 111, 114, 10, 77, 105, 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, + 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 45, 39, 10, 80, 108, 117, 115, 80, 114, 101, + 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 43, 39, 10, 84, + 105, 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, + 45, 32, 39, 126, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 54, 32, 40, 72, 105, + 103, 104, 101, 115, 116, 41, 10, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 83, 105, 110, 103, 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 73, + 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, + 100, 105, 114, 101, 99, 116, 105, 111, 110, 43, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, + 111, 110, 32, 60, 45, 32, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, + 32, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 83, 108, 105, 99, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 116, 102, 105, 120, + 79, 112, 101, 114, 97, 116, 111, 114, 10, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 60, 45, 32, 39, 58, 58, 39, 32, 84, 121, 112, 101, 10, 68, 111, 116, 79, 112, + 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, + 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, + 112, 101, 114, 97, 116, 111, 114, 10, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, + 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 46, 39, 32, 77, 101, 116, 104, 111, 100, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, + 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 46, 39, 32, 67, 111, 108, 76, 97, + 98, 101, 108, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 67, 111, 108, 76, 97, 98, 101, 108, 32, 77, 101, 116, 104, 111, 100, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 10, 77, + 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, + 101, 110, 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 77, 101, 116, 104, 111, + 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, + 105, 115, 116, 41, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 68, 105, 115, + 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 32, 77, 101, 116, 104, 111, 100, 70, 117, + 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 63, 32, 79, 114, 100, + 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 73, 103, 110, 111, 114, 101, 79, 114, + 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 63, 10, 77, 101, 116, 104, 111, 100, + 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, + 32, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, + 110, 116, 41, 10, 83, 108, 105, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 39, 91, 39, 32, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 39, 93, + 39, 10, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 63, 32, 69, 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, + 100, 63, 32, 83, 116, 101, 112, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 10, 69, + 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, + 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, 108, 117, 101, 63, 10, 69, 110, 100, 83, 108, + 105, 99, 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 47, 32, 69, 110, 100, 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 10, 69, + 110, 100, 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 32, 60, 45, 32, 39, 45, 39, 10, + 83, 116, 101, 112, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, + 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 80, 111, 115, 116, 102, 105, + 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 33, 39, 10, 83, 112, 101, + 99, 105, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 47, 32, 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 47, 32, 84, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 32, 67, 111, 108, 117, 109, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 32, 69, 120, 116, 114, 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 32, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, + 32, 78, 117, 108, 108, 73, 102, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, + 80, 111, 115, 105, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, + 32, 82, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 83, 117, 98, + 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, + 114, 105, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 79, 118, 101, 114, + 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 97, 108, 101, 115, + 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 65, + 76, 69, 83, 67, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 85, 110, 112, 97, 99, 107, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 85, 78, 80, 65, 67, 75, 39, + 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, + 84, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, + 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 41, 10, 67, 111, 108, 117, 109, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 63, 32, 39, 67, 79, 76, 85, + 77, 78, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 39, 69, 88, 84, 82, 65, 67, 84, 39, 32, 80, 97, 114, 101, 110, + 115, 40, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, + 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, + 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 39, 70, 82, 79, + 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, 97, 109, 98, 100, 97, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 76, 65, 77, 66, 68, + 65, 39, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, + 103, 41, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 117, + 108, 108, 73, 102, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 78, + 85, 76, 76, 73, 70, 39, 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 108, 108, 73, 102, + 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 78, 117, 108, 108, 73, 102, 65, 114, 103, + 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 39, 44, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 111, 115, 105, + 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 80, + 79, 83, 73, 84, 73, 79, 78, 39, 32, 80, 97, 114, 101, 110, 115, 40, 80, 111, 115, 105, + 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 80, 111, 115, 105, 116, + 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 116, 104, 101, + 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 39, 73, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 82, 111, 119, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 41, 63, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 60, 45, 32, 39, 83, 85, 66, 83, 84, 82, 73, 78, 71, 39, 32, + 80, 97, 114, 101, 110, 115, 40, 83, 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, + 109, 101, 110, 116, 115, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, + 109, 101, 110, 116, 115, 32, 60, 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, + 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 83, 117, 98, 115, 116, + 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, + 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 83, + 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, + 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 83, 117, 98, 115, 116, 114, 105, + 110, 103, 70, 114, 111, 109, 70, 111, 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, + 114, 111, 109, 70, 111, 114, 32, 60, 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, + 114, 111, 109, 79, 112, 116, 105, 111, 110, 97, 108, 70, 111, 114, 32, 47, 32, 83, 117, 98, + 115, 116, 114, 105, 110, 103, 70, 111, 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, + 114, 111, 109, 79, 112, 116, 105, 111, 110, 97, 108, 70, 111, 114, 32, 60, 45, 32, 70, 114, + 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 63, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, 114, + 32, 60, 45, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 114, + 105, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 73, + 77, 39, 32, 80, 97, 114, 101, 110, 115, 40, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, + 110, 116, 115, 41, 10, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, + 45, 32, 84, 114, 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 63, 32, 84, 114, 105, + 109, 83, 111, 117, 114, 99, 101, 63, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 41, 10, 84, 114, 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 32, + 60, 45, 32, 84, 114, 105, 109, 66, 111, 116, 104, 32, 47, 32, 84, 114, 105, 109, 76, 101, + 97, 100, 105, 110, 103, 32, 47, 32, 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, + 10, 84, 114, 105, 109, 66, 111, 116, 104, 32, 60, 45, 32, 39, 66, 79, 84, 72, 39, 10, + 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, 32, 60, 45, 32, 39, 76, 69, 65, 68, + 73, 78, 71, 39, 10, 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, 32, 60, 45, + 32, 39, 84, 82, 65, 73, 76, 73, 78, 71, 39, 10, 84, 114, 105, 109, 83, 111, 117, 114, + 99, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 70, + 82, 79, 77, 39, 10, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 39, 79, 86, 69, 82, 76, 65, 89, 39, 32, 80, 97, 114, 101, + 110, 115, 40, 79, 118, 101, 114, 108, 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, + 10, 79, 118, 101, 114, 108, 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, + 32, 79, 118, 101, 114, 108, 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, + 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, + 115, 116, 10, 79, 118, 101, 114, 108, 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, + 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 80, 76, 65, 67, + 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 114, 111, 109, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 63, 10, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, + 70, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 118, 101, 114, + 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, + 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, + 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, + 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, + 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 83, 116, + 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 10, 69, 120, 116, 114, 97, 99, 116, + 68, 97, 116, 101, 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, + 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 10, 69, 120, 116, 114, + 97, 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, + 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 69, 120, 116, 114, + 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, + 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 114, 97, + 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 32, 60, 45, 10, 32, 32, 32, 32, 89, 101, + 97, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 111, 110, 116, 104, 75, 101, 121, + 119, 111, 114, 100, 32, 47, 32, 68, 97, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, + 72, 111, 117, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 110, 117, 116, 101, + 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 83, 101, 99, 111, 110, 100, 75, 101, 121, 119, + 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 77, 105, 108, 108, 105, 115, 101, 99, 111, 110, + 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 99, 114, 111, 115, 101, 99, 111, + 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 87, 101, 101, 107, 75, 101, 121, 119, + 111, 114, 100, 32, 47, 32, 81, 117, 97, 114, 116, 101, 114, 75, 101, 121, 119, 111, 114, 100, + 32, 47, 32, 68, 101, 99, 97, 100, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, + 32, 32, 32, 67, 101, 110, 116, 117, 114, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, + 77, 105, 108, 108, 101, 110, 110, 105, 117, 109, 75, 101, 121, 119, 111, 114, 100, 10, 35, 32, + 69, 118, 101, 114, 121, 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 97, 98, 111, 117, + 116, 32, 101, 120, 116, 101, 114, 110, 97, 108, 32, 114, 101, 115, 111, 117, 114, 99, 101, 115, + 44, 32, 115, 111, 32, 116, 104, 101, 32, 116, 111, 112, 45, 108, 101, 118, 101, 108, 32, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 104, 111, 105, 99, 101, 32, 99, 97, 114, 114, + 105, 101, 115, 32, 111, 110, 101, 32, 101, 110, 116, 114, 121, 10, 35, 32, 114, 97, 116, 104, + 101, 114, 32, 116, 104, 97, 110, 32, 111, 110, 101, 32, 112, 101, 114, 32, 102, 111, 114, 109, + 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, + 82, 101, 103, 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 68, 101, 115, 116, 114, 111, 121, 69, 120, + 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, + 32, 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 115, 83, 116, 109, 116, 32, 47, 32, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 32, 47, 32, 67, 111, 110, 110, + 101, 99, 116, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, + 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, + 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, + 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, + 111, 110, 115, 63, 10, 82, 101, 103, 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, + 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 82, 69, + 71, 73, 83, 84, 69, 82, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, + 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 39, + 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 101, 115, + 116, 114, 111, 121, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, + 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 69, 83, 84, 82, 79, 89, 39, 32, 69, 120, + 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, + 100, 32, 67, 111, 108, 73, 100, 10, 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 115, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 72, + 79, 87, 39, 32, 83, 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 63, + 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, + 69, 83, 39, 10, 83, 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 32, + 60, 45, 32, 39, 65, 76, 76, 39, 10, 35, 32, 83, 121, 110, 116, 97, 120, 32, 111, 110, + 108, 121, 58, 32, 116, 104, 101, 32, 107, 101, 121, 119, 111, 114, 100, 32, 112, 97, 105, 114, + 32, 101, 118, 101, 114, 121, 32, 115, 105, 110, 103, 117, 108, 97, 114, 32, 102, 111, 114, 109, + 32, 114, 101, 112, 101, 97, 116, 115, 46, 32, 84, 104, 101, 32, 112, 108, 117, 114, 97, 108, + 32, 105, 110, 32, 83, 72, 79, 87, 32, 99, 97, 110, 110, 111, 116, 32, 115, 104, 97, 114, + 101, 32, 105, 116, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, + 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 69, 88, 84, 69, 82, 78, + 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 39, 10, 35, 32, 84, 104, 101, + 32, 114, 101, 99, 105, 112, 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, + 97, 109, 115, 46, 32, 73, 116, 115, 32, 111, 119, 110, 32, 114, 117, 108, 101, 32, 114, 97, + 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, + 111, 110, 115, 58, 32, 116, 104, 101, 32, 116, 119, 111, 32, 111, 112, 116, 105, 111, 110, 32, + 98, 97, 103, 115, 32, 97, 114, 101, 10, 35, 32, 100, 105, 115, 116, 105, 110, 99, 116, 44, + 32, 97, 110, 100, 32, 97, 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 97, 110, + 32, 99, 97, 114, 114, 121, 32, 98, 111, 116, 104, 46, 10, 69, 120, 116, 101, 114, 110, 97, + 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, + 105, 111, 110, 115, 32, 60, 45, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, + 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 35, 32, 84, 104, 101, 32, 97, 116, 116, 97, + 99, 104, 32, 97, 108, 105, 97, 115, 32, 105, 115, 32, 109, 97, 110, 100, 97, 116, 111, 114, + 121, 58, 32, 105, 116, 32, 115, 101, 112, 97, 114, 97, 116, 101, 115, 32, 116, 104, 101, 32, + 114, 101, 99, 105, 112, 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, + 109, 115, 44, 32, 119, 104, 105, 99, 104, 32, 112, 114, 101, 99, 101, 100, 101, 32, 105, 116, + 44, 32, 102, 114, 111, 109, 32, 116, 104, 101, 10, 35, 32, 97, 116, 116, 97, 99, 104, 109, + 101, 110, 116, 39, 115, 32, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 115, 44, 32, 119, + 104, 105, 99, 104, 32, 102, 111, 108, 108, 111, 119, 46, 32, 87, 105, 116, 104, 111, 117, 116, + 32, 105, 116, 32, 97, 32, 115, 105, 110, 103, 108, 101, 32, 111, 112, 116, 105, 111, 110, 32, + 108, 105, 115, 116, 32, 119, 111, 117, 108, 100, 32, 98, 101, 32, 97, 109, 98, 105, 103, 117, + 111, 117, 115, 46, 10, 35, 32, 67, 79, 78, 78, 69, 67, 84, 32, 104, 97, 115, 32, 110, + 111, 32, 115, 117, 99, 104, 32, 115, 101, 112, 97, 114, 97, 116, 111, 114, 46, 32, 66, 111, + 114, 114, 111, 119, 105, 110, 103, 32, 97, 32, 114, 101, 103, 105, 115, 116, 101, 114, 101, 100, + 32, 114, 101, 115, 111, 117, 114, 99, 101, 32, 104, 97, 115, 32, 110, 111, 32, 99, 114, 101, + 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 32, 116, 111, 32, 98, 101, 32, 99, 111, 110, + 102, 117, 115, 101, 100, 10, 35, 32, 119, 105, 116, 104, 44, 32, 115, 111, 32, 97, 32, 108, + 105, 115, 116, 32, 116, 104, 101, 114, 101, 32, 105, 115, 32, 116, 104, 101, 32, 99, 111, 110, + 110, 101, 99, 116, 105, 111, 110, 39, 115, 59, 32, 112, 114, 111, 118, 105, 115, 105, 111, 110, + 105, 110, 103, 32, 100, 111, 101, 115, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 116, 114, + 97, 110, 115, 102, 111, 114, 109, 101, 114, 32, 114, 101, 106, 101, 99, 116, 115, 32, 116, 104, + 101, 32, 115, 101, 99, 111, 110, 100, 10, 35, 32, 108, 105, 115, 116, 32, 114, 97, 116, 104, + 101, 114, 32, 116, 104, 97, 110, 32, 108, 101, 116, 32, 112, 111, 115, 105, 116, 105, 111, 110, + 32, 100, 101, 99, 105, 100, 101, 46, 10, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 65, 84, + 84, 65, 67, 72, 39, 32, 39, 84, 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, + 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, + 65, 108, 105, 97, 115, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, + 10, 67, 111, 110, 110, 101, 99, 116, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, + 115, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 67, 79, 78, 78, 69, 67, 84, 39, 32, + 39, 84, 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 83, 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, + 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, + 111, 117, 114, 99, 101, 32, 60, 45, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, + 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 47, 32, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, + 114, 101, 110, 99, 101, 67, 108, 97, 117, 115, 101, 10, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, + 32, 60, 45, 32, 39, 78, 69, 87, 39, 32, 39, 84, 69, 77, 80, 79, 82, 65, 82, 89, + 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, + 121, 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, + 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, + 108, 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, 73, 110, + 115, 101, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, + 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 73, 78, 83, 69, 82, 84, 39, 32, 79, 114, + 65, 99, 116, 105, 111, 110, 63, 32, 39, 73, 78, 84, 79, 39, 32, 73, 110, 115, 101, 114, + 116, 84, 97, 114, 103, 101, 116, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, + 116, 105, 111, 110, 63, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, + 115, 116, 63, 32, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 79, 110, 67, + 111, 110, 102, 108, 105, 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, + 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 79, 114, 65, 99, 116, 105, 111, 110, + 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, + 47, 32, 73, 110, 115, 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, 10, 73, 110, 115, + 101, 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, 60, 45, 32, 39, 79, 82, 39, + 32, 39, 82, 69, 80, 76, 65, 67, 69, 39, 10, 73, 110, 115, 101, 114, 116, 79, 114, 73, + 103, 110, 111, 114, 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 73, 71, 78, 79, 82, + 69, 39, 10, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, + 60, 45, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, + 32, 47, 32, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, + 114, 100, 101, 114, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, + 101, 114, 32, 60, 45, 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, + 97, 109, 101, 10, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, + 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, + 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, + 97, 109, 101, 32, 60, 45, 32, 39, 78, 65, 77, 69, 39, 10, 73, 110, 115, 101, 114, 116, + 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, + 73, 79, 78, 39, 10, 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, + 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, + 116, 65, 108, 105, 97, 115, 63, 10, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 32, + 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, + 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, + 108, 73, 100, 41, 10, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, + 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, + 115, 116, 41, 10, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, + 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 47, + 32, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 10, 83, 101, 108, 101, 99, + 116, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, + 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, + 10, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, + 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 110, 67, + 111, 110, 102, 108, 105, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, + 39, 32, 39, 67, 79, 78, 70, 76, 73, 67, 84, 39, 32, 79, 110, 67, 111, 110, 102, 108, + 105, 99, 116, 84, 97, 114, 103, 101, 116, 63, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, + 116, 65, 99, 116, 105, 111, 110, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, + 114, 103, 101, 116, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 47, 32, 79, 110, 67, + 111, 110, 102, 108, 105, 99, 116, 73, 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 10, 79, + 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, + 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, + 116, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, + 102, 108, 105, 99, 116, 73, 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, + 39, 79, 78, 39, 32, 39, 67, 79, 78, 83, 84, 82, 65, 73, 78, 84, 39, 32, 67, 111, + 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, 10, 79, 110, 67, 111, 110, 102, 108, + 105, 99, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, + 105, 99, 116, 85, 112, 100, 97, 116, 101, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, + 99, 116, 78, 111, 116, 104, 105, 110, 103, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, + 85, 112, 100, 97, 116, 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 85, 80, 68, 65, + 84, 69, 39, 32, 39, 83, 69, 84, 39, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, + 108, 97, 117, 115, 101, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, + 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, 116, 104, 105, 110, 103, 32, 60, 45, 32, + 39, 68, 79, 39, 32, 39, 78, 79, 84, 72, 73, 78, 71, 39, 10, 82, 101, 116, 117, 114, + 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 82, 69, 84, 85, 82, + 78, 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 76, 111, 97, + 100, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 76, 79, 65, 68, 39, + 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 70, 114, 111, 109, 83, + 111, 117, 114, 99, 101, 63, 32, 69, 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, + 115, 63, 10, 69, 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 32, 60, 45, + 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 73, 110, 115, + 116, 97, 108, 108, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, + 82, 67, 69, 39, 63, 32, 39, 73, 78, 83, 84, 65, 76, 76, 39, 32, 73, 110, 115, 116, + 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 70, 114, + 111, 109, 83, 111, 117, 114, 99, 101, 63, 32, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, + 98, 101, 114, 63, 10, 73, 110, 115, 116, 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 32, + 60, 45, 32, 39, 65, 78, 68, 39, 32, 39, 76, 79, 65, 68, 39, 10, 85, 112, 100, 97, + 116, 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 115, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 69, 88, 84, 69, 78, + 83, 73, 79, 78, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 41, 41, 63, 10, 70, 114, 111, 109, 83, 111, 117, + 114, 99, 101, 32, 60, 45, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, + 83, 116, 114, 105, 110, 103, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, + 116, 114, 105, 110, 103, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, + 98, 101, 114, 32, 60, 45, 32, 39, 86, 69, 82, 83, 73, 79, 78, 39, 32, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, + 97, 108, 10, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, + 114, 121, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, + 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, + 83, 116, 109, 116, 32, 47, 32, 68, 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, + 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 10, 67, 114, 101, 97, 116, + 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, + 83, 116, 109, 116, 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, + 101, 112, 108, 97, 99, 101, 63, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, + 39, 82, 69, 80, 79, 83, 73, 84, 79, 82, 89, 39, 32, 73, 102, 78, 111, 116, 69, 120, + 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, + 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 114, 101, 102, 105, 120, 32, 82, 101, 112, + 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, 105, 99, 75, 101, 121, 63, 10, 82, 101, + 112, 111, 115, 105, 116, 111, 114, 121, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 87, + 73, 84, 72, 39, 63, 32, 39, 80, 82, 69, 70, 73, 88, 39, 32, 83, 116, 114, 105, 110, + 103, 76, 105, 116, 101, 114, 97, 108, 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, + 117, 98, 108, 105, 99, 75, 101, 121, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 63, + 32, 39, 80, 85, 66, 76, 73, 67, 39, 32, 40, 39, 75, 69, 89, 83, 39, 32, 47, 32, + 39, 75, 69, 89, 39, 41, 32, 76, 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, + 116, 101, 114, 97, 108, 41, 10, 68, 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, + 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, + 82, 79, 80, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, + 80, 79, 83, 73, 84, 79, 82, 89, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, + 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 77, 101, 114, 103, 101, 73, + 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, + 67, 108, 97, 117, 115, 101, 63, 32, 39, 77, 69, 82, 71, 69, 39, 32, 39, 73, 78, 84, + 79, 39, 32, 84, 97, 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 77, 101, + 114, 103, 101, 73, 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 74, + 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, 77, 101, 114, 103, 101, 77, 97, + 116, 99, 104, 43, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, + 63, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 84, 97, 98, 108, 101, 82, + 101, 102, 10, 77, 101, 114, 103, 101, 77, 97, 116, 99, 104, 32, 60, 45, 32, 77, 97, 116, + 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 47, 32, 78, 111, 116, 77, 97, 116, 99, + 104, 101, 100, 67, 108, 97, 117, 115, 101, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, + 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 78, 39, 32, 39, 77, 65, 84, 67, 72, + 69, 68, 39, 32, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, + 84, 72, 69, 78, 39, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, + 99, 116, 105, 111, 110, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, + 99, 116, 105, 111, 110, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, + 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, + 67, 108, 97, 117, 115, 101, 32, 47, 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, + 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, + 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 69, 114, 114, 111, 114, 77, 97, 116, + 99, 104, 67, 108, 97, 117, 115, 101, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, + 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, 10, 85, 112, 100, 97, + 116, 101, 77, 97, 116, 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, + 101, 77, 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 47, 32, 85, 112, + 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, + 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, + 110, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, + 108, 97, 117, 115, 101, 10, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, 114, + 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, + 80, 111, 115, 105, 116, 105, 111, 110, 10, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 73, + 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 39, 73, 78, 83, 69, 82, 84, 39, 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, + 73, 110, 102, 111, 63, 10, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, + 111, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, + 116, 32, 47, 32, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, + 117, 101, 115, 32, 47, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, + 80, 111, 115, 105, 116, 105, 111, 110, 10, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, + 108, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, + 39, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, + 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, + 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 63, 32, 39, 42, 39, 63, 10, + 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 60, 45, 32, + 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 39, 86, + 65, 76, 85, 69, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 68, 111, 78, 111, 116, 104, 105, 110, + 103, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 79, 39, + 32, 39, 78, 79, 84, 72, 73, 78, 71, 39, 10, 69, 114, 114, 111, 114, 77, 97, 116, 99, + 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 69, 82, 82, 79, 82, 39, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, + 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 84, 39, + 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 10, + 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 32, 60, + 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, + 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 10, 65, 110, 100, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 60, 45, 32, 39, 65, 78, 68, 39, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 10, 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 87, 72, 69, 78, 39, 32, 39, 78, 79, 84, 39, 32, 39, 77, + 65, 84, 67, 72, 69, 68, 39, 32, 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, + 114, 103, 101, 116, 63, 32, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, + 32, 39, 84, 72, 69, 78, 39, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, + 101, 65, 99, 116, 105, 111, 110, 10, 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, + 114, 103, 101, 116, 32, 60, 45, 32, 66, 121, 83, 111, 117, 114, 99, 101, 32, 47, 32, 66, + 121, 84, 97, 114, 103, 101, 116, 10, 66, 121, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, + 39, 66, 89, 39, 32, 39, 83, 79, 85, 82, 67, 69, 39, 10, 66, 121, 84, 97, 114, 103, + 101, 116, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 84, 65, 82, 71, 69, 84, 39, 10, + 80, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 105, + 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 80, 105, 118, 111, 116, 79, 110, 63, 32, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 63, + 32, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, + 105, 118, 111, 116, 79, 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 80, 105, 118, 111, 116, + 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 85, 115, 105, 110, + 103, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, + 105, 115, 116, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, + 60, 45, 32, 76, 105, 115, 116, 40, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, + 110, 116, 114, 121, 41, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, + 114, 121, 32, 60, 45, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, + 113, 117, 101, 114, 121, 32, 47, 32, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, + 115, 116, 32, 47, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, + 114, 121, 32, 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 39, 73, 78, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 80, 105, + 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, + 39, 32, 47, 32, 39, 80, 73, 86, 79, 84, 95, 87, 73, 68, 69, 82, 39, 10, 85, 110, + 112, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 85, 78, 80, + 73, 86, 79, 84, 39, 32, 47, 32, 39, 80, 73, 86, 79, 84, 95, 76, 79, 78, 71, 69, + 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, + 98, 108, 101, 82, 101, 102, 32, 39, 79, 78, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, + 115, 116, 32, 73, 110, 116, 111, 78, 97, 109, 101, 86, 97, 108, 117, 101, 115, 63, 10, 73, + 110, 116, 111, 78, 97, 109, 101, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 73, 78, + 84, 79, 39, 32, 39, 78, 65, 77, 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, + 114, 105, 110, 103, 32, 86, 97, 108, 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 79, + 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, + 116, 10, 86, 97, 108, 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, + 86, 65, 76, 85, 69, 39, 32, 47, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 112, + 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, + 32, 60, 45, 32, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, + 101, 76, 105, 115, 116, 32, 47, 32, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, + 10, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, + 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, + 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 66, 97, 114, 101, 78, 97, + 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, + 79, 114, 83, 116, 114, 105, 110, 103, 41, 10, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, + 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 73, 110, 99, 108, 117, + 100, 101, 78, 117, 108, 108, 115, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, + 108, 115, 10, 73, 110, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, + 73, 78, 67, 76, 85, 68, 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 69, 120, 99, + 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, + 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, + 97, 100, 101, 114, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, + 114, 83, 105, 110, 103, 108, 101, 32, 47, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, + 100, 101, 114, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, + 114, 83, 105, 110, 103, 108, 101, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, + 114, 105, 110, 103, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, + 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, + 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 80, 114, 97, 103, 109, 97, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 65, 71, 77, 65, + 39, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, + 116, 105, 111, 110, 10, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, + 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, + 105, 103, 110, 32, 47, 32, 80, 114, 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, + 10, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 32, 60, 45, 32, 83, 101, 116, + 116, 105, 110, 103, 78, 97, 109, 101, 32, 39, 61, 39, 32, 86, 97, 114, 105, 97, 98, 108, + 101, 76, 105, 115, 116, 10, 80, 114, 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, + 32, 60, 45, 32, 80, 114, 97, 103, 109, 97, 78, 97, 109, 101, 32, 80, 114, 97, 103, 109, + 97, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 63, 10, 80, 114, 97, 103, 109, 97, 80, + 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, + 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 80, 114, + 101, 112, 97, 114, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, + 82, 69, 80, 65, 82, 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, + 103, 32, 84, 121, 112, 101, 76, 105, 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, + 116, 101, 109, 101, 110, 116, 10, 84, 121, 112, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 84, 121, 112, 101, 41, 41, 10, 83, 101, + 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 108, + 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, + 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, + 114, 110, 97, 108, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, + 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 32, 82, 101, 115, + 117, 108, 116, 77, 111, 100, 105, 102, 105, 101, 114, 115, 63, 10, 83, 101, 108, 101, 99, 116, + 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 32, 60, 45, 32, 73, 110, 116, 101, 114, 115, + 101, 99, 116, 67, 104, 97, 105, 110, 32, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, + 67, 104, 97, 105, 110, 84, 97, 105, 108, 42, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, + 79, 112, 67, 104, 97, 105, 110, 84, 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 111, 112, + 67, 108, 97, 117, 115, 101, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, + 110, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 32, 60, 45, 32, + 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, + 67, 104, 97, 105, 110, 84, 97, 105, 108, 42, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, + 67, 104, 97, 105, 110, 84, 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 73, 110, 116, 101, + 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 65, 116, + 111, 109, 10, 83, 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 83, 69, 67, 84, 39, 32, 68, 105, 115, + 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 10, 83, 101, 108, 101, 99, 116, 65, 116, + 111, 109, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, + 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, + 10, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, + 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, + 110, 116, 101, 114, 110, 97, 108, 41, 10, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, + 32, 60, 45, 32, 83, 101, 116, 111, 112, 84, 121, 112, 101, 32, 68, 105, 115, 116, 105, 110, + 99, 116, 79, 114, 65, 108, 108, 63, 32, 66, 121, 78, 97, 109, 101, 63, 10, 83, 101, 116, + 111, 112, 84, 121, 112, 101, 32, 60, 45, 32, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, + 32, 47, 32, 83, 101, 116, 111, 112, 69, 120, 99, 101, 112, 116, 10, 83, 101, 116, 111, 112, + 85, 110, 105, 111, 110, 32, 60, 45, 32, 39, 85, 78, 73, 79, 78, 39, 10, 83, 101, 116, + 111, 112, 69, 120, 99, 101, 112, 116, 32, 60, 45, 32, 39, 69, 88, 67, 69, 80, 84, 39, + 10, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 78, 65, 77, + 69, 39, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, + 112, 101, 32, 60, 45, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, + 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 47, 32, 86, 97, 108, 117, 101, + 115, 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 32, 47, 32, 80, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 47, 32, 85, 110, 112, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 10, 82, 101, 115, 117, 108, 116, 77, 111, 100, 105, 102, 105, 101, 114, 115, 32, 60, 45, 32, + 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 76, 105, 109, 105, 116, + 79, 102, 102, 115, 101, 116, 63, 10, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 32, + 60, 45, 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, + 32, 47, 32, 79, 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, + 32, 47, 32, 79, 102, 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, + 32, 47, 32, 70, 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 10, 76, + 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, + 97, 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, + 117, 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, + 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 70, + 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, + 67, 108, 97, 117, 115, 101, 32, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 70, + 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, + 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 66, 97, 115, 101, + 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, + 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, + 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, + 32, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 10, 83, 105, 109, 112, 108, 101, + 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, + 110, 115, 40, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 41, 10, 83, 105, 109, + 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, + 114, 111, 109, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 71, 114, 111, + 117, 112, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 72, 97, 118, 105, 110, 103, 67, 108, + 97, 117, 115, 101, 63, 32, 87, 105, 110, 100, 111, 119, 67, 108, 97, 117, 115, 101, 63, 32, + 81, 117, 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, 108, + 101, 67, 108, 97, 117, 115, 101, 63, 10, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 32, + 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, + 47, 32, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 10, 83, + 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, + 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, + 115, 101, 63, 10, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, + 32, 60, 45, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, + 116, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, + 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 32, 85, 115, 105, 110, 103, + 75, 101, 121, 63, 32, 39, 65, 83, 39, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, + 101, 100, 63, 32, 67, 84, 69, 66, 111, 100, 121, 10, 67, 84, 69, 66, 111, 100, 121, 32, + 60, 45, 32, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, 121, 32, 47, 32, 67, + 84, 69, 68, 77, 76, 66, 111, 100, 121, 10, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, + 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 67, + 84, 69, 68, 77, 76, 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 41, 10, 85, 115, 105, 110, 103, 75, 101, 121, 32, + 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 75, 69, 89, 39, 32, 80, 97, 114, + 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 77, 97, 116, 101, + 114, 105, 97, 108, 105, 122, 101, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 63, 32, 39, + 77, 65, 84, 69, 82, 73, 65, 76, 73, 90, 69, 68, 39, 10, 87, 105, 116, 104, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 99, 117, 114, + 115, 105, 118, 101, 63, 32, 76, 105, 115, 116, 40, 87, 105, 116, 104, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 41, 10, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, 45, 32, 39, + 82, 69, 67, 85, 82, 83, 73, 86, 69, 39, 10, 83, 101, 108, 101, 99, 116, 67, 108, 97, + 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 76, 69, 67, 84, 39, 32, 68, 105, 115, 116, + 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 84, 97, 114, 103, 101, 116, 76, 105, + 115, 116, 63, 10, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, + 115, 116, 40, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 41, 10, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 32, 60, 45, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, + 114, 105, 110, 103, 41, 41, 10, 68, 105, 115, 116, 105, 110, 99, 116, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, 47, 32, 68, 105, + 115, 116, 105, 110, 99, 116, 65, 108, 108, 10, 68, 105, 115, 116, 105, 110, 99, 116, 65, 108, + 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 68, 105, 115, 116, 105, 110, 99, 116, 79, + 110, 32, 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 68, 105, 115, 116, + 105, 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 63, 10, 68, 105, 115, 116, 105, + 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 32, 60, 45, 32, 39, 79, 78, 39, + 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 41, 41, 10, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 60, 45, 32, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 47, 32, 84, 97, 98, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 84, 97, 98, 108, 101, 83, 117, 98, 113, + 117, 101, 114, 121, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 47, 32, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 84, 97, 98, + 108, 101, 82, 101, 102, 32, 60, 45, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, + 101, 102, 32, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 42, 10, 84, 97, 98, 108, + 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, + 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, + 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 84, 97, 98, + 108, 101, 65, 108, 105, 97, 115, 63, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, + 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, + 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 84, 97, 98, 108, + 101, 65, 108, 105, 97, 115, 63, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, + 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, + 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, + 114, 105, 110, 103, 32, 39, 58, 39, 10, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, + 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 86, + 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 84, 97, 98, 108, 101, 65, 108, 105, + 97, 115, 63, 10, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, + 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 80, + 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 84, 97, 98, 108, + 101, 65, 108, 105, 97, 115, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, + 63, 10, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 32, 60, 45, 32, 74, 111, 105, + 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, + 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, + 116, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 80, 97, 114, 101, + 110, 115, 40, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, + 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, + 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, + 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 39, 70, 79, 82, 39, 32, 80, 105, + 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 32, 80, 105, 118, 111, 116, 71, + 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 71, 114, 111, + 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, + 39, 66, 89, 39, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, + 97, 109, 101, 76, 105, 115, 116, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, + 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, + 115, 63, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, - 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, - 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, - 32, 39, 70, 79, 82, 39, 32, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, - 116, 43, 32, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, - 10, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, - 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, 89, 39, 32, 79, 112, 116, 105, 111, 110, - 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 10, 84, 97, 98, - 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, - 85, 78, 80, 73, 86, 79, 84, 39, 32, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, - 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 63, 32, 80, 97, 114, 101, 110, 115, 40, 84, - 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, - 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, - 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, - 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 39, 70, 79, 82, 39, - 32, 85, 110, 112, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 10, 80, - 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 60, 45, 32, 66, 97, 115, 101, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, - 105, 115, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 39, - 73, 78, 39, 32, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 84, 97, 114, 103, 101, 116, - 10, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, - 32, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, 97, 114, 103, 101, 116, 32, 47, 32, 80, - 105, 118, 111, 116, 76, 105, 115, 116, 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, - 69, 110, 117, 109, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 10, 80, 105, 118, 111, 116, 76, 105, 115, 116, 84, 97, 114, 103, 101, 116, - 32, 60, 45, 32, 80, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, - 85, 110, 112, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, - 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 85, - 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, - 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 85, 110, 112, 105, 118, - 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 76, 97, 116, 101, 114, - 97, 108, 32, 60, 45, 32, 39, 76, 65, 84, 69, 82, 65, 76, 39, 10, 66, 97, 115, 101, - 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, - 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 47, 32, 85, 110, 113, 117, 97, 108, - 105, 102, 105, 101, 100, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 85, - 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, - 97, 109, 101, 32, 60, 45, 32, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 81, 117, 97, - 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 67, - 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, - 84, 97, 98, 108, 101, 32, 47, 32, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, - 101, 100, 84, 97, 98, 108, 101, 10, 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, - 101, 100, 84, 97, 98, 108, 101, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, - 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, - 97, 98, 108, 101, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, - 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 32, 60, 45, 32, 67, - 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, - 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, - 105, 99, 97, 116, 105, 111, 110, 43, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, - 108, 101, 78, 97, 109, 101, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, - 32, 60, 45, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, - 101, 114, 97, 108, 79, 112, 116, 32, 47, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, - 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 10, 84, 97, 98, 108, 101, 70, - 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, 60, 45, - 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, - 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, - 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, 32, 84, 97, 98, 108, 101, 65, 108, 105, - 97, 115, 63, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, - 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 67, 111, 108, 111, 110, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, - 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, - 105, 110, 97, 108, 105, 116, 121, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, - 101, 63, 10, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 32, 60, 45, - 32, 39, 87, 73, 84, 72, 39, 32, 39, 79, 82, 68, 73, 78, 65, 76, 73, 84, 89, 39, - 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, - 105, 111, 110, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, - 105, 99, 97, 116, 105, 111, 110, 63, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, - 102, 105, 99, 97, 116, 105, 111, 110, 42, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, - 105, 111, 110, 78, 97, 109, 101, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, - 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, - 40, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, - 110, 116, 41, 63, 41, 10, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, - 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, - 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, - 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 10, 78, 97, 109, - 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, - 45, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 80, 111, 115, - 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, - 101, 110, 116, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 97, - 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 32, 60, 45, 32, 84, 121, 112, 101, - 70, 117, 110, 99, 78, 97, 109, 101, 32, 84, 121, 112, 101, 63, 32, 78, 97, 109, 101, 100, - 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, - 109, 101, 116, 101, 114, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 39, - 58, 61, 39, 32, 47, 32, 39, 61, 62, 39, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 65, 115, 32, 47, 32, - 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 10, - 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 65, 115, 32, 60, 45, 32, 39, 65, 83, 39, - 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, - 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 87, 105, 116, 104, 111, 117, 116, 65, - 115, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 67, 111, 108, 117, - 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, 65, 116, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 65, 84, 39, 32, 80, 97, 114, 101, 110, 115, 40, 65, 116, 83, 112, 101, - 99, 105, 102, 105, 101, 114, 41, 10, 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 32, - 60, 45, 32, 65, 116, 85, 110, 105, 116, 32, 39, 61, 62, 39, 32, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 86, 101, 114, 115, - 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 47, 32, 84, 105, 109, 101, 115, 116, 97, 109, - 112, 65, 116, 85, 110, 105, 116, 10, 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, - 116, 32, 60, 45, 32, 39, 86, 69, 82, 83, 73, 79, 78, 39, 10, 84, 105, 109, 101, 115, - 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 39, 84, 73, 77, 69, 83, - 84, 65, 77, 80, 39, 10, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, 101, 32, 47, 32, 82, 101, 103, 117, 108, - 97, 114, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 74, 111, 105, 110, 87, - 105, 116, 104, 111, 117, 116, 79, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 78, 101, 97, - 114, 101, 115, 116, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 10, 35, 32, 78, 69, 65, - 82, 69, 83, 84, 32, 66, 89, 32, 104, 97, 115, 32, 116, 119, 111, 32, 97, 108, 116, 101, - 114, 110, 97, 116, 105, 118, 101, 115, 32, 115, 111, 32, 80, 69, 71, 32, 99, 97, 110, 32, - 98, 97, 99, 107, 116, 114, 97, 99, 107, 58, 32, 116, 104, 101, 32, 98, 97, 114, 101, 32, - 102, 111, 114, 109, 32, 117, 115, 101, 115, 32, 97, 108, 105, 97, 115, 45, 108, 101, 115, 115, - 32, 116, 97, 114, 103, 101, 116, 32, 109, 105, 114, 114, 111, 114, 115, 32, 40, 116, 114, 105, - 101, 100, 10, 35, 32, 102, 105, 114, 115, 116, 44, 32, 115, 111, 32, 97, 110, 32, 117, 110, - 97, 108, 105, 97, 115, 101, 100, 32, 116, 97, 114, 103, 101, 116, 32, 100, 111, 101, 115, 32, - 110, 111, 116, 32, 103, 114, 101, 101, 100, 105, 108, 121, 32, 99, 111, 110, 115, 117, 109, 101, - 32, 78, 69, 65, 82, 69, 83, 84, 47, 65, 80, 80, 82, 79, 88, 47, 69, 88, 65, 67, - 84, 32, 97, 115, 32, 97, 110, 32, 97, 108, 105, 97, 115, 41, 44, 32, 97, 110, 100, 32, - 116, 104, 101, 32, 97, 108, 105, 97, 115, 101, 100, 10, 35, 32, 102, 111, 114, 109, 32, 102, - 97, 108, 108, 115, 32, 98, 97, 99, 107, 32, 116, 111, 32, 97, 32, 102, 117, 108, 108, 32, - 84, 97, 98, 108, 101, 82, 101, 102, 32, 119, 104, 101, 110, 32, 97, 32, 114, 101, 97, 108, - 32, 97, 108, 105, 97, 115, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 102, 111, - 108, 108, 111, 119, 115, 32, 116, 104, 101, 32, 116, 97, 114, 103, 101, 116, 46, 10, 78, 101, - 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 78, - 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 66, 97, 114, 101, 32, 47, 32, 78, 101, 97, - 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, 105, 97, 115, 101, 100, 10, 78, 101, 97, 114, - 101, 115, 116, 74, 111, 105, 110, 65, 108, 105, 97, 115, 101, 100, 32, 60, 45, 32, 74, 111, - 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, - 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, 99, 116, 63, 32, 39, - 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, - 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, - 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 66, 97, 114, 101, 32, 60, 45, 32, - 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 78, 101, 97, - 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, - 114, 111, 120, 79, 114, 69, 120, 97, 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, - 39, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, - 39, 32, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, - 116, 121, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, - 116, 66, 97, 114, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 78, 101, 97, - 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, - 101, 115, 116, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 78, - 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, - 47, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, - 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, - 108, 101, 82, 101, 102, 10, 78, 101, 97, 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, - 101, 102, 32, 60, 45, 32, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 10, 78, - 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, - 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, - 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, - 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, - 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, 10, 78, 101, 97, 114, 101, 115, - 116, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 76, 97, - 116, 101, 114, 97, 108, 63, 32, 83, 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, - 101, 110, 99, 101, 10, 78, 101, 97, 114, 101, 115, 116, 66, 97, 115, 101, 84, 97, 98, 108, - 101, 82, 101, 102, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, - 101, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, - 97, 117, 115, 101, 63, 10, 78, 101, 97, 114, 101, 115, 116, 80, 97, 114, 101, 110, 115, 84, - 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, - 98, 108, 101, 82, 101, 102, 41, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, - 63, 10, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, 99, 116, 32, 60, 45, 32, 78, - 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, 120, 32, 47, 32, 78, 101, 97, 114, 101, - 115, 116, 69, 120, 97, 99, 116, 10, 78, 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, - 120, 32, 60, 45, 32, 39, 65, 80, 80, 82, 79, 88, 39, 10, 78, 101, 97, 114, 101, 115, - 116, 69, 120, 97, 99, 116, 32, 60, 45, 32, 39, 69, 88, 65, 67, 84, 39, 10, 68, 105, - 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, - 45, 32, 78, 101, 97, 114, 101, 115, 116, 68, 105, 115, 116, 97, 110, 99, 101, 32, 47, 32, - 78, 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 10, 78, 101, - 97, 114, 101, 115, 116, 68, 105, 115, 116, 97, 110, 99, 101, 32, 60, 45, 32, 39, 68, 73, - 83, 84, 65, 78, 67, 69, 39, 10, 78, 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, 108, - 97, 114, 105, 116, 121, 32, 60, 45, 32, 39, 83, 73, 77, 73, 76, 65, 82, 73, 84, 89, - 39, 10, 82, 101, 103, 117, 108, 97, 114, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 65, 115, 111, 102, 63, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, - 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 74, 111, 105, 110, 81, - 117, 97, 108, 105, 102, 105, 101, 114, 10, 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 74, 79, 73, 78, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, - 101, 110, 115, 40, 39, 84, 89, 80, 69, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 41, - 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, - 105, 101, 114, 10, 65, 115, 111, 102, 32, 60, 45, 32, 39, 65, 83, 79, 70, 39, 10, 74, - 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, - 45, 32, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 39, 74, 79, 73, 78, 39, 32, - 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, 10, 74, 111, 105, 110, 81, 117, - 97, 108, 105, 102, 105, 101, 114, 32, 60, 45, 32, 79, 110, 67, 108, 97, 117, 115, 101, 32, - 47, 32, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 10, 79, 110, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, - 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, - 117, 109, 110, 78, 97, 109, 101, 41, 41, 10, 74, 111, 105, 110, 84, 121, 112, 101, 32, 60, - 45, 32, 70, 117, 108, 108, 74, 111, 105, 110, 32, 47, 32, 76, 101, 102, 116, 74, 111, 105, - 110, 32, 47, 32, 82, 105, 103, 104, 116, 74, 111, 105, 110, 32, 47, 32, 83, 101, 109, 105, - 74, 111, 105, 110, 32, 47, 32, 65, 110, 116, 105, 74, 111, 105, 110, 32, 47, 32, 73, 110, - 110, 101, 114, 74, 111, 105, 110, 10, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, - 45, 32, 67, 114, 111, 115, 115, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, - 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, - 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, - 10, 67, 114, 111, 115, 115, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, - 39, 67, 82, 79, 83, 83, 39, 10, 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, - 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 78, 65, 84, 85, 82, 65, 76, 39, 32, 74, - 111, 105, 110, 84, 121, 112, 101, 63, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, - 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, - 79, 78, 65, 76, 39, 10, 70, 117, 108, 108, 74, 111, 105, 110, 32, 60, 45, 32, 39, 70, - 85, 76, 76, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 76, 101, 102, 116, 74, 111, - 105, 110, 32, 60, 45, 32, 39, 76, 69, 70, 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, - 63, 10, 82, 105, 103, 104, 116, 74, 111, 105, 110, 32, 60, 45, 32, 39, 82, 73, 71, 72, - 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 83, 101, 109, 105, 74, 111, 105, 110, - 32, 60, 45, 32, 39, 83, 69, 77, 73, 39, 10, 65, 110, 116, 105, 74, 111, 105, 110, 32, - 60, 45, 32, 39, 65, 78, 84, 73, 39, 10, 73, 110, 110, 101, 114, 74, 111, 105, 110, 32, - 60, 45, 32, 39, 73, 78, 78, 69, 82, 39, 10, 70, 114, 111, 109, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 76, 105, 115, 116, 40, 84, 97, 98, - 108, 101, 82, 101, 102, 41, 10, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 32, 60, - 45, 32, 39, 87, 72, 69, 82, 69, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 10, 71, 114, 111, 117, 112, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, - 82, 79, 85, 80, 39, 32, 39, 66, 89, 39, 32, 71, 114, 111, 117, 112, 66, 121, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 115, 10, 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 72, 65, 86, 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 81, 117, 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 81, 85, 65, 76, 73, 70, 89, 39, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 10, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 40, 84, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 47, 32, 85, 115, 105, 110, 103, - 83, 97, 109, 112, 108, 101, 41, 32, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 10, - 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, - 71, 39, 32, 39, 83, 65, 77, 80, 76, 69, 39, 10, 84, 97, 98, 108, 101, 83, 97, 109, - 112, 108, 101, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 83, 65, 77, 80, 76, 69, 39, - 10, 87, 105, 110, 100, 111, 119, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, - 78, 68, 79, 87, 39, 32, 76, 105, 115, 116, 40, 87, 105, 110, 100, 111, 119, 68, 101, 102, - 105, 110, 105, 116, 105, 111, 110, 41, 10, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, - 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, - 39, 65, 83, 39, 32, 87, 105, 110, 100, 111, 119, 70, 114, 97, 109, 101, 68, 101, 102, 105, - 110, 105, 116, 105, 111, 110, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 32, 60, - 45, 32, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, - 110, 32, 47, 32, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, - 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 32, 60, 45, - 32, 83, 97, 109, 112, 108, 101, 67, 111, 117, 110, 116, 32, 80, 97, 114, 101, 110, 115, 40, - 83, 97, 109, 112, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 41, 63, 10, 83, - 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, - 45, 32, 83, 97, 109, 112, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 63, 32, 80, 97, - 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 67, 111, 117, 110, 116, 41, 32, 82, 101, - 112, 101, 97, 116, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 63, 10, 83, 97, 109, 112, - 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, - 83, 97, 109, 112, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 32, 60, 45, 32, - 67, 111, 108, 73, 100, 32, 40, 39, 44, 39, 32, 83, 97, 109, 112, 108, 101, 83, 101, 101, - 100, 41, 63, 10, 82, 101, 112, 101, 97, 116, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, - 32, 60, 45, 32, 39, 82, 69, 80, 69, 65, 84, 65, 66, 76, 69, 39, 32, 80, 97, 114, - 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 41, 10, 83, 97, 109, 112, - 108, 101, 83, 101, 101, 100, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, - 114, 97, 108, 10, 83, 97, 109, 112, 108, 101, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, - 97, 109, 112, 108, 101, 86, 97, 108, 117, 101, 32, 83, 97, 109, 112, 108, 101, 85, 110, 105, - 116, 63, 10, 83, 97, 109, 112, 108, 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 78, 117, - 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 80, 97, 114, 97, 109, 101, - 116, 101, 114, 10, 83, 97, 109, 112, 108, 101, 85, 110, 105, 116, 32, 60, 45, 32, 83, 97, - 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, 116, 97, 103, 101, 32, 47, 32, 83, 97, 109, - 112, 108, 101, 82, 111, 119, 115, 10, 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, - 116, 97, 103, 101, 32, 60, 45, 32, 39, 37, 39, 32, 47, 32, 39, 80, 69, 82, 67, 69, - 78, 84, 39, 10, 83, 97, 109, 112, 108, 101, 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, - 79, 87, 83, 39, 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 115, 32, 60, 45, 32, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 47, - 32, 71, 114, 111, 117, 112, 66, 121, 65, 108, 108, 10, 71, 114, 111, 117, 112, 66, 121, 65, - 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 71, 114, 111, 117, 112, 66, 121, 76, - 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 109, 112, 116, 121, 71, 114, 111, - 117, 112, 105, 110, 103, 73, 116, 101, 109, 32, 47, 32, 67, 117, 98, 101, 79, 114, 82, 111, - 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, - 103, 83, 101, 116, 115, 67, 108, 97, 117, 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 66, - 121, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, - 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, - 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, 109, 112, 116, 121, 71, 114, 111, - 117, 112, 105, 110, 103, 73, 116, 101, 109, 32, 60, 45, 32, 39, 40, 39, 32, 39, 41, 39, - 10, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, - 41, 10, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 32, 60, 45, 32, 67, 117, - 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 82, 111, 108, 108, 117, 112, 75, 101, - 121, 119, 111, 114, 100, 10, 67, 117, 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, - 32, 39, 67, 85, 66, 69, 39, 10, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, - 100, 32, 60, 45, 32, 39, 82, 79, 76, 76, 85, 80, 39, 10, 71, 114, 111, 117, 112, 105, - 110, 103, 83, 101, 116, 115, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, - 85, 80, 73, 78, 71, 39, 32, 39, 83, 69, 84, 83, 39, 32, 80, 97, 114, 101, 110, 115, - 40, 76, 105, 115, 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 41, 41, 10, 83, 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, - 110, 99, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 79, - 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, - 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, - 68, 101, 115, 99, 79, 114, 65, 115, 99, 32, 60, 45, 32, 68, 101, 115, 99, 101, 110, 100, - 105, 110, 103, 79, 114, 100, 101, 114, 32, 47, 32, 65, 115, 99, 101, 110, 100, 105, 110, 103, - 79, 114, 100, 101, 114, 10, 68, 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, - 114, 32, 60, 45, 32, 39, 68, 69, 83, 67, 39, 32, 47, 32, 39, 68, 69, 83, 67, 69, - 78, 68, 73, 78, 71, 39, 10, 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, - 114, 32, 60, 45, 32, 39, 65, 83, 67, 39, 32, 47, 32, 39, 65, 83, 67, 69, 78, 68, - 73, 78, 71, 39, 10, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, - 116, 32, 60, 45, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 32, 47, 32, 78, 117, - 108, 108, 115, 76, 97, 115, 116, 10, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 32, 60, - 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, 70, 73, 82, 83, 84, 39, 10, 78, 117, - 108, 108, 115, 76, 97, 115, 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, - 76, 65, 83, 84, 39, 10, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 79, 82, 68, 69, 82, 39, 32, 39, 66, 89, 39, 32, 79, 114, 100, 101, - 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 10, 79, 114, 100, 101, 114, - 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 79, 114, 100, - 101, 114, 66, 121, 65, 108, 108, 32, 47, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 79, 114, 100, 101, 114, 66, 121, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, - 116, 40, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, - 10, 79, 114, 100, 101, 114, 66, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, - 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, - 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 76, 73, 77, 73, 84, 39, 32, 76, 105, 109, 105, 116, 86, 97, - 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 39, 79, 70, 70, 83, 69, 84, 39, 32, 79, 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, - 10, 79, 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, 63, 10, 82, 111, - 119, 79, 114, 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 47, 32, 39, - 82, 79, 87, 83, 39, 10, 76, 105, 109, 105, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, - 76, 105, 109, 105, 116, 65, 108, 108, 32, 47, 32, 76, 105, 109, 105, 116, 76, 105, 116, 101, - 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, 32, 47, 32, 76, 105, 109, 105, 116, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, 105, 109, 105, 116, 65, 108, 108, 32, 60, 45, - 32, 39, 65, 76, 76, 39, 10, 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, - 101, 114, 99, 101, 110, 116, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, - 114, 97, 108, 32, 39, 80, 69, 82, 67, 69, 78, 84, 39, 10, 76, 105, 109, 105, 116, 69, + 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, + 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, + 101, 97, 100, 101, 114, 32, 39, 70, 79, 82, 39, 32, 85, 110, 112, 105, 118, 111, 116, 86, + 97, 108, 117, 101, 76, 105, 115, 116, 43, 10, 80, 105, 118, 111, 116, 72, 101, 97, 100, 101, + 114, 32, 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 105, + 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 80, 105, 118, 111, 116, + 86, 97, 108, 117, 101, 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 86, 97, 108, + 117, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 69, 110, 117, + 109, 84, 97, 114, 103, 101, 116, 32, 47, 32, 80, 105, 118, 111, 116, 76, 105, 115, 116, 84, + 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, 97, 114, 103, 101, + 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 105, 118, 111, + 116, 76, 105, 115, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, + 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 86, 97, + 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, + 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, + 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, + 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, + 76, 105, 115, 116, 41, 10, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, + 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, + 76, 105, 115, 116, 41, 10, 76, 97, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 76, 65, + 84, 69, 82, 65, 76, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, + 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, + 109, 101, 32, 47, 32, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, 97, 115, 101, + 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, + 100, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 84, 97, + 98, 108, 101, 78, 97, 109, 101, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, + 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, + 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 32, 47, 32, 83, + 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 10, 83, + 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 32, 60, + 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, + 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, + 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, + 97, 84, 97, 98, 108, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, + 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, + 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, + 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 84, 97, + 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, 47, + 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, + 111, 108, 111, 110, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, + 116, 101, 114, 97, 108, 79, 112, 116, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, + 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, + 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, + 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, + 121, 63, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 60, + 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 81, 117, + 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, + 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, + 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, 32, + 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 79, 114, + 100, 105, 110, 97, 108, 105, 116, 121, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, + 79, 82, 68, 73, 78, 65, 76, 73, 84, 89, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, + 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, + 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, 32, + 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 42, + 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, 84, + 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, + 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 70, 117, 110, + 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 63, 41, 10, 70, 117, 110, + 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, + 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, + 32, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 65, + 114, 103, 117, 109, 101, 110, 116, 10, 78, 97, 109, 101, 100, 70, 117, 110, 99, 116, 105, 111, + 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, 97, + 114, 97, 109, 101, 116, 101, 114, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, + 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, + 116, 101, 114, 32, 60, 45, 32, 84, 121, 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, 32, + 84, 121, 112, 101, 63, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, + 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, 115, 105, + 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 39, 58, 61, 39, 32, 47, 32, 39, 61, 62, + 39, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, 84, 97, 98, 108, + 101, 65, 108, 105, 97, 115, 65, 115, 32, 47, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, + 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, + 115, 65, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 67, 111, + 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, 84, 97, 98, 108, 101, 65, 108, + 105, 97, 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 32, 60, 45, 32, 73, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, + 63, 10, 65, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 65, 84, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 41, 10, 65, + 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 65, 116, 85, 110, 105, 116, + 32, 39, 61, 62, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 85, + 110, 105, 116, 32, 60, 45, 32, 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, + 32, 47, 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 10, 86, + 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 39, 86, 69, 82, + 83, 73, 79, 78, 39, 10, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, + 116, 32, 60, 45, 32, 39, 84, 73, 77, 69, 83, 84, 65, 77, 80, 39, 10, 74, 111, 105, + 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 66, 121, 67, 108, 97, + 117, 115, 101, 32, 47, 32, 82, 101, 103, 117, 108, 97, 114, 74, 111, 105, 110, 67, 108, 97, + 117, 115, 101, 32, 47, 32, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, 110, 67, + 108, 97, 117, 115, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, + 108, 97, 117, 115, 101, 10, 35, 32, 78, 69, 65, 82, 69, 83, 84, 32, 66, 89, 32, 104, + 97, 115, 32, 116, 119, 111, 32, 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 115, 32, + 115, 111, 32, 80, 69, 71, 32, 99, 97, 110, 32, 98, 97, 99, 107, 116, 114, 97, 99, 107, + 58, 32, 116, 104, 101, 32, 98, 97, 114, 101, 32, 102, 111, 114, 109, 32, 117, 115, 101, 115, + 32, 97, 108, 105, 97, 115, 45, 108, 101, 115, 115, 32, 116, 97, 114, 103, 101, 116, 32, 109, + 105, 114, 114, 111, 114, 115, 32, 40, 116, 114, 105, 101, 100, 10, 35, 32, 102, 105, 114, 115, + 116, 44, 32, 115, 111, 32, 97, 110, 32, 117, 110, 97, 108, 105, 97, 115, 101, 100, 32, 116, + 97, 114, 103, 101, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 103, 114, 101, 101, 100, + 105, 108, 121, 32, 99, 111, 110, 115, 117, 109, 101, 32, 78, 69, 65, 82, 69, 83, 84, 47, + 65, 80, 80, 82, 79, 88, 47, 69, 88, 65, 67, 84, 32, 97, 115, 32, 97, 110, 32, 97, + 108, 105, 97, 115, 41, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 97, 108, 105, 97, 115, + 101, 100, 10, 35, 32, 102, 111, 114, 109, 32, 102, 97, 108, 108, 115, 32, 98, 97, 99, 107, + 32, 116, 111, 32, 97, 32, 102, 117, 108, 108, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 119, 104, 101, 110, 32, 97, 32, 114, 101, 97, 108, 32, 97, 108, 105, 97, 115, 32, 105, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 32, 102, 111, 108, 108, 111, 119, 115, 32, 116, 104, 101, + 32, 116, 97, 114, 103, 101, 116, 46, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, + 110, 66, 97, 114, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, + 108, 105, 97, 115, 101, 100, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, + 105, 97, 115, 101, 100, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, + 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, + 120, 79, 114, 69, 120, 97, 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, + 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, + 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, + 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 74, + 111, 105, 110, 66, 97, 114, 101, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, + 32, 39, 74, 79, 73, 78, 39, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, + 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, 99, + 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, 109, 98, 101, 114, 76, + 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, 115, 116, 97, 110, 99, + 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, 108, + 101, 82, 101, 102, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 86, 97, 108, 117, 101, + 115, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 70, + 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, + 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, + 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, + 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 78, 101, 97, + 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 86, 97, 108, + 117, 101, 115, 67, 108, 97, 117, 115, 101, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, + 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, + 108, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, + 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, + 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, + 105, 116, 121, 63, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 83, 117, 98, + 113, 117, 101, 114, 121, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, + 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 78, 101, 97, 114, + 101, 115, 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 66, + 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 65, 116, 67, 108, 97, 117, 115, + 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 78, 101, 97, + 114, 101, 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, + 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 83, + 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 65, 112, 112, 114, 111, 120, 79, + 114, 69, 120, 97, 99, 116, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 65, 112, 112, + 114, 111, 120, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 10, 78, + 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, 120, 32, 60, 45, 32, 39, 65, 80, 80, + 82, 79, 88, 39, 10, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 32, 60, 45, + 32, 39, 69, 88, 65, 67, 84, 39, 10, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, + 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, + 68, 105, 115, 116, 97, 110, 99, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 83, 105, + 109, 105, 108, 97, 114, 105, 116, 121, 10, 78, 101, 97, 114, 101, 115, 116, 68, 105, 115, 116, + 97, 110, 99, 101, 32, 60, 45, 32, 39, 68, 73, 83, 84, 65, 78, 67, 69, 39, 10, 78, + 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, + 39, 83, 73, 77, 73, 76, 65, 82, 73, 84, 89, 39, 10, 82, 101, 103, 117, 108, 97, 114, + 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 65, 115, 111, 102, 63, 32, + 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 84, 97, 98, + 108, 101, 82, 101, 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, + 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 74, 79, 73, + 78, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 39, 84, 89, 80, 69, + 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 41, 32, 84, 97, 98, 108, 101, 82, 101, 102, + 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 65, 115, 111, 102, 32, + 60, 45, 32, 39, 65, 83, 79, 70, 39, 10, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, + 116, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 80, 114, 101, + 102, 105, 120, 32, 39, 74, 79, 73, 78, 39, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, + 101, 82, 101, 102, 10, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, 60, + 45, 32, 79, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 85, 115, 105, 110, 103, 67, 108, + 97, 117, 115, 101, 10, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, + 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 115, 105, 110, 103, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 80, 97, 114, 101, + 110, 115, 40, 76, 105, 115, 116, 40, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, + 97, 109, 101, 41, 41, 10, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, 109, + 101, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, 83, 116, + 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 10, 74, 111, 105, 110, 84, 121, 112, 101, 32, 60, 45, 32, 70, 117, 108, 108, 74, 111, + 105, 110, 32, 47, 32, 76, 101, 102, 116, 74, 111, 105, 110, 32, 47, 32, 82, 105, 103, 104, + 116, 74, 111, 105, 110, 32, 47, 32, 83, 101, 109, 105, 74, 111, 105, 110, 32, 47, 32, 65, + 110, 116, 105, 74, 111, 105, 110, 32, 47, 32, 73, 110, 110, 101, 114, 74, 111, 105, 110, 10, + 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 67, 114, 111, 115, 115, 74, + 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 78, 97, 116, 117, 114, 97, 108, 74, + 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, + 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 10, 67, 114, 111, 115, 115, 74, 111, + 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 67, 82, 79, 83, 83, 39, 10, + 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, + 32, 39, 78, 65, 84, 85, 82, 65, 76, 39, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, + 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, + 120, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 65, 76, 39, 10, 70, 117, + 108, 108, 74, 111, 105, 110, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 32, 39, 79, 85, + 84, 69, 82, 39, 63, 10, 76, 101, 102, 116, 74, 111, 105, 110, 32, 60, 45, 32, 39, 76, + 69, 70, 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 82, 105, 103, 104, 116, 74, + 111, 105, 110, 32, 60, 45, 32, 39, 82, 73, 71, 72, 84, 39, 32, 39, 79, 85, 84, 69, + 82, 39, 63, 10, 83, 101, 109, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 83, 69, 77, + 73, 39, 10, 65, 110, 116, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 65, 78, 84, 73, + 39, 10, 73, 110, 110, 101, 114, 74, 111, 105, 110, 32, 60, 45, 32, 39, 73, 78, 78, 69, + 82, 39, 10, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, 82, + 79, 77, 39, 32, 76, 105, 115, 116, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, 87, + 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 82, 69, + 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, + 89, 39, 32, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 115, 10, 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 72, + 65, 86, 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 81, 117, + 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 81, 85, 65, 76, + 73, 70, 89, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 97, 109, 112, + 108, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 40, 84, 97, 98, 108, 101, 83, 97, + 109, 112, 108, 101, 32, 47, 32, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, 101, 41, 32, + 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 10, 85, 115, 105, 110, 103, 83, 97, 109, + 112, 108, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 83, 65, 77, 80, + 76, 69, 39, 10, 84, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, + 84, 65, 66, 76, 69, 83, 65, 77, 80, 76, 69, 39, 10, 87, 105, 110, 100, 111, 119, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 78, 68, 79, 87, 39, 32, 76, 105, + 115, 116, 40, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 41, + 10, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, + 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 65, 83, 39, 32, 87, 105, 110, + 100, 111, 119, 70, 114, 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 10, 83, + 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, + 69, 110, 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 83, 97, 109, 112, + 108, 101, 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 10, 83, 97, 109, 112, 108, 101, 69, + 110, 116, 114, 121, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 67, + 111, 117, 110, 116, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 80, 114, + 111, 112, 101, 114, 116, 105, 101, 115, 41, 63, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, + 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 63, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, + 112, 108, 101, 67, 111, 117, 110, 116, 41, 32, 82, 101, 112, 101, 97, 116, 97, 98, 108, 101, + 83, 97, 109, 112, 108, 101, 63, 10, 83, 97, 109, 112, 108, 101, 70, 117, 110, 99, 116, 105, + 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 83, 97, 109, 112, 108, 101, 80, 114, + 111, 112, 101, 114, 116, 105, 101, 115, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 40, 39, + 44, 39, 32, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 41, 63, 10, 82, 101, 112, 101, + 97, 116, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 82, 69, 80, + 69, 65, 84, 65, 66, 76, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, + 108, 101, 83, 101, 101, 100, 41, 10, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 32, 60, + 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 83, 97, 109, 112, + 108, 101, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 86, 97, 108, + 117, 101, 32, 83, 97, 109, 112, 108, 101, 85, 110, 105, 116, 63, 10, 83, 97, 109, 112, 108, + 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, + 114, 97, 108, 32, 47, 32, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 83, 97, 109, 112, + 108, 101, 85, 110, 105, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, + 101, 110, 116, 97, 103, 101, 32, 47, 32, 83, 97, 109, 112, 108, 101, 82, 111, 119, 115, 10, + 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, 116, 97, 103, 101, 32, 60, 45, 32, + 39, 37, 39, 32, 47, 32, 39, 80, 69, 82, 67, 69, 78, 84, 39, 10, 83, 97, 109, 112, + 108, 101, 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, 79, 87, 83, 39, 10, 71, 114, 111, + 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 71, + 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, + 65, 108, 108, 10, 71, 114, 111, 117, 112, 66, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, + 76, 76, 39, 10, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 76, + 105, 115, 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 41, 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, + 109, 32, 47, 32, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 67, 108, 97, 117, + 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, 97, + 117, 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 39, 37, 39, 63, 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, 70, 105, 114, 115, 116, 79, 114, 78, - 101, 120, 116, 32, 70, 101, 116, 99, 104, 86, 97, 108, 117, 101, 32, 82, 111, 119, 79, 114, - 82, 111, 119, 115, 32, 39, 79, 78, 76, 89, 39, 10, 70, 105, 114, 115, 116, 79, 114, 78, - 101, 120, 116, 32, 60, 45, 32, 39, 70, 73, 82, 83, 84, 39, 32, 47, 32, 39, 78, 69, - 88, 84, 39, 10, 70, 101, 116, 99, 104, 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, - 67, 111, 108, 108, 97, 98, 101, 108, 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 73, 100, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, - 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, 32, 60, 45, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 65, 83, 39, 32, 67, 111, 108, 76, 97, - 98, 101, 108, 79, 114, 83, 116, 114, 105, 110, 103, 10, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 63, 10, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 86, - 65, 76, 85, 69, 83, 39, 32, 76, 105, 115, 116, 40, 86, 97, 108, 117, 101, 115, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 115, 41, 10, 86, 97, 108, 117, 101, 115, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, - 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 101, 116, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 83, - 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 79, 114, 84, 105, 109, 101, 90, 111, - 110, 101, 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 79, 114, 84, 105, - 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, - 47, 32, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, - 32, 47, 32, 83, 101, 116, 84, 105, 109, 101, 90, 111, 110, 101, 10, 82, 101, 115, 101, 116, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, 39, - 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, - 103, 10, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, 39, 83, 67, 72, 69, - 77, 65, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 116, - 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, - 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, - 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 10, 83, 101, 116, 86, 97, - 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, - 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 47, 32, 83, 101, 116, 83, 101, 116, 116, - 105, 110, 103, 10, 83, 101, 116, 84, 105, 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 39, - 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 32, 90, 111, 110, 101, 86, 97, 108, - 117, 101, 10, 90, 111, 110, 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 90, 111, 110, 101, - 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, - 110, 32, 47, 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, - 73, 110, 116, 101, 114, 118, 97, 108, 32, 47, 32, 90, 111, 110, 101, 76, 111, 99, 97, 108, - 32, 47, 32, 90, 111, 110, 101, 68, 101, 102, 97, 117, 108, 116, 32, 47, 32, 90, 111, 110, - 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 47, 32, 90, 111, 110, - 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 78, 117, 109, 98, 101, 114, - 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, 76, 111, 99, 97, 108, 32, 60, 45, - 32, 39, 76, 79, 67, 65, 76, 39, 10, 90, 111, 110, 101, 68, 101, 102, 97, 117, 108, 116, - 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 10, 90, 111, 110, 101, 83, 116, - 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 83, 116, 114, 105, 110, - 103, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 90, 111, - 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, - 97, 108, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 86, 65, 76, 39, 32, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 73, 110, 116, 101, 114, 118, 97, 108, 63, - 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 80, 114, 101, - 99, 105, 115, 105, 111, 110, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 86, 65, 76, 39, - 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, - 108, 41, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 101, 116, - 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 83, 99, - 111, 112, 101, 63, 32, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, 10, 83, 101, 116, - 86, 97, 114, 105, 97, 98, 108, 101, 32, 60, 45, 32, 86, 97, 114, 105, 97, 98, 108, 101, - 83, 99, 111, 112, 101, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 86, 97, 114, - 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 86, 65, 82, 73, 65, - 66, 76, 69, 39, 10, 83, 101, 116, 116, 105, 110, 103, 83, 99, 111, 112, 101, 32, 60, 45, - 32, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, 47, 32, 83, 101, 115, 115, 105, 111, - 110, 83, 99, 111, 112, 101, 32, 47, 32, 71, 108, 111, 98, 97, 108, 83, 99, 111, 112, 101, - 10, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 76, 79, 67, 65, - 76, 39, 10, 83, 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, - 83, 69, 83, 83, 73, 79, 78, 39, 10, 71, 108, 111, 98, 97, 108, 83, 99, 111, 112, 101, - 32, 60, 45, 32, 39, 71, 76, 79, 66, 65, 76, 39, 10, 83, 101, 116, 65, 115, 115, 105, - 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, - 115, 105, 103, 110, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 10, 86, 97, - 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 60, 45, 32, 39, 61, 39, 32, - 47, 32, 39, 84, 79, 39, 10, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 32, - 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, - 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 60, 45, 32, 66, 101, 103, 105, 110, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, - 32, 47, 32, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, 97, 110, 115, 97, 99, 116, 105, - 111, 110, 32, 47, 32, 67, 111, 109, 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, 105, - 111, 110, 10, 66, 101, 103, 105, 110, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, - 60, 45, 32, 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, 32, 84, 114, 97, 110, - 115, 97, 99, 116, 105, 111, 110, 63, 32, 82, 101, 97, 100, 79, 114, 87, 114, 105, 116, 101, - 63, 10, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, - 110, 32, 60, 45, 32, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, 107, - 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 10, 67, 111, 109, 109, 105, 116, - 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 111, 109, 109, 105, - 116, 79, 114, 69, 110, 100, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 10, - 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, 32, 60, 45, 32, 39, 83, 84, 65, - 82, 84, 39, 32, 47, 32, 39, 66, 69, 71, 73, 78, 39, 10, 84, 114, 97, 110, 115, 97, - 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 87, 79, 82, 75, 39, 32, 47, 32, 39, 84, - 82, 65, 78, 83, 65, 67, 84, 73, 79, 78, 39, 10, 82, 101, 97, 100, 79, 114, 87, 114, - 105, 116, 101, 32, 60, 45, 32, 39, 82, 69, 65, 68, 39, 32, 82, 101, 97, 100, 79, 110, - 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, 101, 10, 82, 101, 97, 100, 79, 110, - 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, 45, 32, 82, 101, 97, - 100, 79, 110, 108, 121, 32, 47, 32, 82, 101, 97, 100, 87, 114, 105, 116, 101, 10, 82, 101, - 97, 100, 79, 110, 108, 121, 32, 60, 45, 32, 39, 79, 78, 76, 89, 39, 10, 82, 101, 97, - 100, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 87, 82, 73, 84, 69, 39, 10, 65, 98, - 111, 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, 107, 32, 60, 45, 32, 39, 65, 66, - 79, 82, 84, 39, 32, 47, 32, 39, 82, 79, 76, 76, 66, 65, 67, 75, 39, 10, 67, 111, - 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 60, 45, 32, 39, 67, 79, 77, 77, 73, 84, - 39, 32, 47, 32, 39, 69, 78, 68, 39, 10, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, - 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, - 101, 116, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 70, - 114, 111, 109, 67, 108, 97, 117, 115, 101, 63, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, - 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, - 10, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, - 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, - 101, 65, 108, 105, 97, 115, 83, 101, 116, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, - 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, - 39, 83, 69, 84, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, - 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, - 32, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 63, 32, 39, 83, 69, 84, 39, 10, - 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 63, - 32, 67, 111, 108, 73, 100, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, - 110, 116, 76, 105, 115, 116, 32, 47, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 84, 117, - 112, 108, 101, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 84, 117, 112, 108, 101, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 117, 109, 110, - 78, 97, 109, 101, 41, 41, 32, 39, 61, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 76, 105, - 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 85, 112, 100, 97, 116, 101, 83, 101, 116, - 69, 108, 101, 109, 101, 110, 116, 41, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 111, - 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 39, 61, 39, 32, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 111, 108, 117, 109, - 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, - 101, 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 42, 10, 85, 115, 101, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 85, 83, 69, 39, 32, 85, - 115, 101, 84, 97, 114, 103, 101, 116, 10, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, - 45, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, - 104, 101, 109, 97, 32, 47, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, - 115, 101, 84, 97, 114, 103, 101, 116, 32, 47, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, - 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 10, 83, 99, 104, 101, 109, 97, - 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 83, - 99, 104, 101, 109, 97, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, - 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 97, 116, 97, - 108, 111, 103, 78, 97, 109, 101, 10, 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, 97, 116, - 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, - 103, 78, 97, 109, 101, 32, 39, 46, 39, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, - 104, 101, 109, 97, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 42, 10, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, - 32, 39, 46, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 86, 97, 99, 117, - 117, 109, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 86, 65, 67, 85, - 85, 77, 39, 32, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 115, 63, 32, 65, - 110, 97, 108, 121, 122, 101, 84, 97, 114, 103, 101, 116, 63, 10, 86, 97, 99, 117, 117, 109, - 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 86, 97, 99, 117, 117, 109, 80, 97, 114, - 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 47, 32, 86, 97, 99, 117, 117, 109, 76, - 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, 10, 86, 97, 99, 117, 117, 109, 80, - 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, - 41, 41, 10, 86, 97, 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, - 110, 115, 32, 60, 45, 32, 79, 112, 116, 70, 117, 108, 108, 63, 32, 79, 112, 116, 70, 114, - 101, 101, 122, 101, 63, 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 63, 32, 79, 112, - 116, 65, 110, 97, 108, 121, 122, 101, 63, 10, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, - 111, 110, 32, 60, 45, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, 32, 47, 32, 79, - 112, 116, 70, 114, 101, 101, 122, 101, 32, 47, 32, 79, 112, 116, 70, 117, 108, 108, 32, 47, - 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 47, 32, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 10, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, 32, 60, 45, 32, 65, - 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 10, 79, 112, 116, 70, 117, 108, - 108, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 10, 79, 112, 116, 70, 114, 101, 101, 122, - 101, 32, 60, 45, 32, 39, 70, 82, 69, 69, 90, 69, 39, 10, 79, 112, 116, 86, 101, 114, - 98, 111, 115, 101, 32, 60, 45, 32, 39, 86, 69, 82, 66, 79, 83, 69, 39, 10, 78, 97, - 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, - 116, 40, 67, 111, 108, 73, 100, 41, 41, 10, 0, + 105, 111, 110, 10, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, + 109, 32, 60, 45, 32, 39, 40, 39, 32, 39, 41, 39, 10, 67, 117, 98, 101, 79, 114, 82, + 111, 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 67, 117, 98, 101, 79, + 114, 82, 111, 108, 108, 117, 112, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 67, 117, 98, 101, 79, 114, + 82, 111, 108, 108, 117, 112, 32, 60, 45, 32, 67, 117, 98, 101, 75, 101, 121, 119, 111, 114, + 100, 32, 47, 32, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 10, 67, 117, + 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 85, 66, 69, 39, 10, + 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 82, 79, + 76, 76, 85, 80, 39, 10, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 32, 39, + 83, 69, 84, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 71, 114, + 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 117, + 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, 80, + 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, + 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 68, 101, 115, 99, 79, 114, 65, 115, + 99, 32, 60, 45, 32, 68, 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, + 32, 47, 32, 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 10, 68, 101, + 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 68, 69, + 83, 67, 39, 32, 47, 32, 39, 68, 69, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 65, + 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 65, 83, + 67, 39, 32, 47, 32, 39, 65, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 78, 117, 108, + 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 32, 60, 45, 32, 78, 117, 108, + 108, 115, 70, 105, 114, 115, 116, 32, 47, 32, 78, 117, 108, 108, 115, 76, 97, 115, 116, 10, + 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, 83, + 39, 32, 39, 70, 73, 82, 83, 84, 39, 10, 78, 117, 108, 108, 115, 76, 97, 115, 116, 32, + 60, 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, 76, 65, 83, 84, 39, 10, 79, 114, + 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 82, 68, 69, + 82, 39, 32, 39, 66, 89, 39, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 115, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 65, 108, 108, 32, + 47, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, + 105, 115, 116, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 79, 114, 100, 101, 114, 66, + 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 79, 114, 100, 101, 114, 66, 121, + 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 32, 68, 101, 115, 99, 79, 114, 65, + 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, + 63, 10, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 76, 73, + 77, 73, 84, 39, 32, 76, 105, 109, 105, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, + 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 70, 70, 83, 69, 84, 39, + 32, 79, 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, 86, + 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 82, + 111, 119, 79, 114, 82, 111, 119, 115, 63, 10, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, + 60, 45, 32, 39, 82, 79, 87, 39, 32, 47, 32, 39, 82, 79, 87, 83, 39, 10, 76, 105, + 109, 105, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 65, 108, 108, + 32, 47, 32, 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, + 110, 116, 32, 47, 32, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 10, 76, 105, 109, 105, 116, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 76, + 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, 32, 60, + 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 39, 80, 69, 82, + 67, 69, 78, 84, 39, 10, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 37, 39, 63, + 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, 69, 84, + 67, 72, 39, 32, 70, 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 70, 101, 116, 99, + 104, 86, 97, 108, 117, 101, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, 78, + 76, 89, 39, 10, 70, 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 60, 45, 32, 39, + 70, 73, 82, 83, 84, 39, 32, 47, 32, 39, 78, 69, 88, 84, 39, 10, 70, 101, 116, 99, + 104, 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 10, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, + 45, 32, 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, + 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 39, 58, 39, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, 67, + 111, 108, 108, 97, 98, 101, 108, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 39, 65, 83, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, 116, 114, + 105, 110, 103, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 63, 10, 86, 97, 108, 117, 101, 115, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 76, + 105, 115, 116, 40, 86, 97, 108, 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 115, 41, 10, 86, 97, 108, 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, + 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, + 109, 101, 110, 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 10, 83, 101, 116, 65, 115, + 115, 105, 103, 110, 109, 101, 110, 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 32, 60, + 45, 32, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, 116, 97, 110, 100, 97, + 114, 100, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 47, 32, 83, 101, 116, 84, 105, + 109, 101, 90, 111, 110, 101, 10, 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, 39, 32, 83, 101, 116, 86, 97, 114, 105, + 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 83, 99, 104, + 101, 109, 97, 32, 60, 45, 32, 39, 83, 67, 72, 69, 77, 65, 39, 32, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, + 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, + 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, 32, 83, 101, 116, 65, 115, 115, 105, + 103, 110, 109, 101, 110, 116, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, + 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, + 108, 101, 32, 47, 32, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 84, + 105, 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, + 79, 78, 69, 39, 32, 90, 111, 110, 101, 86, 97, 108, 117, 101, 10, 90, 111, 110, 101, 86, + 97, 108, 117, 101, 32, 60, 45, 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, + 87, 105, 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 47, 32, 90, 111, 110, 101, + 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, + 32, 47, 32, 90, 111, 110, 101, 76, 111, 99, 97, 108, 32, 47, 32, 90, 111, 110, 101, 68, + 101, 102, 97, 117, 108, 116, 32, 47, 32, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, + 105, 116, 101, 114, 97, 108, 32, 47, 32, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, + 90, 111, 110, 101, 76, 111, 99, 97, 108, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, + 10, 90, 111, 110, 101, 68, 101, 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, 69, 70, + 65, 85, 76, 84, 39, 10, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, + 114, 97, 108, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 10, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, + 97, 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, 32, 60, 45, 32, 39, 73, + 78, 84, 69, 82, 86, 65, 76, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, + 97, 108, 32, 73, 110, 116, 101, 114, 118, 97, 108, 63, 10, 90, 111, 110, 101, 73, 110, 116, + 101, 114, 118, 97, 108, 87, 105, 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 60, + 45, 32, 39, 73, 78, 84, 69, 82, 86, 65, 76, 39, 32, 80, 97, 114, 101, 110, 115, 40, + 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 41, 32, 83, 116, 114, 105, 110, + 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 32, + 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 83, 99, 111, 112, 101, 63, 32, 83, 101, 116, + 116, 105, 110, 103, 78, 97, 109, 101, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, + 32, 60, 45, 32, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 10, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, + 112, 101, 32, 60, 45, 32, 39, 86, 65, 82, 73, 65, 66, 76, 69, 39, 10, 83, 101, 116, + 116, 105, 110, 103, 83, 99, 111, 112, 101, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, 99, + 111, 112, 101, 32, 47, 32, 83, 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, 32, 47, + 32, 71, 108, 111, 98, 97, 108, 83, 99, 111, 112, 101, 10, 76, 111, 99, 97, 108, 83, 99, + 111, 112, 101, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, 83, 101, 115, 115, 105, + 111, 110, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 83, 69, 83, 83, 73, 79, 78, 39, + 10, 71, 108, 111, 98, 97, 108, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 71, 76, 79, + 66, 65, 76, 39, 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, + 45, 32, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 86, 97, 114, + 105, 97, 98, 108, 101, 76, 105, 115, 116, 10, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, + 115, 105, 103, 110, 32, 60, 45, 32, 39, 61, 39, 32, 47, 32, 39, 84, 79, 39, 10, 86, + 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 97, 110, 115, 97, 99, 116, + 105, 111, 110, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 66, 101, 103, 105, + 110, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 82, 111, 108, 108, 98, + 97, 99, 107, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 67, 111, 109, + 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 10, 66, 101, 103, 105, 110, + 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 116, + 79, 114, 66, 101, 103, 105, 110, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, + 32, 82, 101, 97, 100, 79, 114, 87, 114, 105, 116, 101, 63, 10, 82, 111, 108, 108, 98, 97, + 99, 107, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 65, 98, 111, + 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, 107, 32, 84, 114, 97, 110, 115, 97, 99, + 116, 105, 111, 110, 63, 10, 67, 111, 109, 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, + 105, 111, 110, 32, 60, 45, 32, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 84, + 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 10, 83, 116, 97, 114, 116, 79, 114, 66, + 101, 103, 105, 110, 32, 60, 45, 32, 39, 83, 84, 65, 82, 84, 39, 32, 47, 32, 39, 66, + 69, 71, 73, 78, 39, 10, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, + 32, 39, 87, 79, 82, 75, 39, 32, 47, 32, 39, 84, 82, 65, 78, 83, 65, 67, 84, 73, + 79, 78, 39, 10, 82, 101, 97, 100, 79, 114, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, + 82, 69, 65, 68, 39, 32, 82, 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, + 87, 114, 105, 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, + 87, 114, 105, 116, 101, 32, 60, 45, 32, 82, 101, 97, 100, 79, 110, 108, 121, 32, 47, 32, + 82, 101, 97, 100, 87, 114, 105, 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 32, 60, + 45, 32, 39, 79, 78, 76, 89, 39, 10, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, + 45, 32, 39, 87, 82, 73, 84, 69, 39, 10, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, + 108, 98, 97, 99, 107, 32, 60, 45, 32, 39, 65, 66, 79, 82, 84, 39, 32, 47, 32, 39, + 82, 79, 76, 76, 66, 65, 67, 75, 39, 10, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, + 100, 32, 60, 45, 32, 39, 67, 79, 77, 77, 73, 84, 39, 32, 47, 32, 39, 69, 78, 68, + 39, 10, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 85, 80, 68, 65, 84, 69, + 39, 32, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, 101, 116, 32, 85, 112, 100, 97, 116, + 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, + 101, 63, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, + 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 85, 112, 100, 97, 116, 101, 84, + 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, + 116, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, + 116, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 60, 45, 32, 66, 97, + 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 39, 83, 69, 84, 39, 10, 66, 97, + 115, 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, 116, 32, 60, 45, 32, 66, + 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 85, 112, 100, 97, 116, 101, 65, + 108, 105, 97, 115, 63, 32, 39, 83, 69, 84, 39, 10, 85, 112, 100, 97, 116, 101, 65, 108, + 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 63, 32, 67, 111, 108, 73, 100, 10, 85, + 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 85, 112, + 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 47, + 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 84, 117, 112, 108, 101, 10, 85, 112, 100, 97, + 116, 101, 83, 101, 116, 84, 117, 112, 108, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, + 40, 76, 105, 115, 116, 40, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 41, 41, 32, 39, + 61, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, + 115, 116, 40, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 41, + 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, + 101, 116, 32, 39, 61, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, + 100, 97, 116, 101, 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, + 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 42, 10, 85, 115, 101, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 85, 83, 69, 39, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, + 10, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 85, 115, 101, 84, 97, 114, + 103, 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, + 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, + 32, 47, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, + 97, 114, 103, 101, 116, 10, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, 115, + 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, + 101, 10, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, + 114, 103, 101, 116, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 10, + 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, + 109, 97, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 46, + 39, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, + 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 42, 10, 68, 111, 116, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 46, 39, 32, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 10, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 32, 60, 45, 32, 39, 86, 65, 67, 85, 85, 77, 39, 32, 86, 97, 99, 117, + 117, 109, 79, 112, 116, 105, 111, 110, 115, 63, 32, 65, 110, 97, 108, 121, 122, 101, 84, 97, + 114, 103, 101, 116, 63, 10, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 115, 32, + 60, 45, 32, 86, 97, 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, + 110, 115, 32, 47, 32, 86, 97, 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, + 105, 111, 110, 115, 10, 86, 97, 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, + 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, + 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 41, 41, 10, 86, 97, 99, 117, 117, + 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 79, 112, + 116, 70, 117, 108, 108, 63, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, 63, 32, 79, 112, + 116, 86, 101, 114, 98, 111, 115, 101, 63, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, + 63, 10, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 79, 112, + 116, 65, 110, 97, 108, 121, 122, 101, 32, 47, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, + 32, 47, 32, 79, 112, 116, 70, 117, 108, 108, 32, 47, 32, 79, 112, 116, 86, 101, 114, 98, + 111, 115, 101, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 79, 112, 116, + 65, 110, 97, 108, 121, 122, 101, 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, + 121, 119, 111, 114, 100, 10, 79, 112, 116, 70, 117, 108, 108, 32, 60, 45, 32, 39, 70, 85, + 76, 76, 39, 10, 79, 112, 116, 70, 114, 101, 101, 122, 101, 32, 60, 45, 32, 39, 70, 82, + 69, 69, 90, 69, 39, 10, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 60, 45, 32, + 39, 86, 69, 82, 66, 79, 83, 69, 39, 10, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, + 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, + 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 0, }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/keyword_categories.hpp b/src/duckdb/src/include/duckdb/parser/peg/keyword_categories.hpp new file mode 100644 index 000000000..df8de58f3 --- /dev/null +++ b/src/duckdb/src/include/duckdb/parser/peg/keyword_categories.hpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/peg/keyword_categories.hpp +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/exception.hpp" + +namespace duckdb { + +//! Opaque, dialect-defined keyword category flags. +struct keyword_categories_t { // NOLINT +private: + using UNDERLYING_TYPE = uint8_t; + +public: + //! Category IDs are zero-based; the empty mask has no bits set. + static constexpr idx_t MAX_CATEGORY_ID = sizeof(UNDERLYING_TYPE) * 8; + + constexpr keyword_categories_t() : value(0) { + } + explicit constexpr keyword_categories_t(UNDERLYING_TYPE value) : value(value) { + } + + static constexpr keyword_categories_t CreateCategory(idx_t category_id) { + if (category_id >= MAX_CATEGORY_ID) { + throw InvalidInputException("Keyword category ID must be between 0 and %llu", MAX_CATEGORY_ID - 1); + } + return keyword_categories_t(static_cast(UNDERLYING_TYPE(1) << category_id)); + } + + explicit constexpr operator UNDERLYING_TYPE() const { + return value; + } + + constexpr bool operator==(keyword_categories_t other) const { + return value == other.value; + } + constexpr bool operator!=(keyword_categories_t other) const { + return value != other.value; + } + constexpr keyword_categories_t operator|(keyword_categories_t other) const { + return keyword_categories_t(static_cast(value | other.value)); + } + keyword_categories_t &operator|=(keyword_categories_t other) { + value |= other.value; + return *this; + } + constexpr keyword_categories_t operator&(keyword_categories_t other) const { + return keyword_categories_t(static_cast(value & other.value)); + } + constexpr keyword_categories_t operator~() const { + return keyword_categories_t(static_cast(~value)); + } + +private: + UNDERLYING_TYPE value; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper.hpp b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper.hpp index cc5d72904..1d986f4f9 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper.hpp @@ -9,27 +9,32 @@ #pragma once #include "duckdb/common/case_insensitive_map.hpp" +#include "duckdb/parser/peg/grammar_literal_table.hpp" #include "duckdb/parser/simplified_token.hpp" +#include "duckdb/parser/peg/literal_info.hpp" namespace duckdb { -enum class PEGKeywordCategory : uint8_t { - KEYWORD_NONE, - KEYWORD_UNRESERVED, - KEYWORD_RESERVED, - KEYWORD_TYPE_FUNC, - KEYWORD_COL_NAME, - KEYWORD_TYPE_NAME -}; +class GrammarLiteralTable; + +enum class SuggestionState : uint8_t; class PEGKeywordHelper { public: virtual ~PEGKeywordHelper() = default; public: - virtual bool KeywordCategoryType(const string &text, PEGKeywordCategory type) const = 0; - virtual bool IsKeyword(const string &text) const = 0; + LiteralInfo LookupKeyword(const string &text) const { + return GetLiteralTable().Lookup(text); + } + bool IsKeyword(const string &text) const { + return LookupKeyword(text).IsKeyword(); + } + //! Opaque flags accepted in this identifier position, computed when creating a matcher. + virtual keyword_categories_t GetIdentifierMask(SuggestionState type) const = 0; virtual vector KeywordList() const = 0; + //! Every helper provides an immutable table containing its literals and keyword flags. + virtual const GrammarLiteralTable &GetLiteralTable() const = 0; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/default_keyword_maps.hpp b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/default_keyword_maps.hpp index 07bd09dd9..1c3d2d9bd 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/default_keyword_maps.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/default_keyword_maps.hpp @@ -1,15 +1,21 @@ #pragma once #include "duckdb/common/case_insensitive_map.hpp" -#include "duckdb/parser/peg/keyword_helper.hpp" +#include "duckdb/parser/peg/literal_info.hpp" #include "duckdb/parser/simplified_token.hpp" namespace duckdb { +enum class SuggestionState : uint8_t; + class DefaultKeywordMaps { public: - bool IsKeywordOfCategory(const string &text, PEGKeywordCategory type) const; - bool IsKeyword(const string &text) const; + DUCKDB_API LiteralInfo LookupKeyword(const string &text, uint16_t literal_id = 0) const; + DUCKDB_API static keyword_categories_t GetIdentifierMask(SuggestionState type); + DUCKDB_API static KeywordCategory GetKeywordCategory(LiteralInfo info); + //! All recognized categories, in reserved, unreserved, type-function, column-name, type-name order. + DUCKDB_API static vector GetKeywordCategories(LiteralInfo info); + DUCKDB_API case_insensitive_map_t ToLiteralMap() const; vector ToList() const; public: diff --git a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/duckdb_keyword_helper.hpp b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/duckdb_keyword_helper.hpp index 4e58bf314..c152a33bd 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/duckdb_keyword_helper.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/duckdb_keyword_helper.hpp @@ -13,18 +13,19 @@ class DuckDBKeywordHelper : public PEGKeywordHelper { static const DuckDBKeywordHelper &Instance(); public: - bool KeywordCategoryType(const std::string &text, const PEGKeywordCategory type) const override; - bool IsKeyword(const string &text) const override; + keyword_categories_t GetIdentifierMask(SuggestionState type) const override; + KeywordCategory GetKeywordCategory(const string &text) const; vector KeywordList() const override; + const GrammarLiteralTable &GetLiteralTable() const override { + return literal_table; + } private: - void InitializeKeywordMaps(); + static DefaultKeywordMaps InitializeKeywordMaps(); private: DefaultKeywordMaps keyword_maps; - -private: - bool initialized; + GrammarLiteralTable literal_table; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/parsed_grammar_keyword_helper.hpp b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/parsed_grammar_keyword_helper.hpp index c5b890d8d..76fd70c80 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/parsed_grammar_keyword_helper.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/keyword_helper/parsed_grammar_keyword_helper.hpp @@ -2,6 +2,7 @@ #include "duckdb/parser/peg/keyword_helper.hpp" #include "duckdb/parser/peg/keyword_helper/default_keyword_maps.hpp" +#include "duckdb/parser/peg/grammar_literal_table.hpp" namespace duckdb { @@ -12,12 +13,15 @@ class ParsedGrammarKeywordHelper : public PEGKeywordHelper { explicit ParsedGrammarKeywordHelper(const ParsedGrammar &grammar); public: - bool KeywordCategoryType(const string &text, PEGKeywordCategory type) const override; - bool IsKeyword(const string &text) const override; + keyword_categories_t GetIdentifierMask(SuggestionState type) const override; vector KeywordList() const override; + const GrammarLiteralTable &GetLiteralTable() const override { + return literal_table; + } private: DefaultKeywordMaps keyword_maps; + GrammarLiteralTable literal_table; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/literal_info.hpp b/src/duckdb/src/include/duckdb/parser/peg/literal_info.hpp new file mode 100644 index 000000000..94a1927ef --- /dev/null +++ b/src/duckdb/src/include/duckdb/parser/peg/literal_info.hpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/peg/literal_info.hpp +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/parser/peg/keyword_categories.hpp" +#include + +namespace duckdb { + +//! A grammar-local literal ID and opaque keyword properties. +class LiteralInfo { +public: + static constexpr uint16_t MAX_LITERAL_ID = 0xFFFF; + +public: + //! Zero denotes an unknown literal with no keyword flags, such as a non-keyword identifier. + LiteralInfo() : literal_id(0) { + } + explicit LiteralInfo(uint16_t literal_id, keyword_categories_t category_flags = keyword_categories_t()) + : literal_id(literal_id), category_flags(category_flags) { + } + + //! Zero means no grammar-local ID has been assigned; keyword flags may still be present. + uint16_t LiteralId() const { + return literal_id; + } + + keyword_categories_t CategoryFlags() const { + return category_flags; + } + + void AddCategories(keyword_categories_t flags) { + category_flags |= flags; + } + + bool IsKeyword() const { + return category_flags != keyword_categories_t(); + } + + bool HasAnyFlags(keyword_categories_t mask) const { + return (category_flags & mask) != keyword_categories_t(); + } + + bool operator==(const LiteralInfo &other) const { + return literal_id == other.literal_id && category_flags == other.category_flags; + } + +private: + uint16_t literal_id = 0; + keyword_categories_t category_flags = keyword_categories_t(); +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher.hpp index 4079345ca..dfdeec1bd 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/matcher.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher.hpp @@ -151,10 +151,10 @@ struct MatchContext { ArenaAllocator &process_allocator_p, idx_t &max_token_index_p, MatchMode mode_p = MatchMode::BUILD_PARSE_RESULT, IdentifierCaseMode identifier_case_mode_p = IdentifierCaseMode::PRESERVE_CASE, - bool use_heap_based_parser_p = false, ParserPackratCache *packrat_cache_p = nullptr) + ParserPackratCache *packrat_cache_p = nullptr) : suggestions(suggestions_p), allocator(allocator_p), process_allocator(process_allocator_p), max_token_index(max_token_index_p), identifier_case_mode(identifier_case_mode_p), - packrat_cache(packrat_cache_p), mode(mode_p), use_heap_based_parser(use_heap_based_parser_p) { + packrat_cache(packrat_cache_p), mode(mode_p) { } vector &suggestions; @@ -164,7 +164,6 @@ struct MatchContext { IdentifierCaseMode identifier_case_mode; ParserPackratCache *packrat_cache; MatchMode mode; - bool use_heap_based_parser; }; struct MatchState { @@ -235,7 +234,7 @@ class MatchStep { private: MatchStep(optional child_p, optional result_p) - : child(std::move(child_p)), result(std::move(result_p)) { + : child(std::move(child_p)), result(result_p) { } private: diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher/identifier_matcher.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher/identifier_matcher.hpp index fbb302b73..65df82b2b 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/matcher/identifier_matcher.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher/identifier_matcher.hpp @@ -12,7 +12,8 @@ class IdentifierMatcher : public AtomicMatcher { public: IdentifierMatcher(SuggestionState suggestion_type, const PEGKeywordHelper &keyword_helper_p) - : AtomicMatcher(TYPE), suggestion_type(suggestion_type), keyword_helper(keyword_helper_p) { + : AtomicMatcher(TYPE), suggestion_type(suggestion_type), literal_table(keyword_helper_p.GetLiteralTable()), + identifier_mask(keyword_helper_p.GetIdentifierMask(suggestion_type)) { } bool IsQuoted(const string &text) const { @@ -110,18 +111,6 @@ class IdentifierMatcher : public AtomicMatcher { } } - PEGKeywordCategory GetAllowedCategory() const { - switch (suggestion_type) { - case SuggestionState::SUGGEST_TYPE_NAME: - return PEGKeywordCategory::KEYWORD_TYPE_NAME; - case SuggestionState::SUGGEST_SCALAR_FUNCTION_NAME: - case SuggestionState::SUGGEST_TABLE_FUNCTION_NAME: - return PEGKeywordCategory::KEYWORD_TYPE_FUNC; - default: - return PEGKeywordCategory::KEYWORD_COL_NAME; - } - } - SuggestionType AddSuggestionInternal(MatchState &state) const override { state.AddSuggestion(MatcherSuggestion(suggestion_type)); return SuggestionType::MANDATORY; @@ -159,14 +148,9 @@ class IdentifierMatcher : public AtomicMatcher { } private: - bool IsAllowedKeyword(const string &token_text) const { - if (!keyword_helper.IsKeyword(token_text)) { - return true; - } - if (keyword_helper.KeywordCategoryType(token_text, PEGKeywordCategory::KEYWORD_UNRESERVED)) { - return true; - } - return keyword_helper.KeywordCategoryType(token_text, GetAllowedCategory()); + bool IsAllowedKeyword(TokenIterator &tokens) const { + auto info = tokens.CurrentLiteralInfo(literal_table); + return !info.IsKeyword() || info.HasAnyFlags(identifier_mask); } bool MatchIdentifier(MatchState &state) const { @@ -175,7 +159,7 @@ class IdentifierMatcher : public AtomicMatcher { return false; } auto &token_text = token->text; - if (!IsAllowedKeyword(token_text) || !IsIdentifier(token_text)) { + if (!IsAllowedKeyword(state.token_iterator) || !IsIdentifier(token_text)) { return false; } state.token_iterator.Advance(); @@ -184,7 +168,8 @@ class IdentifierMatcher : public AtomicMatcher { } SuggestionState suggestion_type; - const PEGKeywordHelper &keyword_helper; + const GrammarLiteralTable &literal_table; + const keyword_categories_t identifier_mask; }; class ReservedIdentifierMatcher : public IdentifierMatcher { diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher/keyword_matcher.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher/keyword_matcher.hpp index e433215ce..2d6c735bc 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/matcher/keyword_matcher.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher/keyword_matcher.hpp @@ -13,6 +13,14 @@ class KeywordMatcher : public AtomicMatcher { explicit KeywordMatcher(string keyword_p, const KeywordInfo &info) : AtomicMatcher(TYPE), keyword(std::move(keyword_p)), info(info) { } + KeywordMatcher(string keyword_p, const KeywordInfo &info, const PEGKeywordHelper &keyword_helper) + : KeywordMatcher(std::move(keyword_p), info) { + literal_table = keyword_helper.GetLiteralTable(); + literal_info = literal_table->Lookup(keyword); + if (!literal_info.LiteralId()) { + literal_table = nullptr; + } + } MatcherResult MatchAtomic(MatchState &state) const override { auto token = state.token_iterator.Current(); @@ -44,13 +52,20 @@ class KeywordMatcher : public AtomicMatcher { return "'" + keyword + "'"; } + //! Custom matchers must not be filtered using ordinary literal semantics by default. + virtual optional_idx GetDispatchLiteral(const GrammarLiteralTable &) const { + return optional_idx(); + } + private: bool MatchKeyword(MatchState &state) const { auto token = state.token_iterator.Current(); if (!token) { return false; } - if (StringUtil::CIEquals(keyword, token->text)) { + const auto matches = literal_table ? state.token_iterator.CurrentLiteralInfo(*literal_table) == literal_info + : StringUtil::CIEquals(keyword, token->text); + if (matches) { // move to the next token state.token_iterator.Advance(); state.UpdateMaxTokenIndex(); @@ -62,6 +77,10 @@ class KeywordMatcher : public AtomicMatcher { private: const string keyword; const KeywordInfo info; + +protected: + optional_ptr literal_table; + LiteralInfo literal_info; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher/literal_choice_matcher.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher/literal_choice_matcher.hpp new file mode 100644 index 000000000..d078f4d5d --- /dev/null +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher/literal_choice_matcher.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "duckdb/parser/peg/matcher/choice_matcher.hpp" + +namespace duckdb { + +class LiteralChoiceMatcher final : public ChoiceMatcher { +public: + LiteralChoiceMatcher(vector> &&matchers, const GrammarLiteralTable &table_p, + unordered_map &&literal_children_p) + : ChoiceMatcher(std::move(matchers)), table(table_p), literal_children(std::move(literal_children_p)) { + } + + arena_ptr StartMatch(MatchState &state) const override; + +private: + const GrammarLiteralTable &table; + unordered_map literal_children; +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher/operator_matcher.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher/operator_matcher.hpp index 9f369448d..8a8812b2f 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/matcher/operator_matcher.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher/operator_matcher.hpp @@ -6,12 +6,15 @@ namespace duckdb { +enum class OperatorMatcherMode : uint8_t { GENERIC_PRECEDENCE, ALL_OPERATORS }; + class OperatorMatcher : public AtomicMatcher { public: static constexpr MatcherType TYPE = MatcherType::OPERATOR; public: - explicit OperatorMatcher() : AtomicMatcher(TYPE) { + explicit OperatorMatcher(OperatorMatcherMode mode_p = OperatorMatcherMode::GENERIC_PRECEDENCE) + : AtomicMatcher(TYPE), mode(mode_p) { } MatcherResult MatchAtomic(MatchState &state) const override { @@ -43,26 +46,11 @@ class OperatorMatcher : public AtomicMatcher { return false; } auto &token_text = token->text; - // Exclude the lambda arrow and JSON arrow — these have dedicated grammar roles - if (token_text == "->" || token_text == "->>") { - return false; - } - // Single-character operators are handled at specific precedence levels (comparison, additive, etc.) - if (token_text.size() == 1) { - return false; - } - // Exclude known comparison operators — handled by ComparisonExpression, not as function calls - if (token_text == "<=" || token_text == ">=" || token_text == "!=" || token_text == "==" || - token_text == "<>") { - return false; - } - // Exclude LIKE/SIMILAR operators — handled by LikeVariations at a higher precedence level - if (token_text == "~~" || token_text == "~~*" || token_text == "~~~" || token_text == "~*" || - token_text == "!~~" || token_text == "!~~*" || token_text == "!~" || token_text == "!~*") { + if (mode == OperatorMatcherMode::GENERIC_PRECEDENCE && HasSpecialPrecedence(token_text)) { return false; } for (auto &c : token_text) { - if (!IsOperatorChar(c)) { + if (!Tokenizer::CharacterIsOperator(c)) { return false; } } @@ -71,28 +59,10 @@ class OperatorMatcher : public AtomicMatcher { return true; } -protected: - bool IsOperatorChar(char c) const { - switch (c) { - case '+': - case '-': - case '*': - case '/': - case '%': - case '^': - case '<': - case '>': - case '=': - case '~': - case '!': - case '@': - case '&': - case '|': - return true; - default: - return false; - } - } +private: + static bool HasSpecialPrecedence(const string &operator_name); + + OperatorMatcherMode mode; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher_factory.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher_factory.hpp index a80d79d6e..b1387caab 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/matcher_factory.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher_factory.hpp @@ -31,7 +31,7 @@ class MatcherFactory { public: MatcherFactory(MatcherAllocator &allocator, const ParsedGrammar &grammar_p, const compiled_rules_map_t &rules, - terminal_rule_overrides_t terminal_rule_overrides_p); + const PEGKeywordHelper &keyword_helper, terminal_rule_overrides_t terminal_rule_overrides_p); virtual ~MatcherFactory() = default; public: @@ -70,6 +70,7 @@ class MatcherFactory { MatcherAllocator &allocator; const ParsedGrammar &grammar; const compiled_rules_map_t &rules; + const PEGKeywordHelper &keyword_helper; //! Keeps terminal rule names alive while the matcher graph is constructed. terminal_rule_overrides_t terminal_rule_overrides; string_map_t> matchers; diff --git a/src/duckdb/src/include/duckdb/parser/peg/matcher_token.hpp b/src/duckdb/src/include/duckdb/parser/peg/matcher_token.hpp index a5eb32eeb..fba6a2744 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/matcher_token.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/matcher_token.hpp @@ -10,6 +10,7 @@ #include "duckdb/common/string.hpp" #include "duckdb/parser/peg/token_type.hpp" +#include "duckdb/parser/peg/grammar_literal_table.hpp" namespace duckdb { @@ -27,6 +28,22 @@ struct MatcherToken { bool unterminated = false; bool preceded_by_newline = false; bool preceded_by_block_comment = false; + + LiteralInfo GetLiteralInfo(const GrammarLiteralTable &table) { + if (literal_table_id != table.CacheId()) { + literal_info = table.Lookup(text); + literal_table_id = table.CacheId(); + } + return literal_info; + } + + void ResetLiteralInfo() { + literal_table_id = 0; + } + +private: + LiteralInfo literal_info; + uint64_t literal_table_id = 0; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/parsed_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/parsed_grammar.hpp index a89cb5906..48cbd37ac 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/parsed_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/parsed_grammar.hpp @@ -71,6 +71,7 @@ class ParsedGrammar { private: friend class DialectExtension; friend class MatcherFactory; + friend class GrammarLiteralTable; friend struct CompiledGrammar; friend class PEGTransformerFactory; friend class GrammarChange; diff --git a/src/duckdb/src/include/duckdb/parser/peg/peg_parser.hpp b/src/duckdb/src/include/duckdb/parser/peg/peg_parser.hpp index 3edcb2bd7..f91f06df4 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/peg_parser.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/peg_parser.hpp @@ -23,7 +23,7 @@ struct PEGExpression { public: explicit PEGExpression(Type type_p) : type(type_p), text(string_t("")) { } - PEGExpression(Type type_p, string_t text_p) : type(type_p), text(std::move(text_p)) { + PEGExpression(Type type_p, string_t text_p) : type(type_p), text(text_p) { } public: diff --git a/src/duckdb/src/include/duckdb/parser/peg/tokenizer/tokenizer.hpp b/src/duckdb/src/include/duckdb/parser/peg/tokenizer/tokenizer.hpp index 999d777b4..c2e3dcb5f 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/tokenizer/tokenizer.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/tokenizer/tokenizer.hpp @@ -74,9 +74,9 @@ class Tokenizer { //! `TokenizeInput()` is the one that appends `GetTerminator()` (clean) or `END_OF_INPUT` //! (dirty) based on the return value. bool TokenizeInputInternal(TokenizerBehavior &behavior) const; + bool IsCompoundColonToken(const string &sql, idx_t pos, idx_t &token_length) const; public: - bool IsSpecialOperator(const string &sql, idx_t pos, idx_t &op_len) const; static bool IsSingleByteOperator(char c); static bool CharacterIsInitialNumber(char c); static bool CharacterIsNumber(char c); diff --git a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp index 8481c5b88..2268919c7 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp @@ -197,6 +197,8 @@ DUCKDB_REGISTER_TRANSFORM_RESULT_TYPE("duckdb.transform_result.unique_ptr); DUCKDB_REGISTER_TRANSFORM_RESULT_TYPE("duckdb.transform_result.unique_ptr", unique_ptr); DUCKDB_REGISTER_TRANSFORM_RESULT_TYPE("duckdb.transform_result.unique_ptr", unique_ptr); +DUCKDB_REGISTER_TRANSFORM_RESULT_TYPE("duckdb.transform_result.unique_ptr", + unique_ptr); DUCKDB_REGISTER_TRANSFORM_RESULT_TYPE("duckdb.transform_result.unique_ptr", unique_ptr); DUCKDB_REGISTER_TRANSFORM_RESULT_TYPE("duckdb.transform_result.unique_ptr", unique_ptr); @@ -263,7 +265,8 @@ unique_ptr> TryBridgeTransformResultValue(TransformResul //! Input to start a transformer execution. The rule can be supplied explicitly for transparent parse nodes. struct TransformInput { - TransformInput(ParseResult &parse_result_p) : parse_result(parse_result_p) { + TransformInput(ParseResult &parse_result_p) // NOLINT(google-explicit-constructor): enables braced PushChild calls. + : parse_result(parse_result_p) { } TransformInput(const CompiledGrammarRule &rule_p, ParseResult &parse_result_p) : rule(rule_p), parse_result(parse_result_p) { @@ -502,7 +505,6 @@ class PEGTransformer { private: unique_ptr TransformInternal(ParseResult &parse_result); - unique_ptr ExecuteRecursive(TransformInput input); void SetResultLocation(ParseResult &parse_result, TransformResultValue &result); template @@ -604,14 +606,6 @@ TryBridgeTransformResultValue>(TransformResultValue &base_res return nullptr; } -typedef unique_ptr (*transform_finalize_t)(PEGTransformer &transformer, - ParseResult &parse_result); - -struct TransformFinalizeRule { - const char *name; - transform_finalize_t finalize; -}; - class PEGTransformerFactory { public: static void RegisterDefaultTransforms(ParsedGrammar &grammar); @@ -648,6 +642,11 @@ class PEGTransformerFactory { static void SplitGenericOptions(const vector &options_in, case_insensitive_map_t> &parsed_options, unordered_map &options, const char *statement_name); + //! Fold `(k v, ...)` into unbound expressions, for statements that resolve every option at bind time + //! instead of splitting literals out at parse time. Validates like SplitGenericOptions. + static void CollectGenericOptions(const vector &options_in, + case_insensitive_map_t> &options, + const char *statement_name); static void AddToMultiStatement(const unique_ptr &multi_statement, unique_ptr alter_info); static void AddUpdateToMultiStatement(const unique_ptr &multi_statement, const string &column_name, @@ -696,6 +695,10 @@ class PEGTransformerFactory { static void InitializeStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeIdentifierOrKeywordTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr FinalizeIdentifierOrKeywordTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeAlterStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeAlterStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -847,6 +850,13 @@ class PEGTransformerFactory { static void InitializeCommentStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeCommentStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeCommentTargetTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static unique_ptr FinalizeCommentTargetTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static void InitializeCommentStringLiteralIdentifierTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeCommentStringLiteralIdentifierTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static void InitializeCommentOnTypeTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeCommentOnTypeTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -1218,6 +1228,9 @@ class PEGTransformerFactory { static void InitializeIdentifierColIdTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeIdentifierColIdTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeCopyFileNameSuffixTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static unique_ptr FinalizeCopyFileNameSuffixTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeCopyOptionsTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeCopyOptionsTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -2694,6 +2707,9 @@ class PEGTransformerFactory { static void InitializeOperatorLiteralTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeOperatorLiteralTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeAnyOperatorLiteralTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static unique_ptr FinalizeAnyOperatorLiteralTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeAnyAllOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeAnyAllOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -2706,18 +2722,6 @@ class PEGTransformerFactory { static void InitializeSubqueryAllTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeSubqueryAllTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static void InitializeInetOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static unique_ptr FinalizeInetOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process); - static void InitializeJsonOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static unique_ptr FinalizeJsonOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process); - static void InitializeListOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static unique_ptr FinalizeListOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process); - static void InitializeStringOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static unique_ptr FinalizeStringOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process); static void InitializeQualifiedOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeQualifiedOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -2725,9 +2729,6 @@ class PEGTransformerFactory { GeneratedTransformProcess &process); static unique_ptr FinalizeQualifiedOperatorContentsTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static void InitializeAnyOpTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - static unique_ptr FinalizeAnyOpTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process); static void InitializeBitwiseExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeBitwiseExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -3006,6 +3007,26 @@ class PEGTransformerFactory { GeneratedTransformProcess &process); static unique_ptr FinalizeExternalResourceCreationOptionsTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeAttachToExternalResourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeAttachToExternalResourceTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeConnectToExternalResourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeConnectToExternalResourceTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeExternalResourceSourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeExternalResourceSourceTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeExternalResourceCreateClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeExternalResourceCreateClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeExternalResourceReferenceClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeExternalResourceReferenceClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static void InitializeInsertStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeInsertStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -3622,6 +3643,9 @@ class PEGTransformerFactory { static void InitializeUsingClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeUsingClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeUsingColumnNameTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static unique_ptr FinalizeUsingColumnNameTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeJoinTypeTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeJoinTypeTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -4018,807 +4042,329 @@ class PEGTransformerFactory { static void InitializeNameListTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeNameListTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); - //===--------------------------------------------------------------------===// - // END GENERATED TRAMPOLINE RULES - //===--------------------------------------------------------------------===// - - // Registration methods - void RegisterCommon(); - void RegisterCreateTable(); - void RegisterExpression(); - void RegisterPivot(); - void RegisterSelect(); - void RegisterKeywordsAndIdentifiers(); - void RegisterGenerated(); - template - void Register(const string &rule_name, FUNC function) { - auto &rule = grammar.GetMutableRule(rule_name); - if (rule.transform_process) { - throw InternalException("Rule %s already exists", rule_name); - } - grammar.SetTransformProcess( - rule_name, - [function](PEGTransformer &transformer, ParseResult &parse_result) -> unique_ptr { - transform_finalize_function_t finalize = - [function](PEGTransformer &transformer, - ParseResult &parse_result) -> unique_ptr { - auto result_value = function(transformer, parse_result); - return make_uniq>(std::move(result_value)); - }; - return make_uniq(transformer, parse_result, std::move(finalize)); - }); - } - - PEGTransformerFactory(const PEGTransformerFactory &) = delete; - - static unique_ptr TransformStatement(PEGTransformer &, ParseResult &list); - static const case_insensitive_map_t &GeneratedTransformFrameOps(); - - // common.gram - static unique_ptr TransformNumberLiteral(PEGTransformer &transformer, ParseResult &parse_result); - static string TransformStringLiteral(PEGTransformer &transformer, ParseResult &parse_result); - static DatePartSpecifier TransformIntervalToIntervalAsType(PEGTransformer &transformer, ParseResult &parse_result); - - static string ExtractFormat(const string &file_path); - - // create_table.gram - static string TransformIdentifier(PEGTransformer &transformer, ParseResult &parse_result); - - // expression.gram - static unique_ptr TransformExpression(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformPrefixExpression(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOverClause(PEGTransformer &transformer, ParseResult &parse_result); - - // pivot.gram - static unique_ptr TransformPivotStatement(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformUnpivotStatement(PEGTransformer &transformer, - ParseResult &parse_result); - - // select.gram - static unique_ptr TransformSelectStatementInternalRule(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSimpleSelect(PEGTransformer &transformer, ParseResult &parse_result); - - static unique_ptr TransformTableRef(PEGTransformer &transformer, ParseResult &parse_result); - - static CommonTableExpressionMap TransformWithClause(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformWindowDefinition(PEGTransformer &transformer, - ParseResult &parse_result); - static string TransformIdentifierOrKeyword(PEGTransformer &transformer, ParseResult &parse_result); - - //===--------------------------------------------------------------------===// - // START GENERATED RULES - //===--------------------------------------------------------------------===// - static unique_ptr TransformAlterStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterStatement(PEGTransformer &transformer, unique_ptr alter_options); - static unique_ptr TransformAlterOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAlterTableStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterTableStmt(PEGTransformer &transformer, const optional &if_exists, unique_ptr base_table_name, vector> alter_table_options); - static unique_ptr TransformAlterSchemaStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterSchemaStmt(PEGTransformer &transformer, const optional &if_exists, const QualifiedName &qualified_name, unique_ptr rename_alter); - static unique_ptr TransformAlterTableOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAddConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAddConstraint(PEGTransformer &transformer, unique_ptr top_level_constraint); - static unique_ptr TransformDropConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropConstraint(PEGTransformer &transformer, const optional &if_exists, const Identifier &identifier, const optional &drop_behavior); - static unique_ptr TransformAddColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAddColumn(PEGTransformer &transformer, const bool &has_result, const optional &if_not_exists, AddColumnEntry add_column_entry); - static unique_ptr TransformAddColumnEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static AddColumnEntry TransformAddColumnEntry(PEGTransformer &transformer, const vector &dotted_identifier, const optional &type, optional generated_column, optional> column_constraint); - static unique_ptr TransformDropColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropColumn(PEGTransformer &transformer, const bool &has_result, const optional &if_exists, unique_ptr nested_column_name, const optional &drop_behavior); - static unique_ptr TransformAlterColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterColumn(PEGTransformer &transformer, const bool &has_result, unique_ptr nested_column_name, unique_ptr alter_column_entry); - static unique_ptr TransformRenameColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRenameColumn(PEGTransformer &transformer, const bool &has_result, unique_ptr nested_column_name, const Identifier &identifier); - static unique_ptr TransformNestedColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNestedColumnName(PEGTransformer &transformer, const optional> &identifier_dot, const Identifier &column_name); - static unique_ptr TransformIdentifierDotInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformIdentifierDot(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformRenameAlterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRenameAlter(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformSetPartitionedByInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetPartitionedBy(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformResetPartitionedByInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformResetPartitionedBy(PEGTransformer &transformer); - static unique_ptr TransformSetSortedByInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetSortedBy(PEGTransformer &transformer, vector order_by_expressions); - static unique_ptr TransformResetSortedByInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformResetSortedBy(PEGTransformer &transformer); - static unique_ptr TransformSetOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetOptions(PEGTransformer &transformer, case_insensitive_map_t> rel_option_list); - static unique_ptr TransformResetOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformResetOptions(PEGTransformer &transformer, case_insensitive_map_t> rel_option_list); - static unique_ptr TransformAlterColumnEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAddOrDropDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAddDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAddDefault(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformDropDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropDefault(PEGTransformer &transformer); - static unique_ptr TransformChangeNullabilityInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformChangeNullability(PEGTransformer &transformer, const string &drop_or_set); - static unique_ptr TransformDropOrSetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDropNullabilityInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformDropNullability(PEGTransformer &transformer); - static unique_ptr TransformSetNullabilityInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformSetNullability(PEGTransformer &transformer); - static unique_ptr TransformAlterTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterType(PEGTransformer &transformer, const bool &has_result, const optional &type, optional> using_expression); - static unique_ptr TransformUsingExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUsingExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformAlterViewStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterViewStmt(PEGTransformer &transformer, const optional &if_exists, unique_ptr base_table_name, unique_ptr rename_alter); - static unique_ptr TransformAlterSequenceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterSequenceStmt(PEGTransformer &transformer, const optional &if_exists, const QualifiedName &qualified_sequence_name, unique_ptr alter_sequence_options); - static unique_ptr TransformQualifiedSequenceNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformQualifiedSequenceName(PEGTransformer &transformer, const optional &catalog_qualification, const optional &schema_qualification, const Identifier &sequence_name); - static unique_ptr TransformAlterSequenceOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformRenameAlterSequenceOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRenameAlterSequenceOptions(PEGTransformer &transformer, unique_ptr rename_alter); - static unique_ptr TransformSetSequenceOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetSequenceOption(PEGTransformer &transformer, vector>> sequence_option); - static unique_ptr TransformAlterDatabaseStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAlterDatabaseStmt(PEGTransformer &transformer, const optional &if_exists, const Identifier &identifier, const Identifier &identifier_1); - static unique_ptr TransformAnalyzeStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAnalyzeStatement(PEGTransformer &transformer, const Identifier &analyze_keyword, const optional &analyze_verbose, optional analyze_target); - static unique_ptr TransformAnalyzeTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static AnalyzeTarget TransformAnalyzeTarget(PEGTransformer &transformer, unique_ptr base_table_name, const optional> &name_list); - static unique_ptr TransformAnalyzeVerboseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformAnalyzeVerbose(PEGTransformer &transformer); - static unique_ptr TransformAttachStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAttachStatement(PEGTransformer &transformer, const optional &or_replace, const optional &if_not_exists, const bool &has_result, unique_ptr database_path, const optional &attach_alias, const optional> &attach_options); - static unique_ptr TransformDatabasePathInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDatabasePath(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformAttachAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformAttachAlias(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformAttachOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformAttachOptions(PEGTransformer &transformer, const vector &generic_copy_option_list); - static unique_ptr TransformCallStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCallStatement(PEGTransformer &transformer, const QualifiedName &qualified_table_function, vector table_function_arguments); - static unique_ptr TransformCheckpointStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCheckpointStatement(PEGTransformer &transformer, const optional &checkpoint_force, const optional &catalog_name); - static unique_ptr TransformCheckpointForceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCheckpointForce(PEGTransformer &transformer); - static unique_ptr TransformCommentStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCommentStatement(PEGTransformer &transformer, const CatalogType &comment_on_type, - const vector &dotted_identifier, + const vector &comment_target, const Value &comment_value); - static unique_ptr TransformCommentOnTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCommentTableInternal(PEGTransformer &transformer, - ParseResult &parse_result); + static vector TransformCommentStringLiteralIdentifier(PEGTransformer &transformer, + const Identifier &string_literal_identifier); static CatalogType TransformCommentTable(PEGTransformer &transformer); - static unique_ptr TransformCommentSequenceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentSequence(PEGTransformer &transformer); - static unique_ptr TransformCommentFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentFunction(PEGTransformer &transformer); - static unique_ptr TransformCommentMacroTableInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentMacroTable(PEGTransformer &transformer); - static unique_ptr TransformCommentMacroInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentMacro(PEGTransformer &transformer); - static unique_ptr TransformCommentViewInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentView(PEGTransformer &transformer); - static unique_ptr TransformCommentDatabaseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentDatabase(PEGTransformer &transformer); - static unique_ptr TransformCommentIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentIndex(PEGTransformer &transformer); - static unique_ptr TransformCommentSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentSchema(PEGTransformer &transformer); - static unique_ptr TransformCommentTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentType(PEGTransformer &transformer); - static unique_ptr TransformCommentColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformCommentColumn(PEGTransformer &transformer); - static unique_ptr TransformCommentValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformStringLiteralValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Value TransformStringLiteralValue(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformAnalyzeKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformAnalyzeKeyword(PEGTransformer &transformer); - static unique_ptr TransformExpressionStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExpressionStatement(PEGTransformer &transformer, vector> expression_alias); - static unique_ptr TransformExpressionAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformConstraintNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformConstraintName(PEGTransformer &transformer, const Identifier &col_id_or_string); - static unique_ptr TransformCollationNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformCollationName(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); + static unique_ptr TransformNumberLiteral(PEGTransformer &transformer, ParseResult &parse_result); + static string TransformStringLiteral(PEGTransformer &transformer, ParseResult &parse_result); static LogicalType TransformType(PEGTransformer &transformer, unique_ptr type_variations, const optional> &array_bounds); - static unique_ptr TransformTypeVariationsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSimpleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCharacterSimpleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCharacterSimpleType(PEGTransformer &transformer, optional>> type_modifiers); - static unique_ptr TransformQualifiedSimpleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformQualifiedSimpleType(PEGTransformer &transformer, const QualifiedName &qualified_type_name, optional>> type_modifiers); - static unique_ptr TransformIntervalTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntervalIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntervalWithSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntervalWithRangeSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIntervalWithRangeSpecifier(PEGTransformer &transformer, const DatePartSpecifier &interval_to_interval_as_type); - static unique_ptr TransformIntervalWithSimpleSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIntervalWithSimpleSpecifier(PEGTransformer &transformer, const DatePartSpecifier &interval); - static unique_ptr TransformIntervalWithoutSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIntervalWithoutSpecifier(PEGTransformer &transformer); - static unique_ptr TransformYearKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); + static DatePartSpecifier TransformIntervalToIntervalAsType(PEGTransformer &transformer, ParseResult &parse_result); static DatePartSpecifier TransformYearKeyword(PEGTransformer &transformer); - static unique_ptr TransformMonthKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformMonthKeyword(PEGTransformer &transformer); - static unique_ptr TransformDayKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformDayKeyword(PEGTransformer &transformer); - static unique_ptr TransformHourKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformHourKeyword(PEGTransformer &transformer); - static unique_ptr TransformMinuteKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformMinuteKeyword(PEGTransformer &transformer); - static unique_ptr TransformSecondKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformSecondKeyword(PEGTransformer &transformer); - static unique_ptr TransformMillisecondKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformMillisecondKeyword(PEGTransformer &transformer); - static unique_ptr TransformMicrosecondKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformMicrosecondKeyword(PEGTransformer &transformer); - static unique_ptr TransformWeekKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformWeekKeyword(PEGTransformer &transformer); - static unique_ptr TransformQuarterKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformQuarterKeyword(PEGTransformer &transformer); - static unique_ptr TransformDecadeKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformDecadeKeyword(PEGTransformer &transformer); - static unique_ptr TransformCenturyKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformCenturyKeyword(PEGTransformer &transformer); - static unique_ptr TransformMillenniumKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformMillenniumKeyword(PEGTransformer &transformer); - static unique_ptr TransformIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntervalToIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformYearToMonthInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformYearToMonth(PEGTransformer &transformer, const DatePartSpecifier &year_keyword, const DatePartSpecifier &month_keyword); - static unique_ptr TransformDayToHourInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformDayToHour(PEGTransformer &transformer, const DatePartSpecifier &day_keyword, const DatePartSpecifier &hour_keyword); - static unique_ptr TransformDayToMinuteInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformDayToMinute(PEGTransformer &transformer, const DatePartSpecifier &day_keyword, const DatePartSpecifier &minute_keyword); - static unique_ptr TransformDayToSecondInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformDayToSecond(PEGTransformer &transformer, const DatePartSpecifier &day_keyword, const DatePartSpecifier &second_keyword); - static unique_ptr TransformHourToMinuteInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformHourToMinute(PEGTransformer &transformer, const DatePartSpecifier &hour_keyword, const DatePartSpecifier &minute_keyword); - static unique_ptr TransformHourToSecondInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformHourToSecond(PEGTransformer &transformer, const DatePartSpecifier &hour_keyword, const DatePartSpecifier &second_keyword); - static unique_ptr TransformMinuteToSecondInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DatePartSpecifier TransformMinuteToSecond(PEGTransformer &transformer, const DatePartSpecifier &minute_keyword, const DatePartSpecifier &second_keyword); - static unique_ptr TransformBitTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBitType(PEGTransformer &transformer, const bool &has_result, optional>> expression); - static unique_ptr TransformGeometryTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformGeometryType(PEGTransformer &transformer, optional> expression); - static unique_ptr TransformVariantTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformVariantType(PEGTransformer &transformer); - static unique_ptr TransformNumericTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSimpleNumericTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSimpleNumericType(PEGTransformer &transformer, const string &child); - static unique_ptr TransformDecimalNumericTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformIntType(PEGTransformer &transformer); - static unique_ptr TransformIntegerTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformIntegerType(PEGTransformer &transformer); - static unique_ptr TransformSmallintTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformSmallintType(PEGTransformer &transformer); - static unique_ptr TransformBigintTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformBigintType(PEGTransformer &transformer); - static unique_ptr TransformRealTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRealType(PEGTransformer &transformer); - static unique_ptr TransformBooleanTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformBooleanType(PEGTransformer &transformer); - static unique_ptr TransformDoubleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformDoubleType(PEGTransformer &transformer); - static unique_ptr TransformFloatTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFloatType(PEGTransformer &transformer, optional> number_literal); - static unique_ptr TransformDecimalTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDecimalType(PEGTransformer &transformer, optional>> type_modifiers); - static unique_ptr TransformDecTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDecType(PEGTransformer &transformer, optional>> type_modifiers); - static unique_ptr TransformNumericModTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNumericModType(PEGTransformer &transformer, optional>> type_modifiers); - static unique_ptr TransformQualifiedTypeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTypeNameAsQualifiedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformTypeNameAsQualifiedName(PEGTransformer &transformer, const Identifier &type_name); - static unique_ptr TransformCatalogReservedSchemaTypeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformCatalogReservedSchemaTypeName(PEGTransformer &transformer, const Identifier &catalog_qualification, const vector &reserved_schema_qualification, const Identifier &reserved_type_name); - static unique_ptr TransformSchemaReservedTypeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformSchemaReservedTypeName(PEGTransformer &transformer, const Identifier &schema_qualification, const Identifier &reserved_type_name); - static unique_ptr TransformTypeModifiersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformTypeModifiers(PEGTransformer &transformer, optional>> expression); - static unique_ptr TransformRowTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRowType(PEGTransformer &transformer, const optional> &col_id_type_list); - static unique_ptr TransformSetofTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetofType(PEGTransformer &transformer, const LogicalType &type); - static unique_ptr TransformUnionTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUnionType(PEGTransformer &transformer, const child_list_t &col_id_type_list); - static unique_ptr TransformColIdTypeListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static child_list_t TransformColIdTypeList(PEGTransformer &transformer, const vector> &col_id_type); - static unique_ptr TransformMapTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMapType(PEGTransformer &transformer, const optional> &type); - static unique_ptr TransformTupleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTupleType(PEGTransformer &transformer, const vector &type); - static unique_ptr TransformColIdTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair TransformColIdType(PEGTransformer &transformer, const Identifier &col_id, const LogicalType &type); - static unique_ptr TransformArrayBoundsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformArrayKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static int64_t TransformArrayKeyword(PEGTransformer &transformer); - static unique_ptr TransformArrayKeywordWithBoundsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static int64_t TransformArrayKeywordWithBounds(PEGTransformer &transformer, const int64_t &square_brackets_array); - static unique_ptr TransformSquareBracketsArrayInternal(PEGTransformer &transformer, - ParseResult &parse_result); static int64_t TransformSquareBracketsArray(PEGTransformer &transformer, optional> expression); - static unique_ptr TransformTimeTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTimeType(PEGTransformer &transformer, const LogicalTypeId &time_or_timestamp, optional>> type_modifiers, const optional &time_zone); - static unique_ptr TransformTimeOrTimestampInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTimeTypeIdInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LogicalTypeId TransformTimeTypeId(PEGTransformer &transformer); - static unique_ptr TransformTimestampTypeIdInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LogicalTypeId TransformTimestampTypeId(PEGTransformer &transformer); - static unique_ptr TransformTimeZoneInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformTimeZone(PEGTransformer &transformer, const bool &with_or_without); - static unique_ptr TransformWithOrWithoutInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformWithRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithRule(PEGTransformer &transformer); - static unique_ptr TransformWithoutRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithoutRule(PEGTransformer &transformer); - static unique_ptr TransformConnectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformConnectStatement(PEGTransformer &transformer, optional> session_target); - static unique_ptr TransformDisconnectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDisconnectStatement(PEGTransformer &transformer); - static unique_ptr TransformSessionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLocalSessionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLocalSessionTarget(PEGTransformer &transformer); - static unique_ptr TransformStringSessionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformStringSessionTarget(PEGTransformer &transformer, const string &string_literal, const optional> &generic_copy_option_list); - static unique_ptr TransformCatalogSessionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCatalogSessionTarget(PEGTransformer &transformer, const Identifier &catalog_name); - static unique_ptr TransformCopyStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyStatement(PEGTransformer &transformer, unique_ptr copy_variations); - static unique_ptr TransformCopyVariationsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCopyTableInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyTable(PEGTransformer &transformer, unique_ptr base_table_name, const optional> &insert_column_list, const bool &from_or_to, unique_ptr copy_file_name, const optional> ©_options); - static unique_ptr TransformFromOrToInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCopyFromInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCopyFrom(PEGTransformer &transformer); - static unique_ptr TransformCopyToInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCopyTo(PEGTransformer &transformer); - static unique_ptr TransformCopySelectInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopySelect(PEGTransformer &transformer, unique_ptr select_statement_internal, unique_ptr copy_file_name, const optional> ©_options); - static unique_ptr TransformCopyFileNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCopyFileNameExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCopyFileNameStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyFileNameStringLiteral(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformCopyFileNameIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyFileNameIdentifier(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformCopyFileNameIdentifierColIdInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyFileNameIdentifierColId(PEGTransformer &transformer, const Identifier &identifier_col_id); - static unique_ptr TransformIdentifierColIdInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformIdentifierColId(PEGTransformer &transformer, const Identifier &identifier, - const Identifier &col_id); - static unique_ptr TransformCopyOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); + const vector ©_file_name_suffix); static vector TransformCopyOptions(PEGTransformer &transformer, const bool &has_result, const vector ©_option_list); - static unique_ptr TransformCopyOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSpecializedOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformSpecializedOptionList(PEGTransformer &transformer, const GenericCopyOption &specialized_option, const optional> &specialized_option_tail); - static unique_ptr TransformSpecializedOptionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformSpecializedOptionTail(PEGTransformer &transformer, const bool &has_result, const GenericCopyOption &specialized_option); - static unique_ptr TransformSpecializedOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSingleOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformBinaryOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformBinaryOption(PEGTransformer &transformer); - static unique_ptr TransformFreezeOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformFreezeOption(PEGTransformer &transformer); - static unique_ptr TransformOidsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformOidsOption(PEGTransformer &transformer); - static unique_ptr TransformCsvOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformCsvOption(PEGTransformer &transformer); - static unique_ptr TransformHeaderOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformHeaderOption(PEGTransformer &transformer); - static unique_ptr TransformNullAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformNullAsOption(PEGTransformer &transformer, const bool &has_result, const string &string_literal); - static unique_ptr TransformDelimiterAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformDelimiterAsOption(PEGTransformer &transformer, const bool &has_result, const string &string_literal); - static unique_ptr TransformQuoteAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformQuoteAsOption(PEGTransformer &transformer, const bool &has_result, const string &string_literal); - static unique_ptr TransformEscapeAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformEscapeAsOption(PEGTransformer &transformer, const bool &has_result, const string &string_literal); - static unique_ptr TransformEncodingOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformEncodingOption(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformForceQuoteOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformForceQuoteOption(PEGTransformer &transformer, const optional &force_quote, const vector &star_symbol_column_list); - static unique_ptr TransformStarSymbolColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformForceQuoteInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformForceQuote(PEGTransformer &transformer); - static unique_ptr TransformPartitionByOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformPartitionByOption(PEGTransformer &transformer, const vector &partition_by_column_list); - static unique_ptr TransformPartitionByColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformStarPartitionByColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformStarPartitionByColumnList(PEGTransformer &transformer); - static unique_ptr - TransformParenthesizedPartitionByColumnListInternal(PEGTransformer &transformer, ParseResult &parse_result); static vector TransformParenthesizedPartitionByColumnList(PEGTransformer &transformer, const vector &column_list); - static unique_ptr TransformSinglePartitionByColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformSinglePartitionByColumnList(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformForceNullOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformForceNullOption(PEGTransformer &transformer, const optional &force_not_null, const vector &column_list); - static unique_ptr TransformForceNotNullInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformForceNotNull(PEGTransformer &transformer); - static unique_ptr TransformCopyGenericOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformCopyGenericOptionList(PEGTransformer &transformer, const vector ©_generic_option); - static unique_ptr TransformCopyGenericOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOrderByCopyOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformOrderByCopyOption(PEGTransformer &transformer, optional generic_copy_option_value); - static unique_ptr TransformPartitionedByCopyOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformPartitionedByCopyOption(PEGTransformer &transformer, optional generic_copy_option_value); - static unique_ptr TransformGenericCopyOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformGenericCopyOptionList(PEGTransformer &transformer, const vector &generic_copy_option); - static unique_ptr TransformGenericCopyOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformGenericCopyOption(PEGTransformer &transformer, const Identifier ©_option_name, optional generic_copy_option_value); - static unique_ptr TransformGenericCopyOptionValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformGenericCopyOptionOrderListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOptionValue TransformGenericCopyOptionOrderList(PEGTransformer &transformer, vector generic_copy_option_parenthesized_expression_list); - static unique_ptr TransformGenericCopyOptionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOptionValue TransformGenericCopyOptionExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr - TransformGenericCopyOptionParenthesizedExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformGenericCopyOptionParenthesizedExpressionList(PEGTransformer &transformer, vector order_by_expression_list); - static unique_ptr TransformCopyFromDatabaseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCopyFromDatabaseWithFlagInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyFromDatabaseWithFlag(PEGTransformer &transformer, const Identifier &col_id, const Identifier &col_id_1, const CopyDatabaseType ©_database_flag); - static unique_ptr TransformCopyFromDatabaseWithoutFlagInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCopyFromDatabaseWithoutFlag(PEGTransformer &transformer, const Identifier &col_id, const Identifier &col_id_1); - static unique_ptr TransformCopyDatabaseFlagInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CopyDatabaseType TransformCopyDatabaseFlag(PEGTransformer &transformer, const CopyDatabaseType &schema_or_data); - static unique_ptr TransformSchemaOrDataInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCopySchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CopyDatabaseType TransformCopySchema(PEGTransformer &transformer); - static unique_ptr TransformCopyDataInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CopyDatabaseType TransformCopyData(PEGTransformer &transformer); - static unique_ptr TransformCreateIndexStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateIndexStmt(PEGTransformer &transformer, const optional &unique_index, const optional &if_not_exists, const optional &index_name, @@ -4827,1826 +4373,841 @@ class PEGTransformerFactory { optional>> index_element, optional>> with_list, optional> where_clause); - static unique_ptr TransformWithListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static case_insensitive_map_t> TransformWithList(PEGTransformer &transformer, case_insensitive_map_t> rel_option_or_oids); - static unique_ptr TransformRelOptionOrOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformRelOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static case_insensitive_map_t> TransformRelOptionList(PEGTransformer &transformer, vector>> rel_option); - static unique_ptr TransformOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static case_insensitive_map_t> TransformOids(PEGTransformer &transformer, const bool &with_or_without_oids); - static unique_ptr TransformWithOrWithoutOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformWithOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithOids(PEGTransformer &transformer); - static unique_ptr TransformWithoutOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithoutOids(PEGTransformer &transformer); - static unique_ptr TransformIndexElementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIndexElement(PEGTransformer &transformer, unique_ptr expression, const optional &desc_or_asc, const optional &nulls_first_or_last); - static unique_ptr TransformUniqueIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformUniqueIndex(PEGTransformer &transformer); - static unique_ptr TransformIndexTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformIndexType(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformRelOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformRelOption(PEGTransformer &transformer, const Identifier &rel_option_name, optional> rel_option_argument_opt); - static unique_ptr TransformRelOptionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformRelOptionName(PEGTransformer &transformer, const string &child); - static unique_ptr TransformDottedIdentifierStringInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformDottedIdentifierString(PEGTransformer &transformer, const vector &dotted_identifier); - static unique_ptr TransformRelOptionArgumentOptInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRelOptionArgumentOpt(PEGTransformer &transformer, unique_ptr def_arg); - static unique_ptr TransformDefArgInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDefArgNullInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDefArgNull(PEGTransformer &transformer, const Value &null_literal); - static unique_ptr TransformDefArgKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDefArgKeyword(PEGTransformer &transformer, const string &reserved_keyword); - static unique_ptr TransformDefArgStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDefArgStringLiteral(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformNoneLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNoneLiteral(PEGTransformer &transformer); - static unique_ptr TransformCreateMacroStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateMacroStmt(PEGTransformer &transformer, const bool ¯o_or_function, const optional &if_not_exists, const QualifiedName &qualified_name, vector> macro_definition); - static unique_ptr TransformMacroOrFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMacroKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformMacroKeyword(PEGTransformer &transformer); - static unique_ptr TransformFunctionKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformFunctionKeyword(PEGTransformer &transformer); - static unique_ptr TransformMacroDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMacroDefinition(PEGTransformer &transformer, optional> macro_parameters, unique_ptr macro_definition_body); - static unique_ptr TransformMacroDefinitionBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMacroParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformMacroParameters(PEGTransformer &transformer, vector macro_parameter); - static unique_ptr TransformMacroParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSimpleParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MacroParameter TransformSimpleParameter(PEGTransformer &transformer, const Identifier &type_func_name, const optional &type); - static unique_ptr TransformScalarMacroDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformScalarMacroDefinition(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformTableMacroDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableMacroDefinition(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformCreateSchemaStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateSchemaStmt(PEGTransformer &transformer, const optional &if_not_exists, const QualifiedName &qualified_name); - static unique_ptr TransformCreateSecretStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateSecretStmt(PEGTransformer &transformer, const optional &if_not_exists, const optional &secret_name, const optional &secret_storage_specifier, const vector &generic_copy_option_list); - static unique_ptr TransformSecretStorageSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformSecretStorageSpecifier(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformSecretNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformSecretName(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformCreateSequenceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateSequenceStmt(PEGTransformer &transformer, const optional &if_not_exists, const QualifiedName &qualified_name, optional>>> sequence_option); - static unique_ptr TransformSequenceOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSeqSetCycleInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSeqCycleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqCycle(PEGTransformer &transformer); - static unique_ptr TransformSeqNoCycleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqNoCycle(PEGTransformer &transformer); - static unique_ptr TransformSeqSetIncrementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqSetIncrement(PEGTransformer &transformer, const bool &has_result, unique_ptr expression); - static unique_ptr TransformSeqSetMinMaxInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqSetMinMax(PEGTransformer &transformer, const string &seq_min_or_max, unique_ptr expression); - static unique_ptr TransformSeqNoMinMaxInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqNoMinMax(PEGTransformer &transformer, const string &seq_min_or_max); - static unique_ptr TransformSeqStartWithInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqStartWith(PEGTransformer &transformer, const bool &has_result, unique_ptr expression); - static unique_ptr TransformSeqOwnedByInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformSeqOwnedBy(PEGTransformer &transformer, const QualifiedName &qualified_name); - static unique_ptr TransformSeqMinOrMaxInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMinValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformMinValue(PEGTransformer &transformer); - static unique_ptr TransformMaxValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformMaxValue(PEGTransformer &transformer); - static unique_ptr TransformCreateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateStatement(PEGTransformer &transformer, const optional &or_replace, const optional &temporary, unique_ptr create_statement_variation); - static unique_ptr TransformCreateStatementVariationInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOrReplaceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformOrReplace(PEGTransformer &transformer); - static unique_ptr TransformTemporaryInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPersistentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SecretPersistType TransformPersistent(PEGTransformer &transformer); - static unique_ptr TransformTempPersistentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SecretPersistType TransformTempPersistent(PEGTransformer &transformer); - static unique_ptr TransformTemporaryPersistentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SecretPersistType TransformTemporaryPersistent(PEGTransformer &transformer); - static unique_ptr TransformCreateTableStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateTableStmt(PEGTransformer &transformer, const optional &if_not_exists, const QualifiedName &qualified_name, CreateTableDefinition create_table_definition, const optional &commit_action); - static unique_ptr TransformCreateTableDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCreateTableAsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CreateTableDefinition TransformCreateTableAs(PEGTransformer &transformer, optional identifier_list, optional partition_sorted_options, optional>> with_list, unique_ptr statement, const optional &with_data); - static unique_ptr TransformPartitionSortedOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPartitionOptSortedOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PartitionSortedOptions TransformPartitionOptSortedOptions(PEGTransformer &transformer, vector> partition_options, optional>> sorted_options); - static unique_ptr TransformSortedOptPartitionOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PartitionSortedOptions TransformSortedOptPartitionOptions(PEGTransformer &transformer, vector> sorted_options, optional>> partition_options); - static unique_ptr TransformPartitionOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformPartitionOptions(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformSortedOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSortedOptions(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformWithDataInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformWithDataOnlyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithDataOnly(PEGTransformer &transformer); - static unique_ptr TransformWithNoDataInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithNoData(PEGTransformer &transformer); - static unique_ptr TransformIdentifierListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnList TransformIdentifierList(PEGTransformer &transformer, const vector &identifier); - static unique_ptr TransformCreateColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CreateTableDefinition TransformCreateColumnList(PEGTransformer &transformer, optional create_table_column_list, optional partition_sorted_options, optional>> with_list); - static unique_ptr TransformIfNotExistsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformIfNotExists(PEGTransformer &transformer); - static unique_ptr TransformQualifiedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr - TransformSchemaReservedIdentifierOrStringLiteralInternal(PEGTransformer &transformer, ParseResult &parse_result); static QualifiedName TransformSchemaReservedIdentifierOrStringLiteral(PEGTransformer &transformer, const Identifier &schema_qualification, const Identifier &reserved_identifier_or_string_literal); - static unique_ptr - TransformCatalogReservedSchemaIdentifierInternal(PEGTransformer &transformer, ParseResult &parse_result); static QualifiedName TransformCatalogReservedSchemaIdentifier(PEGTransformer &transformer, const Identifier &catalog_qualification, const vector &reserved_schema_qualification, const Identifier &reserved_identifier_or_string_literal); - static unique_ptr TransformIdentifierOrStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformIdentifierOrStringLiteral(PEGTransformer &transformer, const string &child); - static unique_ptr - TransformReservedIdentifierOrStringLiteralInternal(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformCatalogQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformCatalogQualification(PEGTransformer &transformer, const Identifier &catalog_name); - static unique_ptr TransformSchemaQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformSchemaQualification(PEGTransformer &transformer, const Identifier &schema_name); - static unique_ptr TransformReservedSchemaQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformReservedSchemaQualification(PEGTransformer &transformer, const Identifier &reserved_schema_name); - static unique_ptr TransformTableQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformTableQualification(PEGTransformer &transformer, const Identifier &table_name); - static unique_ptr TransformReservedTableQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformReservedTableQualification(PEGTransformer &transformer, const Identifier &reserved_table_name); - static unique_ptr TransformCreateTableColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnElements TransformCreateTableColumnList(PEGTransformer &transformer, vector create_table_column_element); - static unique_ptr TransformCreateTableColumnElementInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCreateTableColumnDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CreateTableColumnElement TransformCreateTableColumnDefinition(PEGTransformer &transformer, ConstraintColumnDefinition column_definition); - static unique_ptr TransformCreateTableConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CreateTableColumnElement TransformCreateTableConstraint(PEGTransformer &transformer, unique_ptr top_level_constraint); - static unique_ptr TransformColumnDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ConstraintColumnDefinition TransformColumnDefinition(PEGTransformer &transformer, const vector &dotted_identifier, const optional &type, optional generated_column, const bool &has_result, optional> column_constraint); - static unique_ptr TransformColumnConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNotNullConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformNotNullConstraint(PEGTransformer &transformer, const bool &child); - static unique_ptr TransformNullConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformNullConstraint(PEGTransformer &transformer); - static unique_ptr TransformNotNullColumnConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformNotNullColumnConstraint(PEGTransformer &transformer); - static unique_ptr TransformUniqueConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformUniqueConstraint(PEGTransformer &transformer); - static unique_ptr TransformPrimaryKeyConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformPrimaryKeyConstraint(PEGTransformer &transformer); - static unique_ptr TransformDefaultValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformDefaultValue(PEGTransformer &transformer, unique_ptr column_default_expr); - static unique_ptr TransformCheckConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformCheckConstraint(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformForeignKeyConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformForeignKeyConstraint(PEGTransformer &transformer, unique_ptr base_table_name, const optional> &column_list, const KeyActions &key_actions); - static unique_ptr TransformColumnCollationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformColumnCollation(PEGTransformer &transformer, const vector &dotted_identifier); - static unique_ptr TransformColumnCompressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ColumnConstraintEntry TransformColumnCompression(PEGTransformer &transformer, const Identifier &col_id_or_string); - static unique_ptr TransformKeyActionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static KeyActions TransformKeyActions(PEGTransformer &transformer, const optional &update_action, const optional &delete_action); - static unique_ptr TransformUpdateActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformUpdateAction(PEGTransformer &transformer, const string &key_action); - static unique_ptr TransformDeleteActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformDeleteAction(PEGTransformer &transformer, const string &key_action); - static unique_ptr TransformKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNoKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformNoKeyAction(PEGTransformer &transformer); - static unique_ptr TransformRestrictKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRestrictKeyAction(PEGTransformer &transformer); - static unique_ptr TransformCascadeKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformCascadeKeyAction(PEGTransformer &transformer); - static unique_ptr TransformSetNullKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformSetNullKeyAction(PEGTransformer &transformer); - static unique_ptr TransformSetDefaultKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformSetDefaultKeyAction(PEGTransformer &transformer); - static unique_ptr TransformTopLevelConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTopLevelConstraint(PEGTransformer &transformer, const bool &has_result, unique_ptr top_level_constraint_list); - static unique_ptr TransformTopLevelConstraintListInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTopCheckConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTopCheckConstraint(PEGTransformer &transformer, ColumnConstraintEntry check_constraint); - static unique_ptr TransformTopPrimaryKeyConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTopPrimaryKeyConstraint(PEGTransformer &transformer, const vector &column_id_list); - static unique_ptr TransformTopUniqueConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTopUniqueConstraint(PEGTransformer &transformer, const vector &column_id_list); - static unique_ptr TransformTopForeignKeyConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTopForeignKeyConstraint(PEGTransformer &transformer, const vector &column_id_list, ColumnConstraintEntry foreign_key_constraint); - static unique_ptr TransformColumnIdListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformColumnIdList(PEGTransformer &transformer, const vector &col_id); - static unique_ptr TransformDottedIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformDottedIdentifier(PEGTransformer &transformer, const Identifier &identifier, const optional> &dot_col_label); - static unique_ptr TransformDotColLabelInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformDotColLabel(PEGTransformer &transformer, const string &col_label); - static unique_ptr TransformColIdInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformColIdOrStringInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTypeFuncNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTypeFuncKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformColLabelInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformColLabelOrStringInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformColLabelIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformColLabelIdentifier(PEGTransformer &transformer, const string &col_label); - static unique_ptr TransformStringLiteralIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformStringLiteralIdentifier(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformGeneratedColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GeneratedColumnDefinition TransformGeneratedColumn(PEGTransformer &transformer, const bool &has_result, unique_ptr expression, const optional &generated_column_type); - static unique_ptr TransformGeneratedColumnTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCommitActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCommitAction(PEGTransformer &transformer, const bool &preserve_or_delete); - static unique_ptr TransformPreserveOrDeleteInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPreserveRowsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformPreserveRows(PEGTransformer &transformer); - static unique_ptr TransformDeleteRowsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformDeleteRows(PEGTransformer &transformer); - static unique_ptr TransformVirtualGeneratedColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformVirtualGeneratedColumn(PEGTransformer &transformer); - static unique_ptr TransformStoredGeneratedColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformStoredGeneratedColumn(PEGTransformer &transformer); - static unique_ptr TransformCreateTriggerStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateTriggerStmt(PEGTransformer &transformer, const optional &if_not_exists, const Identifier &trigger_name, const TriggerTiming &trigger_timing, const TriggerEventInfo &trigger_event, unique_ptr base_table_name, const optional &referencing_clause, const optional &for_each_clause, unique_ptr trigger_body); - static unique_ptr TransformTriggerBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTriggerNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformTriggerName(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformReferencingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerTableReferencingInfo TransformReferencingClause(PEGTransformer &transformer, const TriggerTableReferencingInfo &referencing_item, const optional &referencing_item_1); - static unique_ptr TransformReferencingItemInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformReferencingNewTableAsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerTableReferencingInfo TransformReferencingNewTableAs(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformReferencingOldTableAsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerTableReferencingInfo TransformReferencingOldTableAs(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformTriggerTimingInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTriggerBeforeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerTiming TransformTriggerBefore(PEGTransformer &transformer); - static unique_ptr TransformTriggerAfterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerTiming TransformTriggerAfter(PEGTransformer &transformer); - static unique_ptr TransformTriggerInsteadOfInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerTiming TransformTriggerInsteadOf(PEGTransformer &transformer); - static unique_ptr TransformTriggerEventInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTriggerEventInsertInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerEventInfo TransformTriggerEventInsert(PEGTransformer &transformer); - static unique_ptr TransformTriggerEventDeleteInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerEventInfo TransformTriggerEventDelete(PEGTransformer &transformer); - static unique_ptr TransformTriggerEventUpdateInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerEventInfo TransformTriggerEventUpdate(PEGTransformer &transformer); - static unique_ptr TransformTriggerEventUpdateOfInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerEventInfo TransformTriggerEventUpdateOf(PEGTransformer &transformer, const vector &trigger_column_list); - static unique_ptr TransformTriggerColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformTriggerColumnList(PEGTransformer &transformer, const vector &col_id); - static unique_ptr TransformForEachClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformForEachRowInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerForEach TransformForEachRow(PEGTransformer &transformer); - static unique_ptr TransformForEachStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TriggerForEach TransformForEachStatement(PEGTransformer &transformer); - static unique_ptr TransformCreateTypeStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateTypeStmt(PEGTransformer &transformer, const optional &if_not_exists, const QualifiedName &qualified_name, unique_ptr create_type); - static unique_ptr TransformCreateTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCreateTypeFromTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateTypeFromType(PEGTransformer &transformer, const LogicalType &type); - static unique_ptr TransformEnumSelectTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformEnumSelectType(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformEnumStringLiteralListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformEnumStringLiteralList(PEGTransformer &transformer, const optional> &string_literal); - static unique_ptr TransformCreateViewStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateViewStmt(PEGTransformer &transformer, const optional &create_secure, const optional &create_recursive, const optional &if_not_exists, const QualifiedName &qualified_name, const optional> &insert_column_list, optional>> with_list, unique_ptr select_statement_internal); - static unique_ptr TransformCreateRecursiveInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCreateRecursive(PEGTransformer &transformer); - static unique_ptr TransformCreateSecureInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCreateSecure(PEGTransformer &transformer); - static unique_ptr TransformDeallocateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDeallocateStatement(PEGTransformer &transformer, const optional &deallocate_prepare, const Identifier &identifier); - static unique_ptr TransformDeallocatePrepareInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformDeallocatePrepare(PEGTransformer &transformer); - static unique_ptr TransformDeleteStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDeleteStatement(PEGTransformer &transformer, optional with_clause, unique_ptr target_opt_alias, optional>> delete_using_clause, optional> where_clause, optional>> returning_clause); - static unique_ptr TransformTruncateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTruncateStatement(PEGTransformer &transformer, const bool &has_result, unique_ptr base_table_name); - static unique_ptr TransformTargetOptAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTargetOptAlias(PEGTransformer &transformer, unique_ptr base_table_name, const bool &has_result, const optional &col_id); - static unique_ptr TransformDeleteUsingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformDeleteUsingClause(PEGTransformer &transformer, vector> table_ref); - static unique_ptr TransformDescribeStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDescribeStatement(PEGTransformer &transformer, unique_ptr child); - static unique_ptr TransformShowDeprecatedSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformShowDeprecatedSelect(PEGTransformer &transformer, const ShowType &show_rule, unique_ptr select_statement_internal); - static unique_ptr TransformDescribeSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDescribeSelect(PEGTransformer &transformer, const ShowType &describe_or_summarize, unique_ptr select_statement_internal); - static unique_ptr TransformShowAllTablesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformShowAllTables(PEGTransformer &transformer, const ShowType &show_or_describe, const bool &has_result); - static unique_ptr TransformShowTablesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformShowTables(PEGTransformer &transformer, const ShowType &show_or_describe, const QualifiedName &qualified_name); - static unique_ptr TransformShowByNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformShowByName(PEGTransformer &transformer, const ShowType &show_rule, optional show_target); - static unique_ptr TransformDescribeByNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDescribeByName(PEGTransformer &transformer, const ShowType &describe_or_summarize, optional describe_target); - static unique_ptr TransformDescribeOrSummarizeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformShowTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr - TransformShowDeprecatedQualifiedTableNameInternal(PEGTransformer &transformer, ParseResult &parse_result); static DescribeTarget TransformShowDeprecatedQualifiedTableName(PEGTransformer &transformer, unique_ptr qualified_table_name); - static unique_ptr TransformShowSettingNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DescribeTarget TransformShowSettingName(PEGTransformer &transformer, const Identifier &setting_name); - static unique_ptr TransformDescribeTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDescribeBaseTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DescribeTarget TransformDescribeBaseTableName(PEGTransformer &transformer, unique_ptr base_table_name); - static unique_ptr TransformDescribeStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DescribeTarget TransformDescribeStringLiteral(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformSummarizeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ShowType TransformSummarize(PEGTransformer &transformer, const ShowType &summarize_rule); - static unique_ptr TransformSummarizeRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ShowType TransformSummarizeRule(PEGTransformer &transformer); - static unique_ptr TransformShowOrDescribeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformShowRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ShowType TransformShowRule(PEGTransformer &transformer); - static unique_ptr TransformDescribeRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDescribeLongRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ShowType TransformDescribeLongRule(PEGTransformer &transformer); - static unique_ptr TransformDescRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ShowType TransformDescRule(PEGTransformer &transformer); - static unique_ptr TransformDetachStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDetachStatement(PEGTransformer &transformer, const bool &has_result, const optional &if_exists, const Identifier &catalog_name); - static unique_ptr TransformDropStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropStatement(PEGTransformer &transformer, unique_ptr drop_entries, const optional &drop_behavior); - static unique_ptr TransformDropEntriesInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDropTriggerInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropTrigger(PEGTransformer &transformer, const optional &if_exists, const Identifier &trigger_name, unique_ptr base_table_name); - static unique_ptr TransformDropTableInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropTable(PEGTransformer &transformer, const CatalogType &table_or_view, const optional &if_exists, vector> base_table_name); - static unique_ptr TransformDropTableFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropTableFunction(PEGTransformer &transformer, const CatalogType &comment_macro_table, const optional &if_exists, const vector &table_function_name); - static unique_ptr TransformDropFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropFunction(PEGTransformer &transformer, const bool &function_type_macro, const optional &if_exists, const vector &function_identifier); - static unique_ptr TransformDropSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropSchema(PEGTransformer &transformer, const optional &if_exists, const vector &qualified_name); - static unique_ptr TransformDropIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropIndex(PEGTransformer &transformer, const optional &if_exists, const vector &qualified_index_name); - static unique_ptr TransformQualifiedIndexNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformQualifiedIndexNameStringInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformQualifiedIndexNameString(PEGTransformer &transformer, const Identifier &index_name); - static unique_ptr TransformSchemaReservedIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformSchemaReservedIndex(PEGTransformer &transformer, const Identifier &schema_qualification, const Identifier &reserved_index_name); - static unique_ptr TransformCatalogReservedSchemaIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformCatalogReservedSchemaIndex(PEGTransformer &transformer, const Identifier &catalog_qualification, const Identifier &reserved_schema_qualification, const Identifier &reserved_index_name); - static unique_ptr TransformDropSequenceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropSequence(PEGTransformer &transformer, const optional &if_exists, const vector &qualified_sequence_name); - static unique_ptr TransformDropCollationInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropCollation(PEGTransformer &transformer, const optional &if_exists, const vector &collation_name); - static unique_ptr TransformDropTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropType(PEGTransformer &transformer, const optional &if_exists, const vector &qualified_type_name); - static unique_ptr TransformDropSecretInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropSecret(PEGTransformer &transformer, const optional &temporary, const optional &if_exists, const Identifier &secret_name, const optional &drop_secret_storage); - static unique_ptr TransformTableOrViewInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMaterializedViewEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CatalogType TransformMaterializedViewEntry(PEGTransformer &transformer); - static unique_ptr TransformFunctionTypeMacroInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformFunctionTypeMacroKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformFunctionTypeMacroKeyword(PEGTransformer &transformer); - static unique_ptr TransformFunctionTypeFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformFunctionTypeFunction(PEGTransformer &transformer); - static unique_ptr TransformDropBehaviorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCascadeDropBehaviorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCascadeDropBehavior(PEGTransformer &transformer); - static unique_ptr TransformRestrictDropBehaviorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformRestrictDropBehavior(PEGTransformer &transformer); - static unique_ptr TransformIfExistsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformIfExists(PEGTransformer &transformer); - static unique_ptr TransformDropSecretStorageInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformDropSecretStorage(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformExecuteStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExecuteStatement(PEGTransformer &transformer, const Identifier &identifier, optional> table_function_arguments); - static unique_ptr TransformExplainStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExplainStatement(PEGTransformer &transformer, const optional &analyze_keyword, const optional> &explain_option_list, unique_ptr explainable_statements); - static unique_ptr TransformExplainOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformExplainOptionList(PEGTransformer &transformer, const vector &explain_option); - static unique_ptr TransformExplainOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GenericCopyOption TransformExplainOption(PEGTransformer &transformer, const Identifier &explain_option_name, optional> expression); - static unique_ptr TransformExplainOptionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformExplainOptionName(PEGTransformer &transformer, ParseResult &choice_result); - static unique_ptr TransformExplainSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExplainSelectStatement(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformExplainableStatementsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExportStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExportStatement(PEGTransformer &transformer, const optional &export_source, const string &string_literal, const optional> &generic_copy_option_list); - static unique_ptr TransformExportSourceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformExportSource(PEGTransformer &transformer, const Identifier &catalog_name); - static unique_ptr TransformImportStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformImportStatement(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformColumnReferenceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColumnReference(PEGTransformer &transformer, unique_ptr child); - static unique_ptr TransformNestedSchemaTableColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNestedSchemaTableColumnName( PEGTransformer &transformer, const Identifier &catalog_qualification, const Identifier &reserved_schema_qualification, const Identifier &reserved_schema_qualification_1, const vector &reserved_schema_qualification_2, const Identifier &reserved_column_name); - static unique_ptr - TransformCatalogReservedSchemaTableColumnNameInternal(PEGTransformer &transformer, ParseResult &parse_result); static unique_ptr TransformCatalogReservedSchemaTableColumnName(PEGTransformer &transformer, const Identifier &catalog_qualification, const Identifier &reserved_schema_qualification, const Identifier &reserved_table_qualification, const Identifier &reserved_column_name); - static unique_ptr TransformSchemaReservedTableColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSchemaReservedTableColumnName(PEGTransformer &transformer, const Identifier &schema_qualification, const Identifier &reserved_table_qualification, const Identifier &reserved_column_name); - static unique_ptr TransformTableReservedColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableReservedColumnName(PEGTransformer &transformer, const Identifier &table_qualification, const Identifier &reserved_column_name); - static unique_ptr TransformFunctionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFunctionExpression(PEGTransformer &transformer, const QualifiedName &function_identifier, MethodArguments function_expression_arguments, optional> within_group_clause, optional> filter_clause, const bool &has_result, optional> over_clause); - static unique_ptr TransformFunctionExpressionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MethodArguments TransformFunctionExpressionArguments(PEGTransformer &transformer, MethodArguments function_expression_argument_list); - static unique_ptr TransformFunctionExpressionArgumentListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MethodArguments TransformFunctionExpressionArgumentList(PEGTransformer &transformer, const optional &distinct_or_all, optional> function_argument_list, optional> order_by_clause, const optional &ignore_or_respect_nulls); - static unique_ptr TransformFunctionArgumentListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformFunctionArgumentList(PEGTransformer &transformer, vector function_argument); - static unique_ptr TransformFunctionIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformFunctionNameAsQualifiedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformFunctionNameAsQualifiedName(PEGTransformer &transformer, const Identifier &function_name); - static unique_ptr - TransformCatalogReservedSchemaFunctionNameInternal(PEGTransformer &transformer, ParseResult &parse_result); static QualifiedName TransformCatalogReservedSchemaFunctionName(PEGTransformer &transformer, const Identifier &catalog_qualification, const optional> &reserved_schema_qualification, const Identifier &reserved_function_name); - static unique_ptr TransformSchemaReservedFunctionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformSchemaReservedFunctionName(PEGTransformer &transformer, const Identifier &schema_qualification, const Identifier &reserved_function_name); - static unique_ptr TransformDistinctOrAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDistinctKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformDistinctKeyword(PEGTransformer &transformer); - static unique_ptr TransformAllKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformAllKeyword(PEGTransformer &transformer); - static unique_ptr TransformWithinGroupClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformWithinGroupClause(PEGTransformer &transformer, vector order_by_clause); - static unique_ptr TransformFilterClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFilterClause(PEGTransformer &transformer, unique_ptr filter_clause_expression); - static unique_ptr TransformFilterClauseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFilterClauseExpression(PEGTransformer &transformer, unique_ptr filter_clause_contents); - static unique_ptr TransformFilterClauseContentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFilterClauseContents(PEGTransformer &transformer, const bool &has_result, unique_ptr expression); - static unique_ptr TransformIgnoreOrRespectNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIgnoreNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformIgnoreNulls(PEGTransformer &transformer); - static unique_ptr TransformRespectNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformRespectNulls(PEGTransformer &transformer); - static unique_ptr TransformParenthesisExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformParenthesisExpression(PEGTransformer &transformer, optional>> expression); - static unique_ptr TransformLiteralExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLiteralExpression(PEGTransformer &transformer, ParseResult &choice_result); - static unique_ptr TransformConstantLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformConstantLiteral(PEGTransformer &transformer, const Value &child); - static unique_ptr TransformNullLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Value TransformNullLiteral(PEGTransformer &transformer); - static unique_ptr TransformTrueLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Value TransformTrueLiteral(PEGTransformer &transformer); - static unique_ptr TransformFalseLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Value TransformFalseLiteral(PEGTransformer &transformer); - static unique_ptr TransformCastExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCastExpression(PEGTransformer &transformer, const bool &cast_or_try_cast, CastArguments cast_arguments); - static unique_ptr TransformCastArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CastArguments TransformCastArguments(PEGTransformer &transformer, unique_ptr expression, const LogicalType &type); - static unique_ptr TransformCastOrTryCastInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCastKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformCastKeyword(PEGTransformer &transformer); - static unique_ptr TransformTryCastKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformTryCastKeyword(PEGTransformer &transformer); - static unique_ptr TransformColIdDotInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformColIdDot(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformStarExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformStarExpression(PEGTransformer &transformer, const optional> &star_qualifier_list, const optional &exclude_list, optional>> replace_list, const optional> &rename_list); - static unique_ptr TransformStarQualifierListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformStarQualifierList(PEGTransformer &transformer, const vector &col_id_dot); - static unique_ptr TransformExcludeListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static qualified_column_set_t TransformExcludeList(PEGTransformer &transformer, const qualified_column_set_t &exclude_names); - static unique_ptr TransformExcludeNamesInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExcludeNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static qualified_column_set_t TransformExcludeNameList(PEGTransformer &transformer, const vector &exclude_name); - static unique_ptr TransformExcludeNameSingleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static qualified_column_set_t TransformExcludeNameSingle(PEGTransformer &transformer, const QualifiedColumnName &exclude_name); - static unique_ptr TransformExcludeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExcludeDottedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedColumnName TransformExcludeDottedName(PEGTransformer &transformer, const vector &dotted_identifier); - static unique_ptr TransformExcludeColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedColumnName TransformExcludeColumnName(PEGTransformer &transformer, const Identifier &col_id_or_string); - static unique_ptr TransformReplaceListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static case_insensitive_map_t> TransformReplaceList(PEGTransformer &transformer, case_insensitive_map_t> replace_entries); - static unique_ptr TransformReplaceEntriesInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformReplaceEntrySingleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static case_insensitive_map_t> TransformReplaceEntrySingle(PEGTransformer &transformer, pair> replace_entry); - static unique_ptr TransformReplaceEntryListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static case_insensitive_map_t> TransformReplaceEntryList(PEGTransformer &transformer, vector>> replace_entry); - static unique_ptr TransformReplaceEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformReplaceEntry(PEGTransformer &transformer, unique_ptr expression, unique_ptr column_reference); - static unique_ptr TransformRenameListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static qualified_column_map_t TransformRenameList(PEGTransformer &transformer, const qualified_column_map_t &rename_entries); - static unique_ptr TransformRenameEntriesInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformRenameEntryListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static qualified_column_map_t TransformRenameEntryList(PEGTransformer &transformer, const vector> &rename_entry); - static unique_ptr TransformSingleRenameEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static qualified_column_map_t TransformSingleRenameEntry(PEGTransformer &transformer, const pair &rename_entry); - static unique_ptr TransformRenameEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair TransformRenameEntry(PEGTransformer &transformer, const QualifiedColumnName &exclude_name, const Identifier &identifier); - static unique_ptr TransformSubqueryExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSubqueryExpression(PEGTransformer &transformer, const optional &subquery_not, const optional &subquery_exists, unique_ptr subquery_reference); - static unique_ptr TransformSubqueryNotInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformSubqueryNot(PEGTransformer &transformer); - static unique_ptr TransformSubqueryExistsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformSubqueryExists(PEGTransformer &transformer); - static unique_ptr TransformCaseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCaseExpression(PEGTransformer &transformer, optional> expression, vector case_when_then, optional> case_else); - static unique_ptr TransformCaseWhenThenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static CaseCheck TransformCaseWhenThen(PEGTransformer &transformer, unique_ptr expression, unique_ptr expression_1); - static unique_ptr TransformCaseElseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCaseElse(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformTypeLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTypeLiteral(PEGTransformer &transformer, const LogicalType &type, const string &string_literal); - static unique_ptr TransformIntervalLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIntervalLiteral(PEGTransformer &transformer, unique_ptr interval_parameter, const optional &interval); - static unique_ptr TransformIntervalParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIntervalStringParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIntervalStringParameter(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformFrameClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowFrame TransformFrameClause(PEGTransformer &transformer, const string &framing, vector frame_extent, const optional &window_exclude_clause); - static unique_ptr TransformFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformRowsFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRowsFraming(PEGTransformer &transformer); - static unique_ptr TransformRangeFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRangeFraming(PEGTransformer &transformer); - static unique_ptr TransformGroupsFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformGroupsFraming(PEGTransformer &transformer); - static unique_ptr TransformFrameExtentInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSingleFrameExtentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformSingleFrameExtent(PEGTransformer &transformer, WindowBoundaryExpression frame_bound); - static unique_ptr TransformBetweenFrameExtentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformBetweenFrameExtent(PEGTransformer &transformer, WindowBoundaryExpression frame_bound, WindowBoundaryExpression frame_bound_1); - static unique_ptr TransformFrameBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformFrameUnboundedInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowBoundaryExpression TransformFrameUnbounded(PEGTransformer &transformer, const bool &preceding_or_following); - static unique_ptr TransformFrameExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowBoundaryExpression TransformFrameExpression(PEGTransformer &transformer, unique_ptr expression, const bool &preceding_or_following); - static unique_ptr TransformFrameCurrentRowInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowBoundaryExpression TransformFrameCurrentRow(PEGTransformer &transformer); - static unique_ptr TransformPrecedingOrFollowingInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPrecedingFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformPrecedingFrame(PEGTransformer &transformer); - static unique_ptr TransformFollowingFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformFollowingFrame(PEGTransformer &transformer); - static unique_ptr TransformWindowExcludeClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowExcludeMode TransformWindowExcludeClause(PEGTransformer &transformer, const WindowExcludeMode &window_exclude_element); - static unique_ptr TransformWindowExcludeElementInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExcludeCurrentRowInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowExcludeMode TransformExcludeCurrentRow(PEGTransformer &transformer); - static unique_ptr TransformExcludeGroupInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowExcludeMode TransformExcludeGroup(PEGTransformer &transformer); - static unique_ptr TransformExcludeTiesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowExcludeMode TransformExcludeTies(PEGTransformer &transformer); - static unique_ptr TransformExcludeNoOthersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static WindowExcludeMode TransformExcludeNoOthers(PEGTransformer &transformer); - static unique_ptr TransformWindowFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIdentifierWindowFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIdentifierWindowFrame(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformParensIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformParensIdentifier(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformWindowFrameDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformWindowFrameNameContentsParensInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformWindowFrameNameContentsParens(PEGTransformer &transformer, unique_ptr window_frame_name_contents); - static unique_ptr TransformWindowFrameNameContentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformWindowFrameNameContents(PEGTransformer &transformer, const optional &base_window_name, unique_ptr window_frame_contents); - static unique_ptr TransformWindowFrameContentsParensInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformWindowFrameContentsParens(PEGTransformer &transformer, unique_ptr window_frame_contents); - static unique_ptr TransformWindowFrameContentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformWindowFrameContents(PEGTransformer &transformer, optional>> window_partition, optional> order_by_clause, optional frame_clause); - static unique_ptr TransformBaseWindowNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformBaseWindowName(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformWindowPartitionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformWindowPartition(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformListExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformArrayBoundedListExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformArrayBoundedListExpression(PEGTransformer &transformer, const bool &has_result, vector> bounded_list_expression); - static unique_ptr TransformArrayParensSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformArrayParensSelect(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformBoundedListExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformBoundedListExpression(PEGTransformer &transformer, optional>> expression); - static unique_ptr TransformStructExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformStructExpression(PEGTransformer &transformer, optional> struct_field); - static unique_ptr TransformStructFieldInternal(PEGTransformer &transformer, - ParseResult &parse_result); static FunctionArgument TransformStructField(PEGTransformer &transformer, const Identifier &col_id_or_string, unique_ptr expression); - static unique_ptr TransformMapExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMapExpression(PEGTransformer &transformer, vector> map_struct_expression); - static unique_ptr TransformMapStructExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformMapStructExpression(PEGTransformer &transformer, optional>>> map_struct_field); - static unique_ptr TransformMapStructFieldInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformMapStructField(PEGTransformer &transformer, unique_ptr expression, unique_ptr expression_1); - static unique_ptr TransformGroupingExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformGroupingExpression(PEGTransformer &transformer, const bool &grouping_or_grouping_id, optional>> expression); - static unique_ptr TransformGroupingOrGroupingIdInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformGroupingKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformGroupingKeyword(PEGTransformer &transformer); - static unique_ptr TransformGroupingIdKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformGroupingIdKeyword(PEGTransformer &transformer); - static unique_ptr TransformParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformQuestionMarkNumberedParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformQuestionMarkNumberedParameter(PEGTransformer &transformer, unique_ptr number_literal); - static unique_ptr TransformAnonymousParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAnonymousParameter(PEGTransformer &transformer); - static unique_ptr TransformNumberedParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNumberedParameter(PEGTransformer &transformer, unique_ptr number_literal); - static unique_ptr TransformColLabelParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColLabelParameter(PEGTransformer &transformer, const string &col_label); - static unique_ptr TransformPositionalExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPositionalExpression(PEGTransformer &transformer, unique_ptr number_literal); - static unique_ptr TransformDefaultExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDefaultExpression(PEGTransformer &transformer); - static unique_ptr TransformListComprehensionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformListComprehensionExpression(PEGTransformer &transformer, unique_ptr expression, const vector &col_id_or_string, unique_ptr expression_1, optional> list_comprehension_filter); - static unique_ptr TransformListComprehensionFilterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformListComprehensionFilter(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformParensExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformParensExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformSingleExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExpression(PEGTransformer &transformer, - unique_ptr lambda_arrow_expression); - static unique_ptr TransformColumnDefaultExprInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColumnDefaultExpr(PEGTransformer &transformer, unique_ptr col_def_or_expr); - static unique_ptr TransformLambdaArrowExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLambdaArrowExpression(PEGTransformer &transformer, unique_ptr logical_or_expression, optional>> single_arrow_pair); - static unique_ptr TransformSingleArrowPairInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSingleArrowPair(PEGTransformer &transformer, unique_ptr logical_or_expression); - static unique_ptr TransformLogicalOrExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLogicalOrExpression(PEGTransformer &transformer, unique_ptr logical_and_expression, optional>> logical_or_expression_tail); - static unique_ptr TransformLogicalOrExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLogicalOrExpressionTail(PEGTransformer &transformer, unique_ptr logical_and_expression); - static unique_ptr TransformColDefOrExprInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColDefOrExpr(PEGTransformer &transformer, unique_ptr col_def_and_expr, optional>> col_def_or_expression_tail); - static unique_ptr TransformColDefOrExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColDefOrExpressionTail(PEGTransformer &transformer, unique_ptr col_def_and_expr); - static unique_ptr TransformLogicalAndExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLogicalAndExpression(PEGTransformer &transformer, unique_ptr logical_not_expression, optional>> logical_and_expression_tail); - static unique_ptr TransformLogicalAndExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLogicalAndExpressionTail(PEGTransformer &transformer, unique_ptr logical_not_expression); - static unique_ptr TransformColDefAndExprInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColDefAndExpr(PEGTransformer &transformer, unique_ptr is_distinct_from_expression, optional>> col_def_and_expression_tail); - static unique_ptr TransformColDefAndExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColDefAndExpressionTail(PEGTransformer &transformer, unique_ptr is_distinct_from_expression); - static unique_ptr TransformLogicalNotExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLogicalNotExpression(PEGTransformer &transformer, optional> not_expression, unique_ptr is_expression); - static unique_ptr TransformNotExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformNotExpression(PEGTransformer &transformer, const vector ¬_keyword); - static unique_ptr TransformNotKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformNotKeyword(PEGTransformer &transformer); - static unique_ptr TransformIsExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIsExpression(PEGTransformer &transformer, unique_ptr is_distinct_from_expression, optional>> is_test); - static unique_ptr TransformIsTestInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIsLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIsLiteral(PEGTransformer &transformer, const bool &has_result, const Value &is_literal_value); - static unique_ptr TransformIsLiteralValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUnknownLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Value TransformUnknownLiteral(PEGTransformer &transformer); - static unique_ptr TransformNotNullInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNotNullKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNotNullKeyword(PEGTransformer &transformer); - static unique_ptr TransformNotNullOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNotNullOperator(PEGTransformer &transformer); - static unique_ptr TransformIsNullInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIsNull(PEGTransformer &transformer, unique_ptr is_null_operator); - static unique_ptr TransformIsNullOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIsNullOperator(PEGTransformer &transformer); - static unique_ptr TransformIsDistinctFromExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIsDistinctFromExpression(PEGTransformer &transformer, unique_ptr comparison_expression, optional> is_distinct_from_tail); - static unique_ptr TransformIsDistinctFromTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static IsDistinctFromTail TransformIsDistinctFromTail(PEGTransformer &transformer, const ExpressionType &is_distinct_from_op, unique_ptr comparison_expression); - static unique_ptr TransformIsDistinctFromOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformIsDistinctFromOp(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformComparisonExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformComparisonExpression(PEGTransformer &transformer, unique_ptr between_in_like_expression, optional> comparison_expression_tail); - static unique_ptr TransformComparisonExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ComparisonExpressionTail TransformComparisonExpressionTail(PEGTransformer &transformer, const ExpressionType &comparison_operator, optional> not_expression, unique_ptr between_in_like_expression); - static unique_ptr TransformComparisonOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOperatorEqualInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformOperatorEqual(PEGTransformer &transformer); - static unique_ptr TransformOperatorNotEqualInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformOperatorNotEqual(PEGTransformer &transformer); - static unique_ptr TransformOperatorLessThanInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformOperatorLessThan(PEGTransformer &transformer); - static unique_ptr TransformOperatorGreaterThanInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformOperatorGreaterThan(PEGTransformer &transformer); - static unique_ptr TransformOperatorLessThanEqualsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformOperatorLessThanEquals(PEGTransformer &transformer); - static unique_ptr TransformOperatorGreaterThanEqualsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExpressionType TransformOperatorGreaterThanEquals(PEGTransformer &transformer); - static unique_ptr TransformBetweenInLikeExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBetweenInLikeExpression(PEGTransformer &transformer, unique_ptr other_operator_expression, optional between_in_like_op); - static unique_ptr TransformBetweenInLikeOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); static BetweenInLikeOperator TransformBetweenInLikeOp(PEGTransformer &transformer, const bool &has_result, unique_ptr between_in_like_op_expression); - static unique_ptr TransformBetweenInLikeOpExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLikeClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLikeClause(PEGTransformer &transformer, const string &like_variations, unique_ptr other_operator_expression, optional> escape_clause); - static unique_ptr TransformEscapeClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformEscapeClause(PEGTransformer &transformer, unique_ptr comparison_expression); - static unique_ptr TransformLikeVariationsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLikeTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformLikeToken(PEGTransformer &transformer); - static unique_ptr TransformILikeTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformILikeToken(PEGTransformer &transformer); - static unique_ptr TransformGlobTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformGlobToken(PEGTransformer &transformer); - static unique_ptr TransformSimilarToTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformSimilarToToken(PEGTransformer &transformer); - static unique_ptr TransformRegexMatchTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRegexMatchToken(PEGTransformer &transformer); - static unique_ptr TransformRegexInsensitiveMatchTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRegexInsensitiveMatchToken(PEGTransformer &transformer); - static unique_ptr TransformNotILikeOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformNotILikeOp(PEGTransformer &transformer); - static unique_ptr TransformNotLikeOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformNotLikeOp(PEGTransformer &transformer); - static unique_ptr TransformNotRegexInsensitiveMatchOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformNotRegexInsensitiveMatchOp(PEGTransformer &transformer); - static unique_ptr TransformNotSimilarToOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformNotSimilarToOp(PEGTransformer &transformer); - static unique_ptr TransformInClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInClause(PEGTransformer &transformer, unique_ptr in_expression); - static unique_ptr TransformInExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformInContainsExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInContainsExpression(PEGTransformer &transformer, unique_ptr other_operator_expression); - static unique_ptr TransformInExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInExpressionList(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformInSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInSelectStatement(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformBetweenClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBetweenClause(PEGTransformer &transformer, unique_ptr other_operator_expression, unique_ptr other_operator_expression_1); - static unique_ptr TransformOtherOperatorExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOtherOperatorExpression(PEGTransformer &transformer, unique_ptr bitwise_expression, optional> other_operator_tail); - static unique_ptr TransformOtherOperatorTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OtherOperatorTail TransformOtherOperatorTail(PEGTransformer &transformer, ParsedOperator other_operator, unique_ptr bitwise_expression); - static unique_ptr TransformOtherOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAnyAllParsedOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ParsedOperator TransformAnyAllParsedOperator(PEGTransformer &transformer, const pair &any_all_operator); - static unique_ptr TransformNamedOtherOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ParsedOperator TransformNamedOtherOperator(PEGTransformer &transformer, const string &child); - static unique_ptr TransformAnyAllOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static pair TransformAnyAllOperator(PEGTransformer &transformer, const string &any_op, + static pair TransformAnyAllOperator(PEGTransformer &transformer, const string &any_operator_literal, const bool &any_or_all); - static unique_ptr TransformAnyOrAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSubqueryAnyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformSubqueryAny(PEGTransformer &transformer); - static unique_ptr TransformSubqueryAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformSubqueryAll(PEGTransformer &transformer); - static unique_ptr TransformInetOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformJsonOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformListOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformStringOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformQualifiedOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformQualifiedOperator(PEGTransformer &transformer, const string &qualified_operator_contents); - static unique_ptr TransformQualifiedOperatorContentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformQualifiedOperatorContents(PEGTransformer &transformer, - const optional> &col_id_dot, const string &any_op); - static unique_ptr TransformAnyOpInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformBitwiseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); + const optional> &col_id_dot, + const string &any_operator_literal); static unique_ptr TransformBitwiseExpression(PEGTransformer &transformer, unique_ptr additive_expression, optional> bitwise_expression_tail); - static unique_ptr TransformBitwiseExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static BinaryExpressionTail TransformBitwiseExpressionTail(PEGTransformer &transformer, const string &bit_operator, unique_ptr additive_expression); - static unique_ptr TransformBitOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAdditiveExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAdditiveExpression(PEGTransformer &transformer, unique_ptr multiplicative_expression, optional> additive_expression_tail); - static unique_ptr TransformAdditiveExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static BinaryExpressionTail TransformAdditiveExpressionTail(PEGTransformer &transformer, const string &term, unique_ptr multiplicative_expression, optional_idx query_location); - static unique_ptr TransformTermInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMultiplicativeExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMultiplicativeExpression(PEGTransformer &transformer, unique_ptr exponentiation_expression, optional> multiplicative_expression_tail); - static unique_ptr TransformMultiplicativeExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static BinaryExpressionTail TransformMultiplicativeExpressionTail(PEGTransformer &transformer, const string &factor, unique_ptr exponentiation_expression); - static unique_ptr TransformFactorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExponentiationExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExponentiationExpression(PEGTransformer &transformer, unique_ptr collate_expression, optional> exponentiation_expression_tail); - static unique_ptr TransformExponentiationExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static BinaryExpressionTail TransformExponentiationExpressionTail(PEGTransformer &transformer, const string &exponent_operator, unique_ptr collate_expression); - static unique_ptr TransformExponentOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCollateExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCollateExpression(PEGTransformer &transformer, unique_ptr at_time_zone_expression, optional>> collate_expression_tail); - static unique_ptr TransformCollateExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCollateExpressionTail(PEGTransformer &transformer, unique_ptr at_time_zone_expression); - static unique_ptr TransformAtTimeZoneExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAtTimeZoneExpression(PEGTransformer &transformer, unique_ptr prefix_expression, optional>> at_time_zone_expression_tail); - static unique_ptr TransformAtTimeZoneExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAtTimeZoneExpressionTail(PEGTransformer &transformer, unique_ptr prefix_expression); - static unique_ptr TransformPrefixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMinusPrefixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPlusPrefixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTildePrefixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformBaseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBaseExpression(PEGTransformer &transformer, unique_ptr single_expression, optional>> indirection_list); - static unique_ptr TransformIndirectionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformIndirectionList(PEGTransformer &transformer, vector> indirection); - static unique_ptr TransformIndirectionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCastOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCastOperator(PEGTransformer &transformer, const LogicalType &type); - static unique_ptr TransformDotOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDotMethodOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDotMethodOperator(PEGTransformer &transformer, unique_ptr method_expression); - static unique_ptr TransformDotColumnOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDotColumnOperator(PEGTransformer &transformer, const string &col_label); - static unique_ptr TransformMethodExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMethodExpression(PEGTransformer &transformer, const string &col_label, MethodArguments method_expression_arguments); - static unique_ptr TransformMethodExpressionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MethodArguments TransformMethodExpressionArguments(PEGTransformer &transformer, MethodArguments method_expression_argument_list); - static unique_ptr TransformMethodExpressionArgumentListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MethodArguments TransformMethodExpressionArgumentList(PEGTransformer &transformer, const optional &distinct_or_all, optional> method_function_arguments, optional> order_by_clause, const optional &ignore_or_respect_nulls); - static unique_ptr TransformMethodFunctionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformMethodFunctionArguments(PEGTransformer &transformer, vector function_argument); - static unique_ptr TransformSliceExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSliceExpression(PEGTransformer &transformer, vector> slice_bound); - static unique_ptr TransformSliceBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSliceBound(PEGTransformer &transformer, optional> expression, optional> end_slice_bound, optional> step_slice_bound); - static unique_ptr TransformEndSliceBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformEndSliceBound(PEGTransformer &transformer, optional> end_slice_value); - static unique_ptr TransformEndSliceValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformEndSliceMinusInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformEndSliceMinus(PEGTransformer &transformer); - static unique_ptr TransformStepSliceBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformStepSliceBound(PEGTransformer &transformer, optional> expression); - static unique_ptr TransformPostfixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPostfixOperator(PEGTransformer &transformer); - static unique_ptr TransformSpecialFunctionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCoalesceExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCoalesceExpression(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformUnpackExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUnpackExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformTryExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTryExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformColumnsExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColumnsExpression(PEGTransformer &transformer, const bool &has_result, unique_ptr expression); - static unique_ptr TransformExtractExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExtractExpression(PEGTransformer &transformer, vector> extract_arguments); - static unique_ptr TransformExtractArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformExtractArguments(PEGTransformer &transformer, unique_ptr extract_argument, unique_ptr expression); - static unique_ptr TransformLambdaExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLambdaExpression(PEGTransformer &transformer, const vector &col_id_or_string, unique_ptr expression); - static unique_ptr TransformNullIfExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNullIfExpression(PEGTransformer &transformer, vector> null_if_arguments); - static unique_ptr TransformNullIfArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformNullIfArguments(PEGTransformer &transformer, unique_ptr expression, unique_ptr expression_1); - static unique_ptr TransformPositionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPositionExpression(PEGTransformer &transformer, vector> position_arguments); - static unique_ptr TransformPositionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformPositionArguments(PEGTransformer &transformer, unique_ptr other_operator_expression, unique_ptr expression); - static unique_ptr TransformRowExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRowExpression(PEGTransformer &transformer, optional>> expression); - static unique_ptr TransformSubstringExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSubstringExpression(PEGTransformer &transformer, vector> substring_arguments); - static unique_ptr TransformSubstringArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSubstringExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSubstringExpressionList(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformSubstringParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSubstringParameters(PEGTransformer &transformer, unique_ptr expression, vector> substring_from_for); - static unique_ptr TransformSubstringFromForInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSubstringFromOptionalForInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSubstringFromOptionalFor(PEGTransformer &transformer, unique_ptr from_expression, optional> for_expression); - static unique_ptr TransformSubstringForInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSubstringFor(PEGTransformer &transformer, unique_ptr for_expression); - static unique_ptr TransformTrimExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTrimExpression(PEGTransformer &transformer, TrimArguments trim_arguments); - static unique_ptr TransformTrimArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TrimArguments TransformTrimArguments(PEGTransformer &transformer, const optional &trim_direction, optional> trim_source, vector> expression); - static unique_ptr TransformTrimDirectionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTrimBothInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformTrimBoth(PEGTransformer &transformer); - static unique_ptr TransformTrimLeadingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformTrimLeading(PEGTransformer &transformer); - static unique_ptr TransformTrimTrailingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformTrimTrailing(PEGTransformer &transformer); - static unique_ptr TransformTrimSourceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTrimSource(PEGTransformer &transformer, optional> expression); - static unique_ptr TransformOverlayExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOverlayExpression(PEGTransformer &transformer, vector> overlay_arguments); - static unique_ptr TransformOverlayArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOverlayParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformOverlayParameters(PEGTransformer &transformer, unique_ptr expression, unique_ptr expression_1, unique_ptr from_expression, optional> for_expression); - static unique_ptr TransformFromExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFromExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformForExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformForExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformOverlayExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformOverlayExpressionList(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformExtractArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExtractDatePartArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExtractDatePartArgument(PEGTransformer &transformer, const DatePartSpecifier &extract_date_part); - static unique_ptr TransformExtractIdentifierArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExtractIdentifierArgument(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformExtractStringArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExtractStringArgument(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformExtractDatePartInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformExternalResourceStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCreateExternalResourceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateExternalResourceStmt(PEGTransformer &transformer, const string &string_literal, const optional &attach_alias, const optional> &external_resource_creation_options); - static unique_ptr TransformRegisterExternalResourceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRegisterExternalResourceStmt(PEGTransformer &transformer, const string &string_literal, const optional &attach_alias, unique_ptr expression); - static unique_ptr TransformDestroyExternalResourceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDestroyExternalResourceStmt(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformShowExternalResourcesStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformShowExternalResourcesStmt(PEGTransformer &transformer, const optional &show_all_modifier); - static unique_ptr TransformShowAllModifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformShowAllModifier(PEGTransformer &transformer); - static unique_ptr - TransformExternalResourceCreationOptionsInternal(PEGTransformer &transformer, ParseResult &parse_result); - static unique_ptr TransformInsertStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); + static unique_ptr TransformAttachToExternalResource( + PEGTransformer &transformer, unique_ptr external_resource_source, + const Identifier &attach_alias, const optional> &attach_options); + static unique_ptr + TransformConnectToExternalResource(PEGTransformer &transformer, + unique_ptr external_resource_source, + const optional> &attach_options); + static unique_ptr TransformExternalResourceCreateClause( + PEGTransformer &transformer, const string &string_literal, + const optional> &external_resource_creation_options); + static unique_ptr TransformExternalResourceReferenceClause(PEGTransformer &transformer, + const Identifier &col_id); static unique_ptr TransformInsertStatement(PEGTransformer &transformer, optional with_clause, const optional &or_action, unique_ptr insert_target, @@ -6654,1148 +5215,528 @@ class PEGTransformerFactory { const optional> &insert_column_list, InsertValues insert_values, optional> on_conflict_clause, optional>> returning_clause); - static unique_ptr TransformOrActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformInsertOrReplaceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OnConflictAction TransformInsertOrReplace(PEGTransformer &transformer); - static unique_ptr TransformInsertOrIgnoreInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OnConflictAction TransformInsertOrIgnore(PEGTransformer &transformer); - static unique_ptr TransformByNameOrPositionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformInsertByNameOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformInsertByPositionOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformInsertByNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static InsertColumnOrder TransformInsertByName(PEGTransformer &transformer); - static unique_ptr TransformInsertByPositionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static InsertColumnOrder TransformInsertByPosition(PEGTransformer &transformer); - static unique_ptr TransformInsertTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInsertTarget(PEGTransformer &transformer, unique_ptr base_table_name, const optional &insert_alias); - static unique_ptr TransformInsertAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformInsertAlias(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformColumnList(PEGTransformer &transformer, const vector &col_id); - static unique_ptr TransformInsertColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformInsertColumnList(PEGTransformer &transformer, const vector &column_list); - static unique_ptr TransformInsertValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSelectInsertValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static InsertValues TransformSelectInsertValues(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformDefaultValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static InsertValues TransformDefaultValues(PEGTransformer &transformer); - static unique_ptr TransformOnConflictClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOnConflictClause(PEGTransformer &transformer, optional on_conflict_target, unique_ptr on_conflict_action); - static unique_ptr TransformOnConflictTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOnConflictExpressionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OnConflictExpressionTarget TransformOnConflictExpressionTarget(PEGTransformer &transformer, const vector &column_id_list, optional> where_clause); - static unique_ptr TransformOnConflictIndexTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OnConflictExpressionTarget TransformOnConflictIndexTarget(PEGTransformer &transformer, const Identifier &constraint_name); - static unique_ptr TransformOnConflictActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOnConflictUpdateInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOnConflictUpdate(PEGTransformer &transformer, unique_ptr update_set_clause, optional> where_clause); - static unique_ptr TransformOnConflictNothingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOnConflictNothing(PEGTransformer &transformer); - static unique_ptr TransformReturningClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformReturningClause(PEGTransformer &transformer, vector> target_list); - static unique_ptr TransformLoadStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLoadStatement(PEGTransformer &transformer, const Identifier &col_id_or_string, const optional &from_source, const optional &extension_alias); - static unique_ptr TransformExtensionAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformExtensionAlias(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformInstallStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInstallStatement(PEGTransformer &transformer, const bool &has_result, const optional &install_and_load, const QualifiedName &identifier_or_string_literal, const optional &from_source, const optional &version_number); - static unique_ptr TransformInstallAndLoadInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformInstallAndLoad(PEGTransformer &transformer); - static unique_ptr TransformUpdateExtensionsStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateExtensionsStatement(PEGTransformer &transformer, const optional> &identifier); - static unique_ptr TransformFromSourceInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformFromSourceIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExtensionRepositoryInfo TransformFromSourceIdentifier(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformFromSourceStringInternal(PEGTransformer &transformer, - ParseResult &parse_result); static ExtensionRepositoryInfo TransformFromSourceString(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformVersionNumberInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformVersionNumber(PEGTransformer &transformer, const QualifiedName &identifier_or_string_literal); - static unique_ptr TransformExtensionRepositoryStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCreateExtensionRepositoryStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCreateExtensionRepositoryStmt(PEGTransformer &transformer, const optional &or_replace, const optional &if_not_exists, const Identifier &col_id_or_string, const string &repository_prefix, const optional> &repository_public_key); - static unique_ptr TransformRepositoryPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRepositoryPrefix(PEGTransformer &transformer, const bool &has_result, const string &string_literal); - static unique_ptr TransformRepositoryPublicKeyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformRepositoryPublicKey(PEGTransformer &transformer, const bool &has_result, const vector &string_literal); - static unique_ptr TransformDropExtensionRepositoryStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDropExtensionRepositoryStmt(PEGTransformer &transformer, const optional &if_exists, const Identifier &col_id_or_string); - static unique_ptr TransformMergeIntoStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMergeIntoStatement(PEGTransformer &transformer, optional with_clause, unique_ptr target_opt_alias, unique_ptr merge_into_using_clause, JoinQualifier join_qualifier, vector>> merge_match, optional>> returning_clause); - static unique_ptr TransformMergeIntoUsingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformMergeIntoUsingClause(PEGTransformer &transformer, unique_ptr table_ref); - static unique_ptr TransformMergeMatchInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformMatchedClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformMatchedClause(PEGTransformer &transformer, optional> and_expression, unique_ptr matched_clause_action); - static unique_ptr TransformMatchedClauseActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUpdateMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateMatchClause(PEGTransformer &transformer, optional> update_match_info); - static unique_ptr TransformUpdateMatchInfoInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUpdateMatchSetActionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateMatchSetAction(PEGTransformer &transformer, unique_ptr update_match_set_clause); - static unique_ptr TransformUpdateByNameOrPositionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateByNameOrPosition(PEGTransformer &transformer, const InsertColumnOrder &by_name_or_position); - static unique_ptr TransformDeleteMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDeleteMatchClause(PEGTransformer &transformer); - static unique_ptr TransformInsertMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInsertMatchClause(PEGTransformer &transformer, optional> insert_match_info); - static unique_ptr TransformInsertMatchInfoInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformInsertDefaultValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInsertDefaultValues(PEGTransformer &transformer); - static unique_ptr TransformInsertByNameOrPositionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInsertByNameOrPosition(PEGTransformer &transformer, const optional &by_name_or_position, const bool &has_result); - static unique_ptr TransformInsertValuesListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformInsertValuesList(PEGTransformer &transformer, const optional> &insert_column_list, vector> expression); - static unique_ptr TransformDoNothingMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformDoNothingMatchClause(PEGTransformer &transformer); - static unique_ptr TransformErrorMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformErrorMatchClause(PEGTransformer &transformer, optional> expression); - static unique_ptr TransformUpdateMatchSetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUpdateMatchSetInfoInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformAndExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAndExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformNotMatchedClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformNotMatchedClause(PEGTransformer &transformer, const optional &by_source_or_target, optional> and_expression, unique_ptr matched_clause_action); - static unique_ptr TransformBySourceOrTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformBySourceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MergeActionCondition TransformBySource(PEGTransformer &transformer); - static unique_ptr TransformByTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MergeActionCondition TransformByTarget(PEGTransformer &transformer); - static unique_ptr TransformPivotOnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformPivotOn(PEGTransformer &transformer, vector pivot_column_list); - static unique_ptr TransformPivotUsingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformPivotUsing(PEGTransformer &transformer, vector> target_list); - static unique_ptr TransformPivotColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformPivotColumnList(PEGTransformer &transformer, vector pivot_column_entry); - static unique_ptr TransformPivotColumnEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPivotColumnExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PivotColumn TransformPivotColumnExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformPivotColumnSubqueryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PivotColumn TransformPivotColumnSubquery(PEGTransformer &transformer, unique_ptr base_expression, unique_ptr select_statement_internal); - static unique_ptr TransformIntoNameValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static UnpivotNameValues TransformIntoNameValues(PEGTransformer &transformer, const Identifier &col_id_or_string, const vector &optional_parens_name_list); - static unique_ptr TransformOptionalParensNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformParenthesizedNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformParenthesizedNameList(PEGTransformer &transformer, const vector &col_id_or_string); - static unique_ptr TransformBareNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformBareNameList(PEGTransformer &transformer, const vector &col_id_or_string); - static unique_ptr TransformIncludeOrExcludeNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformIncludeNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformIncludeNulls(PEGTransformer &transformer); - static unique_ptr TransformExcludeNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformExcludeNulls(PEGTransformer &transformer); - static unique_ptr TransformUnpivotHeaderInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUnpivotHeaderSingleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformUnpivotHeaderSingle(PEGTransformer &transformer, const Identifier &col_id_or_string); - static unique_ptr TransformUnpivotHeaderListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformUnpivotHeaderList(PEGTransformer &transformer, const vector &col_id_or_string); - static unique_ptr TransformPragmaStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPragmaStatement(PEGTransformer &transformer, unique_ptr pragma_assign_or_function); - static unique_ptr TransformPragmaAssignOrFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPragmaAssignInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPragmaAssign(PEGTransformer &transformer, const Identifier &setting_name, vector> variable_list); - static unique_ptr TransformPragmaFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPragmaFunction(PEGTransformer &transformer, const Identifier &pragma_name, optional>> pragma_parameters); - static unique_ptr TransformPragmaParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformPragmaParameters(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformPrepareStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPrepareStatement(PEGTransformer &transformer, const Identifier &identifier, const optional> &type_list, unique_ptr statement); - static unique_ptr TransformTypeListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformTypeList(PEGTransformer &transformer, const vector &type); - static unique_ptr TransformSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSelectStatement(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformSelectSetOpChainInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSelectSetOpChain( PEGTransformer &transformer, unique_ptr intersect_chain, optional, unique_ptr>>> select_set_op_chain_tail); - static unique_ptr TransformSelectSetOpChainTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair, unique_ptr> TransformSelectSetOpChainTail(PEGTransformer &transformer, unique_ptr setop_clause, unique_ptr intersect_chain); - static unique_ptr TransformIntersectChainInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformIntersectChain( PEGTransformer &transformer, unique_ptr select_atom, optional, unique_ptr>>> intersect_chain_tail); - static unique_ptr TransformIntersectChainTailInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair, unique_ptr> TransformIntersectChainTail(PEGTransformer &transformer, unique_ptr set_intersect_clause, unique_ptr select_atom); - static unique_ptr TransformSetIntersectClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetIntersectClause(PEGTransformer &transformer, const optional &distinct_or_all); - static unique_ptr TransformSelectAtomInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSelectParensInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSelectParens(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformSetopClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetopClause(PEGTransformer &transformer, const SetOperationType &setop_type, const optional &distinct_or_all, const bool &has_result); - static unique_ptr TransformSetopTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSetopUnionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SetOperationType TransformSetopUnion(PEGTransformer &transformer); - static unique_ptr TransformSetopExceptInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SetOperationType TransformSetopExcept(PEGTransformer &transformer); - static unique_ptr TransformSelectStatementTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformResultModifiersInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformResultModifiers(PEGTransformer &transformer, optional> order_by_clause, optional> limit_offset); - static unique_ptr TransformLimitOffsetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLimitOffsetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformLimitOffsetClause(PEGTransformer &transformer, LimitPercentResult limit_clause, optional offset_clause); - static unique_ptr TransformOffsetLimitClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOffsetLimitClause(PEGTransformer &transformer, LimitPercentResult offset_clause, optional limit_clause); - static unique_ptr TransformOffsetFetchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformOffsetFetchClause(PEGTransformer &transformer, LimitPercentResult offset_clause, LimitPercentResult fetch_clause); - static unique_ptr TransformFetchOnlyClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFetchOnlyClause(PEGTransformer &transformer, LimitPercentResult fetch_clause); - static unique_ptr TransformTableStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableStatement(PEGTransformer &transformer, unique_ptr base_table_name); - static unique_ptr TransformOptionalParensSimpleSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSimpleSelectParensInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSimpleSelectParens(PEGTransformer &transformer, unique_ptr simple_select); - static unique_ptr TransformSelectFromInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSelectFromClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSelectFromClause(PEGTransformer &transformer, unique_ptr select_clause, optional> from_clause); - static unique_ptr TransformFromSelectClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFromSelectClause(PEGTransformer &transformer, unique_ptr from_clause, optional> select_clause); - static unique_ptr TransformWithStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformWithStatement(PEGTransformer &transformer, const Identifier &col_id_or_string, - const optional> &insert_column_list, + const optional> &column_aliases, optional>> using_key, const optional &materialized, unique_ptr cte_body); - static unique_ptr TransformCTEBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCTESelectBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCTESelectBody(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformCTEDMLBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCTEDMLBody(PEGTransformer &transformer, unique_ptr statement); - static unique_ptr TransformUsingKeyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformUsingKey(PEGTransformer &transformer, vector> target_list); - static unique_ptr TransformMaterializedInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformMaterialized(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformSelectClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSelectClause(PEGTransformer &transformer, optional distinct_clause, optional>> target_list); - static unique_ptr TransformTargetListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformTargetList(PEGTransformer &transformer, vector> aliased_expression); - static unique_ptr TransformColumnAliasesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformColumnAliases(PEGTransformer &transformer, const vector &col_id_or_string); - static unique_ptr TransformDistinctClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDistinctAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DistinctClause TransformDistinctAll(PEGTransformer &transformer); - static unique_ptr TransformDistinctOnInternal(PEGTransformer &transformer, - ParseResult &parse_result); static DistinctClause TransformDistinctOn(PEGTransformer &transformer, optional>> distinct_on_targets); - static unique_ptr TransformDistinctOnTargetsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformDistinctOnTargets(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformInnerTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTableSubqueryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableSubquery(PEGTransformer &transformer, const optional &table_alias_colon, const optional &lateral, unique_ptr subquery_reference, const optional &table_alias); - static unique_ptr TransformBaseTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBaseTableRef(PEGTransformer &transformer, const optional &table_alias_colon, unique_ptr base_table_name, const optional &table_alias, optional> at_clause, optional> sample_clause); - static unique_ptr TransformTableAliasColonInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformTableAliasColon(PEGTransformer &transformer, const Identifier &col_id_or_string); - static unique_ptr TransformValuesRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformValuesRef(PEGTransformer &transformer, const optional &table_alias_colon, unique_ptr values_clause, const optional &table_alias); - static unique_ptr TransformParensTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformParensTableRef(PEGTransformer &transformer, const optional &table_alias_colon, unique_ptr table_ref, const optional &table_alias, optional> sample_clause); - static unique_ptr TransformJoinOrPivotInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTablePivotClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTablePivotClause(PEGTransformer &transformer, unique_ptr table_pivot_clause_body, const optional &table_alias); - static unique_ptr TransformTablePivotClauseBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTablePivotClauseBody(PEGTransformer &transformer, vector> target_list, vector pivot_value_list, const optional> &pivot_group_by_list); - static unique_ptr TransformPivotGroupByListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformPivotGroupByList(PEGTransformer &transformer, const vector &optional_parens_name_list); - static unique_ptr TransformTableUnpivotClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableUnpivotClause(PEGTransformer &transformer, const optional &include_or_exclude_nulls, unique_ptr table_unpivot_clause_body, const optional &table_alias); - static unique_ptr TransformTableUnpivotClauseBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableUnpivotClauseBody(PEGTransformer &transformer, const vector &unpivot_header, vector unpivot_value_list); - static unique_ptr TransformPivotHeaderInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformPivotHeader(PEGTransformer &transformer, unique_ptr base_expression); - static unique_ptr TransformPivotValueListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PivotColumn TransformPivotValueList(PEGTransformer &transformer, unique_ptr pivot_header, PivotColumn pivot_value_target); - static unique_ptr TransformPivotValueTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformPivotEnumTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PivotColumn TransformPivotEnumTarget(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformPivotListTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PivotColumn TransformPivotListTarget(PEGTransformer &transformer, vector pivot_target_list); - static unique_ptr TransformUnpivotValueListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static PivotColumn TransformUnpivotValueList(PEGTransformer &transformer, const vector &unpivot_header, vector unpivot_target_list); - static unique_ptr TransformPivotTargetListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformPivotTargetList(PEGTransformer &transformer, vector> target_list); - static unique_ptr TransformUnpivotTargetListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformUnpivotTargetList(PEGTransformer &transformer, vector> target_list); - static unique_ptr TransformLateralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformLateral(PEGTransformer &transformer); - static unique_ptr TransformBaseTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUnqualifiedBaseTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUnqualifiedBaseTableName(PEGTransformer &transformer, const Identifier &table_name); - static unique_ptr TransformQualifiedTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSchemaReservedTableInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSchemaReservedTable(PEGTransformer &transformer, const Identifier &schema_qualification, const Identifier &reserved_table_name); - static unique_ptr TransformCatalogReservedSchemaTableInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCatalogReservedSchemaTable(PEGTransformer &transformer, const Identifier &catalog_qualification, const vector &reserved_schema_qualification, const Identifier &reserved_table_name); - static unique_ptr TransformTableFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTableFunctionLateralOptInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableFunctionLateralOpt(PEGTransformer &transformer, const optional &lateral, const QualifiedName &qualified_table_function, vector table_function_arguments, const optional &with_ordinality, const optional &table_alias); - static unique_ptr TransformTableFunctionAliasColonInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformTableFunctionAliasColon(PEGTransformer &transformer, const Identifier &table_alias_colon, const QualifiedName &qualified_table_function, vector table_function_arguments, const optional &with_ordinality, optional> sample_clause); - static unique_ptr TransformWithOrdinalityInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformWithOrdinality(PEGTransformer &transformer); - static unique_ptr TransformQualifiedTableFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformQualifiedTableFunction(PEGTransformer &transformer, const optional &catalog_qualification, const optional> &schema_qualification, const Identifier &table_function_name); - static unique_ptr TransformTableFunctionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformTableFunctionArguments(PEGTransformer &transformer, optional> function_argument); - static unique_ptr TransformFunctionArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNamedFunctionArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static FunctionArgument TransformNamedFunctionArgument(PEGTransformer &transformer, MacroParameter named_parameter); - static unique_ptr TransformPositionalFunctionArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static FunctionArgument TransformPositionalFunctionArgument(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformNamedParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result); static MacroParameter TransformNamedParameter(PEGTransformer &transformer, const Identifier &type_func_name, const optional &type, unique_ptr expression); - static unique_ptr TransformTableAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformTableAliasAsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TableAlias TransformTableAliasAs(PEGTransformer &transformer, const QualifiedName &identifier_or_string_literal, const optional> &column_aliases); - static unique_ptr TransformTableAliasWithoutAsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TableAlias TransformTableAliasWithoutAs(PEGTransformer &transformer, const Identifier &identifier, const optional> &column_aliases); - static unique_ptr TransformAtClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAtClause(PEGTransformer &transformer, unique_ptr at_specifier); - static unique_ptr TransformAtSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformAtSpecifier(PEGTransformer &transformer, const string &at_unit, unique_ptr expression); - static unique_ptr TransformAtUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformVersionAtUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformVersionAtUnit(PEGTransformer &transformer); - static unique_ptr TransformTimestampAtUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformTimestampAtUnit(PEGTransformer &transformer); - static unique_ptr TransformJoinClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNearestJoinClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNearestJoinAliasedInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestJoinAliased(PEGTransformer &transformer, const optional &join_type, unique_ptr table_ref, const optional &approx_or_exact, optional> number_literal, const OrderType &distance_or_similarity, unique_ptr expression); - static unique_ptr TransformNearestJoinBareInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestJoinBare(PEGTransformer &transformer, const optional &join_type, unique_ptr nearest_bare_table_ref, const optional &approx_or_exact, optional> number_literal, const OrderType &distance_or_similarity, unique_ptr expression); - static unique_ptr TransformNearestBareTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNearestValuesRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestValuesRef(PEGTransformer &transformer, unique_ptr values_clause); - static unique_ptr TransformNearestTableFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestTableFunction(PEGTransformer &transformer, const optional &lateral, const QualifiedName &qualified_table_function, vector table_function_arguments, const optional &with_ordinality); - static unique_ptr TransformNearestTableSubqueryInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestTableSubquery(PEGTransformer &transformer, const optional &lateral, unique_ptr subquery_reference); - static unique_ptr TransformNearestBaseTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestBaseTableRef(PEGTransformer &transformer, unique_ptr base_table_name, optional> at_clause, optional> sample_clause); - static unique_ptr TransformNearestParensTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformNearestParensTableRef(PEGTransformer &transformer, unique_ptr table_ref, optional> sample_clause); - static unique_ptr TransformApproxOrExactInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNearestApproxInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformNearestApprox(PEGTransformer &transformer); - static unique_ptr TransformNearestExactInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformNearestExact(PEGTransformer &transformer); - static unique_ptr TransformDistanceOrSimilarityInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNearestDistanceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderType TransformNearestDistance(PEGTransformer &transformer); - static unique_ptr TransformNearestSimilarityInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderType TransformNearestSimilarity(PEGTransformer &transformer); - static unique_ptr TransformRegularJoinClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRegularJoinClause(PEGTransformer &transformer, const optional &asof, const optional &join_type, unique_ptr table_ref, JoinQualifier join_qualifier); - static unique_ptr TransformJoinByClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformJoinByClause(PEGTransformer &transformer, const string &col_label, unique_ptr table_ref, JoinQualifier join_qualifier); - static unique_ptr TransformAsofInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformAsof(PEGTransformer &transformer); - static unique_ptr TransformJoinWithoutOnClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformJoinWithoutOnClause(PEGTransformer &transformer, const JoinPrefix &join_prefix, unique_ptr inner_table_ref); - static unique_ptr TransformJoinQualifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOnClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinQualifier TransformOnClause(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformUsingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinQualifier TransformUsingClause(PEGTransformer &transformer, const vector &column_name); - static unique_ptr TransformJoinTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCrossJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinPrefix TransformCrossJoinPrefix(PEGTransformer &transformer); - static unique_ptr TransformNaturalJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinPrefix TransformNaturalJoinPrefix(PEGTransformer &transformer, const optional &join_type); - static unique_ptr TransformPositionalJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinPrefix TransformPositionalJoinPrefix(PEGTransformer &transformer); - static unique_ptr TransformFullJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinType TransformFullJoin(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformLeftJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinType TransformLeftJoin(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformRightJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinType TransformRightJoin(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformSemiJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinType TransformSemiJoin(PEGTransformer &transformer); - static unique_ptr TransformAntiJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinType TransformAntiJoin(PEGTransformer &transformer); - static unique_ptr TransformInnerJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result); static JoinType TransformInnerJoin(PEGTransformer &transformer); - static unique_ptr TransformFromClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformFromClause(PEGTransformer &transformer, vector> table_ref); - static unique_ptr TransformWhereClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformWhereClause(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformGroupByClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByNode TransformGroupByClause(PEGTransformer &transformer, GroupByNode group_by_expressions); - static unique_ptr TransformHavingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformHavingClause(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformQualifyClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformQualifyClause(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformSampleClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSampleClause(PEGTransformer &transformer, unique_ptr sample_entry); - static unique_ptr TransformWindowClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformWindowClause(PEGTransformer &transformer, vector> window_definition); - static unique_ptr TransformSampleEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSampleEntryCountInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSampleEntryCount(PEGTransformer &transformer, unique_ptr sample_count, const optional> &sample_properties); - static unique_ptr TransformSampleEntryFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSampleEntryFunction(PEGTransformer &transformer, const optional &sample_function, unique_ptr sample_count, const optional &repeatable_sample); - static unique_ptr TransformSampleFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SampleMethod TransformSampleFunction(PEGTransformer &transformer, const Identifier &col_id); - static unique_ptr TransformSamplePropertiesInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair TransformSampleProperties(PEGTransformer &transformer, const Identifier &col_id, const optional &sample_seed); - static unique_ptr TransformRepeatableSampleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static optional_idx TransformRepeatableSample(PEGTransformer &transformer, const optional_idx &sample_seed); - static unique_ptr TransformSampleSeedInternal(PEGTransformer &transformer, - ParseResult &parse_result); static optional_idx TransformSampleSeed(PEGTransformer &transformer, unique_ptr number_literal); - static unique_ptr TransformSampleCountInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSampleCount(PEGTransformer &transformer, unique_ptr sample_value, const optional &sample_unit); - static unique_ptr TransformSampleValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSampleUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSamplePercentageInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformSamplePercentage(PEGTransformer &transformer); - static unique_ptr TransformSampleRowsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static bool TransformSampleRows(PEGTransformer &transformer); - static unique_ptr TransformGroupByExpressionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformGroupByAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByNode TransformGroupByAll(PEGTransformer &transformer); - static unique_ptr TransformGroupByListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByNode TransformGroupByList(PEGTransformer &transformer, vector group_by_expression); - static unique_ptr TransformGroupByExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformGroupByBaseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByExpressionInfo TransformGroupByBaseExpression(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformEmptyGroupingItemInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByExpressionInfo TransformEmptyGroupingItem(PEGTransformer &transformer); - static unique_ptr TransformCubeOrRollupClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByExpressionInfo TransformCubeOrRollupClause(PEGTransformer &transformer, const string &cube_or_rollup, optional>> expression); - static unique_ptr TransformCubeOrRollupInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformCubeKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformCubeKeyword(PEGTransformer &transformer); - static unique_ptr TransformRollupKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformRollupKeyword(PEGTransformer &transformer); - static unique_ptr TransformGroupingSetsClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static GroupByExpressionInfo TransformGroupingSetsClause(PEGTransformer &transformer, vector group_by_expression); - static unique_ptr TransformSubqueryReferenceInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSubqueryReference(PEGTransformer &transformer, unique_ptr select_statement_internal); - static unique_ptr TransformOrderByExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderByNode TransformOrderByExpression(PEGTransformer &transformer, unique_ptr expression, const optional &desc_or_asc, const optional &nulls_first_or_last); - static unique_ptr TransformDescOrAscInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformDescendingOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderType TransformDescendingOrder(PEGTransformer &transformer); - static unique_ptr TransformAscendingOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderType TransformAscendingOrder(PEGTransformer &transformer); - static unique_ptr TransformNullsFirstOrLastInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformNullsFirstInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderByNullType TransformNullsFirst(PEGTransformer &transformer); - static unique_ptr TransformNullsLastInternal(PEGTransformer &transformer, - ParseResult &parse_result); static OrderByNullType TransformNullsLast(PEGTransformer &transformer); - static unique_ptr TransformOrderByClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformOrderByClause(PEGTransformer &transformer, vector order_by_expressions); - static unique_ptr TransformOrderByExpressionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOrderByExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformOrderByExpressionList(PEGTransformer &transformer, vector order_by_expression); - static unique_ptr TransformOrderByAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformOrderByAll(PEGTransformer &transformer, const optional &desc_or_asc, const optional &nulls_first_or_last); - static unique_ptr TransformLimitClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformLimitClause(PEGTransformer &transformer, LimitPercentResult limit_value); - static unique_ptr TransformOffsetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformOffsetClause(PEGTransformer &transformer, LimitPercentResult offset_value); - static unique_ptr TransformOffsetValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformOffsetValue(PEGTransformer &transformer, unique_ptr expression, const bool &has_result); - static unique_ptr TransformLimitValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLimitAllInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformLimitAll(PEGTransformer &transformer); - static unique_ptr TransformLimitLiteralPercentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformLimitLiteralPercent(PEGTransformer &transformer, unique_ptr number_literal); - static unique_ptr TransformLimitExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformLimitExpression(PEGTransformer &transformer, unique_ptr expression, const bool &has_result); - static unique_ptr TransformFetchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformFetchValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); static LimitPercentResult TransformFetchValue(PEGTransformer &transformer, unique_ptr expression); - static unique_ptr TransformAliasedExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformColIdExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformColIdExpression(PEGTransformer &transformer, const Identifier &col_id, unique_ptr expression); - static unique_ptr TransformExpressionAsCollabelInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExpressionAsCollabel(PEGTransformer &transformer, unique_ptr expression, const Identifier &col_label_or_string); - static unique_ptr TransformExpressionOptIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformExpressionOptIdentifier(PEGTransformer &transformer, unique_ptr expression, const optional &identifier); - static unique_ptr TransformValuesClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformValuesClause(PEGTransformer &transformer, vector>> values_expressions); - static unique_ptr TransformValuesExpressionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformValuesExpressions(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformSetStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetStatement(PEGTransformer &transformer, unique_ptr set_assignment_or_time_zone); - static unique_ptr TransformSetAssignmentOrTimeZoneInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformResetStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformResetStatement(PEGTransformer &transformer, const SettingInfo &set_variable_or_setting); - static unique_ptr TransformSetSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetSchema(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformStandardAssignmentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformStandardAssignment(PEGTransformer &transformer, const SettingInfo &set_variable_or_setting, vector> set_assignment); - static unique_ptr TransformSetVariableOrSettingInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSetTimeZoneInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformSetTimeZone(PEGTransformer &transformer, unique_ptr zone_value); - static unique_ptr TransformZoneValueInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformZoneLocalInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformZoneLocal(PEGTransformer &transformer); - static unique_ptr TransformZoneDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformZoneDefault(PEGTransformer &transformer); - static unique_ptr TransformZoneStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformZoneStringLiteral(PEGTransformer &transformer, const string &string_literal); - static unique_ptr TransformZoneIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformZoneIdentifier(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformZoneIntervalWithIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformZoneIntervalWithInterval(PEGTransformer &transformer, const string &string_literal, const optional &interval); - static unique_ptr TransformZoneIntervalWithPrecisionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformZoneIntervalWithPrecision(PEGTransformer &transformer, unique_ptr number_literal, const string &string_literal); - static unique_ptr TransformSetSettingInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SettingInfo TransformSetSetting(PEGTransformer &transformer, const optional &setting_scope, const Identifier &setting_name); - static unique_ptr TransformSetVariableInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SettingInfo TransformSetVariable(PEGTransformer &transformer, const SetScope &variable_scope, const Identifier &identifier); - static unique_ptr TransformVariableScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SetScope TransformVariableScope(PEGTransformer &transformer); - static unique_ptr TransformSettingScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformLocalScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SetScope TransformLocalScope(PEGTransformer &transformer); - static unique_ptr TransformSessionScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SetScope TransformSessionScope(PEGTransformer &transformer); - static unique_ptr TransformGlobalScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static SetScope TransformGlobalScope(PEGTransformer &transformer); - static unique_ptr TransformSetAssignmentInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformSetAssignment(PEGTransformer &transformer, vector> variable_list); - static unique_ptr TransformVariableListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector> TransformVariableList(PEGTransformer &transformer, vector> expression); - static unique_ptr TransformTransactionStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformBeginTransactionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBeginTransaction(PEGTransformer &transformer, const bool &has_result, const optional &read_or_write); - static unique_ptr TransformRollbackTransactionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformRollbackTransaction(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformCommitTransactionInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformCommitTransaction(PEGTransformer &transformer, const bool &has_result); - static unique_ptr TransformReadOrWriteInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TransactionModifierType TransformReadOrWrite(PEGTransformer &transformer, const TransactionModifierType &read_only_or_read_write); - static unique_ptr TransformReadOnlyOrReadWriteInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformReadOnlyInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TransactionModifierType TransformReadOnly(PEGTransformer &transformer); - static unique_ptr TransformReadWriteInternal(PEGTransformer &transformer, - ParseResult &parse_result); static TransactionModifierType TransformReadWrite(PEGTransformer &transformer); - static unique_ptr TransformUpdateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateStatement(PEGTransformer &transformer, optional with_clause, unique_ptr update_target, unique_ptr update_set_clause, optional> from_clause, optional> where_clause, optional>> returning_clause); - static unique_ptr TransformUpdateTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformBaseTableSetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBaseTableSet(PEGTransformer &transformer, unique_ptr base_table_name); - static unique_ptr TransformBaseTableAliasSetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformBaseTableAliasSet(PEGTransformer &transformer, unique_ptr base_table_name, const optional &update_alias); - static unique_ptr TransformUpdateAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformUpdateAlias(PEGTransformer &transformer, const bool &has_result, const Identifier &col_id); - static unique_ptr TransformUpdateSetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformUpdateSetTupleInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateSetTuple(PEGTransformer &transformer, const vector &column_name, unique_ptr expression); - static unique_ptr TransformUpdateSetElementListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUpdateSetElementList(PEGTransformer &transformer, vector>> update_set_element); - static unique_ptr TransformUpdateSetElementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static pair> TransformUpdateSetElement(PEGTransformer &transformer, const string &update_set_column_target, unique_ptr expression); - static unique_ptr TransformUpdateSetColumnTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformUpdateSetColumnTarget(PEGTransformer &transformer, const Identifier &column_name, const optional> &dot_identifier); - static unique_ptr TransformUseStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformUseStatement(PEGTransformer &transformer, const QualifiedName &use_target); - static unique_ptr TransformUseTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformSchemaNameAsUseTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformSchemaNameAsUseTarget(PEGTransformer &transformer, const Identifier &schema_name); - static unique_ptr TransformCatalogNameAsUseTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformCatalogNameAsUseTarget(PEGTransformer &transformer, const Identifier &catalog_name); - static unique_ptr TransformUseTargetCatalogSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result); static QualifiedName TransformUseTargetCatalogSchema(PEGTransformer &transformer, const Identifier &catalog_name, const Identifier &reserved_schema_name, const optional> &dot_identifier); - static unique_ptr TransformDotIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result); static Identifier TransformDotIdentifier(PEGTransformer &transformer, const Identifier &identifier); - static unique_ptr TransformVacuumStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result); static unique_ptr TransformVacuumStatement(PEGTransformer &transformer, const optional &vacuum_options, optional analyze_target); - static unique_ptr TransformVacuumOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformVacuumParensOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static VacuumOptions TransformVacuumParensOptions(PEGTransformer &transformer, const vector &vacuum_option); - static unique_ptr TransformVacuumLegacyOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result); static VacuumOptions TransformVacuumLegacyOptions(PEGTransformer &transformer, const optional &opt_full, const optional &opt_freeze, const optional &opt_verbose, const optional &opt_analyze); - static unique_ptr TransformVacuumOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result); - static unique_ptr TransformOptAnalyzeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformOptAnalyze(PEGTransformer &transformer, const Identifier &analyze_keyword); - static unique_ptr TransformOptFullInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformOptFull(PEGTransformer &transformer); - static unique_ptr TransformOptFreezeInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformOptFreeze(PEGTransformer &transformer); - static unique_ptr TransformOptVerboseInternal(PEGTransformer &transformer, - ParseResult &parse_result); static string TransformOptVerbose(PEGTransformer &transformer); - static unique_ptr TransformNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result); static vector TransformNameList(PEGTransformer &transformer, const vector &col_id); //===--------------------------------------------------------------------===// - // END GENERATED RULES + // END GENERATED TRAMPOLINE RULES //===--------------------------------------------------------------------===// + PEGTransformerFactory(const PEGTransformerFactory &) = delete; + + static const case_insensitive_map_t &GeneratedTransformFrameOps(); + + static string ExtractFormat(const string &file_path); + + static string TransformIdentifierOrKeyword(PEGTransformer &transformer, ParseResult &parse_result); + private: explicit PEGTransformerFactory(ParsedGrammar &grammar_p); ParsedGrammar &grammar; diff --git a/src/duckdb/src/include/duckdb/parser/simplified_token.hpp b/src/duckdb/src/include/duckdb/parser/simplified_token.hpp index ff073a3cf..2c98f805a 100644 --- a/src/duckdb/src/include/duckdb/parser/simplified_token.hpp +++ b/src/duckdb/src/include/duckdb/parser/simplified_token.hpp @@ -36,12 +36,13 @@ enum class KeywordCategory : uint8_t { KEYWORD_UNRESERVED, KEYWORD_TYPE_FUNC, KEYWORD_COL_NAME, - KEYWORD_NONE + KEYWORD_NONE, + KEYWORD_TYPE_NAME }; struct ParserKeyword { string name; - KeywordCategory category; + string category; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/tableref/table_function_ref.hpp b/src/duckdb/src/include/duckdb/parser/tableref/table_function_ref.hpp index e20a8eb49..41d488858 100644 --- a/src/duckdb/src/include/duckdb/parser/tableref/table_function_ref.hpp +++ b/src/duckdb/src/include/duckdb/parser/tableref/table_function_ref.hpp @@ -14,6 +14,8 @@ #include "duckdb/common/enums/ordinality_request_type.hpp" namespace duckdb { +struct TableFunctionInfo; + //! Represents a Table producing function class TableFunctionRef : public TableRef { public: @@ -24,6 +26,9 @@ class TableFunctionRef : public TableRef { unique_ptr function; + //! Process-local input for this invocation, retained when copying the reference + shared_ptr bind_info; + // if the function takes a subquery as argument its in here unique_ptr subquery; @@ -38,6 +43,7 @@ class TableFunctionRef : public TableRef { unique_ptr Copy() override; //! Deserializes a blob back into a BaseTableRef + const unique_ptr &SerializableFunction() const; void Serialize(Serializer &serializer) const override; static unique_ptr Deserialize(Deserializer &source); }; diff --git a/src/duckdb/src/include/duckdb/parser/token_iterator.hpp b/src/duckdb/src/include/duckdb/parser/token_iterator.hpp index 74f732f52..8e72ee327 100644 --- a/src/duckdb/src/include/duckdb/parser/token_iterator.hpp +++ b/src/duckdb/src/include/duckdb/parser/token_iterator.hpp @@ -34,6 +34,12 @@ class TokenIterator { DUCKDB_API idx_t EndOffset() const; DUCKDB_API optional_ptr Current() const; + LiteralInfo CurrentLiteralInfo(const GrammarLiteralTable &table) { + if (position >= tokens.size()) { + return LiteralInfo(); + } + return tokens[position].GetLiteralInfo(table); + } DUCKDB_API const MatcherToken &Previous() const; DUCKDB_API const MatcherToken &GetToken(idx_t index) const; diff --git a/src/duckdb/src/include/duckdb/planner/binder.hpp b/src/duckdb/src/include/duckdb/planner/binder.hpp index a5a7e316c..3cfd7f07e 100644 --- a/src/duckdb/src/include/duckdb/planner/binder.hpp +++ b/src/duckdb/src/include/duckdb/planner/binder.hpp @@ -19,6 +19,7 @@ #include "duckdb/common/unordered_set.hpp" #include "duckdb/parser/column_definition.hpp" #include "duckdb/parser/query_node.hpp" +#include "duckdb/parser/tableref/table_function_ref.hpp" #include "duckdb/parser/result_modifier.hpp" #include "duckdb/parser/tableref/delimgetref.hpp" #include "duckdb/parser/tokens.hpp" @@ -44,6 +45,7 @@ class BoundResultModifier; class BoundSelectNode; class ClientContext; class ExpressionBinder; +struct ExternalResourceOptions; class LimitModifier; class OrderBinder; class TableCatalogEntry; @@ -238,6 +240,12 @@ class Binder : public enable_shared_from_this { unordered_map recursive_ctes; +public: + //! Whether the expression is COUNT(tbl.*) + static bool IsQualifiedCountStar(const ParsedExpression &expr); + //! Rewrites COUNT(tbl.*) into a COUNT that skips the rows NULL-extended by an outer join, or returns nullptr + unique_ptr TryRewriteQualifiedCountStar(const ParsedExpression &expr); + public: DUCKDB_API BoundStatement Bind(SQLStatement &statement); DUCKDB_API BoundStatement Bind(QueryNode &node); @@ -483,6 +491,13 @@ class Binder : public enable_shared_from_this { BoundStatement Bind(ConnectStatement &stmt); BoundStatement Bind(DisconnectStatement &stmt); BoundStatement Bind(ExternalResourceStatement &stmt); + //! Bind + constant-fold a single EXTERNAL RESOURCE expression (a create param, or the REGISTER handle). + Value BindExternalResourceValue(unique_ptr &expr); + //! Bind + constant-fold the create params of an EXTERNAL RESOURCE statement or clause. + void BindExternalResourceParams(case_insensitive_map_t> &parsed_params, + unordered_map ¶ms); + //! Bind the `ATTACH/CONNECT TO EXTERNAL RESOURCE ...` clause. Shared by ATTACH and CONNECT. + void BindExternalResource(ExternalResourceOptions &external_resource); //! Resolves the base table for DROP TRIGGER, stamps catalog/schema onto stmt.info, //! and registers the catalog modification. IF EXISTS only guards the trigger, not the table. diff --git a/src/duckdb/src/include/duckdb/planner/expression.hpp b/src/duckdb/src/include/duckdb/planner/expression.hpp index 757053990..9fe3c0fa0 100644 --- a/src/duckdb/src/include/duckdb/planner/expression.hpp +++ b/src/duckdb/src/include/duckdb/planner/expression.hpp @@ -33,10 +33,13 @@ class Expression : public BaseExpression { const LogicalType &GetReturnType() const { return return_type; } - void SetReturnType(LogicalType type) { + virtual void SetReturnType(LogicalType type) { return_type = std::move(type); } + //! Preserve the SQL result type when replacing an expression with an equivalent value. + static unique_ptr PreserveReturnType(const LogicalType &type, unique_ptr replacement); + const unique_ptr &GetVerificationStats() const { return verification_stats; } @@ -80,7 +83,7 @@ class Expression : public BaseExpression { type = other.type; expression_class = other.expression_class; alias = other.alias; - return_type = other.return_type; + SetReturnType(other.return_type); query_location = other.query_location; } }; diff --git a/src/duckdb/src/include/duckdb/planner/expression/bound_constant_expression.hpp b/src/duckdb/src/include/duckdb/planner/expression/bound_constant_expression.hpp index 270f98d68..28342b237 100644 --- a/src/duckdb/src/include/duckdb/planner/expression/bound_constant_expression.hpp +++ b/src/duckdb/src/include/duckdb/planner/expression/bound_constant_expression.hpp @@ -24,9 +24,9 @@ class BoundConstantExpression : public Expression { const Value &GetValue() const { return value; } - Value &GetValueMutable() { - return value; - } + void SetValue(Value value_p); + Value TakeValue(); + void SetReturnType(LogicalType type) override; string ToString() const override; bool Equals(const BaseExpression &other) const override; diff --git a/src/duckdb/src/include/duckdb/planner/expression/bound_window_expression.hpp b/src/duckdb/src/include/duckdb/planner/expression/bound_window_expression.hpp index 0d437ac34..9de76e9c2 100644 --- a/src/duckdb/src/include/duckdb/planner/expression/bound_window_expression.hpp +++ b/src/duckdb/src/include/duckdb/planner/expression/bound_window_expression.hpp @@ -11,6 +11,7 @@ #include "duckdb/parser/expression/window_expression.hpp" #include "duckdb/function/function.hpp" #include "duckdb/planner/expression.hpp" +#include "duckdb/parser/parsed_expression.hpp" #include "duckdb/planner/bound_result_modifier.hpp" namespace duckdb { @@ -111,6 +112,17 @@ class BoundWindowExpression : public Expression { unique_ptr &EndExprMutable() { return end_expr; } + void RetainSQLRange(optional_ptr start, optional_ptr end, + const LogicalType &order_type); + const unique_ptr &SQLRangeStart() const { + return sql_range_start; + } + const unique_ptr &SQLRangeEnd() const { + return sql_range_end; + } + const LogicalType &SQLRangeOrderType() const { + return sql_range_order_type; + } const vector &ArgOrders() const { return arg_orders; } @@ -189,6 +201,11 @@ class BoundWindowExpression : public Expression { unique_ptr start_expr; unique_ptr end_expr; + //! Literal SQL offsets before endpoint arithmetic; these are not execution children. + unique_ptr sql_range_start; + unique_ptr sql_range_end; + LogicalType sql_range_order_type = LogicalType::INVALID; + //! The set of argument ordering clauses //! These are distinct from the frame ordering clauses e.g., the "x" in //! FIRST_VALUE(a ORDER BY x) OVER (PARTITION BY p ORDER BY s) diff --git a/src/duckdb/src/include/duckdb/planner/logical_plan_verification_result.hpp b/src/duckdb/src/include/duckdb/planner/logical_plan_verification_result.hpp index f7f77ee85..f100b8fcd 100644 --- a/src/duckdb/src/include/duckdb/planner/logical_plan_verification_result.hpp +++ b/src/duckdb/src/include/duckdb/planner/logical_plan_verification_result.hpp @@ -158,12 +158,12 @@ class LogicalPlanVerificationResult { T &GetValue() { D_ASSERT(IsSuccess()); - return *value; + return value.value(); } const T &GetValue() const { D_ASSERT(IsSuccess()); - return *value; + return value.value(); } const vector &GetIssues() const { diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp index efbb095e6..0f1f78495 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp @@ -56,6 +56,8 @@ class LogicalCopyToFile : public LogicalOperator { PreserveOrderType preserve_order = PreserveOrderType::AUTOMATIC; vector partition_columns; vector order_columns; + //! Directory of a partition's files relative to file_path (see PhysicalCopyToFile) + unique_ptr partition_path_expression; vector names; vector expected_types; diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp index b9dc9958b..f5d597464 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp @@ -9,6 +9,7 @@ #pragma once #include "duckdb/function/table_function.hpp" +#include "duckdb/common/enums/ordinality_request_type.hpp" #include "duckdb/planner/logical_operator.hpp" #include "duckdb/planner/table_filter_set.hpp" #include "duckdb/common/extra_operator_info.hpp" @@ -35,6 +36,8 @@ class LogicalGet : public LogicalOperator { TableFunction function; //! The bind data of the function unique_ptr bind_data; + //! Process-local input that cannot be reconstructed from SQL parameters + shared_ptr bind_info; //! The types of ALL columns that can be returned by the table function vector returned_types; //! The names of ALL columns that can be returned by the table function @@ -49,6 +52,8 @@ class LogicalGet : public LogicalOperator { vector parameters; //! The set of named input parameters for the table function named_parameter_map_t named_parameters; + //! Whether the source invocation requested an ordinality column + OrdinalityType source_ordinality = OrdinalityType::WITHOUT_ORDINALITY; //! The set of named input table types for the table-in table-out function vector input_table_types; //! The set of named input table names for the table-in table-out function diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_limit.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_limit.hpp index a8becefec..9624e6458 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_limit.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_limit.hpp @@ -23,6 +23,8 @@ class LogicalLimit : public LogicalOperator { BoundLimitNode limit_val; BoundLimitNode offset_val; + //! SQL offset before row group pruning removed rows from the scan. + optional_idx unpruned_offset; public: vector GetColumnBindings() override; diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_materialized_cte.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_materialized_cte.hpp index 1a5eb1773..d4c6369ec 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_materialized_cte.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_materialized_cte.hpp @@ -13,6 +13,16 @@ namespace duckdb { +//! Retaining outer rows preserves every domain partition needed for their results. +//! The domain scan has no consumers independent of the outer-row scan. +struct CTEFilterDependency { + CTEFilterDependency(TableIndex row_scan, TableIndex domain_scan) : row_scan(row_scan), domain_scan(domain_scan) { + } + + TableIndex row_scan; + TableIndex domain_scan; +}; + class LogicalMaterializedCTE : public LogicalCTE { explicit LogicalMaterializedCTE() : LogicalCTE(LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) { } @@ -30,6 +40,8 @@ class LogicalMaterializedCTE : public LogicalCTE { } CTEMaterialize materialize = CTEMaterialize::CTE_MATERIALIZE_ALWAYS; + //! Valid only for the original generated consumers, until CTE filter pushdown. Deliberately not serialized. + unique_ptr filter_dependency; public: InsertionOrderPreservingMap ParamsToString() const override; diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_secure_view.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_secure_view.hpp index 6b3278cb8..20236566a 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_secure_view.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_secure_view.hpp @@ -8,10 +8,14 @@ #pragma once +#include "duckdb/common/types/value.hpp" +#include "duckdb/parser/qualified_name.hpp" #include "duckdb/planner/logical_operator.hpp" namespace duckdb { +class BoundAtClause; + //! LogicalSecureView wraps the expanded plan of a secure view. It does not alter the result of its child - it only //! acts as an optimization barrier that prevents the optimizer from pushing anything into the view. class LogicalSecureView : public LogicalOperator { @@ -20,14 +24,35 @@ class LogicalSecureView : public LogicalOperator { public: LogicalSecureView(string view_name, unique_ptr child); + LogicalSecureView(string view_name, QualifiedName source_name, vector source_types, + optional_ptr at_clause, unique_ptr child); //! The name of the view - used for printing the plan string view_name; //! The filters that the optimizer pushed into the view - these are the caller's own expressions, and they are //! reported as part of the boundary node because the operators inside the view are never shown vector pushed_filters; + //! Whether the statistics of the columns the view emits may escape the boundary. Set by AnalyzeStatistics + bool propagate_statistics = false; + //! Qualified source identity and the original positional schema used by SQL export + bool has_source = false; + QualifiedName source_name; + vector source_types; + bool has_at_clause = false; + Identifier at_unit; + Value at_value; + //! Current child bindings and their expressions over the original positional schema + vector output_bindings; + vector> output_expressions; + //! Caller predicates expressed over the original positional view schema + vector> source_filters; public: + //! Determine for every secure view in the plan whether the statistics of the columns it emits may escape it. + //! This must run before anything is pushed into the views - the filters that the optimizer pushes into a view + //! are the caller's own, and must not be mistaken for the view restricting the rows it emits + static void AnalyzeStatistics(LogicalOperator &plan); + vector GetColumnBindings() override; idx_t EstimateCardinality(ClientContext &context) override; InsertionOrderPreservingMap ParamsToString() const override; diff --git a/src/duckdb/src/include/duckdb/planner/operator/logical_top_n.hpp b/src/duckdb/src/include/duckdb/planner/operator/logical_top_n.hpp index 6a2f38ab6..aaeb99d8b 100644 --- a/src/duckdb/src/include/duckdb/planner/operator/logical_top_n.hpp +++ b/src/duckdb/src/include/duckdb/planner/operator/logical_top_n.hpp @@ -28,6 +28,8 @@ class LogicalTopN : public LogicalOperator { idx_t limit; //! The offset from the start to begin emitting elements idx_t offset; + //! SQL offset before row group pruning removed rows from the scan. + optional_idx unpruned_offset; //! Dynamic table filter (if any) shared_ptr dynamic_filter; diff --git a/src/duckdb/src/include/duckdb/planner/sql_export_helpers.hpp b/src/duckdb/src/include/duckdb/planner/sql_export_helpers.hpp index 1c358698c..adb6665cf 100644 --- a/src/duckdb/src/include/duckdb/planner/sql_export_helpers.hpp +++ b/src/duckdb/src/include/duckdb/planner/sql_export_helpers.hpp @@ -53,5 +53,24 @@ inline bool IsSQLRepresentableType(const LogicalType &type) { !TypeVisitor::Contains(type, [](const LogicalType &child) { return !IsSQLExportType(child.id()); }); } +inline bool SQLTypesMatch(const LogicalType &left, const LogicalType &right) { + if (left != right) { + return false; + } + vector collations; + TypeVisitor::Contains(left, [&](const LogicalType &child) { + if (child.id() == LogicalTypeId::VARCHAR) { + collations.push_back(StringType::GetCollation(child)); + } + return false; + }); + idx_t index = 0; + const auto mismatch = TypeVisitor::Contains(right, [&](const LogicalType &child) { + return child.id() == LogicalTypeId::VARCHAR && + (index >= collations.size() || collations[index++] != StringType::GetCollation(child)); + }); + return !mismatch && index == collations.size(); +} + } // namespace SQLExportHelpers } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/planner/table_binding.hpp b/src/duckdb/src/include/duckdb/planner/table_binding.hpp index 1d7cf1f2e..993f8fe1c 100644 --- a/src/duckdb/src/include/duckdb/planner/table_binding.hpp +++ b/src/duckdb/src/include/duckdb/planner/table_binding.hpp @@ -59,6 +59,9 @@ struct Binding { const vector &GetColumnNames(); idx_t GetColumnCount(); void SetColumnType(idx_t col_idx, LogicalType type); + //! Marks this binding as the NULL-producing side of an outer join + void SetNullExtended(); + bool IsNullExtended() const; static BindingAlias GetAlias(const Identifier &explicit_alias, const StandardEntry &entry); static BindingAlias GetAlias(const Identifier &explicit_alias, optional_ptr entry); @@ -98,6 +101,8 @@ struct Binding { vector names; //! Name -> index for the names identifier_map_t name_map; + //! Whether rows of this binding can be NULL-extended by an outer join + bool null_extended = false; }; struct EntryBinding : public Binding { diff --git a/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp b/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp index 331743ad0..54b5eba86 100644 --- a/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +++ b/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp @@ -29,6 +29,8 @@ class BlockHandle; using BlockLock = unique_lock; +enum class CanUnloadResult : uint8_t { CAN_UNLOAD, ALREADY_UNLOADED, PINNED, NO_TEMP_DIRECTORY }; + class BlockMemory : public enable_shared_from_this { public: BlockMemory(BufferManager &buffer_manager, block_id_t block_id_p, MemoryTag tag_p, idx_t block_alloc_size); @@ -202,10 +204,10 @@ class BlockMemory : public enable_shared_from_this { void ChangeMemoryUsage(BlockLock &l, int64_t delta); void ConvertToPersistent(BlockLock &l, BlockHandle &new_block, unique_ptr new_buffer); void ResizeBuffer(BlockLock &l, idx_t block_size, idx_t block_header_size, int64_t memory_delta); - //! Returns whether the block can be unloaded or not. + //! Returns whether the block can be unloaded or the reason why it cannot be unloaded. //! The state here can change if the block lock is held. //! However, this method does not hold the block lock. - bool CanUnload() const; + CanUnloadResult CanUnload() const; unique_ptr UnloadAndTakeBlock(BlockLock &l, QueryContext context = QueryContext()); void Unload(BlockLock &l, QueryContext context = QueryContext()); diff --git a/src/duckdb/src/include/duckdb/storage/compression/alp/alp_utils.hpp b/src/duckdb/src/include/duckdb/storage/compression/alp/alp_utils.hpp index dbb6fbd91..fd56272ec 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/alp/alp_utils.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/alp/alp_utils.hpp @@ -67,22 +67,24 @@ class AlpUtils { } template - static T FindFirstValueNotInPositionsArray(const T *input_vector, const uint16_t *positions, idx_t values_count) { - T a_non_special_value = 0; + static T FindFirstValueNotInPositionsArray(const T *input_vector, const uint16_t *null_positions, + idx_t values_count, idx_t nulls_count) { + idx_t null_idx = 0; for (idx_t i = 0; i < values_count; i++) { - if (i != positions[i]) { - a_non_special_value = input_vector[i]; - break; + if (null_idx < nulls_count && null_positions[null_idx] == i) { + null_idx++; + continue; } + return input_vector[i]; } - return a_non_special_value; + return T(0); } template - static void ReplaceValueInVectorPositions(T *input_vector, const uint16_t *positions_to_replace, - idx_t special_values_count, T value_to_replace) { - for (idx_t i = 0; i < special_values_count; i++) { - uint16_t null_value_pos = positions_to_replace[i]; + static void ReplaceValueInVectorPositions(T *input_vector, const uint16_t *null_positions, idx_t nulls_count, + T value_to_replace) { + for (idx_t i = 0; i < nulls_count; i++) { + uint16_t null_value_pos = null_positions[i]; input_vector[null_value_pos] = value_to_replace; } } @@ -93,7 +95,8 @@ class AlpUtils { if (nulls_count == 0) { return; } - T a_non_null_value = FindFirstValueNotInPositionsArray(input_vector, vector_null_positions, values_count); + T a_non_null_value = + FindFirstValueNotInPositionsArray(input_vector, vector_null_positions, values_count, nulls_count); ReplaceValueInVectorPositions(input_vector, vector_null_positions, nulls_count, a_non_null_value); } }; diff --git a/src/duckdb/src/include/duckdb/storage/data_table.hpp b/src/duckdb/src/include/duckdb/storage/data_table.hpp index 60964eb3d..7663df4e9 100644 --- a/src/duckdb/src/include/duckdb/storage/data_table.hpp +++ b/src/duckdb/src/include/duckdb/storage/data_table.hpp @@ -291,8 +291,10 @@ class DataTable : public enable_shared_from_this { //! It is either empty, or initialized via its index storage information. void AddIndex(const ColumnList &columns, const vector &column_indexes, const IndexConstraintType type, IndexStorageInfo index_info); - //! AddIndex moves an index to this table's index list. - void AddIndex(unique_ptr index); + //! AddIndex moves a catalog index to this table's index list. + void AddIndex(unique_ptr index, idx_t index_oid); + //! AddConstraintIndex moves a constraint-backed index to this table's index list. + void AddConstraintIndex(unique_ptr index); //! Returns a list of the partition stats vector GetPartitionStats(ClientContext &context); diff --git a/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system.hpp b/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system.hpp index 270519cd9..23dde25c8 100644 --- a/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system.hpp +++ b/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system.hpp @@ -145,10 +145,11 @@ class CachingFileSystem { public: DUCKDB_API static CachingFileSystem Get(ClientContext &context); - DUCKDB_API unique_ptr OpenFile(const OpenFileInfo &path, FileOpenFlags flags, + DUCKDB_API unique_ptr OpenFile(const OpenFileInfo &path, const FileOpenFlags &flags, optional_ptr opener = nullptr); DUCKDB_API unique_ptr OpenFile(QueryContext context, const OpenFileInfo &path, - FileOpenFlags flags, optional_ptr opener = nullptr); + const FileOpenFlags &flags, + optional_ptr opener = nullptr); private: //! The Client FileSystem (needs to be client-specific so we can do, e.g., HTTPFS profiling) diff --git a/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system_wrapper.hpp b/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system_wrapper.hpp index ebb57c290..c89514b63 100644 --- a/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system_wrapper.hpp +++ b/src/duckdb/src/include/duckdb/storage/external_file_cache/caching_file_system_wrapper.hpp @@ -73,6 +73,8 @@ class CachingFileSystemWrapper : public FileSystem, public enable_shared_from_th DUCKDB_API string GetVersionTag(FileHandle &handle) override; DUCKDB_API FileType GetFileType(FileHandle &handle) override; DUCKDB_API FileMetadata Stats(FileHandle &handle) override; + DUCKDB_API optional GetStatsIfExists(const OpenFileInfo &file, + optional_ptr opener = nullptr) override; DUCKDB_API void Truncate(FileHandle &handle, int64_t new_size) override; DUCKDB_API void FileSync(FileHandle &handle) override; diff --git a/src/duckdb/src/include/duckdb/storage/optimistic_data_writer.hpp b/src/duckdb/src/include/duckdb/storage/optimistic_data_writer.hpp index d5ea54be8..abaae1f13 100644 --- a/src/duckdb/src/include/duckdb/storage/optimistic_data_writer.hpp +++ b/src/duckdb/src/include/duckdb/storage/optimistic_data_writer.hpp @@ -26,6 +26,8 @@ struct OptimisticWriteCollection { void MergeStorage(OptimisticWriteCollection &collection); void FinalizeFlush(); + // Reset the accounting fields to match a freshly-replaced collection + void ResetCollectionAccounting(); }; enum class OptimisticWritePartialManagers { PER_COLUMN, GLOBAL }; diff --git a/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp b/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp index a62d5c9f4..150a15a7e 100644 --- a/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +++ b/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp @@ -120,7 +120,7 @@ class StandardBufferManager : public BufferManager { //! Helper template TempBufferPoolReservation EvictBlocksOrThrow(QueryContext context, MemoryTag tag, idx_t memory_delta, - unique_ptr *buffer, ARGS...); + unique_ptr *buffer, const ARGS &...); //! Register an in-memory buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or //! not the buffer can be destroyed instead of evicted, diff --git a/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp b/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp index df47d6075..8d899d895 100644 --- a/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp +++ b/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp @@ -35,7 +35,7 @@ struct NumericStatsData { struct NumericStats { //! Unknown statistics - i.e. "has_min" is false, "has_max" is false DUCKDB_API static BaseStatistics CreateUnknown(LogicalType type); - //! Empty statistics - i.e. "min = MaxValue, max = MinValue" + //! Empty statistics - min and max are initialized to the domain's maximum and minimum DUCKDB_API static BaseStatistics CreateEmpty(LogicalType type); //! Returns true if the stats has a constant value diff --git a/src/duckdb/src/include/duckdb/storage/statistics/stats_writer.hpp b/src/duckdb/src/include/duckdb/storage/statistics/stats_writer.hpp index 90de93b2a..d4be2a15b 100644 --- a/src/duckdb/src/include/duckdb/storage/statistics/stats_writer.hpp +++ b/src/duckdb/src/include/duckdb/storage/statistics/stats_writer.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/bswap.hpp" #include "duckdb/common/types/string_type.hpp" #include "duckdb/storage/statistics/numeric_stats.hpp" #include "duckdb/storage/statistics/string_stats.hpp" @@ -16,6 +17,9 @@ #include "utf8proc_wrapper.hpp" #include "duckdb/main/error_manager.hpp" +#include +#include + namespace duckdb { struct BaseStatsWriter { @@ -61,7 +65,11 @@ struct StatsWriter : public BaseStatsWriter { inline void Clear() { ClearBase(); - min = NumericLimits::Maximum(); + if constexpr (std::is_floating_point_v) { + min = std::numeric_limits::quiet_NaN(); + } else { + min = NumericLimits::Maximum(); + } max = NumericLimits::Minimum(); } @@ -71,8 +79,7 @@ struct StatsWriter : public BaseStatsWriter { } void UpdateMinMax(T new_value) { - min = LessThan::Operation(new_value, min) ? new_value : min; - max = GreaterThan::Operation(new_value, max) ? new_value : max; + NumericStats::UpdateValue(new_value, min, max); } void Merge(BaseStatistics &target) const { @@ -103,6 +110,22 @@ struct StatsWriter : public BaseStatsWriter { } }; +//! Lexicographic compare of two 12-byte string prefixes that are zero-padded past the string length, as the +//! inline area of a string_t is. Returns <0, 0 or >0 like memcmp. +static inline int CompareInlineBytes(const_data_ptr_t a, const_data_ptr_t b) { + const uint32_t a_prefix = Load(a); + const uint32_t b_prefix = Load(b); + if (a_prefix != b_prefix) { + return BSwapIfLE(a_prefix) < BSwapIfLE(b_prefix) ? -1 : 1; + } + const uint64_t a_rest = Load(a + sizeof(uint32_t)); + const uint64_t b_rest = Load(b + sizeof(uint32_t)); + if (a_rest != b_rest) { + return BSwapIfLE(a_rest) < BSwapIfLE(b_rest) ? -1 : 1; + } + return 0; +} + template <> struct StatsWriter : public BaseStatsWriter { friend struct StringStats; @@ -135,7 +158,8 @@ struct StatsWriter : public BaseStatsWriter { } auto data = const_data_ptr_cast(value.GetData()); auto size = value.GetSize(); - +#ifdef DUCKDB_DEBUG_NO_INLINE + // without inlining a short string only has `size` readable bytes auto copy_count = MinValue(size, StringStatsData::CURRENT_MAX_STRING_MINMAX_SIZE); if (is_set) { // compare to current min/max @@ -158,6 +182,32 @@ struct StatsWriter : public BaseStatsWriter { max_size = size; is_set = true; } +#else + // a string_t always has CURRENT_MAX_STRING_MINMAX_SIZE readable bytes at its data pointer, zero-padded + // past the length when inlined, so min and max are kept as zero-padded prefixes and compared as integers + static_assert(StringStatsData::CURRENT_MAX_STRING_MINMAX_SIZE == string_t::INLINE_LENGTH, + "the string statistics prefix is the inline area of a string_t"); + if (is_set) { + // the prefix compare covers the first min(size, min_size) bytes exactly because the shorter side is + // zero-padded, and the length breaks a tie + auto min_cmp = CompareInlineBytes(data, min); + if (min_cmp < 0 || (min_cmp == 0 && size < min_size)) { + memcpy(min, data, StringStatsData::CURRENT_MAX_STRING_MINMAX_SIZE); + min_size = size; + } + auto max_cmp = CompareInlineBytes(data, max); + if (max_cmp > 0 || (max_cmp == 0 && size > max_size)) { + memcpy(max, data, StringStatsData::CURRENT_MAX_STRING_MINMAX_SIZE); + max_size = size; + } + } else { + memcpy(min, data, StringStatsData::CURRENT_MAX_STRING_MINMAX_SIZE); + memcpy(max, data, StringStatsData::CURRENT_MAX_STRING_MINMAX_SIZE); + min_size = size; + max_size = size; + is_set = true; + } +#endif if (size > max_string_length) { max_string_length = UnsafeNumericCast(size); } diff --git a/src/duckdb/src/include/duckdb/storage/table/index_entry.hpp b/src/duckdb/src/include/duckdb/storage/table/index_entry.hpp index 03a73a009..2618499f2 100644 --- a/src/duckdb/src/include/duckdb/storage/table/index_entry.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/index_entry.hpp @@ -111,7 +111,7 @@ class IndexWriteHandle { //! The IndexEntry provides a stable logical identity which refers to an interchangeable snapshot of an index. class IndexEntry : public enable_shared_from_this { public: - explicit IndexEntry(unique_ptr index); + explicit IndexEntry(unique_ptr index, optional_idx catalog_index_oid); //! Append a chunk to the physical index, buffering it while the index is unbound. void Append(DataChunk &chunk, Vector &row_ids); //! Appends a chunk using delete and checkpoint indexes where required. @@ -132,6 +132,8 @@ class IndexEntry : public enable_shared_from_this { Identifier GetName() const; //! Returns the physical index type. string GetIndexType() const; + //! Returns whether an unbound index has buffered WAL operations. + bool HasBufferedReplays() const; //! Destroys the physical index. void Retire(); //! Binds the unbound physical index without replacing it. @@ -187,6 +189,9 @@ class IndexEntry : public enable_shared_from_this { void SetBindState(IndexBindState state) { bind_state = state; } + optional_idx GetCatalogIndexOid() const { + return catalog_index_oid; + } private: template @@ -195,6 +200,7 @@ class IndexEntry : public enable_shared_from_this { friend class IndexWriteHandle; atomic bind_state; + const optional_idx catalog_index_oid; //! Phase-fair lock protecting the physical index and all delta indexes owned by this entry. mutable StorageLock lock; //! The physical index owned by this stable logical entry. diff --git a/src/duckdb/src/include/duckdb/storage/table/row_group.hpp b/src/duckdb/src/include/duckdb/storage/table/row_group.hpp index 6fc033ba5..db8b69417 100644 --- a/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/row_group.hpp @@ -146,7 +146,7 @@ class RowGroup : public SegmentBase { void CommitDrop(); void InitializeEmpty(const vector &types, ColumnDataType data_type); - bool HasChanges() const; + bool HasChanges(VisibilityBound bound) const; //! Initialize a scan over this row_group bool InitializeScan(CollectionScanState &state, SegmentNode &node); diff --git a/src/duckdb/src/include/duckdb/storage/table/row_version_manager.hpp b/src/duckdb/src/include/duckdb/storage/table/row_version_manager.hpp index cf5627b13..60cd19ed4 100644 --- a/src/duckdb/src/include/duckdb/storage/table/row_version_manager.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/row_version_manager.hpp @@ -50,7 +50,7 @@ class RowVersionManager { vector Checkpoint(RowGroupWriter &writer); static shared_ptr Deserialize(MetaBlockPointer delete_pointer, MetadataManager &manager); - bool HasUnserializedChanges(); + bool HasUnserializedChanges(VisibilityBound bound); bool HasDeletes(); bool HasUncommittedChanges(); vector GetStoragePointers(); @@ -59,7 +59,9 @@ class RowVersionManager { mutex version_lock; FixedSizeAllocator allocator; vector> vector_info; - optional_idx uncheckpointed_delete_commit; + //! The newest and the oldest delete commit that has not been written by a checkpoint yet + optional_idx newest_uncheckpointed_delete_commit; + optional_idx oldest_uncheckpointed_delete_commit; vector storage_pointers; //! Whether a compression pass may achieve anything: set when version ids are modified, cleared when a //! pass finds no ids that could still compress. For deserialized version info this is derived from the diff --git a/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp b/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp index 7541492cb..b438014c4 100644 --- a/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp @@ -269,8 +269,6 @@ class CollectionScanState { explicit CollectionScanState(TableScanState &parent_p); //! The query context for this scan QueryContext context; - //! The current row_group we are scanning - optional_ptr> row_group; //! The vector index within the row_group idx_t vector_index; //! The maximum row within the row group @@ -309,6 +307,8 @@ class CollectionScanState { ScanFilterInfo &GetFilterInfo(); ScanSamplingInfo &GetSamplingInfo(); TableScanOptions &GetOptions(); + optional_ptr> GetRowGroup() const; + void SetRowGroup(optional_ptr> row_group); optional_ptr> GetNextRowGroup(SegmentNode &row_group) const; optional_ptr> GetNextRowGroup(SegmentLock &l, SegmentNode &row_group) const; optional_ptr> GetRootSegment() const; @@ -330,6 +330,9 @@ class CollectionScanState { vector> RegisterAssignmentIO(); private: + //! The segment node is the traversal cursor, while the shared pointer pins its replaceable payload + optional_ptr> row_group; + shared_ptr pinned_row_group; TableScanState &parent; }; diff --git a/src/duckdb/src/include/duckdb/storage/table/segment_base.hpp b/src/duckdb/src/include/duckdb/storage/table/segment_base.hpp index a56501c0d..6e89715c2 100644 --- a/src/duckdb/src/include/duckdb/storage/table/segment_base.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/segment_base.hpp @@ -14,7 +14,7 @@ namespace duckdb { template -class SegmentBase { +class SegmentBase { // NOLINT(bugprone-crtp-constructor-accessibility) public: explicit SegmentBase(idx_t count) : count(count) { } diff --git a/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp b/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp index d4ab10d52..456de75b3 100644 --- a/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp @@ -50,7 +50,7 @@ class TableIndexList { //! Iterates over shared ownership of stable index entries while holding the entry-list lock. TableIndexIterationHelper> IndexEntries() const; //! Adds an index entry to the list of index entries. - void AddIndex(unique_ptr index); + void AddIndex(unique_ptr index, optional_idx index_oid); //! Initializes the transaction-local delete and append indexes. void InitializeLocalIndexes(TableIndexList &delete_indexes, TableIndexList &append_indexes) const; //! Appends a chunk to all index entries. @@ -69,12 +69,15 @@ class TableIndexList { optional_idx active_checkpoint = optional_idx()); //! Removes an index entry from the list of index entries and release any storage the index owns. void RemoveIndex(const Identifier &name); + void RemoveIndex(idx_t index_oid); //! Returns true, if the index name does not exist. bool NameIsUnique(const string &name) const; //! Returns true if an index with the given name exists. bool Contains(const Identifier &name) const; //! Returns shared ownership of the stable logical index entry matching the name. shared_ptr FindEntry(const Identifier &name) const; + //! Matches the catalog OID, or the name when both entries have no catalog OID. + shared_ptr FindEntry(const IndexEntry &index) const; //! Binds unbound indexes possibly present after loading an extension. void Bind(ClientContext &context, DataTableInfo &table_info, const optional &index_type = {}); //! Returns true, if there are no index entries. @@ -91,6 +94,8 @@ class TableIndexList { annotated_lock_guard lock(index_entries_lock); return unbound_count != 0; } + //! Returns true if an unbound index has buffered WAL operations. + bool HasBufferedReplays() const; //! Returns true, if there are unique indexes. bool HasUniqueIndexes() const; //! Verifies all unique ART indexes, optionally recording conflicts. @@ -139,7 +144,9 @@ class TableIndexList { unordered_set GetUniqueIndexColumns() const; //! Serialize all indexes of the table. IndexSerializationResult SerializeToDisk(QueryContext context, const IndexSerializationInfo &info); - //! Serializes the index matching the name for the write-ahead log, if it exists. + //! Serializes the index matching the OID for the write-ahead log, if it exists. + unique_ptr SerializeToWAL(idx_t index_oid, const case_insensitive_map_t &options); + //! Serializes the constraint-backed index matching the name for the write-ahead log, if it exists. unique_ptr SerializeToWAL(const Identifier &name, const case_insensitive_map_t &options); public: diff --git a/src/duckdb/src/include/duckdb/transaction/commit_state.hpp b/src/duckdb/src/include/duckdb/transaction/commit_state.hpp index bb2715f7a..3c4988d81 100644 --- a/src/duckdb/src/include/duckdb/transaction/commit_state.hpp +++ b/src/duckdb/src/include/duckdb/transaction/commit_state.hpp @@ -35,7 +35,7 @@ enum class CommitMode { COMMIT, REVERT_COMMIT }; //! An index that has been marked for removal from a table's index list once the commit chain succeeds. struct PendingIndexRemoval { reference indexes; - Identifier name; + idx_t index_oid; }; //! Accumulates block marks and index removals during commit so they can be applied together once the @@ -51,7 +51,7 @@ class CommitDropState { //! Register an index to be removed from a table's index list during FinalizeCommit. Index removal will drop in //! memory index data and also marks all blocks on disk as free blocks allowing for reclamation. Block marking for //! indexes is handled implicitly along destruction paths for index memory. - void RemoveIndex(TableIndexList &indexes, Identifier name); + void RemoveIndex(TableIndexList &indexes, idx_t index_oid); //! Finalize accumulated block marks and index removals. void FinalizeCommit(); //! True if no work has been queued. diff --git a/src/duckdb/src/include/duckdb/transaction/undo_buffer.hpp b/src/duckdb/src/include/duckdb/transaction/undo_buffer.hpp index 389b8d8ab..f71b4e9ed 100644 --- a/src/duckdb/src/include/duckdb/transaction/undo_buffer.hpp +++ b/src/duckdb/src/include/duckdb/transaction/undo_buffer.hpp @@ -76,7 +76,7 @@ class UndoBuffer { template void IterateEntries(UndoBuffer::IteratorState &state, T &&callback); template - void IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback); + void ReverseIterateEntries(UndoBuffer::IteratorState &end_state, T &&callback); template void ReverseIterateEntries(T &&callback); }; diff --git a/src/duckdb/src/include/duckdb_extension_v2.h b/src/duckdb/src/include/duckdb_extension_v2.h index ae66df522..afda09878 100644 --- a/src/duckdb/src/include/duckdb_extension_v2.h +++ b/src/duckdb/src/include/duckdb_extension_v2.h @@ -80,7 +80,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_bignum_encode) (const uint8_t *in_data, idx_t in_length, bool is_negative, uint8_t *out_data, idx_t out_capacity, idx_t *out_length, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR (*duckdb_v2_close)(duckdb_v2_database_handle *db); DUCKDB_V2_ERROR(*duckdb_v2_column_data_collection_append) (duckdb_v2_column_data_collection_handle collection, duckdb_v2_column_data_collection_append_state_handle state, duckdb_v2_data_chunk_handle chunk, duckdb_v2_error_info_handle *err); @@ -118,8 +117,8 @@ typedef struct { duckdb_v2_column_data_collection_worker_scan_state_handle *out_state, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_column_data_collection_worker_scan_state_destroy) (duckdb_v2_column_data_collection_worker_scan_state_handle *state); - DUCKDB_V2_ERROR(*duckdb_v2_connect) - (duckdb_v2_database_handle db, duckdb_v2_connection_handle *out_conn, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_create) + (duckdb_v2_instance_handle instance, duckdb_v2_connection_handle *out_conn, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_connection_create_type_from_id) (duckdb_v2_connection_handle conn, DUCKDB_V2_LOGICAL_TYPE_ID type_id, const duckdb_v2_identifier_t *param_names, const duckdb_v2_value_handle *param_values, idx_t param_count, duckdb_v2_logical_type_handle *out_type, @@ -134,21 +133,23 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_connection_create_type_with_alias) (duckdb_v2_connection_handle conn, duckdb_v2_logical_type_handle base_type, duckdb_v2_identifier_t alias_name, duckdb_v2_logical_type_handle *out_type, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_interrupt) - (duckdb_v2_connection_handle conn, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_get) - (duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_get_by_index) + DUCKDB_V2_ERROR (*duckdb_v2_connection_destroy)(duckdb_v2_connection_handle *conn); + DUCKDB_V2_ERROR(*duckdb_v2_connection_get_option_by_index) (duckdb_v2_connection_handle conn, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_get_count) - (duckdb_v2_connection_handle conn, idx_t *out_count, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_option_set) - (duckdb_v2_connection_handle conn, duckdb_v2_option_handle option, DUCKDB_V2_SETTING_SCOPE scope, + DUCKDB_V2_ERROR(*duckdb_v2_connection_get_option_by_name) + (duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_connection_query_progress) - (duckdb_v2_connection_handle conn, duckdb_v2_query_progress_handle *out_progress, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_get_option_count) + (duckdb_v2_connection_handle conn, idx_t *out_count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_interrupt) + (duckdb_v2_connection_handle conn, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_progress_get) + (duckdb_v2_connection_handle conn, double *out_percentage, uint64_t *out_rows_processed, + uint64_t *out_total_rows_to_process, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_connection_set_option) + (duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, duckdb_v2_str setting, + DUCKDB_V2_SETTING_SCOPE scope, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_context_create_type_from_id) (duckdb_v2_context_handle ctx, DUCKDB_V2_LOGICAL_TYPE_ID type_id, const duckdb_v2_identifier_t *param_names, const duckdb_v2_value_handle *param_values, idx_t param_count, duckdb_v2_logical_type_handle *out_type, @@ -163,8 +164,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_context_create_type_with_alias) (duckdb_v2_context_handle ctx, duckdb_v2_logical_type_handle base_type, duckdb_v2_identifier_t alias_name, duckdb_v2_logical_type_handle *out_type, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_create_environment) - (duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_data_chunk_copy_with_connection) (duckdb_v2_connection_handle conn, duckdb_v2_data_chunk_handle chunk, duckdb_v2_data_chunk_handle *out_chunk, duckdb_v2_error_info_handle *err); @@ -188,26 +187,36 @@ typedef struct { duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_data_chunk_get_vector_count) (duckdb_v2_data_chunk_handle chunk, idx_t *out_count, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_get) - (duckdb_v2_database_handle db, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_get_by_index) - (duckdb_v2_database_handle db, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_get_count) - (duckdb_v2_database_handle db, idx_t *out_count, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_database_option_set) - (duckdb_v2_database_handle db, duckdb_v2_option_handle option, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR (*duckdb_v2_destroy_environment)(duckdb_v2_environment_handle *env); - DUCKDB_V2_ERROR (*duckdb_v2_disconnect)(duckdb_v2_connection_handle *conn); - DUCKDB_V2_ERROR(*duckdb_v2_environment_database_count) + DUCKDB_V2_ERROR(*duckdb_v2_environment_create) + (duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_environment_destroy)(duckdb_v2_environment_handle *env); + DUCKDB_V2_ERROR(*duckdb_v2_environment_get_instance_count) (duckdb_v2_environment_handle env, idx_t *out_count, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_error_info_destroy)(duckdb_v2_error_info_handle *info); DUCKDB_V2_ERROR (*duckdb_v2_error_info_get_code)(duckdb_v2_error_info_handle info, DUCKDB_V2_ERROR *out_code); - DUCKDB_V2_ERROR(*duckdb_v2_error_info_get_raw_message) - (duckdb_v2_error_info_handle info, duckdb_v2_str *out_raw_message); + DUCKDB_V2_ERROR (*duckdb_v2_error_info_get_raw_text)(duckdb_v2_error_info_handle info, duckdb_v2_str *out_raw_text); DUCKDB_V2_ERROR (*duckdb_v2_error_info_get_text)(duckdb_v2_error_info_handle info, duckdb_v2_str *out_text); DUCKDB_V2_ERROR (*duckdb_v2_error_info_set_code)(duckdb_v2_error_info_handle info, DUCKDB_V2_ERROR code); DUCKDB_V2_ERROR (*duckdb_v2_error_info_set_text)(duckdb_v2_error_info_handle info, duckdb_v2_str text); + DUCKDB_V2_ERROR(*duckdb_v2_instance_attach) + (duckdb_v2_instance_handle instance, duckdb_v2_str path, duckdb_v2_identifier_t *name, + duckdb_v2_attach_options_handle options, bool make_default, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_create) + (duckdb_v2_environment_handle env, duckdb_v2_instance_handle *out_instance, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_instance_destroy)(duckdb_v2_instance_handle *instance); + DUCKDB_V2_ERROR(*duckdb_v2_instance_detach) + (duckdb_v2_instance_handle instance, duckdb_v2_str path, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_get_option_by_index) + (duckdb_v2_instance_handle instance, idx_t index, duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_get_option_by_name) + (duckdb_v2_instance_handle instance, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_get_option_count) + (duckdb_v2_instance_handle instance, idx_t *out_count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_set_option) + (duckdb_v2_instance_handle instance, duckdb_v2_identifier_t name, duckdb_v2_str setting, + duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_library_version)(duckdb_v2_str *out_version, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_logical_type_copy) (duckdb_v2_logical_type_handle type, duckdb_v2_logical_type_handle *out_type, duckdb_v2_error_info_handle *err); @@ -227,12 +236,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_logical_type_to_text) (duckdb_v2_logical_type_handle type, char *out_text, idx_t out_capacity, idx_t *out_length, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_open) - (duckdb_v2_environment_handle env, duckdb_v2_str path, duckdb_v2_option_handle *options, idx_t option_count, - duckdb_v2_database_handle *out_db, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_option_create) - (duckdb_v2_identifier_t name, duckdb_v2_str setting, duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_option_destroy)(duckdb_v2_option_handle *option); DUCKDB_V2_ERROR(*duckdb_v2_option_get_alias) (duckdb_v2_option_handle option, idx_t index, duckdb_v2_identifier_t *out_alias, duckdb_v2_error_info_handle *err); @@ -251,13 +254,6 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_parse_sql) (duckdb_v2_connection_handle conn, const char *sql, duckdb_v2_statement_iterator_handle *out_iterator, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR (*duckdb_v2_query_progress_destroy)(duckdb_v2_query_progress_handle *progress); - DUCKDB_V2_ERROR(*duckdb_v2_query_progress_get_percentage) - (duckdb_v2_query_progress_handle progress, double *out_percentage, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_query_progress_get_rows_processed) - (duckdb_v2_query_progress_handle progress, uint64_t *out_rows_processed, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_query_progress_get_total_rows_to_process) - (duckdb_v2_query_progress_handle progress, uint64_t *out_total_rows_to_process, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_result_destroy)(duckdb_v2_result_handle *result); DUCKDB_V2_ERROR(*duckdb_v2_result_drain) (duckdb_v2_result_handle result, idx_t *out_rows_changed, duckdb_v2_error_info_handle *err); @@ -1004,10 +1000,10 @@ typedef struct { duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_connection) (duckdb_v2_connection_handle connection, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); - DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_database) - (duckdb_v2_database_handle database, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_extension) (duckdb_v2_extension_handle extension, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_create_with_instance) + (duckdb_v2_instance_handle instance, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR (*duckdb_v2_replacement_scan_destroy)(duckdb_v2_replacement_scan_handle *scan); DUCKDB_V2_ERROR(*duckdb_v2_replacement_scan_get_name) (duckdb_v2_replacement_scan_info_handle info, duckdb_v2_qname_handle *name, duckdb_v2_error_info_handle *err); @@ -1327,6 +1323,63 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_tokenize_sql) (duckdb_v2_connection_handle conn, duckdb_v2_str sql, duckdb_v2_token_iterator_handle *out_iterator, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_attach_options_create) + (duckdb_v2_instance_handle instance, duckdb_v2_attach_options_handle *out_options, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_attach_options_destroy)(duckdb_v2_attach_options_handle *options); + DUCKDB_V2_ERROR(*duckdb_v2_attach_options_set) + (duckdb_v2_attach_options_handle options, duckdb_v2_identifier_t key, duckdb_v2_str setting, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_context_get_option_by_index) + (duckdb_v2_context_handle ctx, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_context_get_option_by_name) + (duckdb_v2_context_handle ctx, duckdb_v2_identifier_t name, duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_context_get_option_count) + (duckdb_v2_context_handle ctx, idx_t *out_count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_instance_set_default) + (duckdb_v2_instance_handle instance, duckdb_v2_str path, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_bind_data) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_global_state) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_local_state) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_partition_column_count) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_partition_column_index) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_get_user_data) + (duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_requires_batch_index) + (duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_requires_partition_columns) + (duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_set_batch_index) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t batch_index, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partition_data_set_partition_value) + (duckdb_v2_table_function_partition_data_info_handle info, idx_t index, duckdb_v2_value_handle value, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_bind_data) + (duckdb_v2_table_function_partitioning_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_partition_column_count) + (duckdb_v2_table_function_partitioning_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_partition_column_index) + (duckdb_v2_table_function_partitioning_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_get_user_data) + (duckdb_v2_table_function_partitioning_info_handle info, void **data, duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_partitioning_set_partition_info) + (duckdb_v2_table_function_partitioning_info_handle info, DUCKDB_V2_TABLE_PARTITION_INFO partition_info, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_partition_data_callback) + (duckdb_v2_table_function_handle function, duckdb_v2_table_function_partition_data_callback_fn callback, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_partitioning_callback) + (duckdb_v2_table_function_handle function, duckdb_v2_table_function_partitioning_callback_fn callback, + duckdb_v2_error_info_handle *err); + DUCKDB_V2_ERROR (*duckdb_v2_validate_utf8)(duckdb_v2_str text, duckdb_v2_error_info_handle *err); // capigen:end appended } duckdb_ext_api_v2; @@ -1340,7 +1393,6 @@ typedef struct { #define duckdb_v2_arena_allocate duckdb_ext_api.duckdb_v2_arena_allocate #define duckdb_v2_bignum_decode duckdb_ext_api.duckdb_v2_bignum_decode #define duckdb_v2_bignum_encode duckdb_ext_api.duckdb_v2_bignum_encode -#define duckdb_v2_close duckdb_ext_api.duckdb_v2_close #define duckdb_v2_column_data_collection_append duckdb_ext_api.duckdb_v2_column_data_collection_append #define duckdb_v2_column_data_collection_append_state_create \ duckdb_ext_api.duckdb_v2_column_data_collection_append_state_create @@ -1363,69 +1415,66 @@ typedef struct { duckdb_ext_api.duckdb_v2_column_data_collection_worker_scan_state_create #define duckdb_v2_column_data_collection_worker_scan_state_destroy \ duckdb_ext_api.duckdb_v2_column_data_collection_worker_scan_state_destroy -#define duckdb_v2_connect duckdb_ext_api.duckdb_v2_connect -#define duckdb_v2_connection_create_type_from_id duckdb_ext_api.duckdb_v2_connection_create_type_from_id -#define duckdb_v2_connection_create_type_from_name duckdb_ext_api.duckdb_v2_connection_create_type_from_name -#define duckdb_v2_connection_create_type_from_text duckdb_ext_api.duckdb_v2_connection_create_type_from_text -#define duckdb_v2_connection_create_type_with_alias duckdb_ext_api.duckdb_v2_connection_create_type_with_alias -#define duckdb_v2_connection_interrupt duckdb_ext_api.duckdb_v2_connection_interrupt -#define duckdb_v2_connection_option_get duckdb_ext_api.duckdb_v2_connection_option_get -#define duckdb_v2_connection_option_get_by_index duckdb_ext_api.duckdb_v2_connection_option_get_by_index -#define duckdb_v2_connection_option_get_count duckdb_ext_api.duckdb_v2_connection_option_get_count -#define duckdb_v2_connection_option_set duckdb_ext_api.duckdb_v2_connection_option_set -#define duckdb_v2_connection_query_progress duckdb_ext_api.duckdb_v2_connection_query_progress -#define duckdb_v2_context_create_type_from_id duckdb_ext_api.duckdb_v2_context_create_type_from_id -#define duckdb_v2_context_create_type_from_name duckdb_ext_api.duckdb_v2_context_create_type_from_name -#define duckdb_v2_context_create_type_from_text duckdb_ext_api.duckdb_v2_context_create_type_from_text -#define duckdb_v2_context_create_type_with_alias duckdb_ext_api.duckdb_v2_context_create_type_with_alias -#define duckdb_v2_create_environment duckdb_ext_api.duckdb_v2_create_environment -#define duckdb_v2_data_chunk_copy_with_connection duckdb_ext_api.duckdb_v2_data_chunk_copy_with_connection -#define duckdb_v2_data_chunk_copy_with_context duckdb_ext_api.duckdb_v2_data_chunk_copy_with_context -#define duckdb_v2_data_chunk_create duckdb_ext_api.duckdb_v2_data_chunk_create -#define duckdb_v2_data_chunk_create_with_connection duckdb_ext_api.duckdb_v2_data_chunk_create_with_connection -#define duckdb_v2_data_chunk_create_with_context duckdb_ext_api.duckdb_v2_data_chunk_create_with_context -#define duckdb_v2_data_chunk_destroy duckdb_ext_api.duckdb_v2_data_chunk_destroy -#define duckdb_v2_data_chunk_get_size duckdb_ext_api.duckdb_v2_data_chunk_get_size -#define duckdb_v2_data_chunk_get_vector duckdb_ext_api.duckdb_v2_data_chunk_get_vector -#define duckdb_v2_data_chunk_get_vector_count duckdb_ext_api.duckdb_v2_data_chunk_get_vector_count -#define duckdb_v2_database_option_get duckdb_ext_api.duckdb_v2_database_option_get -#define duckdb_v2_database_option_get_by_index duckdb_ext_api.duckdb_v2_database_option_get_by_index -#define duckdb_v2_database_option_get_count duckdb_ext_api.duckdb_v2_database_option_get_count -#define duckdb_v2_database_option_set duckdb_ext_api.duckdb_v2_database_option_set -#define duckdb_v2_destroy_environment duckdb_ext_api.duckdb_v2_destroy_environment -#define duckdb_v2_disconnect duckdb_ext_api.duckdb_v2_disconnect -#define duckdb_v2_environment_database_count duckdb_ext_api.duckdb_v2_environment_database_count -#define duckdb_v2_error_info_destroy duckdb_ext_api.duckdb_v2_error_info_destroy -#define duckdb_v2_error_info_get_code duckdb_ext_api.duckdb_v2_error_info_get_code -#define duckdb_v2_error_info_get_raw_message duckdb_ext_api.duckdb_v2_error_info_get_raw_message -#define duckdb_v2_error_info_get_text duckdb_ext_api.duckdb_v2_error_info_get_text -#define duckdb_v2_error_info_set_code duckdb_ext_api.duckdb_v2_error_info_set_code -#define duckdb_v2_error_info_set_text duckdb_ext_api.duckdb_v2_error_info_set_text -#define duckdb_v2_library_version duckdb_ext_api.duckdb_v2_library_version -#define duckdb_v2_logical_type_copy duckdb_ext_api.duckdb_v2_logical_type_copy -#define duckdb_v2_logical_type_destroy duckdb_ext_api.duckdb_v2_logical_type_destroy -#define duckdb_v2_logical_type_get_id duckdb_ext_api.duckdb_v2_logical_type_get_id -#define duckdb_v2_logical_type_get_name duckdb_ext_api.duckdb_v2_logical_type_get_name -#define duckdb_v2_logical_type_get_param duckdb_ext_api.duckdb_v2_logical_type_get_param -#define duckdb_v2_logical_type_get_param_count duckdb_ext_api.duckdb_v2_logical_type_get_param_count -#define duckdb_v2_logical_type_is_equal duckdb_ext_api.duckdb_v2_logical_type_is_equal -#define duckdb_v2_logical_type_to_text duckdb_ext_api.duckdb_v2_logical_type_to_text -#define duckdb_v2_open duckdb_ext_api.duckdb_v2_open -#define duckdb_v2_option_create duckdb_ext_api.duckdb_v2_option_create -#define duckdb_v2_option_destroy duckdb_ext_api.duckdb_v2_option_destroy -#define duckdb_v2_option_get_alias duckdb_ext_api.duckdb_v2_option_get_alias -#define duckdb_v2_option_get_alias_count duckdb_ext_api.duckdb_v2_option_get_alias_count -#define duckdb_v2_option_get_default_setting duckdb_ext_api.duckdb_v2_option_get_default_setting -#define duckdb_v2_option_get_description duckdb_ext_api.duckdb_v2_option_get_description -#define duckdb_v2_option_get_name duckdb_ext_api.duckdb_v2_option_get_name -#define duckdb_v2_option_get_setting duckdb_ext_api.duckdb_v2_option_get_setting -#define duckdb_v2_option_get_target_scope duckdb_ext_api.duckdb_v2_option_get_target_scope -#define duckdb_v2_parse_sql duckdb_ext_api.duckdb_v2_parse_sql -#define duckdb_v2_query_progress_destroy duckdb_ext_api.duckdb_v2_query_progress_destroy -#define duckdb_v2_query_progress_get_percentage duckdb_ext_api.duckdb_v2_query_progress_get_percentage -#define duckdb_v2_query_progress_get_rows_processed duckdb_ext_api.duckdb_v2_query_progress_get_rows_processed -#define duckdb_v2_query_progress_get_total_rows_to_process \ - duckdb_ext_api.duckdb_v2_query_progress_get_total_rows_to_process +#define duckdb_v2_connection_create duckdb_ext_api.duckdb_v2_connection_create +#define duckdb_v2_connection_create_type_from_id duckdb_ext_api.duckdb_v2_connection_create_type_from_id +#define duckdb_v2_connection_create_type_from_name duckdb_ext_api.duckdb_v2_connection_create_type_from_name +#define duckdb_v2_connection_create_type_from_text duckdb_ext_api.duckdb_v2_connection_create_type_from_text +#define duckdb_v2_connection_create_type_with_alias duckdb_ext_api.duckdb_v2_connection_create_type_with_alias +#define duckdb_v2_connection_destroy duckdb_ext_api.duckdb_v2_connection_destroy +#define duckdb_v2_connection_get_option_by_index duckdb_ext_api.duckdb_v2_connection_get_option_by_index +#define duckdb_v2_connection_get_option_by_name duckdb_ext_api.duckdb_v2_connection_get_option_by_name +#define duckdb_v2_connection_get_option_count duckdb_ext_api.duckdb_v2_connection_get_option_count +#define duckdb_v2_connection_interrupt duckdb_ext_api.duckdb_v2_connection_interrupt +#define duckdb_v2_connection_progress_get duckdb_ext_api.duckdb_v2_connection_progress_get +#define duckdb_v2_connection_set_option duckdb_ext_api.duckdb_v2_connection_set_option +#define duckdb_v2_context_create_type_from_id duckdb_ext_api.duckdb_v2_context_create_type_from_id +#define duckdb_v2_context_create_type_from_name duckdb_ext_api.duckdb_v2_context_create_type_from_name +#define duckdb_v2_context_create_type_from_text duckdb_ext_api.duckdb_v2_context_create_type_from_text +#define duckdb_v2_context_create_type_with_alias duckdb_ext_api.duckdb_v2_context_create_type_with_alias +#define duckdb_v2_data_chunk_copy_with_connection duckdb_ext_api.duckdb_v2_data_chunk_copy_with_connection +#define duckdb_v2_data_chunk_copy_with_context duckdb_ext_api.duckdb_v2_data_chunk_copy_with_context +#define duckdb_v2_data_chunk_create duckdb_ext_api.duckdb_v2_data_chunk_create +#define duckdb_v2_data_chunk_create_with_connection duckdb_ext_api.duckdb_v2_data_chunk_create_with_connection +#define duckdb_v2_data_chunk_create_with_context duckdb_ext_api.duckdb_v2_data_chunk_create_with_context +#define duckdb_v2_data_chunk_destroy duckdb_ext_api.duckdb_v2_data_chunk_destroy +#define duckdb_v2_data_chunk_get_size duckdb_ext_api.duckdb_v2_data_chunk_get_size +#define duckdb_v2_data_chunk_get_vector duckdb_ext_api.duckdb_v2_data_chunk_get_vector +#define duckdb_v2_data_chunk_get_vector_count duckdb_ext_api.duckdb_v2_data_chunk_get_vector_count +#define duckdb_v2_environment_create duckdb_ext_api.duckdb_v2_environment_create +#define duckdb_v2_environment_destroy duckdb_ext_api.duckdb_v2_environment_destroy +#define duckdb_v2_environment_get_instance_count duckdb_ext_api.duckdb_v2_environment_get_instance_count +#define duckdb_v2_error_info_destroy duckdb_ext_api.duckdb_v2_error_info_destroy +#define duckdb_v2_error_info_get_code duckdb_ext_api.duckdb_v2_error_info_get_code +#define duckdb_v2_error_info_get_raw_text duckdb_ext_api.duckdb_v2_error_info_get_raw_text +#define duckdb_v2_error_info_get_text duckdb_ext_api.duckdb_v2_error_info_get_text +#define duckdb_v2_error_info_set_code duckdb_ext_api.duckdb_v2_error_info_set_code +#define duckdb_v2_error_info_set_text duckdb_ext_api.duckdb_v2_error_info_set_text +#define duckdb_v2_instance_attach duckdb_ext_api.duckdb_v2_instance_attach +#define duckdb_v2_instance_create duckdb_ext_api.duckdb_v2_instance_create +#define duckdb_v2_instance_destroy duckdb_ext_api.duckdb_v2_instance_destroy +#define duckdb_v2_instance_detach duckdb_ext_api.duckdb_v2_instance_detach +#define duckdb_v2_instance_get_option_by_index duckdb_ext_api.duckdb_v2_instance_get_option_by_index +#define duckdb_v2_instance_get_option_by_name duckdb_ext_api.duckdb_v2_instance_get_option_by_name +#define duckdb_v2_instance_get_option_count duckdb_ext_api.duckdb_v2_instance_get_option_count +#define duckdb_v2_instance_set_option duckdb_ext_api.duckdb_v2_instance_set_option +#define duckdb_v2_library_version duckdb_ext_api.duckdb_v2_library_version +#define duckdb_v2_logical_type_copy duckdb_ext_api.duckdb_v2_logical_type_copy +#define duckdb_v2_logical_type_destroy duckdb_ext_api.duckdb_v2_logical_type_destroy +#define duckdb_v2_logical_type_get_id duckdb_ext_api.duckdb_v2_logical_type_get_id +#define duckdb_v2_logical_type_get_name duckdb_ext_api.duckdb_v2_logical_type_get_name +#define duckdb_v2_logical_type_get_param duckdb_ext_api.duckdb_v2_logical_type_get_param +#define duckdb_v2_logical_type_get_param_count duckdb_ext_api.duckdb_v2_logical_type_get_param_count +#define duckdb_v2_logical_type_is_equal duckdb_ext_api.duckdb_v2_logical_type_is_equal +#define duckdb_v2_logical_type_to_text duckdb_ext_api.duckdb_v2_logical_type_to_text +#define duckdb_v2_option_destroy duckdb_ext_api.duckdb_v2_option_destroy +#define duckdb_v2_option_get_alias duckdb_ext_api.duckdb_v2_option_get_alias +#define duckdb_v2_option_get_alias_count duckdb_ext_api.duckdb_v2_option_get_alias_count +#define duckdb_v2_option_get_default_setting duckdb_ext_api.duckdb_v2_option_get_default_setting +#define duckdb_v2_option_get_description duckdb_ext_api.duckdb_v2_option_get_description +#define duckdb_v2_option_get_name duckdb_ext_api.duckdb_v2_option_get_name +#define duckdb_v2_option_get_setting duckdb_ext_api.duckdb_v2_option_get_setting +#define duckdb_v2_option_get_target_scope duckdb_ext_api.duckdb_v2_option_get_target_scope +#define duckdb_v2_parse_sql duckdb_ext_api.duckdb_v2_parse_sql #define duckdb_v2_result_destroy duckdb_ext_api.duckdb_v2_result_destroy #define duckdb_v2_result_drain duckdb_ext_api.duckdb_v2_result_drain #define duckdb_v2_result_fetch_chunk duckdb_ext_api.duckdb_v2_result_fetch_chunk @@ -1777,8 +1826,8 @@ typedef struct { #define duckdb_v2_replacement_scan_add_named_argument duckdb_ext_api.duckdb_v2_replacement_scan_add_named_argument #define duckdb_v2_replacement_scan_create_with_connection \ duckdb_ext_api.duckdb_v2_replacement_scan_create_with_connection -#define duckdb_v2_replacement_scan_create_with_database duckdb_ext_api.duckdb_v2_replacement_scan_create_with_database #define duckdb_v2_replacement_scan_create_with_extension duckdb_ext_api.duckdb_v2_replacement_scan_create_with_extension +#define duckdb_v2_replacement_scan_create_with_instance duckdb_ext_api.duckdb_v2_replacement_scan_create_with_instance #define duckdb_v2_replacement_scan_destroy duckdb_ext_api.duckdb_v2_replacement_scan_destroy #define duckdb_v2_replacement_scan_get_name duckdb_ext_api.duckdb_v2_replacement_scan_get_name #define duckdb_v2_replacement_scan_get_user_data duckdb_ext_api.duckdb_v2_replacement_scan_get_user_data @@ -1931,6 +1980,48 @@ typedef struct { #define duckdb_v2_token_iterator_ends_unterminated duckdb_ext_api.duckdb_v2_token_iterator_ends_unterminated #define duckdb_v2_token_iterator_next duckdb_ext_api.duckdb_v2_token_iterator_next #define duckdb_v2_tokenize_sql duckdb_ext_api.duckdb_v2_tokenize_sql +#define duckdb_v2_attach_options_create duckdb_ext_api.duckdb_v2_attach_options_create +#define duckdb_v2_attach_options_destroy duckdb_ext_api.duckdb_v2_attach_options_destroy +#define duckdb_v2_attach_options_set duckdb_ext_api.duckdb_v2_attach_options_set +#define duckdb_v2_context_get_option_by_index duckdb_ext_api.duckdb_v2_context_get_option_by_index +#define duckdb_v2_context_get_option_by_name duckdb_ext_api.duckdb_v2_context_get_option_by_name +#define duckdb_v2_context_get_option_count duckdb_ext_api.duckdb_v2_context_get_option_count +#define duckdb_v2_instance_set_default duckdb_ext_api.duckdb_v2_instance_set_default +#define duckdb_v2_table_function_partition_data_get_bind_data \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_get_bind_data +#define duckdb_v2_table_function_partition_data_get_global_state \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_get_global_state +#define duckdb_v2_table_function_partition_data_get_local_state \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_get_local_state +#define duckdb_v2_table_function_partition_data_get_partition_column_count \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_get_partition_column_count +#define duckdb_v2_table_function_partition_data_get_partition_column_index \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_get_partition_column_index +#define duckdb_v2_table_function_partition_data_get_user_data \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_get_user_data +#define duckdb_v2_table_function_partition_data_requires_batch_index \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_requires_batch_index +#define duckdb_v2_table_function_partition_data_requires_partition_columns \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_requires_partition_columns +#define duckdb_v2_table_function_partition_data_set_batch_index \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_set_batch_index +#define duckdb_v2_table_function_partition_data_set_partition_value \ + duckdb_ext_api.duckdb_v2_table_function_partition_data_set_partition_value +#define duckdb_v2_table_function_partitioning_get_bind_data \ + duckdb_ext_api.duckdb_v2_table_function_partitioning_get_bind_data +#define duckdb_v2_table_function_partitioning_get_partition_column_count \ + duckdb_ext_api.duckdb_v2_table_function_partitioning_get_partition_column_count +#define duckdb_v2_table_function_partitioning_get_partition_column_index \ + duckdb_ext_api.duckdb_v2_table_function_partitioning_get_partition_column_index +#define duckdb_v2_table_function_partitioning_get_user_data \ + duckdb_ext_api.duckdb_v2_table_function_partitioning_get_user_data +#define duckdb_v2_table_function_partitioning_set_partition_info \ + duckdb_ext_api.duckdb_v2_table_function_partitioning_set_partition_info +#define duckdb_v2_table_function_set_partition_data_callback \ + duckdb_ext_api.duckdb_v2_table_function_set_partition_data_callback +#define duckdb_v2_table_function_set_partitioning_callback \ + duckdb_ext_api.duckdb_v2_table_function_set_partitioning_callback +#define duckdb_v2_validate_utf8 duckdb_ext_api.duckdb_v2_validate_utf8 // capigen:end appended #endif // DUCKDB_BUILD_STATIC_EXTENSION diff --git a/src/duckdb/src/include/duckdb_v2.h b/src/duckdb/src/include/duckdb_v2.h index 2a3a2ca6b..29bea6177 100644 --- a/src/duckdb/src/include/duckdb_v2.h +++ b/src/duckdb/src/include/duckdb_v2.h @@ -196,36 +196,44 @@ typedef struct duckdb_v2_opaque duckdb_v2_opaque; /* --- Types for common --- */ /*! - * An opaque, owned handle to the V2 environment: the required root through which databases are opened. All databases - * under one environment share a cache, so file-level conflicts — the same database file opened twice — are detected - * across them. Destroying the environment refuses with ERROR_RESOURCE_IN_USE while any database opened through it is - * still alive; close those first. + * An opaque, owned handle to the V2 environment: the required root through which instance handles are created. All + * instances under one environment share an instance cache, so file-level conflicts — the same database file opened + * twice — are detected across them. Destroying the environment refuses with ERROR_RESOURCE_IN_USE while any instance + * created through it is still alive; destroy those first. */ typedef struct _duckdb_v2_environment { void *internal_ptr; } * duckdb_v2_environment_handle; -//! An opaque, owned handle to a DuckDB database instance. -typedef struct _duckdb_v2_database { +/*! + * An opaque, owned handle to a DuckDB database instance: a buffer pool, a scheduler, a set of GLOBAL settings, and the + * databases attached to it. Created empty by `duckdb_v2_instance_create()`; databases are attached with + * `duckdb_v2_instance_attach()`, made the default with `duckdb_v2_instance_set_default()`, and detached with + * `duckdb_v2_instance_detach()`. Always destroy via `duckdb_v2_instance_destroy()`. + */ +typedef struct _duckdb_v2_instance { void *internal_ptr; -} * duckdb_v2_database_handle; +} * duckdb_v2_instance_handle; -//! An opaque, owned handle to a DuckDB connection. +/*! + * An opaque, owned handle to a DuckDB connection: a session on a database instance with its own LOCAL settings and + * transaction state. Always destroy via `duckdb_v2_connection_destroy()`. + */ typedef struct _duckdb_v2_connection { void *internal_ptr; } * duckdb_v2_connection_handle; /*! - * An opaque, owned handle to a single config option: a name and a setting, plus optional metadata (description, default - * setting, target scope, aliases). You can create an with option_create and pass it when opening a database or - * connection, or you can retrieve one with metadata already filled in using option_get. The caller always destroys it - * via option_destroy, + * An opaque, owned, read-only descriptor of a single config option as seen from an instance, connection, or context: + * its canonical name, current setting, default setting, description, target scope, and aliases. Returned by the + * *_get_option and *_get_option_by_index functions; the caller always destroys it via `duckdb_v2_option_destroy()`. + * Options are written with the *_set_option functions, which take a name and a setting directly. */ typedef struct _duckdb_v2_option { void *internal_ptr; } * duckdb_v2_option_handle; -//! Opaque detail for a failed call; destroy with error_info_destroy. +//! Opaque detail for a failed call; destroy with `duckdb_v2_error_info_destroy()`. typedef struct _duckdb_v2_error_info { void *internal_ptr; } * duckdb_v2_error_info_handle; @@ -234,17 +242,18 @@ typedef struct _duckdb_v2_error_info { * An opaque, owned handle to a logical type. Carries a type id plus any kind-specific metadata: decimal width and * scale, enum dictionary, list / array / struct / map / union child types, alias. A type is read-only once constructed; * instances arrive from a query result schema, or from one of the create_type_* constructors. Always destroy via - * logical_type_destroy. Borrowed strings returned by the getters are valid only until then. + * `duckdb_v2_logical_type_destroy()`. Borrowed strings returned by the getters are valid only until then. */ typedef struct _duckdb_v2_logical_type { void *internal_ptr; } * duckdb_v2_logical_type_handle; /*! - * An opaque, owned handle to a single SQL value: a logical type plus a typed payload. Always destroy via value_destroy. - * The string returned by value_get_varchar / value_get_blob is borrowed and valid only until then. That holds for - * BIGNUM too, where what is borrowed is the opaque storage form; bignum_decode translates it into a magnitude and a - * sign flag, writing into a buffer the caller supplies. + * An opaque, owned handle to a single SQL value: a logical type plus a typed payload. Always destroy via + * `duckdb_v2_value_destroy()`. The string returned by `duckdb_v2_value_get_varchar()` / `duckdb_v2_value_get_blob()` is + * borrowed and valid only until then. That holds for BIGNUM too, where what is borrowed is the opaque storage form; + * `duckdb_v2_bignum_decode()` translates it into a magnitude and a sign flag, writing into a buffer the caller + * supplies. */ typedef struct _duckdb_v2_value { void *internal_ptr; @@ -252,14 +261,15 @@ typedef struct _duckdb_v2_value { /*! * An opaque, owned handle to the streaming result of a query. Carries the schema (column names and logical types), the - * statement type, and the result type from prepare time; row data is produced incrementally by stepping (result_step) - * or draining (result_fetch_chunk). Single consumer: step from one thread at a time. + * statement type, and the result type from prepare time; row data is produced incrementally by stepping + * (`duckdb_v2_result_step()`) or draining (`duckdb_v2_result_fetch_chunk()`). Single consumer: step from one thread at + * a time. * * A result is a cursor on the connection's execution, not a box of data. While it is live — not finished, cancelled, * errored, or destroyed — the connection refuses new queries with ERROR_RESOURCE_IN_USE, and the query's transaction * stays open, deferring version cleanup and checkpointing, so drain or destroy it promptly. Side-effecting statements - * (PRAGMA, ALTER, ...) take effect only once the result is drained. Always destroy via result_destroy, which is safe - * even on a partially consumed stream. + * (PRAGMA, ALTER, ...) take effect only once the result is drained. Always destroy via `duckdb_v2_result_destroy()`, + * which is safe even on a partially consumed stream. */ typedef struct _duckdb_v2_result { void *internal_ptr; @@ -286,9 +296,9 @@ typedef struct _duckdb_v2_vector { /*! * A borrowed handle to a "arena allocator". * - * Bytes handed out by arena_allocate share the same lifetime as the arena itself. vector_get_arena yields the arena - * backing the out-of-line bytes of non-inlined VARCHAR / BLOB / BIT / BIGNUM values, valid until the owning vector is - * flattened, reallocated, or destroyed. + * Bytes handed out by `duckdb_v2_arena_allocate()` share the same lifetime as the arena itself. + * `duckdb_v2_vector_get_arena()` yields the arena backing the out-of-line bytes of non-inlined VARCHAR / BLOB / BIT / + * BIGNUM values, valid until the owning vector is flattened, reallocated, or destroyed. */ typedef struct _duckdb_v2_arena { void *internal_ptr; @@ -298,7 +308,7 @@ typedef struct _duckdb_v2_arena { * A borrowed handle to a client context: a connection seen from inside DuckDB. Handed out within DuckDB-managed scopes * — function bind / init / exec callbacks, replacement scans, and the extension entrypoint — and valid only for the * duration of that scope; the caller never destroys it. A context is the scope for reading (settings, the file system) - * and for constructing values and types, not for registration: catalog entries and database-level hooks are installed + * and for constructing values and types, not for registration: catalog entries and instance-level hooks are installed * through an extension or a connection. A transaction is always active while a context is handed out, which is what the * context-scoped constructors assume. */ @@ -315,7 +325,7 @@ typedef struct _duckdb_v2_context { */ typedef uint32_t duckdb_v2_sel_t; -//! VARCHAR storage. Read the transparent bytes fields directly. +//! VARCHAR storage. The bytes must contain valid UTF-8. Read the transparent bytes fields directly. typedef duckdb_v2_bytes duckdb_v2_varchar_t; //! BLOB storage. Read the transparent bytes fields directly. @@ -324,7 +334,7 @@ typedef duckdb_v2_bytes duckdb_v2_blob_t; //! BIT storage. Byte 0 is the padding-bit count, bytes 1.. the data. typedef duckdb_v2_bytes duckdb_v2_bit_t; -//! BIGNUM storage. Decode via bignum_decode. +//! BIGNUM storage. Decode via `duckdb_v2_bignum_decode()`. typedef duckdb_v2_bytes duckdb_v2_bignum_t; /*! @@ -350,8 +360,8 @@ typedef duckdb_v2_str duckdb_v2_identifier_t; * The view is borrowed for the duration of the call only. Copy what you need before returning, and do not retain * `text.ptr`. The bytes are NOT guaranteed to be null-terminated. * - * `err` is a live error slot, never NULL. Populate it with error_info_set_code / error_info_set_text to signal failure - * to DuckDB. Do not destroy it yourself. + * `err` is a live error slot, never NULL. Populate it with `duckdb_v2_error_info_set_code()` / + * `duckdb_v2_error_info_set_text()` to signal failure to DuckDB. Do not destroy it yourself. * * The sink runs inside DuckDB's call frame: it must not throw or unwind across the boundary, and it must not re-enter * the API on the handle being operated on. @@ -391,6 +401,9 @@ typedef void (*duckdb_v2_opaque_destroy_fn)(void *data); * "valid until the owning handle is destroyed"). `{NULL, 0}` is the canonical empty view, and `ptr` must not be * dereferenced when `len` is 0. Not to be confused with `bytes`, the transparent 16-byte *storage* format for a * variable-size value in a vector. + * + * Text inputs, such as VARCHAR values and names, must contain valid UTF-8. The caller is responsible for ensuring this; + * API functions do not necessarily validate the input. Binary inputs, such as BLOB values, do not require valid UTF-8. */ struct duckdb_v2_str { const char *ptr; @@ -403,7 +416,7 @@ struct duckdb_v2_str { * value.pointer.prefix repeats the first * 4. The union is transparent, so read the fields directly. VARCHAR and * BLOB carry no further encoding; BIT and BIGNUM do. For BIT, byte 0 is the padding-bit count and bytes 1.. are the - * data; BIGNUM is decoded via bignum_decode. + * data; BIGNUM is decoded via `duckdb_v2_bignum_decode()`. */ struct duckdb_v2_bytes { union { @@ -1309,8 +1322,9 @@ duckdb_v2_column_data_collection_append_state_destroy(duckdb_v2_column_data_coll * Appends a data chunk to the collection. * * Appends a copy of the given chunk to the end of the collection. The chunk's column count and types must equal the - * collection's exactly; a mismatch is rejected with INVALID_INPUT before anything is copied. Complex-typed vectors may - * be flattened in place by the copy. + * collection's exactly; a mismatch is rejected with INVALID_INPUT before anything is copied. VARCHAR values must + * already contain valid UTF-8; this function does not validate text. Complex-typed vectors may be flattened in place by + * the copy. * * history: * - stable: v2.0.0 @@ -1433,14 +1447,13 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_column_data_collection_scan( /*! * The scope target of an option: where DuckDB permits its setting to be written. UNKNOWN is reported for an option - * whose declaration carries no explicit scope target, and for one created via option_create that has not yet been - * resolved through a database/connection get. + * whose declaration carries no explicit scope target, which includes every extension option. */ typedef enum DUCKDB_V2_OPTION_TARGET_SCOPE { //! Target scope is not known. DUCKDB_V2_OPTION_TARGET_SCOPE_UNKNOWN = 0, - //! May only be written at GLOBAL (database) scope. + //! May only be written at GLOBAL (instance) scope. DUCKDB_V2_OPTION_TARGET_SCOPE_GLOBAL_ONLY = 1, //! May only be written at LOCAL (session) scope. @@ -1456,14 +1469,14 @@ typedef enum DUCKDB_V2_OPTION_TARGET_SCOPE { /*! * Destination scope for a connection-side option write, as taken by connection_option_set. AUTOMATIC defers to the - * option's target scope, like SQL `SET name = value`. GLOBAL writes through to the database, visible to all + * option's target scope, like SQL `SET name = value`. GLOBAL writes through to the instance, visible to all * connections, like `SET GLOBAL`. LOCAL writes to the connection's session only, like `SET LOCAL` / `SET SESSION`. */ typedef enum DUCKDB_V2_SETTING_SCOPE { //! Resolve from the option's target scope. DUCKDB_V2_SETTING_SCOPE_AUTOMATIC = 0, - //! Write through to the database (visible to all connections). + //! Write through to the instance (visible to all connections). DUCKDB_V2_SETTING_SCOPE_GLOBAL = 1, //! Write to the connection's session only. @@ -1482,27 +1495,7 @@ typedef enum DUCKDB_V2_SETTING_SCOPE { /* --- Functions for configuration --- */ /*! - * Creates an option handle carrying a name and a setting. - * - * The name and setting are copied in. The remaining fields — description, default setting, target scope, aliases — stay - * empty, or UNKNOWN, until the option is resolved through a database/connection get. The caller destroys it via - * option_destroy. - * - * history: - * - stable: v2.0.0 - * - * @param name Option name. - * @param setting Setting (string-encoded value). - * @param out_option Receives the new option handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_create(duckdb_v2_identifier_t name, duckdb_v2_str setting, - duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - -/*! - * Destroys an option handle. + * Destroys an option descriptor. * * Frees the handle along with the strings it owns. On success the slot is set to null. Safe to call on an already-null * slot. @@ -1518,15 +1511,16 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_destroy(duckdb_v2_option_handle *o /*! * Borrows the option's canonical name. * - * When a database/connection get resolved the option from an alias, this still reports the canonical name; the alias is - * reachable via option_get_alias. + * When the option was resolved from an alias, this still reports the canonical name; the alias is reachable via + * `duckdb_v2_option_get_alias()`. * * history: * - stable: v2.0.0 * * @param option The option. * @param out_name Receives a borrowed view of the option name. Valid until the option is destroyed. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_name(duckdb_v2_option_handle option, duckdb_v2_identifier_t *out_name, @@ -1535,15 +1529,15 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_name(duckdb_v2_option_handle o /*! * Borrows the option's current setting (its string-encoded value). * - * For an option created via option_create this is the caller-supplied setting verbatim. For one resolved through a - * database/connection get it is the effective setting at that source's scope. + * The effective setting at the scope of the instance, connection, or context the descriptor was read from. * * history: * - stable: v2.0.0 * * @param option The option. * @param out_setting Receives a borrowed view of the setting. Valid until the option is destroyed. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_setting(duckdb_v2_option_handle option, duckdb_v2_str *out_setting, @@ -1552,14 +1546,15 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_setting(duckdb_v2_option_handl /*! * Borrows the option's static default setting. * - * The empty view for an option created via option_create, until it has been resolved through a database/connection get. + * The empty view for an option whose declaration has no default. * * history: * - stable: v2.0.0 * * @param option The option. * @param out_default_setting Receives a borrowed view of the default setting. Valid until the option is destroyed. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_default_setting(duckdb_v2_option_handle option, @@ -1569,14 +1564,13 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_default_setting(duckdb_v2_opti /*! * Borrows the option's human-readable description. * - * The empty view for an option created via option_create, until it has been resolved through a database/connection get. - * * history: * - stable: v2.0.0 * * @param option The option. * @param out_description Receives a borrowed view of the description. Valid until the option is destroyed. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_description(duckdb_v2_option_handle option, @@ -1586,15 +1580,16 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_description(duckdb_v2_option_h /*! * Returns the option's target scope. * - * OPTION_TARGET_SCOPE_UNKNOWN for an option created via option_create until it has been resolved through a - * database/connection get, and for one whose declaration carries no explicit scope target. + * OPTION_TARGET_SCOPE_UNKNOWN for an option whose declaration carries no explicit scope target, which includes every + * extension option. * * history: * - stable: v2.0.0 * * @param option The option. * @param out_target_scope Receives the target scope. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_target_scope(duckdb_v2_option_handle option, @@ -1604,14 +1599,15 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_target_scope(duckdb_v2_option_ /*! * Returns the number of aliases registered for this option. * - * Zero for an option created via option_create, until it has been resolved through a database/connection get. + * Zero for an extension option; extension options carry no aliases. * * history: * - stable: v2.0.0 * * @param option The option. * @param out_count Receives the alias count. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_alias_count(duckdb_v2_option_handle option, idx_t *out_count, @@ -1628,13 +1624,76 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_alias_count(duckdb_v2_option_h * @param option The option. * @param index The alias index, in [0, alias_count). * @param out_alias Receives a borrowed view of the alias. Valid until the option is destroyed. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_option_get_alias(duckdb_v2_option_handle option, idx_t index, duckdb_v2_identifier_t *out_alias, duckdb_v2_error_info_handle *err); +/*! + * Reads a config option through a context. + * + * The context is a connection seen from inside DuckDB, so this reads the same cascade + * `duckdb_v2_connection_get_option_by_name()` does: the LOCAL override if the connection set one, otherwise the GLOBAL + * value, otherwise the static default. Aliases resolve transparently, and an unknown name returns ERROR_INPUT_INVALID. + * The caller destroys the returned option. A context is a read scope: options are written through an instance or + * connection. + * + * history: + * - stable: v2.0.0 + * + * @param ctx The context. + * @param name Option name (canonical or alias). + * @param out_option Receives the populated option handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_context_get_option_by_name(duckdb_v2_context_handle ctx, + duckdb_v2_identifier_t name, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + +/*! + * Returns the number of config options visible to this context. + * + * The same count `duckdb_v2_instance_get_option_count()` reports for the underlying instance: core plus extension + * options, aliases excluded. + * + * history: + * - stable: v2.0.0 + * + * @param ctx The context. + * @param out_count Receives the option count. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_context_get_option_count(duckdb_v2_context_handle ctx, idx_t *out_count, + duckdb_v2_error_info_handle *err); + +/*! + * Reads the config option at the given index visible to this context. + * + * Index space: [0, core_count) addresses core options, [core_count, total) the extension options visible from this + * context's instance. An out-of-range index returns ERROR_INPUT_INVALID. The caller destroys the returned option. + * + * history: + * - stable: v2.0.0 + * + * @param ctx The context. + * @param index The option index, in [0, option_count). + * @param out_option Receives the populated option handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_context_get_option_by_index(duckdb_v2_context_handle ctx, idx_t index, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + /* --- Struct definitions for configuration --- */ /* ============================================================================ @@ -1971,159 +2030,6 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_data_chunk_get_vector(duckdb_v2_data_chun /* --- Struct definitions for data_chunk --- */ -/* ============================================================================ - * MODULE: database - * ============================================================================ */ - -/* --- Enums for database --- */ - -/* --- Struct forward declarations for database --- */ - -/* --- Types for database --- */ - -/* --- Constants for database --- */ - -/* --- Function pointer typedefs for database --- */ - -/* --- Functions for database --- */ - -/*! - * Opens a database under the environment. - * - * `path` semantics: - * - `nullptr`, ":memory:", or any ":memory:..." path opens a fresh in-memory database. In-memory databases are never - * deduplicated across calls. - * - any other path opens that file as a database, and returns ERROR_RESOURCE_IN_USE if the file is already open under - * the same environment. - * - * `options` is an optional array of pre-created config option handles applied at construction time. Only the name and - * setting of each handle are read; the remaining fields are ignored. Options may include pre-open database settings - * (e.g. access_mode, memory_limit) and ATTACH-style storage options (e.g. BLOCK_SIZE, ENCRYPTION_KEY). Unknown names - * are accepted and kept for a later extension to consume. Pass `options=nullptr` and `option_count=0` to open with - * defaults. - * - * LOCAL_ONLY options are rejected at this scope, as they are by database_option_set. - * - * history: - * - stable: v2.0.0 - * - * @param env The environment. - * @param path Path to the database. An empty view (`{NULL, 0}` or zero length) or any ':memory:...' path opens an - * in-memory database. - * @param options Optional array of pre-created config option handles. May be `nullptr` if option_count is 0. - * @param option_count The number of entries in the options array. - * @param out_db Receives the new database handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_open(duckdb_v2_environment_handle env, duckdb_v2_str path, - duckdb_v2_option_handle *options, idx_t option_count, - duckdb_v2_database_handle *out_db, duckdb_v2_error_info_handle *err); - -/*! - * Closes the database. - * - * Always succeeds. The underlying database instance stays alive for as long as any connection still references it; when - * the last reference drops, the instance is destroyed and its path becomes available to reopen. On success the handle - * is set to null. - * - * history: - * - stable: v2.0.0 - * - * @param db The database to close. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_close(duckdb_v2_database_handle *db); - -/*! - * Sets a config option on the database (GLOBAL scope). - * - * Only the name and setting of the option are read; the remaining fields are ignored. Equivalent to SQL `SET GLOBAL - * name = setting`. Returns ERROR_INPUT_INVALID for an option declared LOCAL_ONLY, and for a legacy option with no - * global setter. Unknown names are accepted and kept for a later extension to consume. - * - * history: - * - stable: v2.0.0 - * - * @param db The database. - * @param option The config option to apply. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_database_option_set(duckdb_v2_database_handle db, duckdb_v2_option_handle option, - duckdb_v2_error_info_handle *err); - -/*! - * Reads a config option from the database (GLOBAL scope) by name. - * - * Allocates a fully populated option: canonical name, current GLOBAL setting, default setting, description, target - * scope, and aliases. Aliases resolve transparently — passing an alias returns the canonical option, with the alias - * listed in its alias array. An unknown name returns ERROR_INPUT_INVALID. The caller destroys the returned option. - * - * history: - * - stable: v2.0.0 - * - * @param db The database. - * @param name Option name (canonical or alias). - * @param out_option Receives the populated option handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_database_option_get(duckdb_v2_database_handle db, duckdb_v2_identifier_t name, - duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - -/*! - * Returns the number of config options registered on the database. - * - * Counts core options plus the extension options registered on this database. Aliases are NOT counted separately; each - * one is reachable through its canonical option's alias array. - * - * history: - * - stable: v2.0.0 - * - * @param db The database. - * @param out_count Receives the option count. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_database_option_get_count(duckdb_v2_database_handle db, idx_t *out_count, - duckdb_v2_error_info_handle *err); - -/*! - * Reads the config option at the given index from the database. - * - * Index space: [0, core_count) addresses core options, [core_count, total) extension options. The mapping is stable for - * as long as no extension registers new options. An out-of-range index returns ERROR_INPUT_INVALID. The caller destroys - * the returned option. - * - * history: - * - stable: v2.0.0 - * - * @param db The database. - * @param index The option index, in [0, option_count). - * @param out_option Receives the populated option handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_database_option_get_by_index(duckdb_v2_database_handle db, idx_t index, - duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - -/*! - * Returns the version of the linked DuckDB library. - * - * history: - * - stable: v2.0.0 - * - * @param out_version The version string. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_library_version(duckdb_v2_str *out_version, duckdb_v2_error_info_handle *err); - -/* --- Struct definitions for database --- */ - /* ============================================================================ * MODULE: environment * ============================================================================ */ @@ -2147,17 +2053,18 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_library_version(duckdb_v2_str *out_versio * - stable: v2.0.0 * * @param out_env Receives the new environment handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_create_environment(duckdb_v2_environment_handle *out_env, +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_environment_create(duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err); /*! * Destroys the environment. * - * Refuses with ERROR_RESOURCE_IN_USE while any database opened through this environment is still alive; close those - * databases first, then retry. On success the handle is set to null. + * Refuses with ERROR_RESOURCE_IN_USE while any instance created through this environment is still alive; destroy those + * instances first, then retry. On success the handle is set to null. * * history: * - stable: v2.0.0 @@ -2165,24 +2072,26 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_create_environment(duckdb_v2_environment_ * @param env The environment. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_destroy_environment(duckdb_v2_environment_handle *env); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_environment_destroy(duckdb_v2_environment_handle *env); /*! - * Returns the number of databases currently open under the environment. + * Returns the number of instances currently alive under the environment. * - * A diagnostic accessor, for tracking down leaked database handles when destroy_environment returns + * A diagnostic accessor, for tracking down leaked instances when `duckdb_v2_environment_destroy()` returns * ERROR_RESOURCE_IN_USE. The count is a snapshot and may change before the next call. * * history: * - stable: v2.0.0 * * @param env The environment. - * @param out_count Receives the number of currently-open databases. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param out_count Receives the number of live instances. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_environment_database_count(duckdb_v2_environment_handle env, idx_t *out_count, - duckdb_v2_error_info_handle *err); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_environment_get_instance_count(duckdb_v2_environment_handle env, + idx_t *out_count, + duckdb_v2_error_info_handle *err); /* --- Struct definitions for environment --- */ @@ -2218,39 +2127,40 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_environment_database_count(duckdb_v2_envi DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_get_code(duckdb_v2_error_info_handle info, DUCKDB_V2_ERROR *out_code); /*! - * Retrieves the error message associated with an error info handle. + * Retrieves the error text associated with an error info handle. * - * Returns a borrowed pointer to the info's null-terminated error message. The pointer is owned by DuckDB and is valid - * until the info is destroyed; callers must not free it, and must not read it once the info has been destroyed. + * Returns a borrowed pointer to the info's null-terminated error text. The pointer is owned by DuckDB and is valid + * until the info is destroyed or a new text is set; callers must not free it, and must not read it once the info has + * been destroyed. * * history: * - stable: v2.0.0 * * @param info The error info handle to query. - * @param out_text Receives a borrowed view of the message. Owned by DuckDB; valid until the info handle is destroyed. + * @param out_text Receives a borrowed view of the text. Owned by DuckDB; valid until the info handle is destroyed. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_get_text(duckdb_v2_error_info_handle info, duckdb_v2_str *out_text); /*! - * Retrieves the error message body without the leading category prefix. + * Retrieves the error text body without the leading category prefix. * - * Returns a borrowed view of the same message error_info_get_text reports, minus the leading " Error: " prefix. - * This is the authoritative unprefixed body: the API exposes no type name, so the prefix cannot be reconstructed and - * the body cannot be derived from error_info_get_text. Unprefixed does not mean plain — the body keeps whatever form it - * was rendered in (a LINE/caret block by default, JSON under errors_as_json). `{NULL, 0}` when there is no message. The + * Returns a borrowed view of the same text error_info_get_text reports, minus the leading " Error: " prefix. This + * is the authoritative unprefixed body: the API exposes no type name, so the prefix cannot be reconstructed and the + * body cannot be derived from error_info_get_text. Unprefixed does not mean plain — the body keeps whatever form it was + * rendered in (a LINE/caret block by default, JSON under errors_as_json). `{NULL, 0}` when there is no text. The * pointer is owned by DuckDB and valid until the info handle is destroyed. * * history: * - stable: v2.0.0 * * @param info The error info handle to query. - * @param out_raw_message Receives a borrowed view of the raw message. Owned by DuckDB; valid until the info handle is + * @param out_raw_text Receives a borrowed view of the raw text. Owned by DuckDB; valid until the info handle is * destroyed. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_get_raw_message(duckdb_v2_error_info_handle info, - duckdb_v2_str *out_raw_message); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_get_raw_text(duckdb_v2_error_info_handle info, + duckdb_v2_str *out_raw_text); /*! * Sets the error code for an error info handle. @@ -2268,17 +2178,16 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_get_raw_message(duckdb_v2_erro DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_set_code(duckdb_v2_error_info_handle info, DUCKDB_V2_ERROR code); /*! - * Sets the error message for an error info handle. + * Sets the error text for an error info handle. * - * On success, replaces the info's message with the provided one; DuckDB allocates its own copy of the string. On - * failure, nothing is changed. Accepts a `nullptr` info handle, in which case the call is a no-op and returns - * ERROR_NONE. + * On success, replaces the info's text with the provided one; DuckDB allocates its own copy of the string. On failure, + * nothing is changed. Accepts a `nullptr` info handle, in which case the call is a no-op and returns ERROR_NONE. * * history: * - stable: v2.0.0 * - * @param info The error info handle to set. On success, updated with the provided message. - * @param text The error message to set in the info. + * @param info The error info handle to set. On success, updated with the provided text. + * @param text The error text to set in the info. * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_error_info_set_text(duckdb_v2_error_info_handle info, duckdb_v2_str text); @@ -2920,6 +2829,303 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_identifier_render_quoted(duckdb_v2_identi /* --- Struct definitions for identifier --- */ +/* ============================================================================ + * MODULE: instance + * ============================================================================ */ + +/* --- Enums for instance --- */ + +/* --- Struct forward declarations for instance --- */ + +/* --- Types for instance --- */ + +/*! + * An opaque, owned handle to the `(KEY value)` options of one `duckdb_v2_instance_attach()` call, as SQL `ATTACH` + * accepts them. Created from the instance handle it will be used with via `duckdb_v2_attach_options_create()`; destroy + * it via `duckdb_v2_attach_options_destroy()`. + */ +typedef struct _duckdb_v2_attach_options { + void *internal_ptr; +} * duckdb_v2_attach_options_handle; + +/* --- Constants for instance --- */ + +/* --- Function pointer typedefs for instance --- */ + +/* --- Functions for instance --- */ + +/*! + * Creates an instance handle under the environment. + * + * The handle starts with no database attached and with its instance not yet started; set startup options with + * `duckdb_v2_instance_set_option()`, then attach a database with `duckdb_v2_instance_attach()` and pick the default + * with `duckdb_v2_instance_set_default()`, or connect with `duckdb_v2_connection_create()`. The caller destroys it via + * `duckdb_v2_instance_destroy()`. + * + * history: + * - stable: v2.0.0 + * + * @param env The environment. + * @param out_instance Receives the new instance handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_create(duckdb_v2_environment_handle env, + duckdb_v2_instance_handle *out_instance, + duckdb_v2_error_info_handle *err); + +/*! + * Destroys the instance handle. + * + * Always succeeds. Every attached database is closed with the instance. The instance itself stays alive for as long as + * any connection still references it; when the last reference drops, it is destroyed and its database files become + * available to open again. On success the handle is set to null. Safe to call on an already-null slot. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle to destroy. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_destroy(duckdb_v2_instance_handle *instance); + +/*! + * Attaches a database to the instance, starting it if it has not started yet. + * + * Attaches the database at `path` exactly like `ATTACH 'path'`: + * - `:memory:` or an empty view attaches a fresh in-memory database named `memory`. + * - any other path attaches that file, creating it if it does not exist, under the name derived from the file's base + * name. `name` is the name to attach under, like `ATTACH ... AS name`; null, or an empty view, uses the name derived + * from the path. Naming is how two files with the same base name, or `:memory:` twice, attach side by side. `options` + * may be null; it carries the `(KEY value)` options of SQL `ATTACH`, for per-database options such as READ_ONLY, + * BLOCK_SIZE or ENCRYPTION_KEY, and must have been created from this instance handle. `make_default` makes the attached + * database the default for connections created afterwards, exactly as a `duckdb_v2_instance_set_default()` call right + * after the attach would; otherwise the default is left alone. A path that is already attached on this or any other + * instance of the environment returns ERROR_RESOURCE_IN_USE, and a name that is already attached fails. Options that + * only apply at startup must be set before the first attach or connection. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param path Path to the database file, or `:memory:` / an empty view for an in-memory database. + * @param name Optional. The name to attach under; null or an empty view for the name derived from the path. Borrowed + * and copied. + * @param options Optional attach options created from `instance`, or null to attach with defaults under the derived + * name. + * @param make_default Whether to make the attached database the default for connections created afterwards. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_attach(duckdb_v2_instance_handle instance, duckdb_v2_str path, + duckdb_v2_identifier_t *name, + duckdb_v2_attach_options_handle options, bool make_default, + duckdb_v2_error_info_handle *err); + +/*! + * Detaches the database that was attached from `path`. + * + * Detaches it like `DETACH`, checkpointing a file database first. Unlike SQL, the default database may be detached too; + * new connections then start without a default until `duckdb_v2_instance_set_default()` names another, and existing + * connections bound to it keep it alive until their transaction on it ends and fail unqualified DDL afterwards. The + * path is matched against the attached databases as `duckdb_v2_instance_attach()` recorded it, so pass the path that + * was passed to `duckdb_v2_instance_attach()`. Returns ERROR_INPUT_INVALID when no database attached from that path + * exists. Connections that still reference the database keep it alive until they release it. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param path The path the database was attached from, or the name it is attached under. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_detach(duckdb_v2_instance_handle instance, duckdb_v2_str path, + duckdb_v2_error_info_handle *err); + +/*! + * Makes the database that was attached from `path` the default database for connections created from now on. + * + * A connection binds to the default database when it is created, so this does not retarget existing connections: their + * default stays what it was when they connected, or what they chose with `USE`. The default is where unqualified DDL + * and unqualified table lookups that miss the temporary catalog go. It stays the default for new connections until + * another `duckdb_v2_instance_set_default()` call or until it is detached; a connection whose default has been detached + * fails unqualified DDL with a message saying so until it selects another with `USE`. `path` is either the path that + * was passed to `duckdb_v2_instance_attach()` or the name the database is attached under; a name match wins. Returns + * ERROR_INPUT_INVALID when neither matches an attached database. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param path The path the database was attached from, or the name it is attached under. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_set_default(duckdb_v2_instance_handle instance, duckdb_v2_str path, + duckdb_v2_error_info_handle *err); + +/*! + * Creates an empty set of attach options for use with `duckdb_v2_instance_attach()` on `instance`. + * + * Starts empty. The caller destroys it via `duckdb_v2_attach_options_destroy()`; the options may be destroyed as soon + * as the attach call returns, and reused for further attaches before that. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle the options will be used with. + * @param out_options Receives the new options handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_attach_options_create(duckdb_v2_instance_handle instance, + duckdb_v2_attach_options_handle *out_options, + duckdb_v2_error_info_handle *err); + +/*! + * Sets one attach option, like a `(KEY value)` entry of SQL `ATTACH`. + * + * The key is matched case-insensitively, as an unquoted SQL identifier is. The setting is passed on as the text a + * quoted SQL literal would produce: the engine casts the options it knows (READ_ONLY, RECOVERY_MODE, TYPE, + * DEFAULT_TABLE, VACUUM_REBUILD_INDEXES, BLOCK_SIZE, ENCRYPTION_KEY, ...) and hands the rest to the storage extension + * that ends up owning the database, which decides what they mean. Nothing is validated here; an unknown or ill-typed + * option fails the attach. Both views are borrowed and copied. Setting the same key again replaces it. + * + * history: + * - stable: v2.0.0 + * + * @param options The attach options. + * @param key The option name, e.g. READ_ONLY. + * @param setting The option value, in the textual form a quoted SQL literal would carry. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_attach_options_set(duckdb_v2_attach_options_handle options, + duckdb_v2_identifier_t key, duckdb_v2_str setting, + duckdb_v2_error_info_handle *err); + +/*! + * Destroys an attach options handle. + * + * On success the slot is set to null. Safe to call on an already-null slot. + * + * history: + * - stable: v2.0.0 + * + * @param options The attach options to destroy. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_attach_options_destroy(duckdb_v2_attach_options_handle *options); + +/*! + * Sets a config option on the instance (GLOBAL scope). + * + * Before the instance has started (no `duckdb_v2_instance_attach()` or `duckdb_v2_connection_create()` yet), the option + * goes into the startup configuration: this is the only way to set an option that can only be chosen at startup, such + * as access_mode or enable_external_access. Unknown names are kept for an extension to consume at startup; if none + * does, startup fails with the unrecognized names. After startup, this is `SET GLOBAL name = setting` and an unknown + * name is rejected unless an extension that defines it can be autoloaded. Returns ERROR_INPUT_INVALID for an option + * declared LOCAL_ONLY, and for a legacy option with no global setter. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param name Option name (canonical or alias). + * @param setting The setting, in the textual form SQL `SET` accepts. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_set_option(duckdb_v2_instance_handle instance, + duckdb_v2_identifier_t name, duckdb_v2_str setting, + duckdb_v2_error_info_handle *err); + +/*! + * Reads a config option from the instance (GLOBAL scope) by name. + * + * Allocates a fully populated option: canonical name, current GLOBAL setting, default setting, description, target + * scope, and aliases. Before startup the current setting is the staged startup value, or the default. Aliases resolve + * transparently — passing an alias returns the canonical option, with the alias listed in its alias array. An unknown + * name returns ERROR_INPUT_INVALID; before startup that includes an option of an extension that has not loaded yet, + * even if a setting for it has been staged. The caller destroys the returned option. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param name Option name (canonical or alias). + * @param out_option Receives the populated option handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_get_option_by_name(duckdb_v2_instance_handle instance, + duckdb_v2_identifier_t name, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + +/*! + * Returns the number of config options registered on the instance. + * + * Counts core options plus the extension options registered on this instance. Aliases are NOT counted separately; each + * one is reachable through its canonical option's alias array. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param out_count Receives the option count. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_get_option_count(duckdb_v2_instance_handle instance, idx_t *out_count, + duckdb_v2_error_info_handle *err); + +/*! + * Reads the config option at the given index from the instance. + * + * Index space: [0, core_count) addresses core options, [core_count, total) extension options. The mapping is stable for + * as long as no extension registers new options. An out-of-range index returns ERROR_INPUT_INVALID. The caller destroys + * the returned option. + * + * history: + * - stable: v2.0.0 + * + * @param instance The instance handle. + * @param index The option index, in [0, option_count). + * @param out_option Receives the populated option handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_instance_get_option_by_index(duckdb_v2_instance_handle instance, idx_t index, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); + +/*! + * Returns the version of the linked DuckDB library. + * + * history: + * - stable: v2.0.0 + * + * @param out_version The version string. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_library_version(duckdb_v2_str *out_version, duckdb_v2_error_info_handle *err); + +/* --- Struct definitions for instance --- */ + /* ============================================================================ * MODULE: logging * ============================================================================ */ @@ -3520,8 +3726,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_vector_get_size(duckdb_v2_vector_handle v /*! * Sets the number of elements in the vector. * - * The counterpart of vector_get_size: it declares how many logical elements the vector now holds, and does not allocate - * or initialize anything. + * The counterpart of vector_get_size: it declares how many logical elements the vector now holds. It reserves enough + * space for size logical elements. * * history: * - stable: v2.0.0 @@ -3589,6 +3795,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_vector_set_value(duckdb_v2_vector_handle * Any other representation returns ERROR_INPUT_INVALID. The pointer is valid until the owning chunk is destroyed, and * the vector's storage shape must not change — through a flatten, say — while it is in use. * + * When writing VARCHAR values, the caller must ensure that the bytes contain valid UTF-8. + * * history: * - stable: v2.0.0 * @@ -3618,18 +3826,18 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_vector_get_data_mutable(duckdb_v2_vector_ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_vector_flatten(duckdb_v2_vector_handle vector, duckdb_v2_error_info_handle *err); /*! - * Repoints a vector at another vector's data and type, without copying. + * Repoints a vector at another vector's data, without copying. * - * `vector` takes on the storage and logical type of `source`: no data moves, and the two alias the same buffers until - * one of them is reset or re-referenced. Works for any type, nested included. The source's data must outlive every read - * of `vector`. Use it to hand an already-materialized vector — a chunk column produced by arrow_array_to_data_chunk, - * say — straight to an output vector without a per-row copy. + * `vector` takes on the storage of `source`: no data moves, and the two alias the same buffers until one of them is + * reset or re-referenced. Works for any type, including nested types. The source's logical type must equal the + * vector's; a mismatch returns ERROR_INPUT_INVALID. The source's data must outlive every read of `vector`. Use it to + * hand an already-materialized vector straight to an output vector without a per-row copy. * * history: * - stable: v2.0.0 * * @param vector The vector to repoint at the source's data. - * @param source The vector whose data and logical type to reference. + * @param source The vector whose data to reference. Its logical type must equal the vector's. * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. * @return DUCKDB_V2_ERROR */ @@ -3873,6 +4081,24 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_bignum_encode(const uint8_t *in_data, idx uint8_t *out_data, idx_t out_capacity, idx_t *out_length, duckdb_v2_error_info_handle *err); +/*! + * Validates all text.len bytes as UTF-8, including bytes after embedded NUL characters. + * + * Returns ERROR_INPUT_INVALID if either: + * - text.ptr is NULL and text.len is nonzero. + * - The input contains malformed UTF-8. + * + * A NULL pointer with zero length is valid. + * + * history: + * - stable: v2.0.0 + * + * @param text The bytes to validate. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_validate_utf8(duckdb_v2_str text, duckdb_v2_error_info_handle *err); + /* --- Struct definitions for vector --- */ struct duckdb_v2_vector_view { @@ -5470,14 +5696,6 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_column_description_destroy(duckdb_v2_colu /* --- Types for connection --- */ -/*! - * An opaque, owned handle to a snapshot of a query's execution progress, taken by connection_query_progress at call - * time. Read it with the query_progress_get_* accessors; destroy it via query_progress_destroy. - */ -typedef struct _duckdb_v2_query_progress { - void *internal_ptr; -} * duckdb_v2_query_progress_handle; - /* --- Constants for connection --- */ /* --- Function pointer typedefs for connection --- */ @@ -5485,59 +5703,64 @@ typedef struct _duckdb_v2_query_progress { /* --- Functions for connection --- */ /*! - * Opens a connection to a database. + * Opens a connection to an instance, starting it if it has not started yet. * - * Each connection carries its own client context and session-scoped (LOCAL) settings. Connections to the same database - * share its catalog, buffer pool, and transaction manager. + * Each connection carries its own client context and session-scoped (LOCAL) settings. Connections to the same instance + * share its catalog, buffer pool, and transaction manager. A connection may be created before any database is attached + * to the instance; until one is, only the system catalog and the connection's temporary catalog are visible. The caller + * destroys it via `duckdb_v2_connection_destroy()`. * * history: * - stable: v2.0.0 * - * @param db The database to connect to. + * @param instance The instance to connect to. * @param out_conn Receives the new connection handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connect(duckdb_v2_database_handle db, duckdb_v2_connection_handle *out_conn, - duckdb_v2_error_info_handle *err); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_create(duckdb_v2_instance_handle instance, + duckdb_v2_connection_handle *out_conn, + duckdb_v2_error_info_handle *err); /*! - * Closes the connection. + * Destroys the connection. * * Always succeeds. Releases the connection's reference on the underlying database instance, which survives for as long - * as anything else still references it. On success the handle is set to null. + * as anything else still references it. On success the handle is set to null. Safe to call on an already-null slot. * * history: * - stable: v2.0.0 * - * @param conn The connection to close. + * @param conn The connection to destroy. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_disconnect(duckdb_v2_connection_handle *conn); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_destroy(duckdb_v2_connection_handle *conn); /*! * Sets a config option through the connection. * - * Only the name and setting of the option are read; the remaining fields are ignored. `scope` chooses the destination, - * mirroring SQL: + * `scope` chooses the destination, mirroring SQL: * - AUTOMATIC resolves it from the option's target scope, like a bare `SET name = setting`. - * - GLOBAL writes through to the database, visible to all connections, like `SET GLOBAL`. + * - GLOBAL writes through to the instance, visible to all connections, like `SET GLOBAL`. * - LOCAL writes to this connection's session only, like `SET LOCAL` / `SET SESSION`. * A disallowed combination returns ERROR_INPUT_INVALID: GLOBAL against a LOCAL_ONLY option, LOCAL against a GLOBAL_ONLY - * one, and the legacy analogues. Unknown option names are rejected; to set an option whose defining extension has not - * loaded yet, use database scope or the startup options of open. + * one, and the legacy analogues. An unknown name is rejected unless an extension that defines it can be autoloaded; to + * stage a setting for an extension before startup, use `duckdb_v2_instance_set_option()`. * * history: * - stable: v2.0.0 * * @param conn The connection. - * @param option The config option to apply. + * @param name Option name (canonical or alias). + * @param setting The setting, in the textual form SQL `SET` accepts. * @param scope Target scope: AUTOMATIC, GLOBAL, or LOCAL. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_option_set(duckdb_v2_connection_handle conn, - duckdb_v2_option_handle option, +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_set_option(duckdb_v2_connection_handle conn, + duckdb_v2_identifier_t name, duckdb_v2_str setting, DUCKDB_V2_SETTING_SCOPE scope, duckdb_v2_error_info_handle *err); @@ -5546,8 +5769,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_option_set(duckdb_v2_connectio * * Returns the option's effective setting at the connection's scope: the LOCAL override if this connection set one, * otherwise the GLOBAL value, otherwise the static default. The remaining fields are populated exactly as by - * database_option_get. Aliases resolve transparently, and an unknown name returns ERROR_INPUT_INVALID. The caller - * destroys the returned option. + * `duckdb_v2_instance_get_option_by_name()`. Aliases resolve transparently, and an unknown name returns + * ERROR_INPUT_INVALID. The caller destroys the returned option. * * history: * - stable: v2.0.0 @@ -5555,148 +5778,98 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_option_set(duckdb_v2_connectio * @param conn The connection. * @param name Option name (canonical or alias). * @param out_option Receives the populated option handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_option_get(duckdb_v2_connection_handle conn, - duckdb_v2_identifier_t name, - duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_get_option_by_name(duckdb_v2_connection_handle conn, + duckdb_v2_identifier_t name, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); /*! * Returns the number of config options visible to this connection. * - * The same count database_option_get_count reports for the underlying database: core plus extension options, aliases - * excluded. + * The same count `duckdb_v2_instance_get_option_count()` reports for the underlying instance: core plus extension + * options, aliases excluded. * * history: * - stable: v2.0.0 * * @param conn The connection. * @param out_count Receives the option count. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_option_get_count(duckdb_v2_connection_handle conn, idx_t *out_count, - duckdb_v2_error_info_handle *err); - -/*! - * Reads the config option at the given index visible to this connection. - * - * Index space: [0, core_count) addresses core options, [core_count, total) the extension options visible from this - * connection's database. An out-of-range index returns ERROR_INPUT_INVALID. The caller destroys the returned option. - * - * history: - * - stable: v2.0.0 - * - * @param conn The connection. - * @param index The option index, in [0, option_count). - * @param out_option Receives the populated option handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_option_get_by_index(duckdb_v2_connection_handle conn, idx_t index, - duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err); - -/*! - * Interrupts the query currently executing on the connection. - * - * The cross-thread cancellation entry point for streaming results: safe to call from any thread, including while - * another thread steps the query's result. A no-op when no query is active. Cancellation surfaces on the consuming side - * as step status CANCELLED (result_step), or as ERROR_RUNTIME_INTERRUPT (result_fetch_chunk). - * - * history: - * - stable: v2.0.0 - * - * @param conn The connection whose active query to interrupt. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_interrupt(duckdb_v2_connection_handle conn, - duckdb_v2_error_info_handle *err); - -/*! - * Captures a snapshot of the active query's execution progress. - * - * Writes the progress of the query currently executing on the connection into an owned snapshot handle; read it with - * the query_progress_get_* accessors and destroy it via query_progress_destroy. Safe to call from any thread, including - * while another thread steps the query's result. - * - * Progress is published only while the enable_progress_bar option is set; this call does not enable tracking itself. A - * percentage of -1, with both row counts 0, means no information is available: tracking is disabled, no query is - * active, or nothing has been published yet. - * - * history: - * - stable: v2.0.0 - * - * @param conn The connection. - * @param out_progress Receives the new progress snapshot handle. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. - * @return DUCKDB_V2_ERROR - */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_query_progress(duckdb_v2_connection_handle conn, - duckdb_v2_query_progress_handle *out_progress, - duckdb_v2_error_info_handle *err); - -/*! - * Returns the snapshot's percentage complete. - * - * A percentage in [0, 100], or -1 when no progress information was available at capture time. - * - * history: - * - stable: v2.0.0 - * - * @param progress The progress snapshot. - * @param out_percentage Receives the percentage. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_query_progress_get_percentage(duckdb_v2_query_progress_handle progress, - double *out_percentage, - duckdb_v2_error_info_handle *err); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_get_option_count(duckdb_v2_connection_handle conn, idx_t *out_count, + duckdb_v2_error_info_handle *err); /*! - * Returns the snapshot's processed row count. + * Reads the config option at the given index visible to this connection. + * + * Index space: [0, core_count) addresses core options, [core_count, total) the extension options visible from this + * connection's instance. An out-of-range index returns ERROR_INPUT_INVALID. The caller destroys the returned option. * * history: * - stable: v2.0.0 * - * @param progress The progress snapshot. - * @param out_rows_processed Receives the number of rows processed so far. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param conn The connection. + * @param index The option index, in [0, option_count). + * @param out_option Receives the populated option handle. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_query_progress_get_rows_processed(duckdb_v2_query_progress_handle progress, - uint64_t *out_rows_processed, - duckdb_v2_error_info_handle *err); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_get_option_by_index(duckdb_v2_connection_handle conn, idx_t index, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err); /*! - * Returns the snapshot's total row count. + * Interrupts the query currently executing on the connection. + * + * The cross-thread (but not cross-connection) cancellation entry point for streaming results: safe to call from any + * thread within the execution of a query through a connection, including while another thread steps the query's result. + * A no-op when no query is active. Cancellation surfaces on the consuming side as step status CANCELLED + * (`duckdb_v2_result_step()`), or as ERROR_RUNTIME_INTERRUPT (`duckdb_v2_result_fetch_chunk()`). * * history: * - stable: v2.0.0 * - * @param progress The progress snapshot. - * @param out_total_rows_to_process Receives the total number of rows the query will process. - * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. + * @param conn The connection whose active query to interrupt. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_query_progress_get_total_rows_to_process( - duckdb_v2_query_progress_handle progress, uint64_t *out_total_rows_to_process, duckdb_v2_error_info_handle *err); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_interrupt(duckdb_v2_connection_handle conn, + duckdb_v2_error_info_handle *err); /*! - * Destroys a progress snapshot handle. + * Captures a snapshot of the active query's execution progress. * - * Null-safe: passing nullptr or a slot already set to nullptr is a no-op. On success the slot is set to nullptr. + * Reads the percentage and row counts from one consistent snapshot of the query currently executing on the connection. + * Safe to call from any thread, including while another thread steps the query's result. + * + * Progress is published only when the enable_progress_bar option is set; the bridge does not enable tracking itself. + * Both row counts are 0 when no information is available. The percentage is -1 when tracking is disabled, no query is + * active, or no progress has been published yet. * * history: * - stable: v2.0.0 * - * @param progress The progress snapshot to destroy. + * @param conn The connection. + * @param out_percentage Receives the percentage complete in [0, 100], -1 if tracking is disabled, no query is active, + * or no progress has been published yet. + * @param out_rows_processed Receives the number of rows processed so far. + * @param out_total_rows_to_process Receives the total number of rows the query will process. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_query_progress_destroy(duckdb_v2_query_progress_handle *progress); +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_progress_get(duckdb_v2_connection_handle conn, double *out_percentage, + uint64_t *out_rows_processed, + uint64_t *out_total_rows_to_process, + duckdb_v2_error_info_handle *err); /* --- Struct definitions for connection --- */ @@ -8019,7 +8192,7 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_connection_create_type_with_alias(duckdb_ /*! * An owned opaque handle to a replacement scan being built. Created with - * `duckdb_v2_replacement_scan_create_with_connection()`, `duckdb_v2_replacement_scan_create_with_database()` or + * `duckdb_v2_replacement_scan_create_with_connection()`, `duckdb_v2_replacement_scan_create_with_instance()` or * `duckdb_v2_replacement_scan_create_with_extension()`, configured with `duckdb_v2_replacement_scan_set_callback()` and * `duckdb_v2_replacement_scan_set_user_data()`, made available with `duckdb_v2_replacement_scan_register()`, and * destroyed with `duckdb_v2_replacement_scan_destroy()`. @@ -8050,9 +8223,9 @@ typedef void (*duckdb_v2_replacement_scan_callback_fn)(duckdb_v2_replacement_sca /*! * Creates a new replacement scan that will be registered on the connection. * - * The scan is visible only to queries on this connection and is released when the connection closes. It is consulted - * before every database-wide scan, so it can claim a name that a built-in scan would otherwise take. The scan starts - * out empty: configure it with `duckdb_v2_replacement_scan_set_callback()` and optionally + * The scan is visible only to queries on this connection and is released when the connection is destroyed. It is + * consulted before every instance-wide scan, so it can claim a name that a built-in scan would otherwise take. The scan + * starts out empty: configure it with `duckdb_v2_replacement_scan_set_callback()` and optionally * `duckdb_v2_replacement_scan_set_user_data()`, then make it available with `duckdb_v2_replacement_scan_register()`. * The caller owns the returned handle and must destroy it with `duckdb_v2_replacement_scan_destroy()`, also after * registration. @@ -8071,10 +8244,10 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_connection(d duckdb_v2_error_info_handle *err); /*! - * Creates a new replacement scan that will be registered on the database. + * Creates a new replacement scan that will be registered on the instance. * - * The scan is visible to every connection to the database and lives until the database closes. The scan starts out - * empty: configure it with `duckdb_v2_replacement_scan_set_callback()` and optionally + * The scan is visible to every connection to the instance and lives until the instance is destroyed. The scan starts + * out empty: configure it with `duckdb_v2_replacement_scan_set_callback()` and optionally * `duckdb_v2_replacement_scan_set_user_data()`, then make it available with `duckdb_v2_replacement_scan_register()`. * The caller owns the returned handle and must destroy it with `duckdb_v2_replacement_scan_destroy()`, also after * registration. @@ -8082,21 +8255,21 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_connection(d * history: * - stable: v2.0.0 * - * @param database The database to create the scan on. + * @param instance The instance to create the scan on. * @param scan On success, receives the newly created replacement scan. Owned by the caller. * @param err Optional. On failure, receives an opaque info handle the caller must destroy via * `duckdb_v2_error_info_destroy()`. * @return DUCKDB_V2_ERROR */ -DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_database(duckdb_v2_database_handle database, +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_instance(duckdb_v2_instance_handle instance, duckdb_v2_replacement_scan_handle *scan, duckdb_v2_error_info_handle *err); /*! - * Creates a new replacement scan that will be registered on the loading extension's database. + * Creates a new replacement scan that will be registered on the loading extension's instance. * * Use this from an extension load callback, where an extension handle is available. The scan is visible to every - * connection to that database and lives until the database closes. The scan starts out empty: configure it with + * connection to that instance and lives until the instance is destroyed. The scan starts out empty: configure it with * `duckdb_v2_replacement_scan_set_callback()` and optionally `duckdb_v2_replacement_scan_set_user_data()`, then make it * available with `duckdb_v2_replacement_scan_register()`. The caller owns the returned handle and must destroy it with * `duckdb_v2_replacement_scan_destroy()`, also after registration. @@ -8348,10 +8521,10 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_replacement_scan_set_alias(duckdb_v2_repl /*! * Registers the replacement scan, making it consulted for names the catalog cannot resolve. * - * The scan is registered on the target given at creation: the connection, the database or the loading extension's - * database. Registration requires a callback. Scans are consulted in registration order within their scope, - * connection-scoped ones before database-wide ones, and the first to claim a name wins. A scan cannot be registered - * twice, and a registered scan cannot be unregistered: it lives until its scope ends. Registering a database-wide scan + * The scan is registered on the target given at creation: the connection, the instance or the loading extension's + * instance. Registration requires a callback. Scans are consulted in registration order within their scope, + * connection-scoped ones before instance-wide ones, and the first to claim a name wins. A scan cannot be registered + * twice, and a registered scan cannot be unregistered: it lives until its scope ends. Registering an instance-wide scan * while queries are binding on other connections is not thread-safe; register from an extension load callback or before * issuing queries. The caller still owns the handle after registration and must destroy it with * `duckdb_v2_replacement_scan_destroy()`, which does not affect the registered scan. @@ -9034,7 +9207,7 @@ typedef struct _duckdb_v2_statement_iterator { * history: * - stable: v2.0.0 * - * @param conn The connection supplying the parser state. + * @param conn The connection supplying the parser configuration. * @param sql Null-terminated SQL string; may contain any number of statements. * @param out_iterator Receives the new iterator handle. * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. @@ -9085,7 +9258,7 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_statement_iterator_next(duckdb_v2_stateme * history: * - stable: v2.0.0 * - * @param conn The connection supplying the catalog, transaction, and parser state. + * @param conn The connection supplying the catalog, transaction, and parser configuration. * @param statement The statement to bind. Borrowed; not consumed. * @param out_schema Receives the owned output schema (result columns). Destroy via schema_destroy. * @param out_parameters Optional. When non-NULL, receives the owned input schema (parameter types, ordered by binding @@ -11760,7 +11933,7 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_result_destroy(duckdb_v2_result_handle *r * - stable: v2.0.0 * * @param result The result to step. - * @param out_chunk Receives an owned chunk iff *out_status is CHUNK; set to nullptr otherwise. + * @param out_chunk Receives an owned chunk if *out_status is CHUNK; set to nullptr otherwise. * @param out_status Receives the step status. * @param err Optional. On failure, receives an opaque info handle the caller must destroy via error_info_destroy. * @return DUCKDB_V2_ERROR @@ -11948,6 +12121,26 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_result_get_schema(duckdb_v2_result_handle /* --- Enums for table --- */ +/*! + * Whether a table function's scan is partitioned by a given set of columns, and how. Reported by + * `duckdb_v2_table_function_set_partitioning_callback()` via + * `duckdb_v2_table_function_partitioning_set_partition_info()`. + */ +typedef enum DUCKDB_V2_TABLE_PARTITION_INFO { + //! The scan is not known to be partitioned by the requested columns. + DUCKDB_V2_TABLE_PARTITION_INFO_NOT_PARTITIONED = 0, + + //! Each partition the scan produces carries exactly one distinct value for the requested columns. + DUCKDB_V2_TABLE_PARTITION_INFO_SINGLE_VALUE_PARTITIONS = 1, + + //! The partitions the scan produces overlap only at their boundaries. + DUCKDB_V2_TABLE_PARTITION_INFO_OVERLAPPING_PARTITIONS = 2, + + //! The partitions the scan produces are disjoint ranges. + DUCKDB_V2_TABLE_PARTITION_INFO_DISJOINT_PARTITIONS = 3, + DUCKDB_V2_TABLE_PARTITION_INFO_MAX_ENUM = 0x7FFFFFFF, +} DUCKDB_V2_TABLE_PARTITION_INFO; + /* --- Struct forward declarations for table --- */ /* --- Types for table --- */ @@ -12018,6 +12211,25 @@ typedef struct _duckdb_v2_table_function_filter_pushdown_info { void *internal_ptr; } * duckdb_v2_table_function_filter_pushdown_info_handle; +/*! + * A borrowed opaque handle to the arguments supplied to a table function during the "partition data" phase. The engine + * invokes the callback on the worker thread that just produced a batch of rows, once per batch, only when a downstream + * operator needs to know the batch's ordering position, the values of a set of partitioning columns, or both; the + * handle reports which of those were actually requested and receives the answer. + */ +typedef struct _duckdb_v2_table_function_partition_data_info { + void *internal_ptr; +} * duckdb_v2_table_function_partition_data_info_handle; + +/*! + * A borrowed opaque handle to the arguments supplied to a table function during the "partitioning" phase of query + * optimization. The engine invokes the callback once per candidate `GROUP BY` column set, before execution starts, to + * decide whether the scan can feed a partitioned aggregate directly instead of hashing. + */ +typedef struct _duckdb_v2_table_function_partitioning_info { + void *internal_ptr; +} * duckdb_v2_table_function_partitioning_info_handle; + /* --- Constants for table --- */ /* --- Function pointer typedefs for table --- */ @@ -12046,6 +12258,14 @@ typedef void (*duckdb_v2_table_function_filter_pushdown_callback_fn)( duckdb_v2_table_function_filter_pushdown_info_handle info, duckdb_v2_context_handle context, duckdb_v2_error_info_handle *err); +typedef void (*duckdb_v2_table_function_partition_data_callback_fn)( + duckdb_v2_table_function_partition_data_info_handle info, duckdb_v2_context_handle context, + duckdb_v2_error_info_handle *err); + +typedef void (*duckdb_v2_table_function_partitioning_callback_fn)( + duckdb_v2_table_function_partitioning_info_handle info, duckdb_v2_context_handle context, + duckdb_v2_error_info_handle *err); + /* --- Functions for table --- */ /*! @@ -12302,6 +12522,52 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_set_filter_pushdown_callba duckdb_v2_table_function_handle function, duckdb_v2_table_function_filter_pushdown_callback_fn callback, duckdb_v2_error_info_handle *err); +/*! + * Sets the optional "partition data" callback of the table function. + * + * The callback reports, for the batch the exec callback just produced, an ordering batch index, the values of a set of + * partitioning columns, or both, depending on what a downstream operator requires; it runs on the worker thread that + * produced the batch. Set `duckdb_v2_table_function_set_partitioning_callback()` too when the function can answer + * partitioning-column requests, since the engine only asks a scan for those when that callback reports + * `TABLE_PARTITION_INFO_SINGLE_VALUE_PARTITIONS`. + * + * history: + * - stable: v2.0.0 + * + * @param function The function to set the partition data callback of. + * @param callback The partition data callback to set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_set_partition_data_callback( + duckdb_v2_table_function_handle function, duckdb_v2_table_function_partition_data_callback_fn callback, + duckdb_v2_error_info_handle *err); + +/*! + * Sets the optional "partitioning" callback of the table function. + * + * The callback tells the query optimizer, for a candidate `GROUP BY` column set, whether every partition the scan + * produces carries exactly one distinct value for those columns; only `TABLE_PARTITION_INFO_SINGLE_VALUE_PARTITIONS` + * unlocks the partitioned aggregate optimization; any other result, or leaving this callback unset, keeps the regular + * hash aggregate. It runs on the planning thread, before execution starts, and must be deterministic for a given column + * set since it may be called on a plan the optimizer later discards. Registration fails unless + * `duckdb_v2_table_function_set_partition_data_callback()` is set too, since the engine asks that callback for the + * partitioning column values once this one claims single-value partitions. + * + * history: + * - stable: v2.0.0 + * + * @param function The function to set the partitioning callback of. + * @param callback The partitioning callback to set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_set_partitioning_callback( + duckdb_v2_table_function_handle function, duckdb_v2_table_function_partitioning_callback_fn callback, + duckdb_v2_error_info_handle *err); + /*! * Retrieves the user data set via `duckdb_v2_table_function_set_user_data()`. * @@ -12981,6 +13247,286 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_filter_pushdown_get_column duckdb_v2_table_function_filter_pushdown_info_handle info, idx_t index, idx_t *column_index, duckdb_v2_error_info_handle *err); +/*! + * Retrieves the user data set via `duckdb_v2_table_function_set_user_data()`. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param data Receives the user data pointer, or null if none was set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_user_data( + duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + +/*! + * Retrieves the bind data set by the function's bind callback. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param data Receives the bind data pointer, or null if none was set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_bind_data( + duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + +/*! + * Retrieves the global state set by the function's global init callback. + * + * Shared with every other thread scanning the function; access to it must be synchronized by the function. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param data Receives the global state pointer, or null if none was set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_global_state( + duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + +/*! + * Retrieves the worker-local local state set by the function's local init callback, for the thread that produced the + * batch this call reports on. No other thread observes it, so it needs no synchronization. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param data Receives the local state pointer, or null if none was set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_local_state( + duckdb_v2_table_function_partition_data_info_handle info, void **data, duckdb_v2_error_info_handle *err); + +/*! + * Returns whether a downstream operator needs this batch's ordering position. + * + * `duckdb_v2_table_function_partition_data_set_batch_index()` must still be called even when this is false: the engine + * validates the reported value regardless of whether it is actually used for ordering, so `0` is always a safe answer + * when this reports false. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param required Receives whether a batch index is required. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_requires_batch_index( + duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err); + +/*! + * Returns whether a downstream operator needs this batch's values for a set of partitioning columns. + * + * When true, call `duckdb_v2_table_function_partition_data_set_partition_value()` once for every index in `[0, count)`, + * where `count` comes from `duckdb_v2_table_function_partition_data_get_partition_column_count()`. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param required Receives whether partitioning column values are required. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_requires_partition_columns( + duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err); + +/*! + * Returns the number of partitioning columns a downstream operator is requesting values for. + * + * `0` when `duckdb_v2_table_function_partition_data_requires_partition_columns()` is false. Valid indices for + * `duckdb_v2_table_function_partition_data_get_partition_column_index()` and + * `duckdb_v2_table_function_partition_data_set_partition_value()` are `0` up to (but excluding) this count. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param count Receives the number of requested partitioning columns. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_partition_column_count( + duckdb_v2_table_function_partition_data_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err); + +/*! + * Returns which declared column the requested partitioning column at the given index stands for. + * + * The result indexes the columns declared with `duckdb_v2_table_function_bind_add_result_column()`, in declaration + * order. Fails if the index is out of bounds. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param index The index of the requested partitioning column. + * @param column_index Receives the index of the declared column. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_partition_column_index( + duckdb_v2_table_function_partition_data_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err); + +/*! + * Reports the ordering position of the batch the exec callback just produced. + * + * Required on every call, whether or not `duckdb_v2_table_function_partition_data_requires_batch_index()` is true: the + * engine validates the reported value regardless. Not calling this before the callback returns fails the query; `0` is + * always a safe answer when the batch index is not actually required. Must not decrease across successive calls on the + * same thread, must be unique across threads for the ordering to be meaningful, must be less than roughly `10^13`, and, + * when partitioning column values are also being reported, must change whenever those values change: the engine only + * re-reads them when the batch index changes, so reporting a new value under an unchanged batch index is treated as a + * caller error rather than applied. Fails with `ERROR_INPUT_INVALID` for an out-of-range value; a decreasing value or + * an unchanged value paired with changed partitioning columns fails the query once the callback returns. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param batch_index The batch's ordering position. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_set_batch_index( + duckdb_v2_table_function_partition_data_info_handle info, idx_t batch_index, duckdb_v2_error_info_handle *err); + +/*! + * Reports the single value of the partitioning column at the given index, for the batch the exec callback just + * produced. + * + * Every partition reported this way carries exactly one distinct value for the column, so the value serves as both the + * minimum and maximum of the partition's range. The value is borrowed and copied, and must be of the declared type of + * the corresponding result column. Required once for every index in `[0, + * `duckdb_v2_table_function_partition_data_get_partition_column_count()`)` before the callback returns; calling it + * again for the same index overwrites the previous value. The reported value only takes effect together with a changed + * `duckdb_v2_table_function_partition_data_set_batch_index()`: reporting a different value under an unchanged batch + * index fails the query once the callback returns. Fails with `ERROR_INPUT_INVALID` when the index is out of bounds or + * the value's type does not match. + * + * history: + * - stable: v2.0.0 + * + * @param info The partition data info handle. + * @param index The index of the partitioning column being reported. + * @param value The single value of the partitioning column. Borrowed and copied. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_set_partition_value( + duckdb_v2_table_function_partition_data_info_handle info, idx_t index, duckdb_v2_value_handle value, + duckdb_v2_error_info_handle *err); + +/*! + * Retrieves the user data set via `duckdb_v2_table_function_set_user_data()`. + * + * history: + * - stable: v2.0.0 + * + * @param info The partitioning info handle. + * @param data Receives the user data pointer, or null if none was set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partitioning_get_user_data( + duckdb_v2_table_function_partitioning_info_handle info, void **data, duckdb_v2_error_info_handle *err); + +/*! + * Retrieves the bind data set by the function's bind callback. + * + * history: + * - stable: v2.0.0 + * + * @param info The partitioning info handle. + * @param data Receives the bind data pointer, or null if none was set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partitioning_get_bind_data( + duckdb_v2_table_function_partitioning_info_handle info, void **data, duckdb_v2_error_info_handle *err); + +/*! + * Returns the number of columns the optimizer is asking about: the candidate `GROUP BY` column set. + * + * Valid indices for `duckdb_v2_table_function_partitioning_get_partition_column_index()` are `0` up to (but excluding) + * this count. + * + * history: + * - stable: v2.0.0 + * + * @param info The partitioning info handle. + * @param count Receives the number of columns in the candidate set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partitioning_get_partition_column_count( + duckdb_v2_table_function_partitioning_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err); + +/*! + * Returns which declared column the candidate `GROUP BY` column at the given index stands for. + * + * The result indexes the columns declared with `duckdb_v2_table_function_bind_add_result_column()`, in declaration + * order. Fails if the index is out of bounds. + * + * history: + * - stable: v2.0.0 + * + * @param info The partitioning info handle. + * @param index The index of the candidate column. + * @param column_index Receives the index of the declared column. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partitioning_get_partition_column_index( + duckdb_v2_table_function_partitioning_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err); + +/*! + * Reports whether every partition the scan produces carries exactly one distinct value for the candidate `GROUP BY` + * column set. + * + * Only `TABLE_PARTITION_INFO_SINGLE_VALUE_PARTITIONS` unlocks the partitioned aggregate optimization; any other value + * keeps the regular hash aggregate. A callback that never calls this is treated as reporting + * `TABLE_PARTITION_INFO_NOT_PARTITIONED`. Fails with `ERROR_INPUT_INVALID` when partition_info is not one of the enum's + * declared values. + * + * history: + * - stable: v2.0.0 + * + * @param info The partitioning info handle. + * @param partition_info Whether, and how, the scan is partitioned by the candidate column set. + * @param err Optional. On failure, receives an opaque info handle the caller must destroy via + * `duckdb_v2_error_info_destroy()`. + * @return DUCKDB_V2_ERROR + */ +DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_partitioning_set_partition_info( + duckdb_v2_table_function_partitioning_info_handle info, DUCKDB_V2_TABLE_PARTITION_INFO partition_info, + duckdb_v2_error_info_handle *err); + /*! * Registers the table function, making it available for use in SQL queries. * diff --git a/src/duckdb/src/logging/log_manager.cpp b/src/duckdb/src/logging/log_manager.cpp index 5d80e08bc..7f5bf160a 100644 --- a/src/duckdb/src/logging/log_manager.cpp +++ b/src/duckdb/src/logging/log_manager.cpp @@ -285,6 +285,7 @@ void LogManager::RegisterDefaultLogTypes() { RegisterLogType(make_uniq()); RegisterLogType(make_uniq()); RegisterLogType(make_uniq()); + RegisterLogType(make_uniq()); } } // namespace duckdb diff --git a/src/duckdb/src/logging/log_types.cpp b/src/duckdb/src/logging/log_types.cpp index b8512505d..798ea47db 100644 --- a/src/duckdb/src/logging/log_types.cpp +++ b/src/duckdb/src/logging/log_types.cpp @@ -23,6 +23,7 @@ constexpr LogLevel CheckpointLogType::LEVEL; constexpr LogLevel AdaptiveFilterLogType::LEVEL; constexpr LogLevel ParquetPrefetchLogType::LEVEL; constexpr LogLevel AsyncTaskScheduleLogType::LEVEL; +constexpr LogLevel ProgressVerificationLogType::LEVEL; //===--------------------------------------------------------------------===// // QueryLogType @@ -384,6 +385,33 @@ string AsyncTaskScheduleLogType::ConstructLogMessage(const string &pool, idx_t t return Value::STRUCT(std::move(child_list)).ToString(); } +//===--------------------------------------------------------------------===// +// ProgressVerificationLogType +//===--------------------------------------------------------------------===// +ProgressVerificationLogType::ProgressVerificationLogType() : LogType(NAME, LEVEL, GetLogType()) { +} + +LogicalType ProgressVerificationLogType::GetLogType() { + child_list_t child_list = { + {"invariant", LogicalType::VARCHAR}, + {"operator", LogicalType::VARCHAR}, + {"pipeline", LogicalType::VARCHAR}, + {"detail", LogicalType::VARCHAR}, + }; + return LogicalType::STRUCT(child_list); +} + +string ProgressVerificationLogType::ConstructLogMessage(const string &invariant, const string &operator_name, + const string &pipeline, const string &detail) { + child_list_t child_list = { + {"invariant", Value(invariant)}, + {"operator", Value(operator_name)}, + {"pipeline", Value(pipeline)}, + {"detail", Value(detail)}, + }; + return Value::STRUCT(std::move(child_list)).ToString(); +} + //===--------------------------------------------------------------------===// // ExternalResourceLogType //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/main/attached_database.cpp b/src/duckdb/src/main/attached_database.cpp index d67f6cd7b..ac6d8989d 100644 --- a/src/duckdb/src/main/attached_database.cpp +++ b/src/duckdb/src/main/attached_database.cpp @@ -7,6 +7,7 @@ #include "duckdb/common/file_system.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/database_manager.hpp" +#include "duckdb/main/external_resources_manager.hpp" #include "duckdb/main/settings.hpp" #include "duckdb/parser/parsed_data/attach_info.hpp" #include "duckdb/parser/qualified_name.hpp" @@ -42,17 +43,26 @@ AttachOptions::AttachOptions(const DBConfigOptions &options) : access_mode(options.access_mode), db_type(options.database_type) { } +//! The spellings of the access mode option, and whether `true` means read-only for each. +static const unordered_map ACCESS_MODE_OPTIONS = { + {"readonly", true}, {"read_only", true}, {"readwrite", false}, {"read_write", false}}; + +string AttachOptions::OptionSetting(const string &name) { + auto lower = StringUtil::Lower(name); + if (ACCESS_MODE_OPTIONS.find(lower) != ACCESS_MODE_OPTIONS.end()) { + return "access_mode"; + } + return lower; +} + AttachOptions::AttachOptions(const unordered_map &attach_options, const AccessMode default_access_mode) : access_mode(default_access_mode) { for (auto &entry : attach_options) { - if (entry.first == "readonly" || entry.first == "read_only") { - // Extract the read access mode. - auto read_only = BooleanValue::Get(entry.second.DefaultCastAs(LogicalType::BOOLEAN)); - if (read_only) { - access_mode = AccessMode::READ_ONLY; - } else { - access_mode = AccessMode::READ_WRITE; - } + auto access_mode_option = ACCESS_MODE_OPTIONS.find(entry.first); + if (access_mode_option != ACCESS_MODE_OPTIONS.end()) { + // Extract the access mode; the option reads inverted for the readwrite spellings. + auto value = BooleanValue::Get(entry.second.DefaultCastAs(LogicalType::BOOLEAN)); + access_mode = value == access_mode_option->second ? AccessMode::READ_ONLY : AccessMode::READ_WRITE; continue; } @@ -63,17 +73,6 @@ AttachOptions::AttachOptions(const unordered_map &attach_options, continue; } - if (entry.first == "readwrite" || entry.first == "read_write") { - // Extract the write access mode. - auto read_write = BooleanValue::Get(entry.second.DefaultCastAs(LogicalType::BOOLEAN)); - if (!read_write) { - access_mode = AccessMode::READ_ONLY; - } else { - access_mode = AccessMode::READ_WRITE; - } - continue; - } - if (entry.first == "type") { // Extract the database type. Normalize case so that // `TYPE sqlite` and `TYPE 'SQLite'` are equivalent. @@ -149,6 +148,11 @@ AttachedDatabase::AttachedDatabase(DatabaseInstance &db, Catalog &catalog_p, Ide ephemeral = options.ephemeral; vacuum_rebuild_threshold = options.vacuum_rebuild_indexes_threshold; original_path = options.original_path; + deleter_function = options.deleter_function; + deleter_payload = options.deleter_payload; + deleter_resource_type = options.deleter_resource_type; + deleter_resource_name = options.deleter_resource_name; + borrowed_resource_name = options.borrowed_resource_name; // We create the storage after the catalog to guarantee we allow extensions to instantiate the DuckCatalog. catalog = make_uniq(*this); @@ -173,6 +177,11 @@ AttachedDatabase::AttachedDatabase(DatabaseInstance &db, Catalog &catalog_p, Sto ephemeral = options.ephemeral; vacuum_rebuild_threshold = options.vacuum_rebuild_indexes_threshold; original_path = options.original_path; + deleter_function = options.deleter_function; + deleter_payload = options.deleter_payload; + deleter_resource_type = options.deleter_resource_type; + deleter_resource_name = options.deleter_resource_name; + borrowed_resource_name = options.borrowed_resource_name; optional_ptr storage_info = storage_extension->storage_info.get(); catalog = storage_extension->attach(storage_info, context, *this, name.GetIdentifierName(), info, options); @@ -363,6 +372,16 @@ void AttachedDatabase::OnDetach(ClientContext &context) { } } +unique_ptr AttachedDatabase::ExtractDeleter() { + if (deleter_function.empty()) { + return nullptr; + } + auto result = make_uniq(db, std::move(deleter_function), std::move(deleter_payload), + std::move(deleter_resource_type), std::move(deleter_resource_name)); + deleter_function.clear(); + return result; +} + void AttachedDatabase::Close(const DatabaseCloseAction action) { if (is_closed) { return; diff --git a/src/duckdb/src/main/buffered_data/batched_buffered_data.cpp b/src/duckdb/src/main/buffered_data/batched_buffered_data.cpp index 4800b30b8..6577731ef 100644 --- a/src/duckdb/src/main/buffered_data/batched_buffered_data.cpp +++ b/src/duckdb/src/main/buffered_data/batched_buffered_data.cpp @@ -1,7 +1,7 @@ #include "duckdb/main/buffered_data/batched_buffered_data.hpp" #include "duckdb/execution/executor.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/stream_query_result.hpp" +#include "duckdb/main/query_result.hpp" #include "duckdb/common/helper.hpp" #include "duckdb/common/stack.hpp" @@ -12,16 +12,15 @@ BatchedBufferedData::BatchedBufferedData(ClientContext &context, ResultLifetime min_batch(0) { } -bool BatchedBufferedData::AppendOrBlock(DataChunk &to_append, idx_t batch, const InterruptState &blocked_sink) { - // Copied outside the lock: both outcomes need the copy, and parallel producers copy concurrently - auto copy = CopyForBuffering(to_append); - const idx_t chunk_data_size = copy->GetDataSize(); +bool BatchedBufferedData::AppendOrBlock(unique_ptr unit, idx_t batch, const InterruptState &blocked_sink) { + const idx_t unit_data_size = unit->byte_size; annotated_lock_guard lock(glock); + D_ASSERT(batch != DConstants::INVALID_INDEX); D_ASSERT(batch >= min_batch); - max_seen_chunk_bytes = MaxValue(max_seen_chunk_bytes, chunk_data_size); - if (ShouldBlockBatch(lock, batch, chunk_data_size)) { - // Park holding the finished copy. Restart selection deposits it at wake time - auto entry = blocked_sinks.emplace(batch, BlockedSink {blocked_sink, chunk_data_size, std::move(copy)}); + max_seen_unit_bytes = MaxValue(max_seen_unit_bytes, unit_data_size); + if (ShouldBlockBatch(lock, batch, unit_data_size)) { + // Park holding the finished unit. Restart selection deposits it at wake time + auto entry = blocked_sinks.emplace(batch, BlockedSink {blocked_sink, std::move(unit)}); (void)entry; D_ASSERT(entry.second); return true; @@ -36,13 +35,13 @@ bool BatchedBufferedData::AppendOrBlock(DataChunk &to_append, idx_t batch, const // There should not be any batches in the buffer that are lower or equal to the minimum batch index throw InternalException("Batches remaining in buffer"); } - read_queue.push(BufferedChunk {std::move(copy), chunk_data_size}); - read_queue_byte_count += chunk_data_size; + read_queue.push(std::move(unit)); + read_queue_byte_count += unit_data_size; } else { auto &in_progress_batch = buffer[batch]; in_progress_batch.completed = false; - in_progress_batch.chunk_refs.push_back(BufferedChunk {std::move(copy), chunk_data_size}); - buffer_byte_count += chunk_data_size; + in_progress_batch.units.push_back(std::move(unit)); + buffer_byte_count += unit_data_size; } peak_buffered_bytes = MaxValue(peak_buffered_bytes, read_queue_byte_count + buffer_byte_count); return false; @@ -52,17 +51,17 @@ bool BatchedBufferedData::ShouldBlockBatch(annotated_lock_guard idx_t incoming_bytes) { const idx_t total = read_queue_byte_count + buffer_byte_count; if (IsMinimumBatchIndex(lock, batch)) { - // Only block the minimum batch producer while the consumer has chunks to pop. + // Only block the minimum batch producer while the consumer has units to pop. // Every pop lowers the total, so consumption always wakes it again return total + incoming_bytes > total_buffer_size && !read_queue.empty(); } if (total == 0) { - // An empty pool always admits one chunk, so every producer keeps progressing + // An empty pool always admits one unit, so every producer keeps progressing return false; } - // Read-ahead batches leave the minimum batch a reserve: the largest chunk seen, capped at half the - // budget so one oversized chunk cannot serialize read-ahead for the rest of the query - const idx_t reserve = MaxValue(MinValue(max_seen_chunk_bytes, total_buffer_size / 2), + // Read-ahead batches leave the minimum batch a reserve: the largest unit seen, capped at half the + // budget so one oversized unit cannot serialize read-ahead for the rest of the query + const idx_t reserve = MaxValue(MinValue(max_seen_unit_bytes, total_buffer_size / 2), MaxValue(total_buffer_size / 8, 1)); const idx_t threshold = MaxValue(total_buffer_size - reserve, 1); return total + incoming_bytes > threshold; @@ -83,7 +82,7 @@ void BatchedBufferedData::CollectRestartableSinks(annotated_lock_guardfirst, it->second.pending_bytes)) { + if (ShouldBlockBatch(lock, it->first, it->second.PendingBytes())) { it++; continue; } @@ -94,22 +93,22 @@ void BatchedBufferedData::CollectRestartableSinks(annotated_lock_guard &lock, idx_t batch, BlockedSink &sink) { - // Deposit before the wake, so the chunk is visible when the producer resumes; the batch may have - // become the minimum meanwhile. The null guard keeps a park without a copy out of the queue - if (!sink.pending_chunk) { + // Deposit before the wake, so the unit is visible when the producer resumes; the batch may have + // become the minimum meanwhile. The null guard keeps a park without a unit out of the queue + if (!sink.pending_unit) { return; } + const idx_t pending_bytes = sink.pending_unit->byte_size; if (IsMinimumBatchIndex(lock, batch)) { - read_queue.push(BufferedChunk {std::move(sink.pending_chunk), sink.pending_bytes}); - read_queue_byte_count += sink.pending_bytes; + read_queue.push(std::move(sink.pending_unit)); + read_queue_byte_count += pending_bytes; } else { auto &in_progress_batch = buffer[batch]; in_progress_batch.completed = false; - in_progress_batch.chunk_refs.push_back(BufferedChunk {std::move(sink.pending_chunk), sink.pending_bytes}); - buffer_byte_count += sink.pending_bytes; + in_progress_batch.units.push_back(std::move(sink.pending_unit)); + buffer_byte_count += pending_bytes; } peak_buffered_bytes = MaxValue(peak_buffered_bytes, read_queue_byte_count + buffer_byte_count); - sink.pending_bytes = 0; } void BatchedBufferedData::InvokeUnblocks(const vector> &to_unblock) { @@ -146,17 +145,17 @@ void BatchedBufferedData::MoveCompletedBatches(annotated_lock_guardbyte_size; + read_queue.push(std::move(unit)); } // Verification to make sure we're not breaking the order by moving batches before the previous ones have // finished if (lowest_moved_batch > batch_index) { throw InternalException("Lowest moved batch is %d, attempted to move %d afterwards\nAttempted to move %d " - "chunks, of %d bytes in total\nmin_batch is %d", - lowest_moved_batch, batch_index, in_progress_batch.chunk_refs.size(), - batch_data_size, min_batch); + "units, of %d bytes in total\nmin_batch is %d", + lowest_moved_batch, batch_index, in_progress_batch.units.size(), batch_data_size, + min_batch); } D_ASSERT(lowest_moved_batch <= batch_index); lowest_moved_batch = batch_index; @@ -188,7 +187,7 @@ void BatchedBufferedData::UpdateMinBatchIndex(idx_t min_batch_index) { // The move conserves the byte total, so only the newly minimum batch's sink can // have a changed block decision: it now falls under the read queue rule auto entry = blocked_sinks.find(min_batch); - if (entry != blocked_sinks.end() && !ShouldBlockBatch(lock, entry->first, entry->second.pending_bytes)) { + if (entry != blocked_sinks.end() && !ShouldBlockBatch(lock, entry->first, entry->second.PendingBytes())) { DepositParked(lock, entry->first, entry->second); to_unblock.emplace_back(entry->first, std::move(entry->second)); blocked_sinks.erase(entry); @@ -215,28 +214,27 @@ void BatchedBufferedData::AssertNoBlockedSinks() { #endif } -unique_ptr BatchedBufferedData::Scan() { - unique_ptr chunk; +unique_ptr BatchedBufferedData::Scan() { + unique_ptr unit; vector> to_unblock; { annotated_lock_guard lock(glock); if (read_queue.empty()) { - context.reset(); + Close(); D_ASSERT(blocked_sinks.empty()); D_ASSERT(buffer.empty()); return nullptr; } - auto ref = std::move(read_queue.front()); + unit = std::move(read_queue.front()); read_queue.pop(); - chunk = std::move(ref.chunk); - read_queue_byte_count -= ref.data_size; + read_queue_byte_count -= unit->byte_size; // The walk is O(blocked sinks), so only run it when a sink exists if (!blocked_sinks.empty()) { CollectRestartableSinks(lock, to_unblock); } } InvokeUnblocks(to_unblock); - return chunk; + return unit; } } // namespace duckdb diff --git a/src/duckdb/src/main/buffered_data/buffered_data.cpp b/src/duckdb/src/main/buffered_data/buffered_data.cpp index 3d19ac7a5..95f045678 100644 --- a/src/duckdb/src/main/buffered_data/buffered_data.cpp +++ b/src/duckdb/src/main/buffered_data/buffered_data.cpp @@ -2,7 +2,7 @@ #include "duckdb/common/exception.hpp" #include "duckdb/common/helper.hpp" #include "duckdb/execution/executor.hpp" -#include "duckdb/main/stream_query_result.hpp" +#include "duckdb/main/query_result.hpp" #include "duckdb/main/client_config.hpp" #include "duckdb/main/client_context.hpp" @@ -56,7 +56,7 @@ bool BufferedData::ParkUndecided(const InterruptState &blocked_sink) { return true; } -bool BufferedData::HasParkedProducer() { +bool BufferedData::WaitsOnConsumer() { // The undecided list is empty once the retention is settled: ParkUndecided re-checks under glock if (lifetime == ResultLifetime::UNDECIDED) { annotated_lock_guard lock(glock); @@ -64,25 +64,13 @@ bool BufferedData::HasParkedProducer() { return true; } } - return HasBlockedSink(); + // A space park is only the consumer's to release when a pop is possible: the batched buffer also + // parks read-ahead batches while the read queue is empty, and the minimum batch releases those + return HasBlockedSink() && HasObservableUnit(); } -StreamExecutionResult BufferedData::MapExecutionResult(PendingExecutionResult execution_result) { - switch (execution_result) { - case PendingExecutionResult::BLOCKED: - case PendingExecutionResult::RESULT_READY: - return StreamExecutionResult::BLOCKED; - case PendingExecutionResult::NO_TASKS_AVAILABLE: - case PendingExecutionResult::RESULT_NOT_READY: - return StreamExecutionResult::CHUNK_NOT_READY; - case PendingExecutionResult::EXECUTION_FINISHED: - return StreamExecutionResult::EXECUTION_FINISHED; - case PendingExecutionResult::EXECUTION_ERROR: - return StreamExecutionResult::EXECUTION_ERROR; - default: - throw InternalException("No conversion from PendingExecutionResult (%s) -> StreamExecutionResult", - EnumUtil::ToString(execution_result)); - } +QueryResultState BufferedData::Cancelled(QueryResult &result) { + return result.Cancelled(); } unique_ptr BufferedData::CopyForBuffering(DataChunk &chunk) { @@ -96,51 +84,79 @@ idx_t BufferedData::LowWaterMark(idx_t capacity) { return MaxValue(capacity / 2, 1); } -StreamExecutionResult BufferedData::ExecuteTaskInternal(StreamQueryResult &result, ClientContextLock &context_lock) { +QueryResultState BufferedData::Participate(ClientContextLock &context_lock, QueryResult &result) { auto cc = context.lock(); if (!cc) { - return StreamExecutionResult::EXECUTION_CANCELLED; + return Cancelled(result); } if (!cc->IsActiveResult(context_lock, result)) { - return StreamExecutionResult::EXECUTION_CANCELLED; + return Cancelled(result); } DecideDraining(); - // Checked with chunks poppable too, so a cancel ends the drain early. A worker error also raises + // Checked with units poppable too, so a cancel ends the drain early. A worker error also raises // the flag, so only a flag without an executor error is a cancel; both loads are seq_cst const bool interrupted = cc->interrupt_state.load() == ClientInterruptState::INTERRUPTED; if (interrupted && !Executor::Get(*cc).HasError()) { throw InterruptException(); } if (!interrupted && ReplenishSatisfied()) { - return StreamExecutionResult::CHUNK_READY; + return QueryResultState::READY; } UnblockSinks(); // Let the executor run until the buffer is no longer empty auto execution_result = cc->ExecuteTaskInternal(context_lock, result); - if (execution_result == PendingExecutionResult::EXECUTION_ERROR) { - // The query has ended, so a still-buffered chunk must not be reported as poppable + if (execution_result == QueryResultState::EXECUTION_ERROR) { + // The query has ended, so a still-buffered unit must not be reported as poppable Close(); - return StreamExecutionResult::EXECUTION_ERROR; + return QueryResultState::EXECUTION_ERROR; } if (ReplenishSatisfied()) { - return StreamExecutionResult::CHUNK_READY; + return QueryResultState::READY; } - if (execution_result == PendingExecutionResult::BLOCKED || - execution_result == PendingExecutionResult::RESULT_READY) { - return StreamExecutionResult::BLOCKED; + // Engine READY means a parked producer with a unit to pop, which satisfies the replenish above + D_ASSERT(execution_result != QueryResultState::READY); + return execution_result; +} + +QueryResultState BufferedData::Poll(ClientContextLock &context_lock, QueryResult &result) { + auto cc = context.lock(); + if (!cc) { + return Cancelled(result); + } + if (!cc->IsActiveResult(context_lock, result)) { + return Cancelled(result); } - return MapExecutionResult(execution_result); + // Checked before the buffer, so a cancel is seen even with units poppable. A worker error also + // raises the flag; only a flag without an executor error is a real cancel + const bool interrupted = cc->interrupt_state.load() == ClientInterruptState::INTERRUPTED; + if (interrupted && !Executor::Get(*cc).HasError()) { + throw InterruptException(); + } + if (!interrupted && HasObservableUnit()) { + return QueryResultState::READY; + } + auto execution_result = cc->PollInternal(context_lock, result); + if (execution_result == QueryResultState::EXECUTION_ERROR) { + Close(); + return QueryResultState::EXECUTION_ERROR; + } + if (HasObservableUnit()) { + return QueryResultState::READY; + } + // Engine READY means a parked producer with a unit to pop, which the check above would have seen + D_ASSERT(execution_result != QueryResultState::READY); + return execution_result; } -StreamExecutionResult BufferedData::ReplenishBuffer(StreamQueryResult &result, ClientContextLock &context_lock) { +QueryResultState BufferedData::ReplenishBuffer(ClientContextLock &context_lock, QueryResult &result) { auto cc = context.lock(); if (!cc) { - return StreamExecutionResult::EXECUTION_CANCELLED; + return Cancelled(result); } - StreamExecutionResult execution_result; - while (!StreamQueryResult::IsChunkReady(execution_result = ExecuteTaskInternal(result, context_lock))) { - if (execution_result == StreamExecutionResult::BLOCKED) { + QueryResultState execution_result; + while (!IsObservable(execution_result = Participate(context_lock, result))) { + if (execution_result == QueryResultState::BLOCKED) { UnblockSinks(); cc->WaitForTask(context_lock, result); } diff --git a/src/duckdb/src/main/buffered_data/simple_buffered_data.cpp b/src/duckdb/src/main/buffered_data/simple_buffered_data.cpp index 534284168..da5a32aac 100644 --- a/src/duckdb/src/main/buffered_data/simple_buffered_data.cpp +++ b/src/duckdb/src/main/buffered_data/simple_buffered_data.cpp @@ -2,7 +2,7 @@ #include "duckdb/common/vector.hpp" #include "duckdb/execution/executor.hpp" #include "duckdb/main/client_context.hpp" -#include "duckdb/main/stream_query_result.hpp" +#include "duckdb/main/query_result.hpp" #include "duckdb/common/helper.hpp" namespace duckdb { @@ -29,6 +29,12 @@ bool SimpleBufferedData::HasBlockedSink() { return !blocked_sinks.empty(); } +bool SimpleBufferedData::HasObservableUnit() { + annotated_lock_guard lock(glock); + // Readiness is the unit queue, never the byte count: units with rows but zero data bytes exist + return !unread_units.empty(); +} + void SimpleBufferedData::CollectRestartableSinks(annotated_lock_guard &lock, vector &to_unblock) { D_ASSERT(to_unblock.empty()); @@ -36,17 +42,16 @@ void SimpleBufferedData::CollectRestartableSinks(annotated_lock_guard 0 && buffered_count + front.pending_bytes > BufferSize()) { + // Sinks restart in FIFO order. Stop at the first unit that does not fit yet + if (buffered_count > 0 && buffered_count + front.PendingBytes() > BufferSize()) { break; } - // Deposit the parked copy, so the chunk is visible before the producer wakes. - // Parks always carry their copy; the guard keeps a null from corrupting the queue - if (front.pending_chunk) { - buffered_count += front.pending_bytes; - unread_chunks.push(BufferedChunk {std::move(front.pending_chunk), front.pending_bytes}); + // Deposit the parked unit, so it is visible before the producer wakes. + // Parks always carry their unit; the guard keeps a null from corrupting the queue + if (front.pending_unit) { + buffered_count += front.pending_unit->byte_size; + unread_units.push(std::move(front.pending_unit)); peak_buffered_bytes = MaxValue(peak_buffered_bytes, buffered_count); - front.pending_bytes = 0; } to_unblock.push_back(std::move(front)); blocked_sinks.pop(); @@ -87,45 +92,42 @@ void SimpleBufferedData::AssertNoBlockedSinks() { #endif } -unique_ptr SimpleBufferedData::Scan() { +unique_ptr SimpleBufferedData::Scan() { if (Closed()) { return nullptr; } - unique_ptr chunk; + unique_ptr unit; vector to_unblock; { annotated_lock_guard lock(glock); - if (unread_chunks.empty()) { + if (unread_units.empty()) { Close(); return nullptr; } - auto ref = std::move(unread_chunks.front()); - unread_chunks.pop(); - chunk = std::move(ref.chunk); - buffered_count -= ref.data_size; + unit = std::move(unread_units.front()); + unread_units.pop(); + buffered_count -= unit->byte_size; // The pop restarts blocked producers below the low-water mark if (buffered_count < LowWaterMark(BufferSize())) { CollectRestartableSinks(lock, to_unblock); } } InvokeUnblocks(to_unblock); - return chunk; + return unit; } -bool SimpleBufferedData::AppendOrBlock(DataChunk &to_append, const InterruptState &blocked_sink) { - // Copied outside the lock: both outcomes need the copy, and parallel producers copy concurrently - auto copy = CopyForBuffering(to_append); - const idx_t chunk_data_size = copy->GetDataSize(); +bool SimpleBufferedData::AppendOrBlock(unique_ptr unit, const InterruptState &blocked_sink) { + const idx_t unit_data_size = unit->byte_size; annotated_lock_guard lock(glock); - // The buffer admits a chunk that fits, and always one chunk when empty - if (buffered_count > 0 && buffered_count + chunk_data_size > BufferSize()) { - // Park holding the finished copy. Restart selection deposits it at wake time - blocked_sinks.push(BlockedSink {blocked_sink, chunk_data_size, std::move(copy)}); + // The buffer admits a unit that fits, and always one unit when empty + if (buffered_count > 0 && buffered_count + unit_data_size > BufferSize()) { + // Park holding the finished unit. Restart selection deposits it at wake time + blocked_sinks.push(BlockedSink {blocked_sink, std::move(unit)}); return true; } - unread_chunks.push(BufferedChunk {std::move(copy), chunk_data_size}); - buffered_count += chunk_data_size; + unread_units.push(std::move(unit)); + buffered_count += unit_data_size; peak_buffered_bytes = MaxValue(peak_buffered_bytes, buffered_count); return false; } diff --git a/src/duckdb/src/main/capi/v1/arrow-c.cpp b/src/duckdb/src/main/capi/v1/arrow-c.cpp index aa57f4591..329bc0d23 100644 --- a/src/duckdb/src/main/capi/v1/arrow-c.cpp +++ b/src/duckdb/src/main/capi/v1/arrow-c.cpp @@ -1,6 +1,7 @@ #include "duckdb/common/arrow/arrow.hpp" #include "duckdb/common/arrow/arrow_converter.hpp" #include "duckdb/function/table/arrow.hpp" +#include "duckdb/common/types/column/column_data_collection.hpp" #include "duckdb/main/capi/capi_internal.hpp" #include "fmt/format.h" @@ -10,7 +11,6 @@ using duckdb::CClientArrowOptionsWrapper; using duckdb::Connection; using duckdb::DataChunk; using duckdb::LogicalType; -using duckdb::MaterializedQueryResult; using duckdb::PreparedStatementWrapper; using duckdb::QueryResult; using duckdb::QueryResultType; @@ -234,7 +234,7 @@ duckdb_state duckdb_query_arrow_array(duckdb_arrow result, duckdb_arrow_array *o return DuckDBSuccess; } auto wrapper = reinterpret_cast(result); - auto success = wrapper->result->TryFetch(wrapper->current_chunk, wrapper->result->GetErrorObject()); + auto success = wrapper->result->TryFetchOrError(wrapper->current_chunk, wrapper->result->GetErrorObject()); if (!success) { // LCOV_EXCL_START return DuckDBError; } // LCOV_EXCL_STOP @@ -254,11 +254,12 @@ void duckdb_result_arrow_array(duckdb_result result, duckdb_data_chunk chunk, du } auto dchunk = reinterpret_cast(chunk); auto &result_data = *(reinterpret_cast(result.internal_data)); - auto extension_type_cast = duckdb::ArrowTypeExtensionData::GetExtensionTypes( - *result_data.result->client_properties.client_context, result_data.result->GetTypes()); + auto &client_properties = result_data.GetClientProperties(); + auto extension_type_cast = + duckdb::ArrowTypeExtensionData::GetExtensionTypes(*client_properties.client_context, result_data.GetTypes()); - ArrowConverter::ToArrowArray(*dchunk, reinterpret_cast(*out_array), - result_data.result->client_properties, extension_type_cast); + ArrowConverter::ToArrowArray(*dchunk, reinterpret_cast(*out_array), client_properties, + extension_type_cast); } idx_t duckdb_arrow_row_count(duckdb_arrow result) { @@ -326,9 +327,9 @@ duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_st } auto arrow_wrapper = new ArrowResultWrapper(); try { - auto result = wrapper->statement->Execute(wrapper->values, false); + auto result = wrapper->statement->Execute(wrapper->values); D_ASSERT(result->GetResultType() == QueryResultType::MATERIALIZED_RESULT); - arrow_wrapper->result = duckdb::unique_ptr_cast(std::move(result)); + arrow_wrapper->result = std::move(result); *out_result = reinterpret_cast(arrow_wrapper); return !arrow_wrapper->result->HasError() ? DuckDBSuccess : DuckDBError; } catch (...) { @@ -394,14 +395,27 @@ int GetNext(struct ArrowArrayStream *stream, struct ArrowArray *out) { return DuckDBSuccess; } -duckdb::unique_ptr FactoryGetNext(uintptr_t stream_factory_ptr, - duckdb::ArrowStreamParameters ¶meters) { - auto stream = reinterpret_cast(stream_factory_ptr); - auto ret = duckdb::make_uniq(); - ret->arrow_array_stream = *stream; - ret->arrow_array_stream.release = EmptyStreamRelease; - return ret; -} +class CArrowScanFactory : public duckdb::ArrowScanFactory { +public: + explicit CArrowScanFactory(ArrowArrayStream &stream_p) : stream(stream_p) { + } + + void GetSchema(ArrowSchema &schema) override { + FactoryGetSchema(&stream.get(), schema); + } + + duckdb::unique_ptr + ProduceStream(duckdb::ArrowStreamParameters ¶meters) override { + auto result = duckdb::make_uniq(); + result->arrow_array_stream = stream.get(); + result->arrow_array_stream.release = EmptyStreamRelease; + return result; + } + +private: + //! The caller retains ownership of the stream and its arrays. + duckdb::reference stream; +}; // LCOV_EXCL_START // This function is never be called, because it's used to construct a stream wrapping around a caller-supplied @@ -423,10 +437,11 @@ void Release(struct ArrowArrayStream *stream) { duckdb_state Ingest(duckdb_connection connection, const char *table_name, struct ArrowArrayStream *input) { try { auto cconn = reinterpret_cast(connection); - cconn - ->TableFunction("arrow_scan", {duckdb::Value::POINTER((uintptr_t)input), - duckdb::Value::POINTER((uintptr_t)FactoryGetNext), - duckdb::Value::POINTER((uintptr_t)FactoryGetSchema)}) + if (!input) { + return DuckDBError; + } + auto factory = duckdb::make_shared_ptr(*input); + cconn->TableFunction("arrow_scan", {}, {}, std::move(factory)) ->CreateView(duckdb::Identifier(table_name), true, false); } catch (...) { // LCOV_EXCL_START // Tried covering this in tests, but it proved harder than expected. At the time of writing: diff --git a/src/duckdb/src/main/capi/v1/pending-c.cpp b/src/duckdb/src/main/capi/v1/pending-c.cpp index 1d4fa4dcb..42e898006 100644 --- a/src/duckdb/src/main/capi/v1/pending-c.cpp +++ b/src/duckdb/src/main/capi/v1/pending-c.cpp @@ -1,17 +1,17 @@ #include "duckdb/main/capi/capi_internal.hpp" #include "duckdb/main/query_result.hpp" -#include "duckdb/main/pending_query_result.hpp" #include "duckdb/common/error_data.hpp" #include "duckdb/common/case_insensitive_map.hpp" #include "duckdb/common/optional_ptr.hpp" using duckdb::case_insensitive_map_t; +using duckdb::IsObservable; using duckdb::make_uniq; using duckdb::optional_ptr; -using duckdb::PendingExecutionResult; -using duckdb::PendingQueryResult; using duckdb::PendingStatementWrapper; using duckdb::PreparedStatementWrapper; +using duckdb::QueryResult; +using duckdb::QueryResultState; using duckdb::Value; duckdb_state duckdb_pending_prepared_internal(duckdb_prepared_statement prepared_statement, @@ -24,9 +24,9 @@ duckdb_state duckdb_pending_prepared_internal(duckdb_prepared_statement prepared result->allow_streaming = allow_streaming; try { - result->statement = wrapper->statement->PendingQuery(wrapper->values, allow_streaming); + result->statement = wrapper->statement->Submit(wrapper->values); } catch (std::exception &ex) { - result->statement = make_uniq(duckdb::ErrorData(ex)); + result->statement = make_uniq(duckdb::ErrorData(ex)); } duckdb_state return_value = !result->statement->HasError() ? DuckDBSuccess : DuckDBError; *out_result = reinterpret_cast(result); @@ -77,20 +77,21 @@ duckdb_pending_state duckdb_pending_execute_check_state(duckdb_pending_result pe if (wrapper->statement->HasError()) { return DUCKDB_PENDING_ERROR; } - PendingExecutionResult return_value; + QueryResultState return_value; try { - return_value = wrapper->statement->CheckPulse(); + return_value = wrapper->statement->Poll(); } catch (std::exception &ex) { wrapper->statement->SetError(duckdb::ErrorData(ex)); return DUCKDB_PENDING_ERROR; } switch (return_value) { - case PendingExecutionResult::BLOCKED: - case PendingExecutionResult::RESULT_READY: + case QueryResultState::BLOCKED: + case QueryResultState::READY: + case QueryResultState::FINISHED: return DUCKDB_PENDING_RESULT_READY; - case PendingExecutionResult::NO_TASKS_AVAILABLE: + case QueryResultState::NO_TASKS_AVAILABLE: return DUCKDB_PENDING_NO_TASKS_AVAILABLE; - case PendingExecutionResult::RESULT_NOT_READY: + case QueryResultState::NOT_READY: return DUCKDB_PENDING_RESULT_NOT_READY; default: return DUCKDB_PENDING_ERROR; @@ -108,7 +109,7 @@ duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_r if (wrapper->statement->HasError()) { return DUCKDB_PENDING_ERROR; } - PendingExecutionResult return_value; + QueryResultState return_value; try { return_value = wrapper->statement->ExecuteTask(); } catch (std::exception &ex) { @@ -116,13 +117,13 @@ duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_r return DUCKDB_PENDING_ERROR; } switch (return_value) { - case PendingExecutionResult::EXECUTION_FINISHED: - case PendingExecutionResult::RESULT_READY: + case QueryResultState::FINISHED: + case QueryResultState::READY: return DUCKDB_PENDING_RESULT_READY; - case PendingExecutionResult::BLOCKED: - case PendingExecutionResult::NO_TASKS_AVAILABLE: + case QueryResultState::BLOCKED: + case QueryResultState::NO_TASKS_AVAILABLE: return DUCKDB_PENDING_NO_TASKS_AVAILABLE; - case PendingExecutionResult::RESULT_NOT_READY: + case QueryResultState::NOT_READY: return DUCKDB_PENDING_RESULT_NOT_READY; default: return DUCKDB_PENDING_ERROR; @@ -132,15 +133,15 @@ duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_r bool duckdb_pending_execution_is_finished(duckdb_pending_state pending_state) { switch (pending_state) { case DUCKDB_PENDING_RESULT_READY: - return PendingQueryResult::IsResultReady(PendingExecutionResult::RESULT_READY); + return IsObservable(QueryResultState::READY); case DUCKDB_PENDING_NO_TASKS_AVAILABLE: - return PendingQueryResult::IsResultReady(PendingExecutionResult::NO_TASKS_AVAILABLE); + return IsObservable(QueryResultState::NO_TASKS_AVAILABLE); case DUCKDB_PENDING_RESULT_NOT_READY: - return PendingQueryResult::IsResultReady(PendingExecutionResult::RESULT_NOT_READY); + return IsObservable(QueryResultState::NOT_READY); case DUCKDB_PENDING_ERROR: - return PendingQueryResult::IsResultReady(PendingExecutionResult::EXECUTION_ERROR); + return IsObservable(QueryResultState::EXECUTION_ERROR); default: - return PendingQueryResult::IsResultReady(PendingExecutionResult::EXECUTION_ERROR); + return IsObservable(QueryResultState::EXECUTION_ERROR); } } @@ -154,14 +155,19 @@ duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb return DuckDBError; } - duckdb::unique_ptr result; + auto result = std::move(wrapper->statement); + // A streaming request drains the result through a stream; every other one collects it + const bool stream_result = wrapper->allow_streaming && !result->HasError() && + result->GetStatementProperties().result_eagerness != duckdb::ResultEagerness::FORCED; try { - result = wrapper->statement->Execute(); + if (stream_result) { + return DuckDBTranslateStreamResult(duckdb::make_uniq(std::move(result)), + out_result); + } + result->Complete(); } catch (std::exception &ex) { duckdb::ErrorData error(ex); - result = duckdb::make_uniq(std::move(error)); + result = duckdb::make_uniq(std::move(error)); } - - wrapper->statement.reset(); return DuckDBTranslateResult(std::move(result), out_result); } diff --git a/src/duckdb/src/main/capi/v1/prepared-c.cpp b/src/duckdb/src/main/capi/v1/prepared-c.cpp index 9f80bd7ac..1526013c3 100644 --- a/src/duckdb/src/main/capi/v1/prepared-c.cpp +++ b/src/duckdb/src/main/capi/v1/prepared-c.cpp @@ -13,7 +13,6 @@ using duckdb::ErrorData; using duckdb::ExtractStatementsWrapper; using duckdb::hugeint_t; using duckdb::LogicalType; -using duckdb::MaterializedQueryResult; using duckdb::optional_ptr; using duckdb::PreparedStatementWrapper; using duckdb::QueryResultType; @@ -432,7 +431,7 @@ duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statemen duckdb::unique_ptr result; try { - result = wrapper->statement->Execute(wrapper->values, false); + result = wrapper->statement->Execute(wrapper->values); } catch (...) { return DuckDBError; } @@ -447,8 +446,14 @@ duckdb_state duckdb_execute_prepared_streaming(duckdb_prepared_statement prepare } try { - auto result = wrapper->statement->Execute(wrapper->values, true); - return DuckDBTranslateResult(std::move(result), out_result); + auto result = wrapper->statement->Submit(wrapper->values); + if (result->HasError() || + result->GetStatementProperties().result_eagerness == duckdb::ResultEagerness::FORCED) { + // The statement cannot be streamed: it completes before its result is returned + result->Complete(); + return DuckDBTranslateResult(std::move(result), out_result); + } + return DuckDBTranslateStreamResult(duckdb::make_uniq(std::move(result)), out_result); } catch (...) { return DuckDBError; } diff --git a/src/duckdb/src/main/capi/v1/result-c.cpp b/src/duckdb/src/main/capi/v1/result-c.cpp index 479042187..011bbfd82 100644 --- a/src/duckdb/src/main/capi/v1/result-c.cpp +++ b/src/duckdb/src/main/capi/v1/result-c.cpp @@ -147,7 +147,7 @@ void WriteData(duckdb_column *column, ColumnDataCollection &source, const vector } } -duckdb_state deprecated_duckdb_translate_column(MaterializedQueryResult &result, duckdb_column *column, idx_t col) { +duckdb_state deprecated_duckdb_translate_column(QueryResult &result, duckdb_column *column, idx_t col) { D_ASSERT(!result.HasError()); auto &collection = result.Collection(); idx_t row_count = collection.Count(); @@ -296,6 +296,29 @@ duckdb_state deprecated_duckdb_translate_column(MaterializedQueryResult &result, return DuckDBSuccess; } +duckdb_state DuckDBTranslateStreamResult(unique_ptr stream_p, duckdb_result *out) { + D_ASSERT(stream_p); + auto &stream = *stream_p; + if (!out) { + // no result to write to, only return the status + return !stream.HasError() ? DuckDBSuccess : DuckDBError; + } + memset(out, 0, sizeof(duckdb_result)); + + auto result_data = new DuckDBResultData(); + result_data->stream = std::move(stream_p); + result_data->result_set_type = CAPIResultSetType::CAPI_RESULT_TYPE_NONE; + out->internal_data = result_data; + + if (stream.HasError()) { + out->deprecated_error_message = (char *)stream.GetError().c_str(); // NOLINT + return DuckDBError; + } + out->deprecated_column_count = stream.ColumnCount(); + out->deprecated_rows_changed = 0; + return DuckDBSuccess; +} + duckdb_state DuckDBTranslateResult(unique_ptr result_p, duckdb_result *out) { auto &result = *result_p; D_ASSERT(result_p); @@ -324,12 +347,30 @@ duckdb_state DuckDBTranslateResult(unique_ptr result_p, duckdb_resu return DuckDBSuccess; } +//! Drain a stream into a retained result, for the random-access deprecated result set +static unique_ptr DrainStreamIntoResult(QueryResultStream &stream) { + auto collection = make_uniq(Allocator::DefaultAllocator(), stream.GetTypes()); + ColumnDataAppendState append_state; + collection->InitializeAppend(append_state); + while (auto chunk = stream.Fetch()) { + if (chunk->size() == 0) { + break; + } + collection->Append(append_state, *chunk); + } + if (stream.HasError()) { + return make_uniq(stream.GetErrorObject()); + } + return make_uniq(stream.GetStatementType(), stream.GetStatementProperties(), stream.GetNames(), + std::move(collection), stream.GetClientProperties()); +} + bool DeprecatedMaterializeResult(duckdb_result *result) { if (!result) { return false; } auto result_data = reinterpret_cast(result->internal_data); - if (result_data->result->HasError()) { + if (result_data->HasError()) { return false; } if (result_data->result_set_type == CAPIResultSetType::CAPI_RESULT_TYPE_DEPRECATED) { @@ -346,27 +387,29 @@ bool DeprecatedMaterializeResult(duckdb_result *result) { } // materialize as deprecated result set result_data->result_set_type = CAPIResultSetType::CAPI_RESULT_TYPE_DEPRECATED; - auto column_count = result_data->result->ColumnCount(); + auto column_count = result_data->ColumnCount(); result->deprecated_columns = (duckdb_column *)duckdb_malloc(sizeof(duckdb_column) * column_count); if (!result->deprecated_columns) { // LCOV_EXCL_START // malloc failure return DuckDBError; } // LCOV_EXCL_STOP - if (result_data->result->GetResultType() == QueryResultType::STREAM_RESULT) { - // if we are dealing with a stream result, convert it to a materialized result first - auto &stream_result = (StreamQueryResult &)*result_data->result; - result_data->result = stream_result.Materialize(); + if (result_data->IsStreaming()) { + // The deprecated result set is random-access: drain the stream into a collection + result_data->result = DrainStreamIntoResult(*result_data->stream); + result_data->stream.reset(); + if (result_data->result->HasError()) { + return false; + } } - D_ASSERT(result_data->result->GetResultType() == QueryResultType::MATERIALIZED_RESULT); - auto &materialized = reinterpret_cast(*result_data->result); + auto &materialized = *result_data->result; // convert the result to a materialized result // zero initialize the columns (so we can cleanly delete it in case a malloc fails) memset(result->deprecated_columns, 0, sizeof(duckdb_column) * column_count); for (idx_t i = 0; i < column_count; i++) { - result->deprecated_columns[i].deprecated_type = LogicalTypeIdToC(result_data->result->GetTypes()[i].id()); - result->deprecated_columns[i].deprecated_name = (char *)result_data->result->ColumnName(i).c_str(); // NOLINT + result->deprecated_columns[i].deprecated_type = LogicalTypeIdToC(materialized.GetTypes()[i].id()); + result->deprecated_columns[i].deprecated_name = (char *)materialized.ColumnName(i).c_str(); // NOLINT } result->deprecated_row_count = materialized.RowCount(); @@ -439,7 +482,7 @@ const char *duckdb_column_name(duckdb_result *result, idx_t col) { return nullptr; } auto &result_data = *(reinterpret_cast(result->internal_data)); - return result_data.result->ColumnName(col).c_str(); + return result_data.ColumnName(col).c_str(); } duckdb_type duckdb_column_type(duckdb_result *result, idx_t col) { @@ -447,7 +490,7 @@ duckdb_type duckdb_column_type(duckdb_result *result, idx_t col) { return DUCKDB_TYPE_INVALID; } auto &result_data = *(reinterpret_cast(result->internal_data)); - return duckdb::LogicalTypeIdToC(result_data.result->GetTypes()[col].id()); + return duckdb::LogicalTypeIdToC(result_data.GetTypes()[col].id()); } duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col) { @@ -455,7 +498,7 @@ duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col) return nullptr; } auto &result_data = *(reinterpret_cast(result->internal_data)); - return reinterpret_cast(new duckdb::LogicalType(result_data.result->GetTypes()[col])); + return reinterpret_cast(new duckdb::LogicalType(result_data.GetTypes()[col])); } duckdb_arrow_options duckdb_result_get_arrow_options(duckdb_result *result) { @@ -463,10 +506,10 @@ duckdb_arrow_options duckdb_result_get_arrow_options(duckdb_result *result) { return nullptr; } auto &result_data = *(reinterpret_cast(result->internal_data)); - if (!result_data.result) { + if (!result_data.result && !result_data.stream) { return nullptr; } - auto arrow_options_wrapper = new duckdb::CClientArrowOptionsWrapper(result_data.result->client_properties); + auto arrow_options_wrapper = new duckdb::CClientArrowOptionsWrapper(result_data.GetClientProperties()); return reinterpret_cast(arrow_options_wrapper); } @@ -478,7 +521,7 @@ idx_t duckdb_column_count(duckdb_result *result) { return 0; } auto &result_data = *(reinterpret_cast(result->internal_data)); - return result_data.result->ColumnCount(); + return result_data.ColumnCount(); } idx_t duckdb_row_count(duckdb_result *result) { @@ -486,12 +529,11 @@ idx_t duckdb_row_count(duckdb_result *result) { return 0; } auto &result_data = *(reinterpret_cast(result->internal_data)); - if (result_data.result->GetResultType() == duckdb::QueryResultType::STREAM_RESULT) { + if (result_data.IsStreaming()) { // We can't know the row count beforehand return 0; } - auto &materialized = reinterpret_cast(*result_data.result); - return materialized.RowCount(); + return result_data.Retained().RowCount(); } idx_t duckdb_rows_changed(duckdb_result *result) { @@ -503,7 +545,10 @@ idx_t duckdb_rows_changed(duckdb_result *result) { // not a materialized result return result->deprecated_rows_changed; } - auto &materialized = reinterpret_cast(*result_data.result); + if (result_data.IsStreaming()) { + return 0; + } + auto &materialized = result_data.Retained(); if (materialized.GetStatementProperties().return_type != duckdb::StatementReturnType::CHANGED_ROWS) { // we can only use this function for CHANGED_ROWS result types return 0; @@ -540,7 +585,7 @@ const char *duckdb_result_error(duckdb_result *result) { return nullptr; } auto &result_data = *(reinterpret_cast(result->internal_data)); - return !result_data.result->HasError() ? nullptr : result_data.result->GetError().c_str(); + return !result_data.HasError() ? nullptr : result_data.GetError().c_str(); } duckdb_error_type duckdb_result_error_type(duckdb_result *result) { @@ -548,10 +593,10 @@ duckdb_error_type duckdb_result_error_type(duckdb_result *result) { return DUCKDB_ERROR_INVALID; } auto &result_data = *(reinterpret_cast(result->internal_data)); - if (!result_data.result->HasError()) { + if (!result_data.HasError()) { return DUCKDB_ERROR_INVALID; } - return duckdb::ErrorTypeToC(result_data.result->GetErrorType()); + return duckdb::ErrorTypeToC(result_data.GetErrorType()); } idx_t duckdb_result_chunk_count(duckdb_result result) { @@ -562,12 +607,11 @@ idx_t duckdb_result_chunk_count(duckdb_result result) { if (result_data.result_set_type == duckdb::CAPIResultSetType::CAPI_RESULT_TYPE_DEPRECATED) { return 0; } - if (result_data.result->GetResultType() != duckdb::QueryResultType::MATERIALIZED_RESULT) { + if (result_data.IsStreaming()) { // Can't know beforehand how many chunks are returned. return 0; } - auto &materialized = reinterpret_cast(*result_data.result); - return materialized.Collection().ChunkCount(); + return result_data.Retained().Collection().ChunkCount(); } duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_idx) { @@ -578,13 +622,12 @@ duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_idx) if (result_data.result_set_type == duckdb::CAPIResultSetType::CAPI_RESULT_TYPE_DEPRECATED) { return nullptr; } - if (result_data.result->GetResultType() != duckdb::QueryResultType::MATERIALIZED_RESULT) { - // This API is only supported for materialized query results + if (result_data.IsStreaming()) { + // This API is only supported for retained query results return nullptr; } result_data.result_set_type = duckdb::CAPIResultSetType::CAPI_RESULT_TYPE_MATERIALIZED; - auto &materialized = reinterpret_cast(*result_data.result); - auto &collection = materialized.Collection(); + auto &collection = result_data.Retained().Collection(); if (chunk_idx >= collection.ChunkCount()) { return nullptr; } @@ -602,7 +645,7 @@ bool duckdb_result_is_streaming(duckdb_result result) { return false; } auto &result_data = *(reinterpret_cast(result.internal_data)); - return result_data.result->GetResultType() == duckdb::QueryResultType::STREAM_RESULT; + return result_data.IsStreaming(); } duckdb_result_type duckdb_result_return_type(duckdb_result result) { @@ -610,7 +653,7 @@ duckdb_result_type duckdb_result_return_type(duckdb_result result) { return DUCKDB_RESULT_TYPE_INVALID; } auto &result_data = *(reinterpret_cast(result.internal_data)); - switch (result_data.result->GetStatementProperties().return_type) { + switch (result_data.GetStatementProperties().return_type) { case duckdb::StatementReturnType::CHANGED_ROWS: return DUCKDB_RESULT_TYPE_CHANGED_ROWS; case duckdb::StatementReturnType::NOTHING: @@ -628,5 +671,5 @@ duckdb_statement_type duckdb_result_statement_type(duckdb_result result) { } auto &pres = *(reinterpret_cast(result.internal_data)); - return StatementTypeToC(pres.result->GetStatementType()); + return StatementTypeToC(pres.GetStatementType()); } diff --git a/src/duckdb/src/main/capi/v1/stream-c.cpp b/src/duckdb/src/main/capi/v1/stream-c.cpp index 5f3d0e012..07ead5b67 100644 --- a/src/duckdb/src/main/capi/v1/stream-c.cpp +++ b/src/duckdb/src/main/capi/v1/stream-c.cpp @@ -7,8 +7,8 @@ duckdb_data_chunk duckdb_stream_fetch_chunk(duckdb_result result) { return nullptr; } auto &result_data = *((duckdb::DuckDBResultData *)result.internal_data); - if (result_data.result->GetResultType() != duckdb::QueryResultType::STREAM_RESULT) { - // We can only fetch from a StreamQueryResult + if (!result_data.IsStreaming()) { + // We can only fetch from a streaming result return nullptr; } return duckdb_fetch_chunk(result); @@ -23,15 +23,17 @@ duckdb_data_chunk duckdb_fetch_chunk(duckdb_result result) { return nullptr; } result_data.result_set_type = duckdb::CAPIResultSetType::CAPI_RESULT_TYPE_STREAMING; - auto &result_instance = (duckdb::QueryResult &)*result_data.result; - // FetchRaw ? Do we care about flattening them? try { - auto chunk = result_instance.Fetch(); + auto chunk = result_data.Fetch(); return reinterpret_cast(chunk.release()); } catch (std::exception &e) { // Set the error on the result so duckdb_result_error can retrieve it duckdb::ErrorData error(e); - result_instance.SetError(error); + if (result_data.stream) { + result_data.stream->SetError(std::move(error)); + } else { + result_data.result->SetError(std::move(error)); + } return nullptr; } } diff --git a/src/duckdb/src/main/capi/v1/value-c.cpp b/src/duckdb/src/main/capi/v1/value-c.cpp index ec2cb5410..27aebfb67 100644 --- a/src/duckdb/src/main/capi/v1/value-c.cpp +++ b/src/duckdb/src/main/capi/v1/value-c.cpp @@ -49,8 +49,7 @@ static bool ResultIsDecimal(duckdb_result *result, idx_t col) { return false; } auto result_data = (duckdb::DuckDBResultData *)result->internal_data; - auto &query_result = result_data->result; - auto &source_type = query_result->GetTypes()[col]; + auto &source_type = result_data->GetTypes()[col]; return source_type.id() == duckdb::LogicalTypeId::DECIMAL; } diff --git a/src/duckdb/src/main/capi/v2/capi_v2.cpp b/src/duckdb/src/main/capi/v2/capi_v2.cpp index 520e6dec7..33ed31500 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2.cpp @@ -248,7 +248,7 @@ auto TryGetExceptionTypeFromErrorCode(DUCKDB_V2_ERROR code) -> optional void { +auto RenderCaughtError(DUCKDB_V2_ERROR &code, string &text, optional &raw_message) noexcept -> void { // Set the fallback code first (non-throwing), then render the detail. code = DUCKDB_V2_ERROR_API; try { @@ -272,11 +272,11 @@ auto RenderCaughtError(DUCKDB_V2_ERROR &code, string &text, string &raw_message) // Rendering the detail exhausted memory: that supersedes the original report. code = DUCKDB_V2_ERROR_RESOURCE_OUT_OF_MEMORY; text.clear(); - raw_message.clear(); + raw_message.reset(); } catch (...) { // Rendering the detail failed: keep the code produced so far with no detail. text.clear(); - raw_message.clear(); + raw_message.reset(); } } @@ -302,7 +302,7 @@ auto NullArgumentError(duckdb_v2_error_info_handle *err, const char *function, c auto &out = *Convert(*err); out.code = code; out.message.clear(); - out.raw_message.clear(); + out.raw_message.reset(); try { // Render through ErrorData so message/raw_message match what WithErrorHandler // produces for a thrown InvalidInputException. @@ -358,19 +358,22 @@ static void PopulateOptionAliases(const unique_ptr &out, const Identi } } -// Read the effective setting for `name` through `client`'s setting cascade. -// For a databases internal connection (no LOCAL overrides) this returns GLOBAL -> static default; -// For a client connection it returns LOCAL -> GLOBAL -> static default. -// Falls back to `fallback_default` if the cascade returned NULL. -static std::string ReadEffectiveSetting(ClientContext &client, const Identifier &name, - const std::string &fallback_default) { - if (Value result; client.TryGetCurrentSetting(name, result) && !result.IsNull()) { +string CV2OptionSource::ReadSetting(const Identifier &name, const string &fallback) const { + if (staged_settings) { + auto staged = staged_settings->find(name); + if (staged != staged_settings->end()) { + return staged->second; + } + } + Value result; + auto found = context ? context->TryGetCurrentSetting(name, result) : config.TryGetCurrentSetting(name, result); + if (found && !result.IsNull()) { return result.ToString(); } - return fallback_default; + return fallback; } -static unique_ptr PopulateOptionFromCore(const ConfigurationOption &option, ClientContext &client) { +static unique_ptr PopulateOptionFromCore(const ConfigurationOption &option, const CV2OptionSource &source) { auto out = make_uniq(); out->name = option.name ? option.name : ""; @@ -379,7 +382,7 @@ static unique_ptr PopulateOptionFromCore(const ConfigurationOption &o out->default_setting = option.default_value ? option.default_value : ""; out->aliases.clear(); PopulateOptionAliases(out, out->name); - out->setting = ReadEffectiveSetting(client, out->name, out->default_setting); + out->setting = source.ReadSetting(out->name, out->default_setting); return out; } @@ -387,7 +390,7 @@ static unique_ptr PopulateOptionFromCore(const ConfigurationOption &o // Populate `out` from an extension option. Extension options carry no // SettingScopeTarget (the V2 enum reports UNKNOWN) and no aliases. static unique_ptr PopulateOptionFromExtension(const Identifier &name, const ExtensionOption &ext_option, - ClientContext &client) { + const CV2OptionSource &source) { auto out = make_uniq(); out->name = name; @@ -395,22 +398,26 @@ static unique_ptr PopulateOptionFromExtension(const Identifier &name, out->target_scope = DUCKDB_V2_OPTION_TARGET_SCOPE_UNKNOWN; out->default_setting = ext_option.default_value.IsNull() ? std::string() : ext_option.default_value.ToString(); out->aliases.clear(); - out->setting = ReadEffectiveSetting(client, name, out->default_setting); + out->setting = source.ReadSetting(name, out->default_setting); return out; } -unique_ptr CV2Option::FromIndex(ClientContext &context, DBConfig &config, idx_t index) { +idx_t CV2Option::Count(const CV2OptionSource &source) { + return DBConfig::GetOptionCount() + source.GetConfig().GetExtensionSettings().size(); +} + +unique_ptr CV2Option::FromIndex(const CV2OptionSource &source, idx_t index) { const auto core_count = DBConfig::GetOptionCount(); if (index < core_count) { auto option = DBConfig::GetOptionByIndex(index); if (!option) { throw InvalidInputException("core option not found at given index"); } - return PopulateOptionFromCore(*option, context); + return PopulateOptionFromCore(*option, source); } const idx_t ext_rel = index - core_count; - auto ext_settings = config.GetExtensionSettings(); + auto ext_settings = source.GetConfig().GetExtensionSettings(); if (ext_rel >= ext_settings.size()) { throw InvalidInputException("option index out of range"); } @@ -418,20 +425,20 @@ unique_ptr CV2Option::FromIndex(ClientContext &context, DBConfig &con for (const auto &[name, option] : ext_settings) { if (i == ext_rel) { - return PopulateOptionFromExtension(name, option, context); + return PopulateOptionFromExtension(name, option, source); } ++i; } throw InvalidInputException("option index out of range"); } -unique_ptr CV2Option::FromName(ClientContext &context, DBConfig &config, std::string_view name) { +unique_ptr CV2Option::FromName(const CV2OptionSource &source, std::string_view name) { Identifier name_id(name); if (auto option = DBConfig::GetOptionByName(name_id)) { - return PopulateOptionFromCore(*option, context); + return PopulateOptionFromCore(*option, source); } - if (ExtensionOption ext_option; config.TryGetExtensionOption(name_id, ext_option)) { - return PopulateOptionFromExtension(name_id, ext_option, context); + if (ExtensionOption ext_option; source.GetConfig().TryGetExtensionOption(name_id, ext_option)) { + return PopulateOptionFromExtension(name_id, ext_option, source); } throw InvalidInputException("unknown configuration option: %s", name_id.GetIdentifierName()); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_column_data_collection.cpp b/src/duckdb/src/main/capi/v2/capi_v2_column_data_collection.cpp index efe6f9d52..de1e5ac23 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_column_data_collection.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_column_data_collection.cpp @@ -6,14 +6,6 @@ namespace duckdb { namespace capiv2 { -static auto Convert(ColumnDataCollection *cdc) -> duckdb_v2_column_data_collection_handle { - return reinterpret_cast(cdc); -} - -static auto Convert(duckdb_v2_column_data_collection_handle cdc) -> ColumnDataCollection * { - return reinterpret_cast(cdc); -} - static auto Convert(ColumnDataAppendState *state) -> duckdb_v2_column_data_collection_append_state_handle { return reinterpret_cast(state); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp b/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp index ac2453a83..7b149c747 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp @@ -16,40 +16,27 @@ SetScope MapSettingScope(DUCKDB_V2_SETTING_SCOPE s) { } } -struct QueryProgressWrapperV2 { - double percentage = -1; - uint64_t rows_processed = 0; - uint64_t total_rows_to_process = 0; -}; - } // namespace -auto Convert(duckdb_v2_query_progress_handle progress) -> QueryProgressWrapperV2 * { - return reinterpret_cast(progress); -} - -auto Convert(QueryProgressWrapperV2 *progress) -> duckdb_v2_query_progress_handle { - return reinterpret_cast(progress); -} - } // namespace capiv2 } // namespace duckdb using namespace duckdb::capiv2; -DUCKDB_V2_ERROR duckdb_v2_connect(duckdb_v2_database_handle db, duckdb_v2_connection_handle *out_conn, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(db); +DUCKDB_V2_ERROR duckdb_v2_connection_create(duckdb_v2_instance_handle instance, duckdb_v2_connection_handle *out_conn, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); DUCKDB_CHECK_ARG(out_conn); *out_conn = nullptr; return WithErrorHandler(err, [&]() { - auto *db_wrapper = Convert(db); - auto connection = duckdb::make_uniq(*db_wrapper->database); + auto &instance_wrapper = *Convert(instance); + duckdb::lock_guard guard(instance_wrapper.lock); + auto connection = duckdb::make_uniq(instance_wrapper.GetDatabase()); *out_conn = Convert(connection.release()); }); } -DUCKDB_V2_ERROR duckdb_v2_disconnect(duckdb_v2_connection_handle *conn) { +DUCKDB_V2_ERROR duckdb_v2_connection_destroy(duckdb_v2_connection_handle *conn) { return WithErrorHandler(nullptr, [&]() { if (!conn) { return; @@ -61,53 +48,48 @@ DUCKDB_V2_ERROR duckdb_v2_disconnect(duckdb_v2_connection_handle *conn) { }); } -DUCKDB_V2_ERROR duckdb_v2_connection_option_set(duckdb_v2_connection_handle conn, duckdb_v2_option_handle option, - DUCKDB_V2_SETTING_SCOPE scope, duckdb_v2_error_info_handle *err) { +DUCKDB_V2_ERROR duckdb_v2_connection_set_option(duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, + duckdb_v2_str setting, DUCKDB_V2_SETTING_SCOPE scope, + duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(conn); - DUCKDB_CHECK_ARG(option); + DUCKDB_CHECK_ARG(name); + DUCKDB_CHECK_ARG(setting); return WithErrorHandler(err, [&]() { - auto *opt = Convert(option); auto &client = *Convert(conn)->context; - duckdb::PhysicalSet::SetVariable(client, opt->name, MapSettingScope(scope), duckdb::Value(opt->setting)); + duckdb::PhysicalSet::SetVariable(client, duckdb::Identifier(Convert(name)), MapSettingScope(scope), + duckdb::Value(duckdb::string(Convert(setting)))); }); } -DUCKDB_V2_ERROR duckdb_v2_connection_option_get(duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, - duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err) { +DUCKDB_V2_ERROR duckdb_v2_connection_get_option_by_name(duckdb_v2_connection_handle conn, duckdb_v2_identifier_t name, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(conn); DUCKDB_CHECK_ARG(name); DUCKDB_CHECK_ARG(out_option); *out_option = nullptr; return WithErrorHandler(err, [&]() { - auto &client = *Convert(conn)->context; - auto &config = duckdb::DBConfig::GetConfig(client); - auto wrapper = CV2Option::FromName(client, config, Convert(name)); - *out_option = Convert(wrapper.release()); + CV2OptionSource source(*Convert(conn)->context); + *out_option = Convert(CV2Option::FromName(source, Convert(name)).release()); }); } -DUCKDB_V2_ERROR duckdb_v2_connection_option_get_count(duckdb_v2_connection_handle conn, idx_t *out_count, +DUCKDB_V2_ERROR duckdb_v2_connection_get_option_count(duckdb_v2_connection_handle conn, idx_t *out_count, duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(conn); DUCKDB_CHECK_ARG(out_count); - return WithErrorHandler(err, [&]() { - auto &client = *Convert(conn)->context; - auto &config = duckdb::DBConfig::GetConfig(client); - *out_count = duckdb::DBConfig::GetOptionCount() + config.GetExtensionSettings().size(); - }); + return WithErrorHandler(err, [&]() { *out_count = CV2Option::Count(CV2OptionSource(*Convert(conn)->context)); }); } -DUCKDB_V2_ERROR duckdb_v2_connection_option_get_by_index(duckdb_v2_connection_handle conn, idx_t index, +DUCKDB_V2_ERROR duckdb_v2_connection_get_option_by_index(duckdb_v2_connection_handle conn, idx_t index, duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(conn); DUCKDB_CHECK_ARG(out_option); *out_option = nullptr; return WithErrorHandler(err, [&]() { - auto &client = *Convert(conn)->context; - auto &config = duckdb::DBConfig::GetConfig(client); - auto wrapper = CV2Option::FromIndex(client, config, index); - *out_option = Convert(wrapper.release()); + CV2OptionSource source(*Convert(conn)->context); + *out_option = Convert(CV2Option::FromIndex(source, index).release()); }); } @@ -127,53 +109,17 @@ DUCKDB_V2_ERROR duckdb_v2_connection_interrupt(duckdb_v2_connection_handle conn, }); } -DUCKDB_V2_ERROR duckdb_v2_connection_query_progress(duckdb_v2_connection_handle conn, - duckdb_v2_query_progress_handle *out_progress, - duckdb_v2_error_info_handle *err) { +DUCKDB_V2_ERROR duckdb_v2_connection_progress_get(duckdb_v2_connection_handle conn, double *out_percentage, + uint64_t *out_rows_processed, uint64_t *out_total_rows_to_process, + duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(conn); - DUCKDB_CHECK_ARG(out_progress); - *out_progress = nullptr; - return WithErrorHandler(err, [&]() { - auto progress = Convert(conn)->context->GetQueryProgress(); - auto wrapper = duckdb::make_uniq(); - wrapper->percentage = progress.GetPercentage(); - wrapper->rows_processed = progress.GetRowsProcessed(); - wrapper->total_rows_to_process = progress.GetTotalRowsToProcess(); - *out_progress = Convert(wrapper.release()); - }); -} - -DUCKDB_V2_ERROR duckdb_v2_query_progress_get_percentage(duckdb_v2_query_progress_handle progress, - double *out_percentage, duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(progress); DUCKDB_CHECK_ARG(out_percentage); - return WithErrorHandler(err, [&]() { *out_percentage = Convert(progress)->percentage; }); -} - -DUCKDB_V2_ERROR duckdb_v2_query_progress_get_rows_processed(duckdb_v2_query_progress_handle progress, - uint64_t *out_rows_processed, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(progress); DUCKDB_CHECK_ARG(out_rows_processed); - return WithErrorHandler(err, [&]() { *out_rows_processed = Convert(progress)->rows_processed; }); -} - -DUCKDB_V2_ERROR duckdb_v2_query_progress_get_total_rows_to_process(duckdb_v2_query_progress_handle progress, - uint64_t *out_total_rows_to_process, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(progress); DUCKDB_CHECK_ARG(out_total_rows_to_process); - return WithErrorHandler(err, [&]() { *out_total_rows_to_process = Convert(progress)->total_rows_to_process; }); -} - -DUCKDB_V2_ERROR duckdb_v2_query_progress_destroy(duckdb_v2_query_progress_handle *progress) { - return WithErrorHandler(nullptr, [&]() { - if (!progress) { - return; - } - if (*progress) { - delete Convert(*progress); - *progress = nullptr; - } + return WithErrorHandler(err, [&]() { + auto progress = Convert(conn)->context->GetQueryProgress(); + *out_percentage = progress.GetPercentage(); + *out_rows_processed = progress.GetRowsProcessed(); + *out_total_rows_to_process = progress.GetTotalRowsToProcess(); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_database.cpp b/src/duckdb/src/main/capi/v2/capi_v2_database.cpp deleted file mode 100644 index 823e686e7..000000000 --- a/src/duckdb/src/main/capi/v2/capi_v2_database.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "duckdb/main/capi_v2/capi_v2_internal.hpp" - -#include "duckdb/common/types/value.hpp" - -using namespace duckdb::capiv2; - -DUCKDB_V2_ERROR duckdb_v2_open(duckdb_v2_environment_handle env, duckdb_v2_str path, duckdb_v2_option_handle *options, - idx_t option_count, duckdb_v2_database_handle *out_db, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(env); - DUCKDB_CHECK_ARG(out_db); - DUCKDB_CHECK_ARG(path); - - return WithErrorHandler(err, [&]() { - if (option_count > 0 && !options) { - throw duckdb::InvalidInputException("option_count > 0 but options is null in duckdb_v2_open"); - } - - *out_db = nullptr; - - const auto config = duckdb::make_uniq(); - for (idx_t i = 0; i < option_count; i++) { - const auto *opt = Convert(options[i]); - if (!opt) { - throw duckdb::InvalidInputException("null option handle in options array passed to duckdb_v2_open"); - } - config->SetOptionByName(opt->name, duckdb::Value(opt->setting)); - } - - // Route through the env's DBInstanceCache with NEVER_CACHE so the path manager is shared across all opens. - // File conflicts get detected, but no instance is memoized. Every open produces a fresh DatabaseInstance. - - auto *env_wrapper = Convert(env); - const auto path_str = duckdb::string(Convert(path)); - const auto db = env_wrapper->cache->GetOrCreateInstance(path_str, *config, duckdb::CacheBehavior::NEVER_CACHE); - auto wrapper = duckdb::make_uniq(*env_wrapper, db); - env_wrapper->open_database_count.fetch_add(1, std::memory_order_release); - *out_db = Convert(wrapper.release()); - }); -} - -DUCKDB_V2_ERROR duckdb_v2_close(duckdb_v2_database_handle *db) { - return WithErrorHandler(nullptr, [&]() { - if (!db) { - return; - } - if (*db) { - const auto *wrapper = Convert(*db); - auto &env = wrapper->env; - delete wrapper; - env.open_database_count.fetch_sub(1, std::memory_order_release); - *db = nullptr; - } - }); -} - -DUCKDB_V2_ERROR duckdb_v2_database_option_set(duckdb_v2_database_handle db, duckdb_v2_option_handle option, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(db); - DUCKDB_CHECK_ARG(option); - return WithErrorHandler(err, [&]() { - const auto *db_wrapper = Convert(db); - const auto *opt = Convert(option); - // Use the database's internal ClientContext as the bridge into PhysicalSet::ApplyVariable. - // Force GLOBAL scope: the internal context has no LOCAL settings of its own, and database-scoped settings only - // make sense as GLOBAL anyway. - auto &client = *db_wrapper->internal_connection->context; - duckdb::PhysicalSet::SetVariable(client, opt->name, duckdb::SetScope::GLOBAL, duckdb::Value(opt->setting)); - }); -} - -DUCKDB_V2_ERROR duckdb_v2_database_option_get(duckdb_v2_database_handle db, duckdb_v2_identifier_t name, - duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(db); - DUCKDB_CHECK_ARG(name); - DUCKDB_CHECK_ARG(out_option); - *out_option = nullptr; - return WithErrorHandler(err, [&]() { - const auto *db_wrapper = Convert(db); - auto &client = *db_wrapper->internal_connection->context; - auto &config = db_wrapper->database->instance->config; - auto wrapper = CV2Option::FromName(client, config, Convert(name)); - *out_option = Convert(wrapper.release()); - }); -} - -DUCKDB_V2_ERROR duckdb_v2_database_option_get_count(duckdb_v2_database_handle db, idx_t *out_count, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(db); - DUCKDB_CHECK_ARG(out_count); - return WithErrorHandler(err, [&]() { - const auto *db_wrapper = Convert(db); - const auto &config = db_wrapper->database->instance->config; - *out_count = duckdb::DBConfig::GetOptionCount() + config.GetExtensionSettings().size(); - }); -} - -DUCKDB_V2_ERROR duckdb_v2_database_option_get_by_index(duckdb_v2_database_handle db, idx_t index, - duckdb_v2_option_handle *out_option, - duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(db); - DUCKDB_CHECK_ARG(out_option); - *out_option = nullptr; - return WithErrorHandler(err, [&]() { - const auto *db_wrapper = Convert(db); - auto &client = *db_wrapper->internal_connection->context; - auto &config = db_wrapper->database->instance->config; - - auto wrapper = CV2Option::FromIndex(client, config, index); - *out_option = Convert(wrapper.release()); - }); -} - -DUCKDB_V2_ERROR duckdb_v2_library_version(duckdb_v2_str *out_version, duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(out_version); - return WithErrorHandler(err, [&]() { - const auto version = duckdb::DuckDB::LibraryVersion(); - *out_version = duckdb_v2_str {version, std::strlen(version)}; - }); -} diff --git a/src/duckdb/src/main/capi/v2/capi_v2_environment.cpp b/src/duckdb/src/main/capi/v2/capi_v2_environment.cpp index 49c65685a..96fe072e9 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_environment.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_environment.cpp @@ -2,7 +2,7 @@ using namespace duckdb::capiv2; -DUCKDB_V2_ERROR duckdb_v2_create_environment(duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err) { +DUCKDB_V2_ERROR duckdb_v2_environment_create(duckdb_v2_environment_handle *out_env, duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(out_env); *out_env = nullptr; return WithErrorHandler(err, [&]() { @@ -12,15 +12,15 @@ DUCKDB_V2_ERROR duckdb_v2_create_environment(duckdb_v2_environment_handle *out_e }); } -// destroy_environment keeps a manual return path so the open-databases case +// environment_destroy keeps a manual return path so the live-instances case // can surface as RESOURCE_IN_USE — there is no ExceptionType that maps to // that V2 code, so routing it through WithErrorHandler would degrade it. -DUCKDB_V2_ERROR duckdb_v2_destroy_environment(duckdb_v2_environment_handle *env) { +DUCKDB_V2_ERROR duckdb_v2_environment_destroy(duckdb_v2_environment_handle *env) { if (!env || !*env) { return DUCKDB_V2_ERROR_NONE; } const auto *wrapper = Convert(*env); - auto count = wrapper->open_database_count.load(std::memory_order_acquire); + auto count = wrapper->instance_count.load(std::memory_order_acquire); if (count != 0) { return DUCKDB_V2_ERROR_RESOURCE_IN_USE; } @@ -29,9 +29,9 @@ DUCKDB_V2_ERROR duckdb_v2_destroy_environment(duckdb_v2_environment_handle *env) return DUCKDB_V2_ERROR_NONE; } -DUCKDB_V2_ERROR duckdb_v2_environment_database_count(duckdb_v2_environment_handle env, idx_t *out_count, - duckdb_v2_error_info_handle *err) { +DUCKDB_V2_ERROR duckdb_v2_environment_get_instance_count(duckdb_v2_environment_handle env, idx_t *out_count, + duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(env); DUCKDB_CHECK_ARG(out_count); - return WithErrorHandler(err, [&]() { *out_count = Convert(env)->open_database_count.load(); }); + return WithErrorHandler(err, [&]() { *out_count = Convert(env)->instance_count.load(); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_error.cpp b/src/duckdb/src/main/capi/v2/capi_v2_error.cpp index 54eb556c3..bd766385a 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_error.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_error.cpp @@ -11,12 +11,12 @@ DUCKDB_V2_ERROR duckdb_v2_error_info_get_text(duckdb_v2_error_info_handle info, return DUCKDB_V2_ERROR_NONE; } -DUCKDB_V2_ERROR duckdb_v2_error_info_get_raw_message(duckdb_v2_error_info_handle info, duckdb_v2_str *out_raw_message) { - if (!info || !out_raw_message) { +DUCKDB_V2_ERROR duckdb_v2_error_info_get_raw_text(duckdb_v2_error_info_handle info, duckdb_v2_str *out_raw_text) { + if (!info || !out_raw_text) { return DUCKDB_V2_ERROR_INPUT_INVALID; } const auto *ei = Convert(info); - *out_raw_message = ei->raw_message.empty() ? duckdb_v2_str {nullptr, 0} : Convert(ei->raw_message); + *out_raw_text = ei->raw_message ? Convert(ei->raw_message.value()) : duckdb_v2_str {nullptr, 0}; return DUCKDB_V2_ERROR_NONE; } @@ -26,7 +26,7 @@ DUCKDB_V2_ERROR duckdb_v2_error_info_set_text(duckdb_v2_error_info_handle info, } auto *ei = Convert(info); ei->message = Convert(text); - ei->raw_message.clear(); // Directly-set message has no raw body. + ei->raw_message.reset(); // Directly-set message has no raw body. return DUCKDB_V2_ERROR_NONE; } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp index 8d56aa1bf..f92c578ea 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp @@ -1,3 +1,4 @@ +#include "duckdb/common/optional_idx.hpp" #include "duckdb/main/capi_v2/capi_v2_internal.hpp" #include "duckdb/catalog/catalog.hpp" #include "duckdb/common/types/column/column_data_collection.hpp" @@ -143,7 +144,7 @@ class CV2CopyToBatchSizeInfo { void *in_user_data = nullptr; void *in_bind_data = nullptr; - idx_t out_target = 0; + optional_idx out_target; }; static auto Convert(duckdb_v2_copy_to_batch_size_info_handle info) -> CV2CopyToBatchSizeInfo * { @@ -363,7 +364,7 @@ static auto CV2CopyToBind(ClientContext &context, CopyFunctionBindInput &input, return std::move(result); } -static auto CV2CopyToBatchSize(ClientContext &context, FunctionData &bind_data) -> idx_t { +static auto CV2CopyToBatchSize(ClientContext &context, FunctionData &bind_data) -> optional_idx { const auto &info = GetFunctionInfo(bind_data); CV2CopyToBatchSizeInfo args = {}; @@ -377,7 +378,7 @@ static auto CV2CopyToBatchSize(ClientContext &context, FunctionData &bind_data) if (err.HasError()) { err.ThrowAsException(); } - if (args.out_target == 0) { + if (args.out_target.IsValid() && args.out_target == 0) { throw InvalidInputException("The batch size callback must set a target greater than 0."); } return args.out_target; diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp index e94d6dcb0..596a0119e 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp @@ -1,5 +1,8 @@ #include "duckdb/main/capi_v2/capi_v2_internal.hpp" #include "duckdb/catalog/catalog.hpp" +#include "duckdb/execution/partition_info.hpp" +#include "duckdb/function/partition_stats.hpp" +#include "duckdb/parallel/pipeline.hpp" #include "duckdb/parser/parsed_data/create_table_function_info.hpp" #include "duckdb/planner/operator/logical_get.hpp" #include "duckdb/storage/statistics/node_statistics.hpp" @@ -21,8 +24,7 @@ class CV2TableFunctionData final : public FunctionData { bool cardinality_is_exact = false; bool cardinality_set = false; - // How many result columns the bind callback declared. - idx_t column_count = 0; + vector column_types; auto Copy() const -> unique_ptr override { auto copy = make_uniq(); @@ -31,7 +33,7 @@ class CV2TableFunctionData final : public FunctionData { copy->cardinality = cardinality; copy->cardinality_is_exact = cardinality_is_exact; copy->cardinality_set = cardinality_set; - copy->column_count = column_count; + copy->column_types = column_types; return std::move(copy); } @@ -57,6 +59,58 @@ class CV2TableGlobalState final : public GlobalTableFunctionState { class CV2TableLocalState final : public LocalTableFunctionState { public: CV2UserData handle; + + // Requested partition columns as declared columns, fixed for the lifetime of the local state's pipeline. + const vector &PartitionColumns(const OperatorPartitionInfo &partition_info, + const vector &scan_columns) { + if (!partition_columns_resolved) { + for (auto scan_position : partition_info.partition_columns) { + D_ASSERT(scan_position < scan_columns.size()); + partition_columns.push_back(scan_columns[scan_position]); + } + partition_columns_resolved = true; + } + D_ASSERT(partition_columns.size() == partition_info.partition_columns.size()); + return partition_columns; + } + + void CheckPartitionData(const Identifier &function_name, const OperatorPartitionData &data) { + if (last_batch_index.IsValid()) { + auto last_index = last_batch_index.GetIndex(); + // The engine would otherwise raise an InternalException, which invalidates the database. + if (data.batch_index < last_index) { + throw InvalidInputException( + "The partition data callback of table function \"%s\" reported batch index %llu after " + "previously reporting %llu on the same thread; the batch index must not decrease.", + function_name, data.batch_index, last_index); + } + // The engine only reads the values when the batch index changes; a changed value would silently be ignored. + if (data.batch_index == last_index) { + D_ASSERT(data.partition_data.size() == last_partition_values.size()); + for (idx_t i = 0; i < last_partition_values.size(); i++) { + if (Value::NotDistinctFrom(data.partition_data[i].min_val, last_partition_values[i])) { + continue; + } + throw InvalidInputException( + "The partition data callback of table function \"%s\" reported a different partitioning " + "column value at index %llu without changing the batch index.", + function_name, i); + } + return; + } + } + last_batch_index = data.batch_index; + last_partition_values.clear(); + for (auto &entry : data.partition_data) { + last_partition_values.push_back(entry.min_val); + } + } + +private: + bool partition_columns_resolved = false; + vector partition_columns; + optional_idx last_batch_index; + vector last_partition_values; }; class CV2TableBindInfo { @@ -166,6 +220,65 @@ static auto Convert(CV2TableFilterPushdownInfo *info) -> duckdb_v2_table_functio return reinterpret_cast(info); } +class CV2TablePartitionDataInfo { +public: + void *in_user_data = nullptr; + void *in_bind_data = nullptr; + void *in_global_state = nullptr; + void *in_local_state = nullptr; + const OperatorPartitionInfo *in_partition_info = nullptr; + const vector *in_partition_columns = nullptr; + const vector *in_column_types = nullptr; + + optional_idx out_batch_index; + vector out_partition_value_set; + vector out_partition_values; +}; + +static auto Convert(duckdb_v2_table_function_partition_data_info_handle info) -> CV2TablePartitionDataInfo * { + return reinterpret_cast(info); +} +static auto Convert(CV2TablePartitionDataInfo *info) -> duckdb_v2_table_function_partition_data_info_handle { + return reinterpret_cast(info); +} + +class CV2TablePartitioningInfo { +public: + void *in_user_data = nullptr; + void *in_bind_data = nullptr; + const vector *in_partition_ids = nullptr; + + // Not calling the setter is not a caller error: it means "not partitioned", the conservative default. + TablePartitionInfo out_partition_info = TablePartitionInfo::NOT_PARTITIONED; +}; + +static auto Convert(duckdb_v2_table_function_partitioning_info_handle info) -> CV2TablePartitioningInfo * { + return reinterpret_cast(info); +} +static auto Convert(CV2TablePartitioningInfo *info) -> duckdb_v2_table_function_partitioning_info_handle { + return reinterpret_cast(info); +} + +static_assert(static_cast(TablePartitionInfo::NOT_PARTITIONED) == DUCKDB_V2_TABLE_PARTITION_INFO_NOT_PARTITIONED, + "TablePartitionInfo::NOT_PARTITIONED mismatch"); +static_assert(static_cast(TablePartitionInfo::SINGLE_VALUE_PARTITIONS) == + DUCKDB_V2_TABLE_PARTITION_INFO_SINGLE_VALUE_PARTITIONS, + "TablePartitionInfo::SINGLE_VALUE_PARTITIONS mismatch"); +static_assert(static_cast(TablePartitionInfo::OVERLAPPING_PARTITIONS) == + DUCKDB_V2_TABLE_PARTITION_INFO_OVERLAPPING_PARTITIONS, + "TablePartitionInfo::OVERLAPPING_PARTITIONS mismatch"); +static_assert(static_cast(TablePartitionInfo::DISJOINT_PARTITIONS) == + DUCKDB_V2_TABLE_PARTITION_INFO_DISJOINT_PARTITIONS, + "TablePartitionInfo::DISJOINT_PARTITIONS mismatch"); + +static auto CV2ConvertPartitionInfo(DUCKDB_V2_TABLE_PARTITION_INFO value) -> TablePartitionInfo { + if (static_cast(value) > DUCKDB_V2_TABLE_PARTITION_INFO_DISJOINT_PARTITIONS) { + throw duckdb::InvalidInputException( + "Invalid value in duckdb_v2_table_function_partitioning_set_partition_info"); + } + return static_cast(value); +} + class CV2TableFunctionInfo : public TableFunctionInfo { public: duckdb_v2_table_function_bind_callback_fn bind_cb = nullptr; @@ -174,9 +287,13 @@ class CV2TableFunctionInfo : public TableFunctionInfo { duckdb_v2_table_function_exec_callback_fn exec_cb = nullptr; duckdb_v2_table_function_progress_callback_fn progress_cb = nullptr; duckdb_v2_table_function_filter_pushdown_callback_fn filter_pushdown_cb = nullptr; + duckdb_v2_table_function_partition_data_callback_fn partition_data_cb = nullptr; + duckdb_v2_table_function_partitioning_callback_fn partitioning_cb = nullptr; shared_ptr user_data = nullptr; bool projection_pushdown = false; + Identifier name; + // The signature's slot plan, captured at registration: every parameter name in signature order, how many of them // lead the positional prefix (the ones without a default), and the default of each remaining parameter. The bind // wrapper assembles the argument list from it, injecting the default for a parameter the call site omitted, so @@ -245,7 +362,7 @@ static auto CV2TableBind(ClientContext &context, TableFunctionBindInput &input, input.table_function.name); } - result->column_count = args.out_column_types.size(); + result->column_types = args.out_column_types; return_types = std::move(args.out_column_types); names = std::move(args.out_column_names); return std::move(result); @@ -259,7 +376,7 @@ static auto CV2TableScanColumns(const CV2TableFunctionData &bind_data, const Tab return input.column_ids; } vector columns; - for (idx_t i = 0; i < bind_data.column_count; i++) { + for (idx_t i = 0; i < bind_data.column_types.size(); i++) { columns.push_back(i); } return columns; @@ -305,8 +422,10 @@ static auto CV2TableInitLocal(ExecutionContext &context, TableFunctionInitInput const auto &bind_data = input.bind_data->Cast(); const auto &info = *bind_data.info; + // Always produced, even without a callback: get_partition_data keeps its per-thread guard state here. + auto result = make_uniq(); if (!info.init_local_cb) { - return nullptr; + return std::move(result); } auto scan_columns = CV2TableScanColumns(bind_data, input); @@ -323,12 +442,9 @@ static auto CV2TableInitLocal(ExecutionContext &context, TableFunctionInitInput auto err_ptr = Convert(&err); info.init_local_cb(Convert(&args), Convert(&context.client), &err_ptr); - unique_ptr result = nullptr; if (args.out_local_state.ptr) { - auto set_result = make_uniq(); - set_result->handle = + result->handle = CV2UserData(args.out_local_state.ptr, args.out_local_state.destroy, args.out_local_state.equals); - result = std::move(set_result); } // Throw after taking ownership of the state, so that it is destroyed even if we error. @@ -336,7 +452,7 @@ static auto CV2TableInitLocal(ExecutionContext &context, TableFunctionInitInput err.ThrowAsException(); } - return result; + return std::move(result); } static auto CV2TableExec(ClientContext &context, TableFunctionInput &input, DataChunk &output) -> void { @@ -351,9 +467,7 @@ static auto CV2TableExec(ClientContext &context, TableFunctionInput &input, Data args.in_global_state = global_state.handle.GetData(); args.in_scan_columns = &global_state.scan_columns; } - if (input.local_state) { - args.in_local_state = input.local_state->Cast().handle.GetData(); - } + args.in_local_state = input.local_state->Cast().handle.GetData(); args.output = &output; CV2ErrorInfo err = {}; @@ -446,6 +560,81 @@ static auto CV2TableFilterPushdown(ClientContext &context, LogicalGet &get, Func filters = std::move(remaining); } +//! Batch index is required on every call, even when unrequested: the pipeline range-checks it regardless. +static auto CV2TakePartitionData(CV2TablePartitionDataInfo &args, const Identifier &function_name) + -> OperatorPartitionData { + if (!args.out_batch_index.IsValid()) { + throw InvalidInputException("The partition data callback of table function \"%s\" did not set a batch index.", + function_name); + } + OperatorPartitionData result(args.out_batch_index.GetIndex()); + result.partition_data.reserve(args.out_partition_values.size()); + for (idx_t i = 0; i < args.out_partition_values.size(); i++) { + if (!args.out_partition_value_set[i]) { + throw InvalidInputException("The partition data callback of table function \"%s\" did not set the " + "partitioning column value at index %llu.", + function_name, i); + } + result.partition_data.emplace_back(std::move(args.out_partition_values[i])); + } + return result; +} + +static auto CV2TableGetPartitionData(ClientContext &context, TableFunctionGetPartitionInput &input) + -> OperatorPartitionData { + const auto &bind_data = input.bind_data->Cast(); + const auto &info = *bind_data.info; + + auto &global_state = input.global_state->Cast(); + auto &local_state = input.local_state->Cast(); + + CV2TablePartitionDataInfo args = {}; + args.in_user_data = info.user_data ? info.user_data->GetData() : nullptr; + args.in_bind_data = bind_data.handle ? bind_data.handle->GetData() : nullptr; + args.in_global_state = global_state.handle.GetData(); + args.in_local_state = local_state.handle.GetData(); + args.in_partition_info = &input.partition_info; + // The planner resolves these to scan positions, unlike get_partition_info's, which it resolves to declared + // columns; the callback is promised declared columns in both. + args.in_partition_columns = &local_state.PartitionColumns(input.partition_info, global_state.scan_columns); + args.in_column_types = &bind_data.column_types; + args.out_partition_value_set.resize(args.in_partition_columns->size(), false); + args.out_partition_values.resize(args.in_partition_columns->size()); + + CV2ErrorInfo err = {}; + auto err_ptr = Convert(&err); + info.partition_data_cb(Convert(&args), Convert(&context), &err_ptr); + + if (err.HasError()) { + err.ThrowAsException(); + } + + auto result = CV2TakePartitionData(args, info.name); + local_state.CheckPartitionData(info.name, result); + return result; +} + +//! Runs at plan time and must be deterministic: the optimizer may call it for a plan shape it later discards. +static auto CV2TableGetPartitionInfo(ClientContext &context, TableFunctionPartitionInput &input) -> TablePartitionInfo { + const auto &bind_data = input.bind_data->Cast(); + const auto &info = *bind_data.info; + + CV2TablePartitioningInfo args = {}; + args.in_user_data = info.user_data ? info.user_data->GetData() : nullptr; + args.in_bind_data = bind_data.handle ? bind_data.handle->GetData() : nullptr; + args.in_partition_ids = &input.partition_ids; + + CV2ErrorInfo err = {}; + auto err_ptr = Convert(&err); + info.partitioning_cb(Convert(&args), Convert(&context), &err_ptr); + + if (err.HasError()) { + err.ThrowAsException(); + } + + return args.out_partition_info; +} + class CV2TableFunction { public: void Register() { @@ -458,6 +647,10 @@ class CV2TableFunction { if (!info.exec_cb) { throw InvalidInputException("Exec callback must be set for the function."); } + // The engine calls get_partition_data without a null check once get_partition_info claims partitions. + if (info.partitioning_cb && !info.partition_data_cb) { + throw InvalidInputException("Partition data callback must be set when the partitioning callback is set."); + } // A table function declares the columns it returns from its bind callback, not through a return type. if (signature.GetReturnType().id() != LogicalTypeId::INVALID) { throw InvalidInputException("A table function signature cannot set a return type."); @@ -489,8 +682,15 @@ class CV2TableFunction { if (info.filter_pushdown_cb) { function.pushdown_complex_filter = CV2TableFilterPushdown; } + if (info.partition_data_cb) { + function.get_partition_data = CV2TableGetPartitionData; + } + if (info.partitioning_cb) { + function.get_partition_info = CV2TableGetPartitionInfo; + } function.projection_pushdown = info.projection_pushdown; + info.name = name; auto function_info = make_shared_ptr(std::move(info)); for (idx_t i = 0; i < signature.GetParameterCount(); i++) { const auto ¶m = signature.GetParameter(i); @@ -667,6 +867,22 @@ duckdb_v2_table_function_set_filter_pushdown_callback(duckdb_v2_table_function_h return WithErrorHandler(err, [&]() { Convert(function)->info.filter_pushdown_cb = callback; }); } +DUCKDB_V2_ERROR +duckdb_v2_table_function_set_partition_data_callback(duckdb_v2_table_function_handle function, + duckdb_v2_table_function_partition_data_callback_fn callback, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(function); + return WithErrorHandler(err, [&]() { Convert(function)->info.partition_data_cb = callback; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_set_partitioning_callback(duckdb_v2_table_function_handle function, + duckdb_v2_table_function_partitioning_callback_fn callback, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(function); + return WithErrorHandler(err, [&]() { Convert(function)->info.partitioning_cb = callback; }); +} + DUCKDB_V2_ERROR duckdb_v2_table_function_bind_get_user_data(duckdb_v2_table_function_bind_info_handle info, void **data, duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(info); @@ -1027,6 +1243,165 @@ duckdb_v2_table_function_filter_pushdown_get_column_index(duckdb_v2_table_functi }); } +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_get_user_data(duckdb_v2_table_function_partition_data_info_handle info, + void **data, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(data); + return WithErrorHandler(err, [&]() { *data = Convert(info)->in_user_data; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_get_bind_data(duckdb_v2_table_function_partition_data_info_handle info, + void **data, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(data); + return WithErrorHandler(err, [&]() { *data = Convert(info)->in_bind_data; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_get_global_state(duckdb_v2_table_function_partition_data_info_handle info, + void **data, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(data); + return WithErrorHandler(err, [&]() { *data = Convert(info)->in_global_state; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_get_local_state(duckdb_v2_table_function_partition_data_info_handle info, + void **data, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(data); + return WithErrorHandler(err, [&]() { *data = Convert(info)->in_local_state; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_requires_batch_index(duckdb_v2_table_function_partition_data_info_handle info, + bool *required, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(required); + return WithErrorHandler(err, [&]() { *required = Convert(info)->in_partition_info->RequiresBatchIndex(); }); +} + +DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_requires_partition_columns( + duckdb_v2_table_function_partition_data_info_handle info, bool *required, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(required); + return WithErrorHandler(err, [&]() { *required = Convert(info)->in_partition_info->RequiresPartitionColumns(); }); +} + +DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_partition_column_count( + duckdb_v2_table_function_partition_data_info_handle info, idx_t *count, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(count); + return WithErrorHandler(err, [&]() { *count = Convert(info)->in_partition_columns->size(); }); +} + +DUCKDB_V2_ERROR duckdb_v2_table_function_partition_data_get_partition_column_index( + duckdb_v2_table_function_partition_data_info_handle info, idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(column_index); + return WithErrorHandler(err, [&]() { + const auto &columns = *Convert(info)->in_partition_columns; + if (index >= columns.size()) { + throw duckdb::InvalidInputException( + "Index out of bounds in duckdb_v2_table_function_partition_data_get_partition_column_index"); + } + *column_index = columns[index]; + }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_set_batch_index(duckdb_v2_table_function_partition_data_info_handle info, + idx_t batch_index, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + return WithErrorHandler(err, [&]() { + // ToPipelinePartitionData adds base + 1 and throws an InternalException from BATCH_INCREMENT - 1 on. + if (batch_index >= duckdb::PipelineBuildState::BATCH_INCREMENT - 2) { + throw duckdb::InvalidInputException( + "duckdb_v2_table_function_partition_data_set_batch_index: batch_index %llu must be less than " + "%llu", + batch_index, duckdb::PipelineBuildState::BATCH_INCREMENT - 2); + } + Convert(info)->out_batch_index = batch_index; + }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partition_data_set_partition_value(duckdb_v2_table_function_partition_data_info_handle info, + idx_t index, duckdb_v2_value_handle value, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(value); + return WithErrorHandler(err, [&]() { + auto &args = *Convert(info); + if (index >= args.out_partition_values.size()) { + throw duckdb::InvalidInputException( + "Index out of bounds in duckdb_v2_table_function_partition_data_set_partition_value"); + } + const auto &expected_type = (*args.in_column_types)[(*args.in_partition_columns)[index]]; + const auto &actual = *Convert(value); + if (actual.type() != expected_type) { + throw duckdb::InvalidInputException( + "duckdb_v2_table_function_partition_data_set_partition_value: expected type %s for the " + "partitioning column at index %llu, got %s", + expected_type.ToString(), index, actual.type().ToString()); + } + args.out_partition_values[index] = actual; + args.out_partition_value_set[index] = true; + }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partitioning_get_user_data(duckdb_v2_table_function_partitioning_info_handle info, void **data, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(data); + return WithErrorHandler(err, [&]() { *data = Convert(info)->in_user_data; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partitioning_get_bind_data(duckdb_v2_table_function_partitioning_info_handle info, void **data, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(data); + return WithErrorHandler(err, [&]() { *data = Convert(info)->in_bind_data; }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partitioning_get_partition_column_count(duckdb_v2_table_function_partitioning_info_handle info, + idx_t *count, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(count); + return WithErrorHandler(err, [&]() { *count = Convert(info)->in_partition_ids->size(); }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partitioning_get_partition_column_index(duckdb_v2_table_function_partitioning_info_handle info, + idx_t index, idx_t *column_index, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + DUCKDB_CHECK_ARG(column_index); + return WithErrorHandler(err, [&]() { + const auto &columns = *Convert(info)->in_partition_ids; + if (index >= columns.size()) { + throw duckdb::InvalidInputException( + "Index out of bounds in duckdb_v2_table_function_partitioning_get_partition_column_index"); + } + *column_index = columns[index]; + }); +} + +DUCKDB_V2_ERROR +duckdb_v2_table_function_partitioning_set_partition_info(duckdb_v2_table_function_partitioning_info_handle info, + DUCKDB_V2_TABLE_PARTITION_INFO partition_info, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(info); + return WithErrorHandler(err, + [&]() { Convert(info)->out_partition_info = CV2ConvertPartitionInfo(partition_info); }); +} + DUCKDB_V2_ERROR duckdb_v2_table_function_register(duckdb_v2_table_function_handle function, duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(function); diff --git a/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp b/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp new file mode 100644 index 000000000..307f0ce62 --- /dev/null +++ b/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp @@ -0,0 +1,358 @@ +#include "duckdb/main/capi_v2/capi_v2_internal.hpp" + +#include "duckdb/catalog/catalog.hpp" +#include "duckdb/common/file_system.hpp" +#include "duckdb/common/types/value.hpp" +#include "duckdb/main/attached_database.hpp" +#include "duckdb/main/database_manager.hpp" +#include "duckdb/main/database_path_and_type.hpp" +#include "duckdb/main/settings.hpp" +#include "duckdb/parser/parsed_data/attach_info.hpp" + +namespace duckdb { +namespace capiv2 { + +CV2Instance::CV2Instance(CV2Environment &env) : env(env), config(make_uniq()) { +} + +void CV2Instance::Start() { + if (IsStarted()) { + return; + } + // Routed through the env's DBInstanceCache so every instance shares its path manager: opening one file twice is + // detected across instances, while no instance is memoized. + database = env.cache->CreateEmptyInstance(*config); + config.reset(); + staged_settings.clear(); + internal_connection = make_uniq(*database); +} + +DuckDB &CV2Instance::GetDatabase() { + Start(); + return *database; +} + +//! Runs `action` inside a transaction on the internal connection, the way the ATTACH / DETACH operators run inside +//! their statement's transaction. +template +static void WithTransaction(Connection &connection, T action) { + connection.BeginTransaction(); + try { + action(*connection.context); + } catch (...) { + connection.Rollback(); + throw; + } + connection.Commit(); +} + +void CV2Instance::Attach(const string &path, const Identifier &name, + optional_ptr attach_options, bool make_default) { + if (attach_options && &attach_options->instance != this) { + throw InvalidInputException("the attach options were created from a different instance handle"); + } + Start(); + WithTransaction(*internal_connection, [&](ClientContext &context) { + // Mirrors PhysicalAttach for `ATTACH 'path' AS name (options)`. + auto &instance = *database->instance; + AttachInfo info; + info.path = path; + info.name = name; + if (attach_options) { + info.options = attach_options->options; + } + AttachOptions options(info.options, instance.config.options.access_mode); + options.original_path = path; + if (options.db_type.empty()) { + DBPathAndType::ExtractExtensionPrefix(info.path, options.db_type); + } + if (info.name.empty()) { + info.name = AttachedDatabase::ExtractDatabaseName(info.path, FileSystem::GetFileSystem(instance)); + } + // The host opening a file is not external access: allow it the way the main database path is allowed. + if (options.db_type.empty() && !DBConfig::IsInMemoryDatabase(info.path.c_str()) && + !FileSystem::IsRemoteFile(info.path) && !Settings::Get(instance)) { + instance.config.AddAllowedDatabasePath(info.path); + } + auto &db_manager = DatabaseManager::Get(instance); + auto attached = db_manager.AttachDatabase(context, info, options); + if (make_default) { + db_manager.SetDefaultDatabase(attached->GetName()); + } + }); +} + +//! Finds the database attached under `path` as a name, else the one attached from it as a path, disambiguated by +//! the name instance_attach derives from the path. Throws when nothing matches. +static shared_ptr FindAttachedDatabase(DatabaseInstance &instance, const string &path) { + auto &db_manager = DatabaseManager::Get(instance); + if (auto by_name = db_manager.GetDatabase(Identifier(path))) { + if (!by_name->IsSystem() && !by_name->IsTemporary()) { + return by_name; + } + } + auto &fs = FileSystem::GetFileSystem(instance); + string stripped = path; + string db_type; + DBPathAndType::ExtractExtensionPrefix(stripped, db_type); + const bool in_memory = DBConfig::IsInMemoryDatabase(stripped.c_str()); + // File-based DuckDB databases are attached under their canonical path; other attaches keep the path verbatim. + string canonical = stripped; + if (!in_memory && db_type.empty() && !FileSystem::IsRemoteFile(stripped)) { + try { + canonical = fs.CanonicalizePath(stripped); + } catch (...) { // NOLINT(bugprone-empty-catch): an uncanonicalizable path just falls back to verbatim matching + } + } + const auto derived_name = AttachedDatabase::ExtractDatabaseName(stripped, fs); + + shared_ptr match; + idx_t match_count = 0; + for (auto &db : db_manager.GetDatabases()) { + if (db->IsSystem() || db->IsTemporary()) { + continue; + } + auto &catalog = db->GetCatalog(); + bool matches; + if (in_memory) { + matches = catalog.InMemory(); + } else { + const auto db_path = catalog.GetDBPath(); + matches = db_path == canonical || db_path == stripped; + } + if (!matches) { + continue; + } + match_count++; + if (!match || db->GetName() == derived_name) { + match = db; + } + } + if (!match) { + throw InvalidInputException("no database is attached from or under '%s'", path); + } + if (match_count > 1 && match->GetName() != derived_name) { + throw InvalidInputException("several databases are attached from '%s'; refer to one by name in SQL", path); + } + return match; +} + +void CV2Instance::Detach(const string &path) { + if (!IsStarted()) { + throw InvalidInputException("no database is attached from or under '%s'", path); + } + auto &instance = *database->instance; + auto attached = FindAttachedDatabase(instance, path); + WithTransaction(*internal_connection, [&](ClientContext &context) { + DatabaseManager::Get(instance).DetachDatabase(context, attached->GetName(), OnEntryNotFound::THROW_EXCEPTION, + true); + }); +} + +void CV2Instance::SetDefault(const string &path) { + if (!IsStarted()) { + throw InvalidInputException("no database is attached from or under '%s'", path); + } + auto &instance = *database->instance; + auto attached = FindAttachedDatabase(instance, path); + DatabaseManager::Get(instance).SetDefaultDatabase(attached->GetName()); +} + +void CV2Instance::SetOption(const Identifier &name, const string &setting) { + if (!IsStarted()) { + // Staged for startup: the only route to options that cannot change once the instance runs. + config->SetOptionByName(name, Value(setting)); + auto option = DBConfig::GetOptionByName(name); + staged_settings[option ? Identifier(option->name) : name] = setting; + return; + } + // Force GLOBAL scope: the internal context has no LOCAL settings of its own, and instance-scoped settings only + // make sense as GLOBAL anyway. + PhysicalSet::SetVariable(*internal_connection->context, name, SetScope::GLOBAL, Value(setting)); +} + +unique_ptr CV2Instance::GetOption(std::string_view name) { + if (!IsStarted()) { + return CV2Option::FromName(CV2OptionSource(*config, staged_settings), name); + } + return CV2Option::FromName(CV2OptionSource(*internal_connection->context), name); +} + +idx_t CV2Instance::GetOptionCount() { + if (!IsStarted()) { + return CV2Option::Count(CV2OptionSource(*config, staged_settings)); + } + return CV2Option::Count(CV2OptionSource(*internal_connection->context)); +} + +unique_ptr CV2Instance::GetOptionByIndex(idx_t index) { + if (!IsStarted()) { + return CV2Option::FromIndex(CV2OptionSource(*config, staged_settings), index); + } + return CV2Option::FromIndex(CV2OptionSource(*internal_connection->context), index); +} + +} // namespace capiv2 +} // namespace duckdb + +using namespace duckdb::capiv2; + +DUCKDB_V2_ERROR duckdb_v2_instance_create(duckdb_v2_environment_handle env, duckdb_v2_instance_handle *out_instance, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(env); + DUCKDB_CHECK_ARG(out_instance); + *out_instance = nullptr; + return WithErrorHandler(err, [&]() { + auto *env_wrapper = Convert(env); + auto wrapper = duckdb::make_uniq(*env_wrapper); + env_wrapper->instance_count.fetch_add(1, std::memory_order_release); + *out_instance = Convert(wrapper.release()); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_destroy(duckdb_v2_instance_handle *instance) { + return WithErrorHandler(nullptr, [&]() { + if (!instance) { + return; + } + if (*instance) { + const auto *wrapper = Convert(*instance); + auto &env = wrapper->env; + delete wrapper; + env.instance_count.fetch_sub(1, std::memory_order_release); + *instance = nullptr; + } + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_attach(duckdb_v2_instance_handle instance, duckdb_v2_str path, + duckdb_v2_identifier_t *name, duckdb_v2_attach_options_handle options, + bool make_default, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(path); + if (name) { + DUCKDB_CHECK_ARG(*name); + } + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + duckdb::Identifier attach_name = name ? duckdb::Identifier(Convert(*name)) : duckdb::Identifier(); + wrapper.Attach(duckdb::string(Convert(path)), attach_name, Convert(options), make_default); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_attach_options_create(duckdb_v2_instance_handle instance, + duckdb_v2_attach_options_handle *out_options, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(out_options); + *out_options = nullptr; + return WithErrorHandler(err, [&]() { + auto options = duckdb::make_uniq(*Convert(instance)); + *out_options = Convert(options.release()); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_attach_options_set(duckdb_v2_attach_options_handle options, duckdb_v2_identifier_t key, + duckdb_v2_str setting, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(options); + DUCKDB_CHECK_ARG(key); + DUCKDB_CHECK_ARG(setting); + return WithErrorHandler(err, [&]() { + // Keys are unquoted SQL identifiers, which the parser lowercases. + auto lowered = duckdb::StringUtil::Lower(duckdb::string(Convert(key))); + Convert(options)->options[lowered] = duckdb::Value(duckdb::string(Convert(setting))); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_attach_options_destroy(duckdb_v2_attach_options_handle *options) { + return WithErrorHandler(nullptr, [&]() { + if (!options) { + return; + } + if (*options) { + delete Convert(*options); + *options = nullptr; + } + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_detach(duckdb_v2_instance_handle instance, duckdb_v2_str path, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(path); + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + wrapper.Detach(duckdb::string(Convert(path))); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_set_default(duckdb_v2_instance_handle instance, duckdb_v2_str path, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(path); + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + wrapper.SetDefault(duckdb::string(Convert(path))); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_set_option(duckdb_v2_instance_handle instance, duckdb_v2_identifier_t name, + duckdb_v2_str setting, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(name); + DUCKDB_CHECK_ARG(setting); + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + wrapper.SetOption(duckdb::Identifier(Convert(name)), duckdb::string(Convert(setting))); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_get_option_by_name(duckdb_v2_instance_handle instance, duckdb_v2_identifier_t name, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(name); + DUCKDB_CHECK_ARG(out_option); + *out_option = nullptr; + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + *out_option = Convert(wrapper.GetOption(Convert(name)).release()); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_get_option_count(duckdb_v2_instance_handle instance, idx_t *out_count, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(out_count); + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + *out_count = wrapper.GetOptionCount(); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_instance_get_option_by_index(duckdb_v2_instance_handle instance, idx_t index, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(instance); + DUCKDB_CHECK_ARG(out_option); + *out_option = nullptr; + return WithErrorHandler(err, [&]() { + auto &wrapper = *Convert(instance); + duckdb::lock_guard guard(wrapper.lock); + *out_option = Convert(wrapper.GetOptionByIndex(index).release()); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_library_version(duckdb_v2_str *out_version, duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(out_version); + return WithErrorHandler(err, [&]() { + const auto version = duckdb::DuckDB::LibraryVersion(); + *out_version = duckdb_v2_str {version, std::strlen(version)}; + }); +} diff --git a/src/duckdb/src/main/capi/v2/capi_v2_option.cpp b/src/duckdb/src/main/capi/v2/capi_v2_option.cpp index ffc3c1367..9a20b0ea1 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_option.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_option.cpp @@ -2,20 +2,6 @@ using namespace duckdb::capiv2; -DUCKDB_V2_ERROR duckdb_v2_option_create(duckdb_v2_identifier_t name, duckdb_v2_str setting, - duckdb_v2_option_handle *out_option, duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(name); - DUCKDB_CHECK_ARG(setting); - DUCKDB_CHECK_ARG(out_option); - *out_option = nullptr; - return WithErrorHandler(err, [&]() { - auto wrapper = duckdb::make_uniq(); - wrapper->name = duckdb::Identifier(Convert(name)); - wrapper->setting = Convert(setting); - *out_option = Convert(wrapper.release()); - }); -} - DUCKDB_V2_ERROR duckdb_v2_option_destroy(duckdb_v2_option_handle *option) { return WithErrorHandler(nullptr, [&]() { if (!option) { @@ -84,3 +70,39 @@ DUCKDB_V2_ERROR duckdb_v2_option_get_alias(duckdb_v2_option_handle option, idx_t *out_alias = Convert(wrapper.aliases[index]); }); } + +// --------------------------------------------------------------------------- +// Context option getters: the connection's cascade, read from inside DuckDB +// --------------------------------------------------------------------------- + +DUCKDB_V2_ERROR duckdb_v2_context_get_option_by_name(duckdb_v2_context_handle ctx, duckdb_v2_identifier_t name, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(ctx); + DUCKDB_CHECK_ARG(name); + DUCKDB_CHECK_ARG(out_option); + *out_option = nullptr; + return WithErrorHandler(err, [&]() { + CV2OptionSource source(*Convert(ctx)); + *out_option = Convert(CV2Option::FromName(source, Convert(name)).release()); + }); +} + +DUCKDB_V2_ERROR duckdb_v2_context_get_option_count(duckdb_v2_context_handle ctx, idx_t *out_count, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(ctx); + DUCKDB_CHECK_ARG(out_count); + return WithErrorHandler(err, [&]() { *out_count = CV2Option::Count(CV2OptionSource(*Convert(ctx))); }); +} + +DUCKDB_V2_ERROR duckdb_v2_context_get_option_by_index(duckdb_v2_context_handle ctx, idx_t index, + duckdb_v2_option_handle *out_option, + duckdb_v2_error_info_handle *err) { + DUCKDB_CHECK_ARG(ctx); + DUCKDB_CHECK_ARG(out_option); + *out_option = nullptr; + return WithErrorHandler(err, [&]() { + CV2OptionSource source(*Convert(ctx)); + *out_option = Convert(CV2Option::FromIndex(source, index).release()); + }); +} diff --git a/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp b/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp index ed5100be3..2e0091053 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp @@ -161,17 +161,17 @@ class CV2ConnectionReplacementScan : public CV2ReplacementScan { Connection &connection; }; -class CV2DatabaseReplacementScan : public CV2ReplacementScan { +class CV2InstanceReplacementScan : public CV2ReplacementScan { public: - explicit CV2DatabaseReplacementScan(DatabaseInstance &db) : db(db) { + explicit CV2InstanceReplacementScan(DatabaseInstance &instance) : instance(instance) { } void RegisterScan(ReplacementScan scan) override { - DBConfig::GetConfig(db).replacement_scans.push_back(std::move(scan)); + DBConfig::GetConfig(instance).replacement_scans.push_back(std::move(scan)); } private: - DatabaseInstance &db; + DatabaseInstance &instance; }; static auto Convert(duckdb_v2_replacement_scan_handle scan) -> CV2ReplacementScan * { @@ -202,15 +202,17 @@ DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_connection(duckdb_v2_conn }); } -DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_database(duckdb_v2_database_handle database, +DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_instance(duckdb_v2_instance_handle instance, duckdb_v2_replacement_scan_handle *out_scan, duckdb_v2_error_info_handle *err) { - DUCKDB_CHECK_ARG(database); + DUCKDB_CHECK_ARG(instance); DUCKDB_CHECK_ARG(out_scan); *out_scan = nullptr; return WithErrorHandler(err, [&]() { - auto &db = *Convert(database)->database->instance; - auto scan = duckdb::make_uniq(db); + auto &instance_wrapper = *Convert(instance); + duckdb::lock_guard guard(instance_wrapper.lock); + auto &db = *instance_wrapper.GetDatabase().instance; + auto scan = duckdb::make_uniq(db); *out_scan = Convert(scan.release()); }); } @@ -223,7 +225,7 @@ DUCKDB_V2_ERROR duckdb_v2_replacement_scan_create_with_extension(duckdb_v2_exten *out_scan = nullptr; return WithErrorHandler(err, [&]() { auto &db = GetExtensionLoader(extension).GetDatabaseInstance(); - auto scan = duckdb::make_uniq(db); + auto scan = duckdb::make_uniq(db); *out_scan = Convert(scan.release()); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_result.cpp b/src/duckdb/src/main/capi/v2/capi_v2_result.cpp index 9d5cf3048..658fb563e 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_result.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_result.cpp @@ -5,8 +5,7 @@ #include "duckdb/common/column_data_collection_render_interface.hpp" #include "duckdb/common/types/column/column_data_collection.hpp" -#include "duckdb/common/enums/pending_execution_result.hpp" -#include "duckdb/common/enums/stream_execution_result.hpp" +#include "duckdb/common/enums/query_result_state.hpp" #include "duckdb/parser/statement/transaction_statement.hpp" namespace duckdb::capiv2 { @@ -36,21 +35,21 @@ DUCKDB_V2_RESULT_TYPE MapResultType(StatementReturnType t) { // ResultWrapperV2 state machine // --------------------------------------------------------------------------- -void ResultWrapperV2::BeginPending(unique_ptr next_pending, bool is_principal) { - if (next_pending->HasError()) { +void ResultWrapperV2::BeginPending(unique_ptr next_handle, bool is_principal) { + if (next_handle->HasError()) { // Re-throw the typed ErrorData so the exception's ExceptionType is // preserved and routed through GetErrorCodeFromExceptionType. - next_pending->GetErrorObject().Throw(); + next_handle->GetErrorObject().Throw(); } principal_active = is_principal; if (is_principal) { - types = next_pending->GetTypes(); - names = next_pending->GetNames(); - statement_type = next_pending->GetStatementType(); - properties = next_pending->GetStatementProperties(); + types = next_handle->GetTypes(); + names = next_handle->GetNames(); + statement_type = next_handle->GetStatementType(); + properties = next_handle->GetStatementProperties(); metadata_available = true; } - pending = std::move(next_pending); + handle = std::move(next_handle); state = State::PENDING; } @@ -70,15 +69,14 @@ void ResultWrapperV2::StartNextFragment() { // Parameters bind only to the first fragment (statement_execute rejects them on // a statement that expands, so that fragment is the user's statement). Later // fragments take the no-values path. - auto next_pending = - (this_index == 0 && !param_values.empty()) - ? context->PendingQuery(std::move(stmt), param_values, QueryResultOutputType::ALLOW_STREAMING) - : context->PendingQuery(std::move(stmt), QueryResultOutputType::ALLOW_STREAMING); + auto next_handle = (this_index == 0 && !param_values.empty()) + ? context->Submit(std::move(stmt), param_values, QueryParameters()) + : context->Submit(std::move(stmt), QueryParameters()); // Principal selection is a property of the fragment group; compute it here, then - // hand the pending to the shared BeginPending seam. A HasError() pending is left + // hand the handle to the shared BeginPending seam. A HasError() handle is left // for BeginPending to raise (return_type is meaningless on it). - bool has_result = !next_pending->HasError() && - next_pending->GetStatementProperties().return_type == StatementReturnType::QUERY_RESULT; + bool has_result = !next_handle->HasError() && + next_handle->GetStatementProperties().return_type == StatementReturnType::QUERY_RESULT; if (principal_seen && has_result) { // ClientContext::Query would chain these as separate results with // separate schemas; a single stream cannot. No known expansion @@ -93,7 +91,7 @@ void ResultWrapperV2::StartNextFragment() { if (has_result) { principal_seen = true; } - BeginPending(std::move(next_pending), is_principal); + BeginPending(std::move(next_handle), is_principal); } void ResultWrapperV2::RequireMetadata() const { @@ -110,8 +108,8 @@ DUCKDB_V2_RESULT_STEP_STATUS ResultWrapperV2::HandleExecutionError(ErrorData err // engine's message, mirroring the eager ClientContext::Query path. bool user_cancelled = error_data.Type() == ExceptionType::INTERRUPT && busy_slot && busy_slot->cancel_requested.load(std::memory_order_relaxed); - pending.reset(); - result.reset(); + stream.reset(); + handle.reset(); fragments.clear(); try { RollbackIncompleteGroup(); @@ -144,104 +142,91 @@ DUCKDB_V2_RESULT_STEP_STATUS ResultWrapperV2::Step(unique_ptr &out_ch // internal results. error.Throw(); case State::PENDING: { - PendingExecutionResult exec; + QueryResultState exec; try { - exec = pending->ExecuteTask(); + exec = handle->ExecuteTask(); } catch (std::exception &ex) { return HandleExecutionError(ErrorData(ex)); } switch (exec) { - case PendingExecutionResult::RESULT_NOT_READY: - case PendingExecutionResult::BLOCKED: - case PendingExecutionResult::NO_TASKS_AVAILABLE: + case QueryResultState::NOT_READY: + case QueryResultState::BLOCKED: + case QueryResultState::NO_TASKS_AVAILABLE: return DUCKDB_V2_RESULT_STEP_STATUS_WAITING; - case PendingExecutionResult::EXECUTION_ERROR: - return HandleExecutionError(pending->GetErrorObject()); - case PendingExecutionResult::RESULT_READY: - case PendingExecutionResult::EXECUTION_FINISHED: { - // Transition to the streaming phase. Execute() is (mostly) - // instant once the pending result is ready. Reporting WAITING - // after the transition keeps the contract simple: one unit of - // work per step; the next step hits the stream. - unique_ptr res; + case QueryResultState::EXECUTION_ERROR: + return HandleExecutionError(handle->GetErrorObject()); + case QueryResultState::READY: + case QueryResultState::FINISHED: { + // Transition to the streaming phase. Reporting WAITING after the + // transition keeps the contract simple: one unit of work per + // step; the next step hits the stream. try { - res = pending->Execute(); + if (handle->GetStatementProperties().result_eagerness == ResultEagerness::FORCED) { + // The statement completes before its result is returned: + // its chunks come from the retained handle instead. + handle->Complete(); + if (handle->HasError()) { + return HandleExecutionError(handle->GetErrorObject()); + } + } else { + stream = make_uniq(std::move(handle)); + } } catch (std::exception &ex) { return HandleExecutionError(ErrorData(ex)); } - pending.reset(); - if (res->HasError()) { - return HandleExecutionError(res->GetErrorObject()); - } - result = std::move(res); state = State::STREAMING; return DUCKDB_V2_RESULT_STEP_STATUS_WAITING; } } - D_ASSERT(false); // unmapped PendingExecutionResult variant + D_ASSERT(false); // unmapped QueryResultState variant return DUCKDB_V2_RESULT_STEP_STATUS_WAITING; } case State::STREAMING: { - if (result->GetResultType() == QueryResultType::STREAM_RESULT) { - auto &stream = result->Cast(); - StreamExecutionResult exec; + if (stream) { + QueryResultState exec; try { - exec = stream.ExecuteTask(); + exec = stream->ExecuteTask(); } catch (std::exception &ex) { - // SimpleBufferedData surfaces a pending interrupt by - // throwing InterruptException from ExecuteTask; route it - // through the same sink as EXECUTION_CANCELLED. + // The stream records an interrupt as an error rather than + // throwing; this is a guard for anything that escapes. return HandleExecutionError(ErrorData(ex)); } switch (exec) { - case StreamExecutionResult::CHUNK_NOT_READY: - case StreamExecutionResult::BLOCKED: - case StreamExecutionResult::NO_TASKS_AVAILABLE: + case QueryResultState::NOT_READY: + case QueryResultState::BLOCKED: + case QueryResultState::NO_TASKS_AVAILABLE: return DUCKDB_V2_RESULT_STEP_STATUS_WAITING; - case StreamExecutionResult::EXECUTION_CANCELLED: - pending.reset(); - result.reset(); - fragments.clear(); - try { - RollbackIncompleteGroup(); - } catch (...) { - // Best effort; cancellation still wins. - } - ReleaseBusySlot(); - state = State::CANCELLED; - return DUCKDB_V2_RESULT_STEP_STATUS_CANCELLED; - case StreamExecutionResult::EXECUTION_ERROR: - return HandleExecutionError(stream.GetErrorObject()); - case StreamExecutionResult::CHUNK_READY: - case StreamExecutionResult::EXECUTION_FINISHED: + case QueryResultState::EXECUTION_ERROR: + return HandleExecutionError(stream->GetErrorObject()); + case QueryResultState::READY: + case QueryResultState::FINISHED: // Both states mean "Fetch without doing more execution - // work": CHUNK_READY has a buffered chunk; after - // EXECUTION_FINISHED the buffer may still hold trailing - // chunks and Fetch drains them until it reports - // end-of-stream. + // work": READY has a buffered chunk; after FINISHED the + // buffer may still hold trailing chunks and Fetch drains + // them until it reports end-of-stream. break; } } - // Fetch the next buffered chunk. For the materialized fallback - // (non-row statements can come back materialized even with - // ALLOW_STREAMING) the data is fully available and every step + // Fetch the next chunk. For a statement that completes before its + // result is returned the data is fully available and every step // lands here directly. unique_ptr chunk; try { - chunk = result->Fetch(); + chunk = stream ? stream->Fetch() : handle->Fetch(); } catch (std::exception &ex) { return HandleExecutionError(ErrorData(ex)); } - if (result->HasError()) { - // StreamQueryResult::Fetch reports late execution errors by - // setting the error and returning null. - return HandleExecutionError(result->GetErrorObject()); + if (stream ? stream->HasError() : handle->HasError()) { + // The stream reports late execution errors by setting the error + // and returning null. + return HandleExecutionError(stream ? stream->GetErrorObject() : handle->GetErrorObject()); } if (!chunk || chunk->size() == 0) { - // Stream results already normalize end-of-stream to null (and - // close) in FetchInternal; the size() == 0 arm is needed for the - // materialized fallback, whose Fetch does not normalize. - result.reset(); + // A stream normalizes end-of-stream to null (and closes); the + // size() == 0 arm is needed for the retained handle, whose Fetch + // does not normalize. + stream.reset(); + handle.reset(); if (fragment_index < fragments.size()) { // More fragments in the group: start the next one and keep // reporting WAITING. FINISHED only after the whole group @@ -278,44 +263,41 @@ void ResultWrapperV2::Wait() { // executability first, the same way the steps do. switch (state) { case State::PENDING: { - // CheckPulse re-validates executability (throwing a clean error when - // the result is closed) and reports the engine state without running - // work. Its outcome decides whether blocking is safe: the engine may - // already have processed an execution error and ended the query - // internally (waiting then dereferences the closed query), and a - // ready or finished query has no task to wake on. - switch (pending->CheckPulse()) { - case PendingExecutionResult::BLOCKED: - case PendingExecutionResult::NO_TASKS_AVAILABLE: + // Poll re-validates executability and reports the engine state + // without running work. Its outcome decides whether blocking is + // safe: the engine may already have processed an execution error and + // ended the query internally (waiting then dereferences the closed + // query), and a ready or finished query has no task to wake on. + switch (handle->Poll()) { + case QueryResultState::BLOCKED: + case QueryResultState::NO_TASKS_AVAILABLE: // No progress possible right now; this is the one case where // blocking is meaningful. - pending->WaitForTask(); + handle->WaitForTask(); return; - case PendingExecutionResult::EXECUTION_ERROR: + case QueryResultState::EXECUTION_ERROR: // The error (interrupts included) is already recorded on the - // pending result and the engine closed the query. Transition the - // state machine now: a later ExecuteTask would trip the engine's + // handle and the engine closed the query. Transition the state + // machine now: a later ExecuteTask would trip the engine's // closed-result check and misreport the error as INVALID_INPUT. - HandleExecutionError(pending->GetErrorObject()); + HandleExecutionError(handle->GetErrorObject()); return; default: - // RESULT_NOT_READY / RESULT_READY / EXECUTION_FINISHED: the next - // step makes progress without blocking. + // NOT_READY / READY / FINISHED: the next step makes progress + // without blocking. return; } } case State::STREAMING: - if (result->GetResultType() == QueryResultType::STREAM_RESULT) { - auto &stream = result->Cast(); - if (!stream.IsOpen()) { + if (stream) { + if (!stream->IsOpen()) { // Closed or invalidated: the next step returns without // blocking, so there is nothing to wait for. return; } - stream.WaitForTask(); + stream->WaitForTask(); } - // Materialized fallback: every step makes progress; nothing to - // wait for. + // A retained result makes progress on every step; nothing to wait for. return; default: // Terminal states: waiting is a no-op, never an error. @@ -359,7 +341,7 @@ auto ExecutePreparedStatementV2(const shared_ptr &context, Prepar identifier_map_t &values) -> duckdb_v2_result_handle { auto wrapper = make_uniq(); // One live result per connection, claimed the way statement_execute claims it and - // before PendingQuery runs, which would otherwise cancel the live stream. + // before the submission runs, which would otherwise cancel the live stream. auto busy_slot = GetBusySlot(*context); void *expected = nullptr; if (!busy_slot->owner.compare_exchange_strong(expected, wrapper.get())) { @@ -374,7 +356,7 @@ auto ExecutePreparedStatementV2(const shared_ptr &context, Prepar // the wrapping transaction all happened at prepare time, so this bypasses the fragment // machinery and is always principal. fragment_count is 1 for metadata symmetry only. wrapper->fragment_count = 1; - wrapper->BeginPending(prepared.PendingQuery(values, /*allow_stream_result=*/true), true); + wrapper->BeginPending(prepared.Submit(values), true); // The engine runs a prepared statement through an internal EXECUTE, whose statement type // would otherwise be what the result reports. Report the type of the statement that was // prepared instead, so a prepared result is indistinguishable from a stateless one. diff --git a/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp b/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp new file mode 100644 index 000000000..fa65fe1fe --- /dev/null +++ b/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp @@ -0,0 +1,14 @@ +#include "duckdb/main/capi_v2/capi_v2_internal.hpp" + +#include "utf8proc_wrapper.hpp" + +using namespace duckdb::capiv2; + +DUCKDB_V2_ERROR duckdb_v2_validate_utf8(duckdb_v2_str text, duckdb_v2_error_info_handle *err) { + return WithErrorHandler(err, [&]() { + auto bytes = Convert(text); + if (!duckdb::Utf8Proc::IsValid(bytes.data(), bytes.size())) { + throw duckdb::InvalidInputException("Input is not valid UTF-8"); + } + }); +} diff --git a/src/duckdb/src/main/capi/v2/capi_v2_vector.cpp b/src/duckdb/src/main/capi/v2/capi_v2_vector.cpp index 47f9bb17f..131130a7a 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_vector.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_vector.cpp @@ -80,7 +80,16 @@ DUCKDB_V2_ERROR duckdb_v2_vector_reference(duckdb_v2_vector_handle vector, duckd duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(vector); DUCKDB_CHECK_ARG(source); - return WithErrorHandler(err, [&]() { Convert(vector)->Reference(*Convert(source)); }); + return WithErrorHandler(err, [&]() { + auto *vec = Convert(vector); + auto *src = Convert(source); + // The engine reports a mismatch as an INTERNAL error, and only by type id. + if (vec->GetType() != src->GetType()) { + throw duckdb::InvalidInputException( + "duckdb_v2_vector_reference: source type does not match the vector's logical type"); + } + vec->Reference(*src); + }); } // --------------------------------------------------------------------------- diff --git a/src/duckdb/src/main/chunk_scan_state/query_result.cpp b/src/duckdb/src/main/chunk_scan_state/query_result.cpp index 76a172dd2..877e61d7b 100644 --- a/src/duckdb/src/main/chunk_scan_state/query_result.cpp +++ b/src/duckdb/src/main/chunk_scan_state/query_result.cpp @@ -1,5 +1,4 @@ #include "duckdb/main/query_result.hpp" -#include "duckdb/main/stream_query_result.hpp" #include "duckdb/main/chunk_scan_state/query_result.hpp" namespace duckdb { @@ -12,13 +11,7 @@ QueryResultChunkScanState::~QueryResultChunkScanState() { bool QueryResultChunkScanState::InternalLoad(ErrorData &error) { D_ASSERT(!finished); - if (result.GetResultType() == QueryResultType::STREAM_RESULT) { - auto &stream_result = result.Cast(); - if (!stream_result.IsOpen()) { - return true; - } - } - return result.TryFetch(current_chunk, error); + return result.TryFetchOrError(current_chunk, error); } bool QueryResultChunkScanState::HasError() const { diff --git a/src/duckdb/src/main/chunk_scan_state/query_result_stream.cpp b/src/duckdb/src/main/chunk_scan_state/query_result_stream.cpp new file mode 100644 index 000000000..ceb6a4faa --- /dev/null +++ b/src/duckdb/src/main/chunk_scan_state/query_result_stream.cpp @@ -0,0 +1,65 @@ +#include "duckdb/main/chunk_scan_state/query_result_stream.hpp" +#include "duckdb/main/query_result_stream.hpp" + +namespace duckdb { + +QueryResultStreamChunkScanState::QueryResultStreamChunkScanState(QueryResultStream &stream) + : ChunkScanState(), stream(stream) { +} + +QueryResultStreamChunkScanState::~QueryResultStreamChunkScanState() { +} + +bool QueryResultStreamChunkScanState::LoadNextChunk(ErrorData &error_p) { + if (finished) { + current_chunk = nullptr; + if (has_error) { + error_p = error; + } + return !has_error; + } + try { + current_chunk = stream.Fetch(); + } catch (std::exception &ex) { + current_chunk = nullptr; + finished = true; + has_error = true; + error = ErrorData(ex); + error_p = error; + return false; + } + offset = 0; + if (!current_chunk) { + finished = true; + // The stream reports an execution error as an end of stream with the error recorded on it + if (stream.HasError()) { + has_error = true; + error = stream.GetErrorObject(); + error_p = error; + return false; + } + } + return true; +} + +bool QueryResultStreamChunkScanState::HasError() const { + return has_error || stream.HasError(); +} + +ErrorData &QueryResultStreamChunkScanState::GetError() { + if (!has_error) { + has_error = true; + error = stream.GetErrorObject(); + } + return error; +} + +const vector &QueryResultStreamChunkScanState::Types() const { + return stream.GetTypes(); +} + +const vector &QueryResultStreamChunkScanState::Names() const { + return stream.GetNames(); +} + +} // namespace duckdb diff --git a/src/duckdb/src/main/client_context.cpp b/src/duckdb/src/main/client_context.cpp index a7b9796a3..c09f111d0 100644 --- a/src/duckdb/src/main/client_context.cpp +++ b/src/duckdb/src/main/client_context.cpp @@ -12,7 +12,10 @@ #include "duckdb/common/types/uuid.hpp" #include "duckdb/execution/column_binding_resolver.hpp" #include "duckdb/execution/operator/helper/physical_result_collector.hpp" +#include "duckdb/execution/operator/helper/physical_result_sink.hpp" #include "duckdb/execution/physical_plan_generator.hpp" +#include "duckdb/main/buffered_data/batched_buffered_data.hpp" +#include "duckdb/main/buffered_data/simple_buffered_data.hpp" #include "duckdb/main/appender.hpp" #include "duckdb/main/attached_database.hpp" #include "duckdb/main/client_context_file_opener.hpp" @@ -23,11 +26,9 @@ #include "duckdb/main/statement_iterator.hpp" #include "duckdb/main/error_manager.hpp" #include "duckdb/main/parse_iterator.hpp" -#include "duckdb/main/materialized_query_result.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/main/query_result.hpp" #include "duckdb/main/relation.hpp" -#include "duckdb/main/stream_query_result.hpp" #include "duckdb/optimizer/optimizer.hpp" #include "duckdb/parser/expression/constant_expression.hpp" #include "duckdb/parser/expression/function_expression.hpp" @@ -292,6 +293,18 @@ void ClientContext::ProcessError(ErrorData &error, const string &query) const { template unique_ptr ClientContext::ErrorResult(ErrorData error, const string &query) { + bool invalidates_transaction = true; + if (!ErrorInvalidatesTransaction(error.Type())) { + // standard exceptions don't invalidate the transaction + invalidates_transaction = false; + } else if (Exception::InvalidatesDatabase(error.Type())) { + auto &db_instance = DatabaseInstance::GetDatabase(*this); + ValidChecker::Invalidate(db_instance, error.RawMessage()); + } + if (invalidates_transaction && HasActiveTransaction()) { + ValidChecker::Invalidate(ActiveTransaction(), error.RawMessage()); + } + ProcessError(error, query); return make_uniq(std::move(error)); } @@ -362,7 +375,11 @@ ErrorData ClientContext::EndQueryInternal(ClientContextLock &lock, bool success, } } else if (invalidate_transaction) { D_ASSERT(!success); - ValidChecker::Invalidate(ActiveTransaction(), "Failed to commit"); + if (transaction.GetAutoRollback()) { + transaction.Rollback(previous_error); + } else { + ValidChecker::Invalidate(ActiveTransaction(), "Failed to commit"); + } } } } catch (std::exception &ex) { @@ -400,6 +417,11 @@ void ClientContext::CleanupInternal(ClientContextLock &lock, BaseQueryResult *re return; } if (active_query->executor) { + // Read before CancelTasks clears the slot, and while the profiler is still running + auto buffer = active_query->executor->GetResultBuffer(); + if (buffer) { + QueryProfiler::Get(*this).SetStreamingPeakBufferSize(buffer->PeakBufferedBytes()); + } active_query->executor->CancelTasks(); } active_query->progress_bar.reset(); @@ -408,14 +430,6 @@ void ClientContext::CleanupInternal(ClientContextLock &lock, BaseQueryResult *re auto &scheduler = TaskScheduler::GetScheduler(*this); scheduler.RelaunchThreads(); - if (result && result->GetResultType() == QueryResultType::STREAM_RESULT) { - // Record the streaming buffer peak while the profiler is still running - auto &stream_result = static_cast(*result); - if (stream_result.HasBufferedData()) { - QueryProfiler::Get(*this).SetStreamingPeakBufferSize(stream_result.GetBufferedData().PeakBufferedBytes()); - } - } - optional_ptr passed_error = nullptr; if (result && result->HasError()) { passed_error = result->GetErrorObject(); @@ -447,25 +461,6 @@ connection_t ClientContext::GetConnectionId() const { return connection_id; } -unique_ptr ClientContext::FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending) { - D_ASSERT(active_query); - D_ASSERT(active_query->IsOpenResult(pending)); - D_ASSERT(active_query->prepared); - auto &executor = GetExecutor(); - // A streaming request always plans a streaming sink, so the collector alone decides - const bool keep_result_open = executor.HasStreamingResultCollector(); - unique_ptr result; - D_ASSERT(executor.HasResultCollector()); - // we have a result collector - fetch the result directly from the result collector - result = executor.GetResult(); - if (!keep_result_open) { - CleanupInternal(lock, result.get(), false); - } else { - active_query->SetOpenResult(*result); - } - return result; -} - static bool IsExplainAnalyze(SQLStatement *statement) { if (!statement) { return false; @@ -479,15 +474,15 @@ static bool IsExplainAnalyze(SQLStatement *statement) { shared_ptr ClientContext::CreatePreparedStatementInternal(ClientContextLock &lock, unique_ptr statement, - PendingQueryParameters parameters) { + const QueryParameters ¶meters) { StatementType statement_type = statement->type; auto result = make_shared_ptr(statement_type); auto &profiler = QueryProfiler::Get(*this); profiler.StartQuery(statement->query, IsExplainAnalyze(statement.get())); Planner logical_planner(*this); - if (parameters.parameters) { - auto ¶meter_values = *parameters.parameters; + if (parameters.statement_args) { + auto ¶meter_values = *parameters.statement_args; for (auto &value : parameter_values) { logical_planner.parameter_data.emplace(value.first, BoundParameterData(value.second)); } @@ -547,7 +542,7 @@ shared_ptr ClientContext::CreatePreparedStatementInternal shared_ptr ClientContext::CreatePreparedStatement(ClientContextLock &lock, unique_ptr statement, - PendingQueryParameters parameters) { + const QueryParameters ¶meters) { // check if any client context state could request a rebind bool can_request_rebind = false; for (auto &state : registered_state->States()) { @@ -597,10 +592,10 @@ QueryProgress ClientContext::GetQueryProgress() { } void BindPreparedStatementParameters(ClientContext &context, PreparedStatementData &statement, - const PendingQueryParameters ¶meters) { + const QueryParameters ¶meters) { identifier_map_t owned_values; - if (parameters.parameters) { - auto ¶ms = *parameters.parameters; + if (parameters.statement_args) { + auto ¶ms = *parameters.statement_args; for (auto &val : params) { owned_values.emplace(val); } @@ -631,10 +626,8 @@ void ClientContext::CheckIfPreparedStatementIsExecutable(PreparedStatementData & } } -unique_ptr -ClientContext::PendingPreparedStatementInternal(ClientContextLock &lock, - shared_ptr statement_data_p, - const PendingQueryParameters ¶meters) { +unique_ptr ClientContext::SubmitPreparedStatementInternal( + ClientContextLock &lock, shared_ptr statement_data_p, const QueryParameters ¶meters) { D_ASSERT(active_query); auto &statement_data = *statement_data_p; BindPreparedStatementParameters(*this, statement_data, parameters); @@ -656,33 +649,83 @@ ClientContext::PendingPreparedStatementInternal(ClientContextLock &lock, query_progress.Restart(); } - const auto stream_result = parameters.query_parameters.output_type == QueryResultOutputType::ALLOW_STREAMING && - statement_data.properties.output_type == QueryResultOutputType::ALLOW_STREAMING; + statement_data.memory_type = parameters.memory_type; // Decide how to get the result collector. get_result_collector_t get_collector = PhysicalResultCollector::GetResultCollector; auto &client_config = ClientConfig::GetConfig(*this); - if (!stream_result && client_config.get_result_collector) { + if (client_config.get_result_collector) { get_collector = client_config.get_result_collector; } - statement_data.output_type = - stream_result ? QueryResultOutputType::ALLOW_STREAMING : QueryResultOutputType::FORCE_MATERIALIZED; - statement_data.memory_type = parameters.query_parameters.memory_type; // Get the result collector and initialize the executor. auto collector = get_collector(*this, statement_data); D_ASSERT(collector->type == PhysicalOperatorType::RESULT_COLLECTOR); + // A custom hook can hand back the default sink, which is then served like any other query + const bool delegating = collector->Cast().BuildsOwnResult(); + + // The buffer is created here, on the client thread, and handed to the sink, the executor and the + // handle. It carries the retention decision, so it exists for every query the sink serves + shared_ptr buffer; + if (!delegating) { + auto &sink = collector->Cast(); + if (sink.ordering == ResultOrdering::BATCH_INDEX_ORDERED) { + buffer = make_shared_ptr(*this, sink.lifetime); + } else { + buffer = make_shared_ptr(*this, sink.lifetime); + } + if (parameters.result_eagerness == ResultEagerness::FORCED || + statement_data.properties.result_eagerness == ResultEagerness::FORCED) { + // Settled before execution starts, so no producer ever parks for the decision + buffer->Decide(ResultLifetime::RETAINED); + } + sink.SetResultBuffer(buffer); + } + executor.SetResultBuffer(buffer); + + // Read before Initialize starts the workers: a SET statement writes the settings from a task + auto client_properties = GetClientProperties(); + auto types = statement_data.types; executor.Initialize(std::move(collector)); - auto types = executor.GetTypes(); - D_ASSERT(types == statement_data.types); + D_ASSERT(executor.GetTypes() == statement_data.types); D_ASSERT(!active_query->HasOpenResult()); - auto pending_result = - make_uniq(shared_from_this(), *statement_data_p, std::move(types), stream_result); + auto result = make_uniq(shared_from_this(), *statement_data_p, std::move(types), + std::move(client_properties), std::move(buffer)); active_query->prepared = std::move(statement_data_p); - active_query->SetOpenResult(*pending_result); - return pending_result; + active_query->SetOpenResult(*result); + if (delegating) { + // The collector builds its own result object: run the query and hand that object out. The + // handle is released first, so destroying it never takes the context lock held here + result->context.reset(); + auto produced = CompleteDelegatedInternal(lock, *result); + if (produced) { + return produced; + } + } + return result; +} + +unique_ptr ClientContext::CompleteDelegatedInternal(ClientContextLock &lock, QueryResult &result) { + QueryResultState state; + while (!IsObservable(state = ExecuteTaskInternal(lock, result))) { + if (state == QueryResultState::BLOCKED) { + WaitForTask(lock, result); + } + } + if (result.HasError()) { + // The error is on the handle, which the caller hands out instead + return nullptr; + } + auto &executor = GetExecutor(); + auto produced = executor.GetResult(); + if (executor.HasStreamingResultCollector()) { + active_query->SetOpenResult(*produced); + } else { + CleanupInternal(lock, produced.get(), false); + } + return produced; } void ClientContext::WaitForTask(ClientContextLock &lock, BaseQueryResult &result) { @@ -704,52 +747,68 @@ bool ClientContext::ErrorInvalidatesTransaction(ExceptionType type) { } } -PendingExecutionResult ClientContext::ExecuteTaskInternal(ClientContextLock &lock, BaseQueryResult &result, - bool dry_run) { +QueryResultState ClientContext::ExecuteTaskInternal(ClientContextLock &lock, BaseQueryResult &result) { D_ASSERT(active_query); D_ASSERT(active_query->IsOpenResult(result)); - bool invalidate_transaction = true; try { // Surface a pending interrupt even when this thread runs no task that reaches InterruptCheck. // IsInterrupted() rather than InterruptCheck(): we must not enforce query_deadline here. - if (!dry_run && IsInterrupted()) { + if (IsInterrupted()) { throw InterruptException(); } - auto query_result = active_query->executor->ExecuteTask(dry_run); - if (active_query->progress_bar) { - auto is_finished = PendingQueryResult::IsResultReady(query_result); - active_query->progress_bar->Update(is_finished); - query_progress = active_query->progress_bar->GetDetailedQueryProgress(); - } - return query_result; + auto state = active_query->executor->ExecuteTask(); + UpdateProgressInternal(state); + return state; } catch (std::exception &ex) { - auto error = ErrorData(ex); - if (error.Type() == ExceptionType::INTERRUPT) { - auto &executor = *active_query->executor; - if (!executor.HasError()) { - // Interrupted by the user - result.SetError(ex); - invalidate_transaction = true; - } else { - // Interrupted by an exception caused in a worker thread - error = executor.GetError(); - invalidate_transaction = ErrorInvalidatesTransaction(error.Type()); - result.SetError(error); - } - } else if (!ErrorInvalidatesTransaction(error.Type())) { - invalidate_transaction = false; - } else if (Exception::InvalidatesDatabase(error.Type()) || error.Type() == ExceptionType::INTERNAL) { - // fatal exceptions invalidate the entire database - auto &db_instance = DatabaseInstance::GetDatabase(*this); - ValidChecker::Invalidate(db_instance, error.RawMessage()); - } - ProcessError(error, active_query->query); - result.SetError(std::move(error)); + return FailQueryInternal(lock, result, ErrorData(ex)); + } catch (...) { // LCOV_EXCL_START + return FailQueryInternal(lock, result, ErrorData("Unhandled exception in ExecuteTaskInternal")); + } // LCOV_EXCL_STOP +} + +QueryResultState ClientContext::PollInternal(ClientContextLock &lock, BaseQueryResult &result) { + D_ASSERT(active_query); + D_ASSERT(active_query->IsOpenResult(result)); + try { + auto state = active_query->executor->Poll(); + UpdateProgressInternal(state); + return state; + } catch (std::exception &ex) { + return FailQueryInternal(lock, result, ErrorData(ex)); } catch (...) { // LCOV_EXCL_START - result.SetError(ErrorData("Unhandled exception in ExecuteTaskInternal")); + return FailQueryInternal(lock, result, ErrorData("Unhandled exception in PollInternal")); } // LCOV_EXCL_STOP +} + +void ClientContext::UpdateProgressInternal(QueryResultState state) { + if (!active_query->progress_bar) { + return; + } + // todo: this is not correct for streaming results + active_query->progress_bar->Update(IsObservable(state)); + query_progress = active_query->progress_bar->GetDetailedQueryProgress(); +} + +QueryResultState ClientContext::FailQueryInternal(ClientContextLock &lock, BaseQueryResult &result, ErrorData error) { + bool invalidate_transaction = true; + if (error.Type() == ExceptionType::INTERRUPT) { + auto &executor = *active_query->executor; + if (executor.HasError()) { + // Interrupted by an exception caused in a worker thread + error = executor.GetError(); + invalidate_transaction = ErrorInvalidatesTransaction(error.Type()); + } + } else if (!ErrorInvalidatesTransaction(error.Type())) { + invalidate_transaction = false; + } else if (Exception::InvalidatesDatabase(error.Type()) || error.Type() == ExceptionType::INTERNAL) { + // fatal exceptions invalidate the entire database + auto &db_instance = DatabaseInstance::GetDatabase(*this); + ValidChecker::Invalidate(db_instance, error.RawMessage()); + } + ProcessError(error, active_query->query); + result.SetError(std::move(error)); EndQueryInternal(lock, false, invalidate_transaction, result.GetErrorObject()); - return PendingExecutionResult::EXECUTION_ERROR; + return QueryResultState::EXECUTION_ERROR; } void ClientContext::InitialCleanup(ClientContextLock &lock) { @@ -861,8 +920,8 @@ unique_ptr ClientContext::PrepareInternal(ClientContextLock & prepare->stmt_location = statement->stmt_location; prepare->statement = std::move(statement); - PendingQueryParameters parameters; - parameters.query_parameters.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + QueryParameters parameters; + parameters.result_eagerness = ResultEagerness::FORCED; auto result = RunStatementInternal(lock, std::move(prepare), parameters, false); if (result->HasError()) { result->ThrowError(); @@ -958,12 +1017,12 @@ unique_ptr ClientContext::Prepare(const string &query) { } } -unique_ptr ClientContext::PendingStatementInternal(ClientContextLock &lock, - unique_ptr statement, - const PendingQueryParameters ¶meters) { +unique_ptr ClientContext::SubmitStatementInternal(ClientContextLock &lock, + unique_ptr statement, + const QueryParameters ¶meters) { // prepare the query for execution - if (!statement->named_param_map.empty() && parameters.parameters) { - PreparedStatement::VerifyParameters(*parameters.parameters, statement->named_param_map, this); + if (!statement->named_param_map.empty() && parameters.statement_args) { + PreparedStatement::VerifyParameters(*parameters.statement_args, statement->named_param_map, this); } else if (!statement->named_param_map.empty()) { identifier_map_t empty_parameters; PreparedStatement::VerifyParameters(empty_parameters, statement->named_param_map, this); @@ -972,20 +1031,25 @@ unique_ptr ClientContext::PendingStatementInternal(ClientCon auto prepared = CreatePreparedStatement(lock, std::move(statement), parameters); if (!prepared->properties.bound_all_parameters) { - return ErrorResult(InvalidInputException("Not all parameters were bound")); + return ErrorResult(InvalidInputException("Not all parameters were bound")); } // execute the prepared statement CheckIfPreparedStatementIsExecutable(*prepared); - return PendingPreparedStatementInternal(lock, std::move(prepared), parameters); + return SubmitPreparedStatementInternal(lock, std::move(prepared), parameters); } unique_ptr ClientContext::RunStatementInternal(ClientContextLock &lock, unique_ptr statement, - const PendingQueryParameters ¶meters, bool verify) { - auto pending = PendingQueryInternal(lock, std::move(statement), parameters, verify); - if (pending->HasError()) { - return ErrorResult(pending->GetErrorObject()); + const QueryParameters ¶meters, bool verify) { + auto result = SubmitInternal(lock, std::move(statement), parameters, verify); + if (result->HasError()) { + return result; } - return ExecutePendingQueryInternal(lock, *pending); + return CompleteInternal(lock, std::move(result)); +} + +unique_ptr ClientContext::CompleteInternal(ClientContextLock &lock, unique_ptr result) { + result->CompleteInternal(lock); + return result; } bool ClientContext::IsActiveResult(ClientContextLock &lock, BaseQueryResult &result) { @@ -1003,17 +1067,16 @@ static bool HasBoundParameterValues(const SQLStatement &statement) { return !statement.Cast().bound_values.empty(); } -unique_ptr ClientContext::PendingStatement(ClientContextLock &lock, - unique_ptr statement, - const PendingQueryParameters ¶meters) { +unique_ptr ClientContext::SubmitStatement(ClientContextLock &lock, unique_ptr statement, + const QueryParameters ¶meters) { // CONNECT chokepoint: when connected, non-control SQL is rewritten in place and falls through to - // the normal pipeline. No recursion — the rewrite goes through PendingStatementInternal, not back here. + // the normal pipeline. No recursion — the rewrite goes through SubmitStatementInternal, not back here. if (is_connected) { if (!IsConnectControlStatement(statement->type)) { // Parameterized prepared statements would need parameter substitution we don't do in v0 — reject. // No-param prepared statements have a fully-resolved `query` already, route them. if (HasBoundParameterValues(*statement)) { - return ErrorResult( + return ErrorResult( ErrorData(InvalidInputException("Parameterized prepared statements cannot be executed while " "CONNECT-ed; DISCONNECT first, or run the SQL as a fresh " "statement to route through the CONNECT binding")), @@ -1022,7 +1085,7 @@ unique_ptr ClientContext::PendingStatement(ClientContextLock auto live = TryGetConnectedCatalog(); if (!live) { // Target was detached elsewhere; user must explicitly DISCONNECT to clear is_connected. - return ErrorResult( + return ErrorResult( ErrorData(InvalidInputException( "The connected database has been detached out from under this connection. Issue " "DISCONNECT to clear the connection before running further SQL.")), @@ -1039,9 +1102,9 @@ unique_ptr ClientContext::PendingStatement(ClientContextLock // statement is now SELECT * FROM ; fall through. } } - // the statement is moved into PendingStatementInternal - keep the source text for error reporting + // the statement is moved into SubmitStatementInternal - keep the source text for error reporting auto query = statement->query; - unique_ptr pending; + unique_ptr result; try { BeginQueryInternal(lock, *statement); } catch (std::exception &ex) { @@ -1051,12 +1114,12 @@ unique_ptr ClientContext::PendingStatement(ClientContextLock auto &db_instance = DatabaseInstance::GetDatabase(*this); ValidChecker::Invalidate(db_instance, error.RawMessage()); } - return ErrorResult(std::move(error), query); + return ErrorResult(std::move(error), query); } bool invalidate_query = true; try { - pending = PendingStatementInternal(lock, std::move(statement), parameters); + result = SubmitStatementInternal(lock, std::move(statement), parameters); } catch (std::exception &ex) { ErrorData error(ex); if (!ErrorInvalidatesTransaction(error.Type())) { @@ -1068,15 +1131,19 @@ unique_ptr ClientContext::PendingStatement(ClientContextLock ValidChecker::Invalidate(db_instance, error.RawMessage()); } // other types of exceptions do invalidate the current transaction - pending = ErrorResult(std::move(error), query); + result = ErrorResult(std::move(error), query); } - if (pending->HasError()) { - // query failed: abort now - EndQueryInternal(lock, false, invalidate_query, pending->GetErrorObject()); - return pending; + if (result->HasError()) { + // query failed: abort now, unless a delegated collector's execution already ended it + if (active_query) { + EndQueryInternal(lock, false, invalidate_query, result->GetErrorObject()); + } + return result; } - D_ASSERT(active_query->IsOpenResult(*pending)); - return pending; + // A collector that builds its own result object finishes the query inside the submission, so + // the query it belonged to may already be gone + D_ASSERT(!active_query || active_query->IsOpenResult(*result)); + return result; } void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) { @@ -1101,14 +1168,21 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) { } unique_ptr ClientContext::Query(unique_ptr statement, QueryParameters parameters) { - auto pending_query = PendingQuery(std::move(statement), parameters); - if (pending_query->HasError()) { + auto lock = LockContext(); + parameters.result_eagerness = ResultEagerness::FORCED; + try { + InitialCleanup(*lock); + } catch (std::exception &ex) { + return ErrorResult(ErrorData(ex), statement->query); + } + auto result = SubmitInternal(*lock, std::move(statement), parameters, true); + if (result->HasError()) { if (transaction.HasActiveTransaction() && transaction.GetAutoRollback()) { - transaction.Rollback(pending_query->GetErrorObject()); + transaction.Rollback(result->GetErrorObject()); } - return ErrorResult(pending_query->GetErrorObject()); + return result; } - return pending_query->Execute(); + return CompleteInternal(*lock, std::move(result)); } unique_ptr ClientContext::Query(const string &query, QueryParameters query_parameters) { @@ -1126,7 +1200,7 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter iterator_storage = make_uniq(ParseIterator(*this, query)); iterator_ptr = *iterator_storage; } catch (const std::exception &ex) { - return ErrorResult(ErrorData(ex), query); + return ErrorResult(ErrorData(ex), query); } auto &iterator = *iterator_ptr; @@ -1135,7 +1209,7 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter has_now = iterator.Peek(); return nullptr; } catch (const std::exception &ex) { - return ErrorResult(ErrorData(ex), query); + return ErrorResult(ErrorData(ex), query); } }; @@ -1148,8 +1222,8 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter StatementProperties properties; vector names; auto collection = make_uniq(Allocator::DefaultAllocator()); - return make_uniq(StatementType::INVALID_STATEMENT, properties, std::move(names), - std::move(collection), GetClientProperties()); + return make_uniq(StatementType::INVALID_STATEMENT, properties, std::move(names), + std::move(collection), GetClientProperties()); } unique_ptr result; @@ -1164,7 +1238,7 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter try { statement = iterator.GetStatementForExecutionWithLock(*lock); } catch (const std::exception &ex) { - return ErrorResult(ErrorData(ex), query); + return ErrorResult(ErrorData(ex), query); } // Look ahead WITHOUT parsing: HasMore() only walks the token cursor, so it never parses (and @@ -1173,20 +1247,19 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter // register grammar (e.g. LOAD an extension) that a following statement then uses. bool has_next = iterator.HasMore(); + if (has_next && query_parameters.statement_args && !query_parameters.statement_args->empty()) { + return ErrorResult( + ErrorData(InvalidInputException("Cannot prepare multiple statements at once!")), query); + } if (statement) { - bool is_last_overall = !has_next; - PendingQueryParameters parameters; - parameters.query_parameters = query_parameters; - if (!is_last_overall) { - parameters.query_parameters.output_type = QueryResultOutputType::FORCE_MATERIALIZED; - } - auto pending_query = PendingQueryInternal(*lock, std::move(statement), parameters); - auto has_result = pending_query->GetStatementProperties().return_type == StatementReturnType::QUERY_RESULT; - unique_ptr current_result; - if (pending_query->HasError()) { - current_result = ErrorResult(pending_query->GetErrorObject()); - } else { - current_result = ExecutePendingQueryInternal(*lock, *pending_query); + auto parameters = query_parameters; + // Every statement of an eager query completes before the call returns, so none of them + // leaves a producer parked for the consumer's choice + parameters.result_eagerness = ResultEagerness::FORCED; + auto current_result = SubmitInternal(*lock, std::move(statement), parameters); + auto has_result = current_result->GetStatementProperties().return_type == StatementReturnType::QUERY_RESULT; + if (!current_result->HasError()) { + current_result = CompleteInternal(*lock, std::move(current_result)); } if (current_result->HasError()) { if (transaction.HasActiveTransaction() && transaction.GetAutoRollback()) { @@ -1216,27 +1289,7 @@ unique_ptr ClientContext::Query(const string &query, QueryParameter return result; } -unique_ptr ClientContext::PendingQuery(const string &query, QueryParameters parameters) { - identifier_map_t empty_param_list; - return PendingQuery(query, empty_param_list, parameters); -} - -unique_ptr ClientContext::PendingQuery(unique_ptr statement, - QueryParameters parameters) { - identifier_map_t empty_param_list; - return PendingQuery(std::move(statement), empty_param_list, parameters); -} - -unique_ptr ClientContext::PendingQuery(const string &query, - identifier_map_t &values, - QueryParameters parameters) { - PendingQueryParameters params; - params.parameters = values; - params.query_parameters = parameters; - return PendingQuery(query, params); -} - -unique_ptr ClientContext::PendingQuery(const string &query, PendingQueryParameters parameters) { +unique_ptr ClientContext::Submit(const string &query, const QueryParameters ¶meters) { auto lock = LockContext(); try { InitialCleanup(*lock); @@ -1249,74 +1302,73 @@ unique_ptr ClientContext::PendingQuery(const string &query, throw InvalidInputException("Cannot prepare multiple statements at once!"); } - return PendingQueryInternal(*lock, std::move(statements[0]), parameters, true); + return SubmitInternal(*lock, std::move(statements[0]), parameters, true); } catch (std::exception &ex) { ErrorData error(ex); ProcessError(error, query); - return make_uniq(std::move(error)); + return make_uniq(std::move(error)); } } -unique_ptr ClientContext::PendingQuery(unique_ptr statement, - identifier_map_t &values, - QueryParameters parameters) { +unique_ptr ClientContext::Submit(unique_ptr statement, const QueryParameters ¶meters) { auto lock = LockContext(); try { InitialCleanup(*lock); - PendingQueryParameters params; - params.query_parameters = parameters; - params.parameters = values; - - return PendingQueryInternal(*lock, std::move(statement), params, true); + return SubmitInternal(*lock, std::move(statement), parameters, true); } catch (std::exception &ex) { - return make_uniq(ErrorData(ex)); + return make_uniq(ErrorData(ex)); } } +unique_ptr ClientContext::Submit(const string &query, identifier_map_t &values, + QueryParameters parameters) { + parameters.statement_args = values; + return Submit(query, parameters); +} + +unique_ptr ClientContext::Submit(unique_ptr statement, + identifier_map_t &values, + QueryParameters parameters) { + parameters.statement_args = values; + return Submit(std::move(statement), parameters); +} + unique_ptr ClientContext::RunInternalStatement(unique_ptr statement, - const PendingQueryParameters ¶meters) { + const QueryParameters ¶meters) { auto lock = LockContext(); try { InitialCleanup(*lock); } catch (std::exception &ex) { - return ErrorResult(ErrorData(ex), statement->query); - } - auto pending = PendingQueryInternal(*lock, std::move(statement), parameters, false); - if (pending->HasError()) { - return ErrorResult(pending->GetErrorObject()); + return ErrorResult(ErrorData(ex), statement->query); } - return pending->ExecuteInternal(*lock); + QueryParameters params = parameters; + params.result_eagerness = ResultEagerness::FORCED; + return RunStatementInternal(*lock, std::move(statement), params, false); } -unique_ptr ClientContext::PendingInternalStatement(unique_ptr statement, - const PendingQueryParameters ¶meters) { +unique_ptr ClientContext::SubmitInternalStatement(unique_ptr statement, + const QueryParameters ¶meters) { auto lock = LockContext(); try { InitialCleanup(*lock); } catch (std::exception &ex) { - return ErrorResult(ErrorData(ex), statement->query); + return ErrorResult(ErrorData(ex), statement->query); } - return PendingQueryInternal(*lock, std::move(statement), parameters, false); + return SubmitInternal(*lock, std::move(statement), parameters, false); } -unique_ptr ClientContext::PendingQueryInternal(ClientContextLock &lock, - unique_ptr statement, - const PendingQueryParameters ¶meters, - bool verify) { +unique_ptr ClientContext::SubmitInternal(ClientContextLock &lock, unique_ptr statement, + const QueryParameters ¶meters, bool verify) { if (verify) { try { StatementVerification(lock, statement, parameters); } catch (std::exception &ex) { // preserve extra error data (like query location) - return ErrorResult(ErrorData(ex), statement->query); + return ErrorResult(ErrorData(ex), statement->query); } } - return PendingStatement(lock, std::move(statement), parameters); -} - -unique_ptr ClientContext::ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query) { - return query.ExecuteInternal(lock); + return SubmitStatement(lock, std::move(statement), parameters); } void ClientContext::Interrupt() { @@ -1450,8 +1502,8 @@ void ClientContext::RunTransactionStatement(const TransactionInfo &info) { if (is_connected) { auto statement = make_uniq(info.Copy()); statement->query = info.ToString(); - PendingQueryParameters parameters; - parameters.query_parameters.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + QueryParameters parameters; + parameters.result_eagerness = ResultEagerness::FORCED; auto result = RunStatementInternal(*lock, std::move(statement), parameters); if (result->HasError()) { if (transaction.HasActiveTransaction() && transaction.GetAutoRollback()) { @@ -1538,7 +1590,7 @@ unique_ptr ClientContext::TableInfo(const Identifier &schema_n } void ClientContext::Append(unique_ptr stmt) { - auto result = Query(std::move(stmt), false); + auto result = Query(std::move(stmt), QueryParameters()); if (result->HasError()) { result->GetErrorObject().Throw("Failed to append: "); } @@ -1596,9 +1648,8 @@ unordered_set ClientContext::GetTableNames(const string &query, const bo return result; } -unique_ptr ClientContext::PendingQueryInternal(ClientContextLock &lock, - const shared_ptr &relation, - QueryParameters query_parameters) { +unique_ptr ClientContext::SubmitInternal(ClientContextLock &lock, const shared_ptr &relation, + const QueryParameters &query_parameters) { InitialCleanup(lock); #ifdef DEBUG @@ -1608,27 +1659,28 @@ unique_ptr ClientContext::PendingQueryInternal(ClientContext #endif auto relation_stmt = make_uniq(relation); - PendingQueryParameters parameters; - parameters.query_parameters = query_parameters; - return PendingQueryInternal(lock, std::move(relation_stmt), parameters); + return SubmitInternal(lock, std::move(relation_stmt), query_parameters); } -unique_ptr ClientContext::PendingQuery(const shared_ptr &relation, - QueryParameters query_parameters) { +unique_ptr ClientContext::Submit(const shared_ptr &relation, + const QueryParameters &query_parameters) { auto lock = LockContext(); - return PendingQueryInternal(*lock, relation, query_parameters); + return SubmitInternal(*lock, relation, query_parameters); } unique_ptr ClientContext::Execute(const shared_ptr &relation) { auto lock = LockContext(); auto &expected_columns = relation->Columns(); - auto pending = PendingQueryInternal(*lock, relation, false); - if (pending->HasError()) { - return ErrorResult(pending->GetErrorObject()); - } + InitialCleanup(*lock); - unique_ptr result; - result = ExecutePendingQueryInternal(*lock, *pending); + auto relation_stmt = make_uniq(relation); + QueryParameters parameters; + parameters.result_eagerness = ResultEagerness::FORCED; + auto result = SubmitInternal(*lock, std::move(relation_stmt), parameters); + if (result->HasError()) { + return result; + } + result = CompleteInternal(*lock, std::move(result)); if (result->HasError()) { return result; } @@ -1661,7 +1713,7 @@ unique_ptr ClientContext::Execute(const shared_ptr &relat err_str += result->ColumnName(i) + " " + result->GetTypes()[i].ToString(); } err_str += "]"; - return ErrorResult(ErrorData(err_str)); + return ErrorResult(ErrorData(err_str)); } SettingLookupResult ClientContext::TryGetCurrentSetting(const Identifier &key, Value &result) const { @@ -1695,7 +1747,6 @@ ParserOptions ClientContext::GetParserOptions() { ParserOptions options; options.identifier_case_mode = Settings::Get(*this); options.integer_division = Settings::Get(*this); - options.heap_based_parser = Settings::Get(*this); options.regex_match_operator_semantics = Settings::Get(*this); options.max_expression_depth = Settings::Get(*this); options.extensions = DBConfig::GetConfig(*this).GetCallbackManager(); diff --git a/src/duckdb/src/main/client_data.cpp b/src/duckdb/src/main/client_data.cpp index cde8488f9..9dd8937a6 100644 --- a/src/duckdb/src/main/client_data.cpp +++ b/src/duckdb/src/main/client_data.cpp @@ -234,6 +234,7 @@ class ClientBufferManager : public BufferManager { ClientData::ClientData(ClientContext &context) : catalog_search_path(make_uniq(context)) { auto &db = DatabaseInstance::GetDatabase(context); + default_database = DatabaseManager::Get(db).GetDefaultDatabase(); profiler = make_shared_ptr(context); temporary_objects = make_shared_ptr(db, AttachedDatabaseType::TEMP_DATABASE); temporary_objects->oid = DatabaseManager::Get(db).NextOid(); diff --git a/src/duckdb/src/main/client_verify.cpp b/src/duckdb/src/main/client_verify.cpp index 92741cd25..31fb8ab3e 100644 --- a/src/duckdb/src/main/client_verify.cpp +++ b/src/duckdb/src/main/client_verify.cpp @@ -74,7 +74,7 @@ static void ReplaceStatement(unique_ptr &statement, unique_ptr &statement, - PendingQueryParameters query_parameters) { + QueryParameters query_parameters) { auto verification = Settings::Get(*this); if (verification == DebugStatementVerification::COPY_STATEMENT) { if (statement->type == StatementType::LOGICAL_PLAN_STATEMENT) { @@ -188,7 +188,7 @@ void ClientContext::StatementVerification(ClientContextLock &lock, unique_ptrempty()) { + if (query_parameters.statement_args && !query_parameters.statement_args->empty()) { // not supported for statements that already have parameters return; } @@ -248,7 +248,7 @@ void ClientContext::StatementVerification(ClientContextLock &lock, unique_ptrempty()) { + if (query_parameters.statement_args && !query_parameters.statement_args->empty()) { // not supported for statements that already have parameters return; } diff --git a/src/duckdb/src/main/config.cpp b/src/duckdb/src/main/config.cpp index 3abee0837..549c707cb 100644 --- a/src/duckdb/src/main/config.cpp +++ b/src/duckdb/src/main/config.cpp @@ -70,7 +70,6 @@ DebugVerificationMode DBConfigOptions::global_verification_mode = DebugVerificat static const ConfigurationOption internal_options[] = { - DUCKDB_GLOBAL(DeltaOnlyVariantEncodingEnabledSetting), DUCKDB_GLOBAL(AccessModeSetting), DUCKDB_LOCAL(ActiveGrammarExtensionsSetting), DUCKDB_SETTING_CALLBACK(AllocatorBackgroundThreadsSetting), @@ -108,7 +107,9 @@ static const ConfigurationOption internal_options[] = { DUCKDB_GLOBAL(CustomUserAgentSetting), DUCKDB_SETTING(DebugAsofIejoinSetting), DUCKDB_SETTING_CALLBACK(DebugCheckpointAbortSetting), + DUCKDB_SETTING(DebugCheckpointScanSleepMsSetting), DUCKDB_SETTING(DebugCheckpointSleepMsSetting), + DUCKDB_GLOBAL(DebugDeltaOnlyVariantEncodingEnabledSetting), DUCKDB_SETTING(DebugDisableOptimizerSetting), DUCKDB_SETTING(EnableCachingOperatorsSetting), DUCKDB_SETTING(DebugEvictionQueueSleepMicroSecondsSetting), @@ -125,12 +126,13 @@ static const ConfigurationOption internal_options[] = { DUCKDB_GLOBAL(DebugOrderVerificationSetting), DUCKDB_SETTING_CALLBACK(DebugPhysicalTableScanExecutionStrategySetting), DUCKDB_SETTING(DebugSkipCheckpointOnCommitSetting), - DUCKDB_SETTING(DebugTransformerTrampolineStyleSetting), DUCKDB_GLOBAL(DebugVerificationModeSetting), DUCKDB_SETTING(DebugVerificationProjectionSetting), DUCKDB_SETTING(DebugVerifyAggregateStateExportSetting), DUCKDB_SETTING(DebugVerifyBlocksSetting), DUCKDB_SETTING(DebugVerifyColumnBindingsSetting), + DUCKDB_SETTING_CALLBACK(DebugVerifyProgressSetting), + DUCKDB_SETTING(DebugVerifyProgressIgnoreSetting), DUCKDB_SETTING(DebugVerifySerializerSetting), DUCKDB_SETTING_CALLBACK(DebugVerifyStatementSetting), DUCKDB_SETTING(DebugVerifyStatsSetting), @@ -166,6 +168,7 @@ static const ConfigurationOption internal_options[] = { DUCKDB_LOCAL(EnableProgressBarPrintSetting), DUCKDB_SETTING(EnableViewDependenciesSetting), DUCKDB_GLOBAL(EnabledLogTypes), + DUCKDB_SETTING_CALLBACK(ErrorOnDivisionByZeroSetting), DUCKDB_SETTING(ErrorsAsJSONSetting), DUCKDB_SETTING_CALLBACK(ExperimentalMetadataReuseSetting), DUCKDB_SETTING_CALLBACK(ExplainOutputSetting), @@ -179,9 +182,10 @@ static const ConfigurationOption internal_options[] = { DUCKDB_SETTING(FileSearchPathSetting), DUCKDB_SETTING_CALLBACK(ForceColumnMetadataReuseSetting), DUCKDB_SETTING_CALLBACK(ForceCompressionSetting), + DUCKDB_SETTING_CALLBACK(FsyncModeSetting), DUCKDB_SETTING(GeometryMinimumShreddingSize), - DUCKDB_SETTING(HeapBasedParserSetting), DUCKDB_SETTING_CALLBACK(HomeDirectorySetting), + DUCKDB_GLOBAL(HTTPClientPoolCapacitySetting), DUCKDB_GLOBAL(HTTPProxySetting), DUCKDB_SETTING(HTTPProxyPasswordSetting), DUCKDB_SETTING(HTTPProxyUsernameSetting), @@ -209,7 +213,6 @@ static const ConfigurationOption internal_options[] = { DUCKDB_SETTING(MaxVacuumTasksSetting), DUCKDB_SETTING(MergeJoinThresholdSetting), DUCKDB_SETTING(NestedLoopJoinThresholdSetting), - DUCKDB_SETTING_CALLBACK(NullOnDivisionByZeroSetting), DUCKDB_SETTING_CALLBACK(OldImplicitCastingSetting), DUCKDB_LOCAL(OperatorMemoryLimitSetting), DUCKDB_SETTING(OrderByNonIntegerLiteralSetting), @@ -258,6 +261,7 @@ static const ConfigurationOption internal_options[] = { FINAL_SETTING}; static const ConfigurationAlias setting_aliases[] = { + DUCKDB_SETTING_ALIAS("__delta_only_variant_encoding_enabled", DebugDeltaOnlyVariantEncodingEnabledSetting), DUCKDB_SETTING_ALIAS("enable_caching_operators", EnableCachingOperatorsSetting), DUCKDB_SETTING_ALIAS("force_bitpacking_mode", ForceBitpackingModeSetting), DUCKDB_SETTING_ALIAS("force_mbedtls_unsafe", ForceMbedtlsUnsafeSetting), @@ -930,14 +934,33 @@ void DBConfig::AddAllowedDirectory(const string &path) { if (!StringUtil::EndsWith(allowed_directory, "/")) { allowed_directory += "/"; } + lock_guard guard(allowed_paths_lock); options.allowed_directories.insert(allowed_directory); } void DBConfig::AddAllowedPath(const string &path) { auto allowed_path = SanitizeAllowedPath(path); + lock_guard guard(allowed_paths_lock); options.allowed_paths.insert(allowed_path); } +void DBConfig::AddAllowedDatabasePath(const string &database_path) { + AddAllowedPath(database_path); + AddAllowedPath(database_path + ".wal"); + AddAllowedPath(database_path + ".wal.checkpoint"); + AddAllowedPath(database_path + ".wal.recovery"); +} + +vector DBConfig::GetAllowedDirectories() const { + lock_guard guard(allowed_paths_lock); + return vector(options.allowed_directories.begin(), options.allowed_directories.end()); +} + +vector DBConfig::GetAllowedPaths() const { + lock_guard guard(allowed_paths_lock); + return vector(options.allowed_paths.begin(), options.allowed_paths.end()); +} + bool DBConfig::CanAccessFile(const string &input_path, FileType type) { if (Settings::Get(*this)) { // all external access is allowed @@ -945,6 +968,7 @@ bool DBConfig::CanAccessFile(const string &input_path, FileType type) { } string path = SanitizeAllowedPath(input_path); + lock_guard guard(allowed_paths_lock); if (options.allowed_paths.count(path) > 0) { // path is explicitly allowed return true; @@ -993,4 +1017,8 @@ HTTPTransportManager &DBConfig::GetHTTPTransportManager() { return *http_transport_manager; } +const HTTPTransportManager &DBConfig::GetHTTPTransportManager() const { + return *http_transport_manager; +} + } // namespace duckdb diff --git a/src/duckdb/src/main/connection.cpp b/src/duckdb/src/main/connection.cpp index 5b12369bf..121258612 100644 --- a/src/duckdb/src/main/connection.cpp +++ b/src/duckdb/src/main/connection.cpp @@ -78,51 +78,34 @@ void Connection::ForceParallelism() { ClientConfig::GetConfig(*context).verify_parallelism = true; } -unique_ptr Connection::SendQuery(const string &query, QueryParameters query_parameters) { - return context->Query(query, query_parameters); +unique_ptr Connection::Query(const string &query) { + return context->Query(query, QueryParameters()); } -unique_ptr Connection::SendQuery(unique_ptr statement, QueryParameters query_parameters) { - return context->Query(std::move(statement), query_parameters); -} - -unique_ptr Connection::Query(const string &query) { +unique_ptr Connection::Query(unique_ptr statement, QueryResultMemoryType memory_type) { QueryParameters query_parameters; - query_parameters.output_type = QueryResultOutputType::FORCE_MATERIALIZED; - auto result = context->Query(query, query_parameters); - D_ASSERT(result->GetResultType() == QueryResultType::MATERIALIZED_RESULT); - return unique_ptr_cast(std::move(result)); -} - -unique_ptr Connection::Query(unique_ptr statement, - QueryResultMemoryType memory_type) { - QueryParameters query_parameters; - query_parameters.output_type = QueryResultOutputType::FORCE_MATERIALIZED; query_parameters.memory_type = memory_type; - auto result = context->Query(std::move(statement), query_parameters); - D_ASSERT(result->GetResultType() == QueryResultType::MATERIALIZED_RESULT); - return unique_ptr_cast(std::move(result)); + return context->Query(std::move(statement), query_parameters); } -unique_ptr Connection::PendingQuery(const string &query, QueryParameters query_parameters) { - return context->PendingQuery(query, query_parameters); +unique_ptr Connection::Submit(const string &query, const QueryParameters &query_parameters) { + return context->Submit(query, query_parameters); } -unique_ptr Connection::PendingQuery(unique_ptr statement, - QueryParameters query_parameters) { - return context->PendingQuery(std::move(statement), query_parameters); +unique_ptr Connection::Submit(unique_ptr statement, + const QueryParameters &query_parameters) { + return context->Submit(std::move(statement), query_parameters); } -unique_ptr Connection::PendingQuery(const string &query, - identifier_map_t &named_values, - QueryParameters query_parameters) { - return context->PendingQuery(query, named_values, query_parameters); +unique_ptr Connection::Submit(const string &query, identifier_map_t &named_values, + const QueryParameters &query_parameters) { + return context->Submit(query, named_values, query_parameters); } -unique_ptr Connection::PendingQuery(unique_ptr statement, - identifier_map_t &named_values, - QueryParameters query_parameters) { - return context->PendingQuery(std::move(statement), named_values, query_parameters); +unique_ptr Connection::Submit(unique_ptr statement, + identifier_map_t &named_values, + const QueryParameters &query_parameters) { + return context->Submit(std::move(statement), named_values, query_parameters); } static identifier_map_t ConvertParamListToMap(vector ¶m_list) { @@ -134,20 +117,16 @@ static identifier_map_t ConvertParamListToMap(vector return named_values; } -unique_ptr Connection::PendingQuery(const string &query, vector &values, - QueryParameters query_parameters) { +unique_ptr Connection::Submit(const string &query, vector &values, + const QueryParameters &query_parameters) { auto named_params = ConvertParamListToMap(values); - return context->PendingQuery(query, named_params, query_parameters); + return context->Submit(query, named_params, query_parameters); } -unique_ptr Connection::PendingQuery(unique_ptr statement, vector &values, - QueryParameters query_parameters) { +unique_ptr Connection::Submit(unique_ptr statement, vector &values, + const QueryParameters &query_parameters) { auto named_params = ConvertParamListToMap(values); - return context->PendingQuery(std::move(statement), named_params, query_parameters); -} - -unique_ptr Connection::PendingQuery(const string &query, PendingQueryParameters parameters) { - return context->PendingQuery(query, parameters); + return context->Submit(std::move(statement), named_params, query_parameters); } unique_ptr Connection::Prepare(const string &query) { @@ -160,15 +139,11 @@ unique_ptr Connection::Prepare(unique_ptr state unique_ptr Connection::QueryParamsRecursive(const string &query, vector &values) { auto named_params = ConvertParamListToMap(values); - PendingQueryParameters parameters; - parameters.parameters = &named_params; - parameters.query_parameters.output_type = QueryResultOutputType::FORCE_MATERIALIZED; - parameters.query_parameters.memory_type = QueryResultMemoryType::BUFFER_MANAGED; - auto pending = PendingQuery(query, parameters); - if (pending->HasError()) { - return make_uniq(pending->GetErrorObject()); - } - return pending->Execute(); + QueryParameters parameters; + parameters.statement_args = named_params; + parameters.memory_type = QueryResultMemoryType::BUFFER_MANAGED; + parameters.result_eagerness = ResultEagerness::FORCED; + return context->Query(query, parameters); } unique_ptr Connection::TableInfo(const Identifier &database_name, const Identifier &schema_name, @@ -261,6 +236,13 @@ shared_ptr Connection::TableFunction(const string &fname, const vector return make_shared_ptr(context, fname, values, named_parameters); } +shared_ptr Connection::TableFunction(const string &fname, const vector &values, + const named_parameter_map_t &named_parameters, + shared_ptr bind_info) { + return make_shared_ptr(context, fname, values, named_parameters, nullptr, true, + std::move(bind_info)); +} + shared_ptr Connection::TableFunction(const string &fname, const vector &values) { return make_shared_ptr(context, fname, values); } diff --git a/src/duckdb/src/main/database.cpp b/src/duckdb/src/main/database.cpp index f18b0d8f6..fe3a7a7ee 100644 --- a/src/duckdb/src/main/database.cpp +++ b/src/duckdb/src/main/database.cpp @@ -300,6 +300,36 @@ static duckdb_ext_api_v1 CreateAPIv1Wrapper() { } void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_config) { + InitializeInstance(database_path, user_config); + if (!db_manager->HasAttachedDatabase()) { + CreateMainDatabase(); + } + // The main database is the default; a storage extension may have attached it during startup instead. + optional_ptr main_database; + for (auto &attached : db_manager->GetDatabases()) { + if (attached->IsSystem()) { + continue; + } + if (!main_database || attached->oid < main_database->oid) { + main_database = attached.get(); + } + } + db_manager->SetDefaultDatabase(main_database->GetName()); + StartScheduler(); +} + +void DatabaseInstance::InitializeEmpty(DBConfig *user_config) { + InitializeInstance(nullptr, user_config); + StartScheduler(); +} + +void DatabaseInstance::StartScheduler() { + scheduler->SetThreads(config.options.maximum_threads, Settings::Get(config)); + scheduler->SetAsyncThreads(config.options.async_threads); + scheduler->RelaunchThreads(); +} + +void DatabaseInstance::InitializeInstance(const char *database_path, DBConfig *user_config) { DBConfig default_config; DBConfig *config_ptr = &default_config; if (user_config) { @@ -361,15 +391,6 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf } LoadExtensionSettings(); - - if (!db_manager->HasAttachedDatabase()) { - CreateMainDatabase(); - } - - // only increase thread count after storage init because we get races on catalog otherwise - scheduler->SetThreads(config.options.maximum_threads, Settings::Get(config)); - scheduler->SetAsyncThreads(config.options.async_threads); - scheduler->RelaunchThreads(); } DuckDB::DuckDB(const char *path, DBConfig *new_config) : instance(make_shared_ptr()) { @@ -383,6 +404,16 @@ DuckDB::DuckDB(const char *path, DBConfig *new_config) : instance(make_shared_pt DuckDB::DuckDB(const string &path, DBConfig *config) : DuckDB(path.c_str(), config) { } +shared_ptr DuckDB::CreateEmpty(DBConfig *config) { + auto instance = make_shared_ptr(); + instance->InitializeEmpty(config); + auto db = make_shared_ptr(*instance); + if (instance->config.options.load_extensions) { + ExtensionHelper::LoadAllExtensions(*db); + } + return db; +} + DuckDB::DuckDB(DatabaseInstance &instance_p) : instance(instance_p.shared_from_this()) { } @@ -515,12 +546,9 @@ void DatabaseInstance::Configure(DBConfig &new_config, const char *database_path } else { config.file_system = make_uniq(FileSystem::CreateLocal()); } - config.http_transport_manager->Initialize(DBConfig::GetSystemMaxThreads(*config.file_system)); + config.http_transport_manager->Initialize(config); if (database_path && !Settings::Get(*this)) { - config.AddAllowedPath(database_path); - config.AddAllowedPath(database_path + string(".wal")); - config.AddAllowedPath(database_path + string(".wal.checkpoint")); - config.AddAllowedPath(database_path + string(".wal.recovery")); + config.AddAllowedDatabasePath(database_path); if (!config.options.temporary_directory.empty()) { config.AddAllowedDirectory(config.options.temporary_directory); } diff --git a/src/duckdb/src/main/database_manager.cpp b/src/duckdb/src/main/database_manager.cpp index 300c2449a..57d33103b 100644 --- a/src/duckdb/src/main/database_manager.cpp +++ b/src/duckdb/src/main/database_manager.cpp @@ -3,6 +3,7 @@ #include "duckdb/catalog/catalog.hpp" #include "duckdb/catalog/catalog_search_path.hpp" #include "duckdb/main/attached_database.hpp" +#include "duckdb/main/external_resources_manager.hpp" #include "duckdb/main/client_data.hpp" #include "duckdb/main/query_profiler.hpp" #include "duckdb/main/database.hpp" @@ -244,9 +245,15 @@ optional_ptr DatabaseManager::FinalizeAttach(ClientContext &co if (detached_db->GetCatalog().Supports(RemoteCapability::IS_REMOTE)) { --remote_catalog_count; } + auto deleter = detached_db->ExtractDeleter(); meta_transaction.DetachDatabase(*detached_db); detached_db->OnDetach(context); detached_db.reset(); + // Best-effort teardown: the replacement is already in effect, so a deleter failure must not + // abort the statement mid-swap; TryDelete logs it as a warning instead. + if (deleter) { + deleter->TryDelete(); + } } if (attached_db->GetCatalog().Supports(RemoteCapability::IS_REMOTE)) { ++remote_catalog_count; @@ -258,8 +265,9 @@ optional_ptr DatabaseManager::FinalizeAttach(ClientContext &co return db_ref; } -void DatabaseManager::DetachDatabase(ClientContext &context, const Identifier &name, OnEntryNotFound if_not_found) { - if (GetDefaultDatabase(context) == name) { +void DatabaseManager::DetachDatabase(ClientContext &context, const Identifier &name, OnEntryNotFound if_not_found, + bool allow_default_database) { + if (!allow_default_database && TryGetDefaultDatabase(context) == name) { throw BinderException("Cannot detach database %s because it is the default database. Select a different " "database using `USE` to allow detaching this database", name); @@ -273,10 +281,59 @@ void DatabaseManager::DetachDatabase(ClientContext &context, const Identifier &n return; } + auto deleter = attached_db->ExtractDeleter(); attached_db->OnDetach(context); // DetachInternal removes the AttachedDatabase from the list of databases that can be referenced. AttachedDatabase::InvokeCloseIfLastReference(attached_db, context); + + // Tear down the owned external resource last (runs SQL): the detach itself is complete either way, + // and a teardown failure surfaces with instructions to retry it manually. + if (deleter) { + deleter->Delete(); + } +} + +void DatabaseManager::AddPendingTeardown(unique_ptr deleter) { + lock_guard guard(pending_teardowns_lock); + pending_teardowns.push_back(std::move(deleter)); +} + +void DatabaseManager::DrainPendingTeardowns() { + vector> to_run; + { + lock_guard guard(pending_teardowns_lock); + to_run = std::move(pending_teardowns); + pending_teardowns.clear(); + } + // Best-effort: the statement that owned these resources is gone, so a failure can only be logged. + for (auto &deleter : to_run) { + deleter->TryDelete(); + } +} + +void DatabaseManager::DetachResourceBorrowers(ClientContext &context, const string &resource_name) { + vector to_detach; + { + lock_guard guard(databases_lock); + for (auto &entry : databases) { + // Both sides come from ColId -> Identifier::GetIdentifierName(), matching how the manager keys names. + if (entry.second->GetBorrowedResourceName() == resource_name) { + to_detach.push_back(entry.second->GetName()); + } + } + } + // Detach outside the lock: DetachDatabase takes databases_lock itself. A borrowed attachment binds no + // deleter, so this runs no teardown -- the resource is already gone. + for (auto &name : to_detach) { + try { + DetachDatabase(context, name, OnEntryNotFound::RETURN_NULL); + } catch (std::exception &) { + // Best-effort: DETACH refuses a connection's default database, and DESTROY goes through anyway. + // Deliberately not marked invalid -- ValidChecker would then throw for every statement + // resolving through it, including the USE and DETACH needed to recover. + } + } } void DatabaseManager::Alter(ClientContext &context, AlterInfo &info) { @@ -320,6 +377,9 @@ void DatabaseManager::RenameDatabase(ClientContext &context, const Identifier &o databases.erase(old_entry); attached_db->SetName(new_name); databases[new_name] = attached_db; + if (default_database == old_name) { + default_database = new_name; + } } } @@ -333,6 +393,21 @@ shared_ptr DatabaseManager::DetachInternal(const Identifier &n } attached_db = std::move(entry->second); databases.erase(entry); + if (default_database == name) { + // Fall back to the oldest remaining database (OIDs are assigned in attach order) + // Arguably, this should not be required - we should just leave the default database unset. + // The default used to be defined as the oldest attached database, so detaching the current default changed + // the new default to "unset". Keep the previous observable behavior rather than leave new connections + // without a default db, since SQL has no way to set the default database at the instance level. + default_database = Identifier(); + idx_t oldest_oid = DConstants::INVALID_INDEX; + for (auto &other : databases) { + if (other.second->oid < oldest_oid) { + oldest_oid = other.second->oid; + default_database = other.first; + } + } + } } if (attached_db && attached_db->GetCatalog().Supports(RemoteCapability::IS_REMOTE)) { --remote_catalog_count; @@ -407,28 +482,58 @@ void DatabaseManager::GetDatabaseType(ClientContext &context, AttachInfo &info, } Identifier DatabaseManager::GetDefaultDatabase(ClientContext &context) { - auto &config = ClientData::Get(context); - auto &default_entry = config.catalog_search_path->GetDefault(); - if (IsInvalidCatalog(default_entry.GetCatalog())) { - auto &manager = DatabaseManager::Get(context); - lock_guard guard(manager.databases_lock); - if (manager.databases.empty()) { - auto modified_database = MetaTransaction::Get(context).ModifiedDatabase(); - if (modified_database) { - return modified_database->GetName(); - } - throw InternalException("Calling DatabaseManager::GetDefaultDatabase with no database attached"); + auto result = TryGetDefaultDatabase(context); + if (!IsInvalidCatalog(result)) { + return result; + } + auto &connected_with = ClientData::Get(context).default_database; + if (!IsInvalidCatalog(connected_with)) { + throw CatalogException("The default database %s has been detached: select another database using `USE`", + connected_with); + } + // Reachable on an instance created without a database (DuckDB::CreateEmpty). + throw CatalogException("No database is attached: attach one with ATTACH before referring to a database"); +} + +Identifier DatabaseManager::TryGetDefaultDatabase(ClientContext &context) { + auto &client_data = ClientData::Get(context); + auto &default_entry = client_data.catalog_search_path->GetDefault(); + if (!IsInvalidCatalog(default_entry.GetCatalog())) { + return default_entry.GetCatalog(); + } + auto &manager = DatabaseManager::Get(context); + // Callable outside a transaction: only consult the transaction's references when one is active. + const bool in_transaction = context.transaction.HasActiveTransaction(); + if (!IsInvalidCatalog(client_data.default_database)) { + // still the default while attached, or while this transaction still references it + if (manager.GetDatabase(client_data.default_database)) { + return client_data.default_database; } - // OIDs are assigned in attach order, so the oldest attached database is the default. - auto default_database = manager.databases.begin(); - for (auto entry = manager.databases.begin(); entry != manager.databases.end(); entry++) { - if (entry->second->oid < default_database->second->oid) { - default_database = entry; - } + if (in_transaction && MetaTransaction::Get(context).GetReferencedDatabase(client_data.default_database)) { + return client_data.default_database; } - return default_database->first; + return Identifier(); + } + if (in_transaction && !manager.HasAttachedDatabase()) { + auto modified_database = MetaTransaction::Get(context).ModifiedDatabase(); + if (modified_database) { + return modified_database->GetName(); + } + } + return Identifier(); +} + +Identifier DatabaseManager::GetDefaultDatabase() { + lock_guard guard(databases_lock); + return default_database; +} + +void DatabaseManager::SetDefaultDatabase(const Identifier &name) { + lock_guard guard(databases_lock); + if (!IsInvalidCatalog(name) && databases.find(name) == databases.end()) { + throw BinderException("Cannot make database %s the default database: it is not attached", name); } - return default_entry.GetCatalog(); + default_database = name; } vector> DatabaseManager::GetDatabases(ClientContext &context, diff --git a/src/duckdb/src/main/db_instance_cache.cpp b/src/duckdb/src/main/db_instance_cache.cpp index c774ba86e..c1920a30e 100644 --- a/src/duckdb/src/main/db_instance_cache.cpp +++ b/src/duckdb/src/main/db_instance_cache.cpp @@ -149,6 +149,11 @@ shared_ptr DBInstanceCache::CreateInstance(const string &database, DBCon return CreateInstanceInternal(database, config, cache_instance, unique_lock(cache_lock), on_create); } +shared_ptr DBInstanceCache::CreateEmptyInstance(DBConfig &config) { + config.path_manager = path_manager; + return DuckDB::CreateEmpty(&config); +} + shared_ptr DBInstanceCache::GetOrCreateInstance(const string &database, DBConfig &config_dict, bool cache_instance, const std::function &on_create) { diff --git a/src/duckdb/src/main/extension/extension_loader.cpp b/src/duckdb/src/main/extension/extension_loader.cpp index 5c0d76384..e4d21a2fc 100644 --- a/src/duckdb/src/main/extension/extension_loader.cpp +++ b/src/duckdb/src/main/extension/extension_loader.cpp @@ -313,7 +313,7 @@ void ExtensionLoader::AddFunctionOverload(ScalarFunctionSet functions) { // NOLI void ExtensionLoader::AddFunctionOverload(TableFunctionSet functions) { // NOLINT auto &table_function = GetTableFunction(functions.name); - functions.ApplyToFunctions([&](TableFunction &function) { function.name = functions.name; }); + functions.ApplyToFunctions([&](TableFunction &function) { table_function.FinalizeFunction(function); }); for (auto &function : functions.functions) { table_function.functions.AddFunction(std::move(function)); } diff --git a/src/duckdb/src/main/http/http_client_pool.cpp b/src/duckdb/src/main/http/http_client_pool.cpp index 576c06624..7fcfe5d23 100644 --- a/src/duckdb/src/main/http/http_client_pool.cpp +++ b/src/duckdb/src/main/http/http_client_pool.cpp @@ -40,8 +40,25 @@ HTTPClientPool::HTTPClientPool(idx_t capacity_p) : capacity(capacity_p) { non_empty_buckets.reserve(capacity); } +void HTTPClientPool::SetCapacity(idx_t new_capacity) { + D_ASSERT(new_capacity > 0); + if (new_capacity > capacity) { + client_buckets.reserve(new_capacity); + non_empty_buckets.reserve(new_capacity); + for (auto &entry : client_buckets) { + entry.second.idle_clients.reserve(new_capacity); + } + } + capacity = new_capacity; + WakeNextAdmission(); +} + +idx_t HTTPClientPool::GetCapacity() const { + return capacity; +} + bool HTTPClientPool::HasAdmissionResource() const { - return reserved_clients < capacity || !non_empty_buckets.empty(); + return reserved_clients < capacity || (reserved_clients == capacity && !non_empty_buckets.empty()); } void HTTPClientPool::WaitForAdmission(annotated_unique_lock &guard, bool owns_capacity) { @@ -179,6 +196,7 @@ void HTTPClientPool::AdoptPreparedBucket(Reservation &reservation) { reservation.bucket = BucketHandle(exact->second); return; } + prepared.idle_clients.reserve(capacity); auto inserted = client_buckets.insert(std::move(reservation.bucket_node.node)); reservation.bucket = BucketHandle(inserted->second); } @@ -198,6 +216,9 @@ void HTTPClientPool::Return(BucketHandle handle, unique_ptr client) HTTPClientPool::Reservation HTTPClientPool::TakeIdleForDisposal(IdleFilter filter, idx_t first, uint64_t second) { Reservation result; + if (filter == IdleFilter::EXCESS && reserved_clients <= capacity) { + return result; + } for (auto &entry : client_buckets) { if (!entry.second.idle_clients.empty() && MatchesFilter(entry.first, filter, first, second)) { result.bucket = BucketHandle(entry.second); @@ -311,6 +332,7 @@ bool HTTPClientPool::MatchesFilter(const ClientKey &key, IdleFilter filter, idx_ return key.provider_epoch == first && key.connection_epoch < second; case IdleFilter::SESSION: return key.session_id == first; + case IdleFilter::EXCESS: case IdleFilter::ALL: return true; } diff --git a/src/duckdb/src/main/http/http_retry_budget.cpp b/src/duckdb/src/main/http/http_retry_budget.cpp index 8010996df..3fb00e874 100644 --- a/src/duckdb/src/main/http/http_retry_budget.cpp +++ b/src/duckdb/src/main/http/http_retry_budget.cpp @@ -29,6 +29,10 @@ HTTPRetryBudget::HTTPRetryBudget(const HTTPParams ¶ms) : retries(params.retries), retry_wait_ms(params.retry_wait_ms), retry_backoff(params.retry_backoff) { } +uint64_t HTTPRetryBudget::ThrottledRetries() const { + return throttled_retries; +} + void HTTPRetryBudget::Run(const std::function &attempt) { Run(attempt, {}); } @@ -63,6 +67,9 @@ bool HTTPRetryBudget::ConsumeAndWait(const HTTPRetryDecision &decision) { return false; } retries_used++; + if (throttled) { + throttled_retries++; + } #ifndef DUCKDB_NO_THREADS if (retries_used > 1 || throttled) { static constexpr uint64_t THROTTLE_MAX_BACKOFF_MS = 10000; diff --git a/src/duckdb/src/main/http/http_transport_manager.cpp b/src/duckdb/src/main/http/http_transport_manager.cpp index c61daaa6e..4205a688d 100644 --- a/src/duckdb/src/main/http/http_transport_manager.cpp +++ b/src/duckdb/src/main/http/http_transport_manager.cpp @@ -213,7 +213,8 @@ HTTPTransportManager::~HTTPTransportManager() { D_ASSERT(clients.IsEmpty()); } -idx_t HTTPTransportManager::CalculateCapacity(idx_t system_concurrency, optional_idx file_descriptor_limit) { +idx_t HTTPTransportManager::CalculateCapacity(idx_t system_concurrency, optional_idx file_descriptor_limit, + idx_t io_concurrency) { idx_t cpu_target; if (system_concurrency >= 128) { cpu_target = HTTP_TRANSPORT_MAX_CAPACITY; @@ -221,6 +222,8 @@ idx_t HTTPTransportManager::CalculateCapacity(idx_t system_concurrency, optional cpu_target = system_concurrency * 2; cpu_target = MaxValue(cpu_target, 16); } + // every async I/O thread can hold a client at once, so do not let the pool be the smaller of the two + cpu_target = MaxValue(cpu_target, io_concurrency); if (!file_descriptor_limit.IsValid()) { return cpu_target; } @@ -255,8 +258,13 @@ bool HTTPTransportManager::AdvanceConnectionEpoch(uint64_t &connection_epoch, bo return false; } -void HTTPTransportManager::Initialize(idx_t system_concurrency) { - auto new_capacity = CalculateCapacity(system_concurrency, GetFileDescriptorLimit()); +void HTTPTransportManager::Initialize(const DBConfig &config) { + auto new_capacity = config.options.http_client_pool_capacity == DConstants::INVALID_INDEX + ? AutomaticCapacity(config) + : config.options.http_client_pool_capacity; + if (new_capacity == 0) { + throw InvalidInputException("The HTTP client pool capacity must be at least 1"); + } HTTPClientPool new_clients(new_capacity); annotated_lock_guard guard(lock); @@ -270,6 +278,36 @@ void HTTPTransportManager::Initialize(idx_t system_concurrency) { initialized = true; } +idx_t HTTPTransportManager::AutomaticCapacity(const DBConfig &config) { + auto &fs = *config.file_system; + auto io_concurrency = config.options.async_threads == DConstants::INVALID_INDEX + ? DBConfig::GetSystemMaxAsyncThreads(fs) + : config.options.async_threads; + return CalculateCapacity(DBConfig::GetSystemMaxThreads(fs), GetFileDescriptorLimit(), io_concurrency); +} + +idx_t HTTPTransportManager::GetCapacity() const { + annotated_lock_guard guard(lock); + return clients.GetCapacity(); +} + +void HTTPTransportManager::SetCapacity(idx_t capacity) { + if (capacity == 0) { + throw InvalidInputException("The HTTP client pool capacity must be at least 1"); + } + { + annotated_lock_guard guard(lock); + if (!initialized) { + throw InternalException("HTTP transport manager capacity was set before initialization"); + } + if (clients.IsClosed()) { + return; + } + clients.SetCapacity(capacity); + } + DisposeIdle(IdleFilter::EXCESS); +} + HTTPTransportManager::SessionReservation HTTPTransportManager::ReserveSession() { annotated_lock_guard guard(lock); if (!initialized) { @@ -469,8 +507,9 @@ unique_ptr HTTPTransportManager::PerformRequest(Session &session, } bool HTTPTransportManager::CanReturnClientLocked(const Lease &lease, bool cleanup_succeeded) const { - if (!cleanup_succeeded || !lease.reusable || !lease.client || clients.IsClosed() || !lease.state || - !lease.bucket.IsValid() || !IsStateValidLocked(*lease.state)) { + if (!cleanup_succeeded || !lease.reusable || !lease.client || clients.IsClosed() || + clients.ReservedClients() > clients.GetCapacity() || !lease.state || !lease.bucket.IsValid() || + !IsStateValidLocked(*lease.state)) { return false; } auto &state = *lease.state; diff --git a/src/duckdb/src/main/materialized_query_result.cpp b/src/duckdb/src/main/materialized_query_result.cpp deleted file mode 100644 index 110c605ae..000000000 --- a/src/duckdb/src/main/materialized_query_result.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "duckdb/main/materialized_query_result.hpp" -#include "duckdb/common/to_string.hpp" -#include "duckdb/main/client_context.hpp" -#include "duckdb/common/box_renderer.hpp" - -namespace duckdb { - -MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type, StatementProperties properties, - vector names_p, - unique_ptr collection_p, - ClientProperties client_properties) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, std::move(properties), collection_p->Types(), - std::move(names_p), std::move(client_properties)), - collection(std::move(collection_p)), scan_initialized(false) { -} - -MaterializedQueryResult::MaterializedQueryResult(ErrorData error) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, std::move(error)), scan_initialized(false) { -} - -string MaterializedQueryResult::ToString() { - string result; - if (!HasError()) { - result = HeaderToString(); - result += "[ Rows: " + to_string(collection->Count()) + "]\n"; - auto &coll = Collection(); - for (auto &row : coll.Rows()) { - for (idx_t col_idx = 0; col_idx < coll.ColumnCount(); col_idx++) { - if (col_idx > 0) { - result += "\t"; - } - auto val = row.GetValue(col_idx); - result += val.IsNull() ? "NULL" : StringUtil::Replace(val.ToString(), string("\0", 1), "\\0"); - } - result += "\n"; - } - result += "\n"; - } else { - result = GetError() + "\n"; - } - return result; -} - -string MaterializedQueryResult::ToBox(BoxRendererContext &context, const BoxRendererConfig &config) { - if (HasError()) { - return GetError() + "\n"; - } - if (!collection) { - return "Internal error - result was successful but there was no collection"; - } - BoxRenderer renderer(config); - ColumnDataCollectionWrapper wrapper(Collection()); - return renderer.ToString(context, IdentifiersToStrings(GetNames()), wrapper); -} - -Value MaterializedQueryResult::GetValue(idx_t column, idx_t index) { - if (!row_collection) { - row_collection = make_uniq(collection->GetRows()); - } - return row_collection->GetValue(column, index); -} - -idx_t MaterializedQueryResult::RowCount() const { - return collection ? collection->Count() : 0; -} - -ColumnDataCollection &MaterializedQueryResult::Collection() { - if (HasError()) { - throw InvalidInputException("Attempting to get collection from an unsuccessful query result\n: Error %s", - GetError()); - } - if (!collection) { - throw InternalException("Missing collection from materialized query result"); - } - return *collection; -} - -unique_ptr MaterializedQueryResult::TakeCollection() { - if (HasError()) { - throw InvalidInputException("Attempting to get collection from an unsuccessful query result\n: Error %s", - GetError()); - } - if (!collection) { - throw InternalException("Missing collection from materialized query result"); - } - return std::move(collection); -} - -unique_ptr MaterializedQueryResult::FetchInternal() { - if (HasError()) { - throw InvalidInputException("Attempting to fetch from an unsuccessful query result\nError: %s", GetError()); - } - auto result = make_uniq(); - collection->InitializeScanChunk(*result); - if (!scan_initialized) { - // we disallow zero copy so the chunk is independently usable even after the result is destroyed - collection->InitializeScan(scan_state, ColumnDataScanProperties::DISALLOW_ZERO_COPY); - scan_initialized = true; - } - collection->Scan(scan_state, *result); - if (result->size() == 0) { - return nullptr; - } - return result; -} - -} // namespace duckdb diff --git a/src/duckdb/src/main/pending_query_result.cpp b/src/duckdb/src/main/pending_query_result.cpp deleted file mode 100644 index 2ad1df1f7..000000000 --- a/src/duckdb/src/main/pending_query_result.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "duckdb/main/pending_query_result.hpp" -#include "duckdb/main/client_context.hpp" -#include "duckdb/main/prepared_statement_data.hpp" -#include "duckdb/main/materialized_query_result.hpp" -#include "duckdb/main/stream_query_result.hpp" - -namespace duckdb { - -PendingQueryResult::PendingQueryResult(shared_ptr context_p, PreparedStatementData &statement, - vector types_p, bool allow_stream_result) - : BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, statement.properties, - std::move(types_p), statement.names), - context(std::move(context_p)), allow_stream_result(allow_stream_result) { -} - -PendingQueryResult::PendingQueryResult(ErrorData error) - : BaseQueryResult(QueryResultType::PENDING_RESULT, std::move(error)) { -} - -PendingQueryResult::~PendingQueryResult() { -} - -unique_ptr PendingQueryResult::LockContext() { - if (!context) { - if (HasError()) { - throw InvalidInputException( - "Attempting to execute an unsuccessful or closed pending query result\nError: %s", GetError()); - } - throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result"); - } - return context->LockContext(); -} - -void PendingQueryResult::CheckExecutableInternal(ClientContextLock &lock) { - bool invalidated = HasError() || !context; - if (!invalidated) { - invalidated = !context->IsActiveResult(lock, *this); - } - if (invalidated) { - if (HasError()) { - throw InvalidInputException( - "Attempting to execute an unsuccessful or closed pending query result\nError: %s", GetError()); - } - throw InvalidInputException("Attempting to execute an unsuccessful or closed pending query result"); - } -} - -void PendingQueryResult::WaitForTask() { - auto lock = LockContext(); - context->WaitForTask(*lock, *this); -} - -PendingExecutionResult PendingQueryResult::ExecuteTask() { - auto lock = LockContext(); - return ExecuteTaskInternal(*lock); -} - -PendingExecutionResult PendingQueryResult::CheckPulse() { - auto lock = LockContext(); - CheckExecutableInternal(*lock); - return context->ExecuteTaskInternal(*lock, *this, true); -} - -bool PendingQueryResult::AllowStreamResult() const { - return allow_stream_result; -} - -PendingExecutionResult PendingQueryResult::ExecuteTaskInternal(ClientContextLock &lock) { - CheckExecutableInternal(lock); - return context->ExecuteTaskInternal(lock, *this, false); -} - -unique_ptr PendingQueryResult::ExecuteInternal(ClientContextLock &lock) { - CheckExecutableInternal(lock); - - PendingExecutionResult execution_result; - while (!IsResultReady(execution_result = ExecuteTaskInternal(lock))) { - if (execution_result == PendingExecutionResult::BLOCKED) { - CheckExecutableInternal(lock); - context->WaitForTask(lock, *this); - } - } - if (HasError()) { - if (allow_stream_result) { - return make_uniq(GetErrorObject()); - } else { - return make_uniq(GetErrorObject()); - } - } - auto result = context->FetchResultInternal(lock, *this); - // release our context reference (cannot use Close(): the context lock is already held here) - context.reset(); - return result; -} - -unique_ptr PendingQueryResult::Execute() { - auto lock = LockContext(); - return ExecuteInternal(*lock); -} - -void PendingQueryResult::Close() { - if (context) { - auto lock = LockContext(); - if (context->IsActiveResult(*lock, *this)) { - // Abandoned before execution finished: release the active-query state now (matching - // InitialCleanup) instead of leaking it until the next query or context teardown. - context->CleanupInternal(*lock, this, false); - } - } - context.reset(); -} - -bool PendingQueryResult::IsResultReady(PendingExecutionResult result) { - return (IsExecutionFinished(result) || result == PendingExecutionResult::RESULT_READY); -} - -bool PendingQueryResult::IsExecutionFinished(PendingExecutionResult result) { - return (result == PendingExecutionResult::EXECUTION_FINISHED || result == PendingExecutionResult::EXECUTION_ERROR); -} - -} // namespace duckdb diff --git a/src/duckdb/src/main/prepared_statement.cpp b/src/duckdb/src/main/prepared_statement.cpp index 52966aa54..3cbeb2b2f 100644 --- a/src/duckdb/src/main/prepared_statement.cpp +++ b/src/duckdb/src/main/prepared_statement.cpp @@ -105,56 +105,50 @@ PreparedStatement::CreateExecuteStatement(const identifier_map_t PreparedStatement::Execute(identifier_map_t &named_values, - bool allow_stream_result) { +unique_ptr PreparedStatement::Execute(identifier_map_t &named_values) { if (!success) { - return make_uniq( + return make_uniq( ErrorData(InvalidInputException("Attempting to execute an unsuccessfully prepared statement!"))); } auto client_context = context.lock(); if (!client_context) { - return make_uniq(ErrorData( + return make_uniq(ErrorData( InvalidInputException("Attempting to execute a prepared statement after its connection was closed!"))); } - PendingQueryParameters parameters; - parameters.query_parameters.output_type = - allow_stream_result ? QueryResultOutputType::ALLOW_STREAMING : QueryResultOutputType::FORCE_MATERIALIZED; + QueryParameters parameters; return client_context->RunInternalStatement(CreateExecuteStatement(named_values), parameters); } -unique_ptr PreparedStatement::Execute(vector &values, bool allow_stream_result) { +unique_ptr PreparedStatement::Execute(vector &values) { identifier_map_t named_values; for (idx_t i = 0; i < values.size(); i++) { named_values[Identifier(std::to_string(i + 1))] = BoundParameterData(values[i]); } - return Execute(named_values, allow_stream_result); + return Execute(named_values); } -unique_ptr PreparedStatement::PendingQuery(vector &values, bool allow_stream_result) { +unique_ptr PreparedStatement::Submit(vector &values, const QueryParameters &query_parameters) { identifier_map_t named_values; for (idx_t i = 0; i < values.size(); i++) { auto &val = values[i]; named_values[Identifier(std::to_string(i + 1))] = BoundParameterData(val); } - return PendingQuery(named_values, allow_stream_result); + return Submit(named_values, query_parameters); } -unique_ptr PreparedStatement::PendingQuery(identifier_map_t &named_values, - bool allow_stream_result) { +unique_ptr PreparedStatement::Submit(identifier_map_t &named_values, + const QueryParameters &query_parameters) { if (!success) { auto exception = InvalidInputException("Attempting to execute an unsuccessfully prepared statement!"); - return make_uniq(ErrorData(exception)); + return make_uniq(ErrorData(exception)); } auto client_context = context.lock(); if (!client_context) { auto exception = InvalidInputException("Attempting to execute a prepared statement after its connection was closed!"); - return make_uniq(ErrorData(exception)); + return make_uniq(ErrorData(exception)); } - PendingQueryParameters parameters; - parameters.query_parameters.output_type = - allow_stream_result ? QueryResultOutputType::ALLOW_STREAMING : QueryResultOutputType::FORCE_MATERIALIZED; - return client_context->PendingInternalStatement(CreateExecuteStatement(named_values), parameters); + return client_context->SubmitInternalStatement(CreateExecuteStatement(named_values), query_parameters); } } // namespace duckdb diff --git a/src/duckdb/src/main/query_result.cpp b/src/duckdb/src/main/query_result.cpp index e6a4b2137..dbc31efcc 100644 --- a/src/duckdb/src/main/query_result.cpp +++ b/src/duckdb/src/main/query_result.cpp @@ -1,9 +1,17 @@ #include "duckdb/main/query_result.hpp" #include "duckdb/common/box_renderer.hpp" +#include "duckdb/common/column_data_collection_render_interface.hpp" #include "duckdb/common/printer.hpp" +#include "duckdb/common/to_string.hpp" +#include "duckdb/common/types/column/column_data_collection.hpp" #include "duckdb/common/vector.hpp" +#include "duckdb/execution/executor.hpp" +#include "duckdb/main/buffered_data/buffered_data.hpp" #include "duckdb/main/client_context.hpp" +#include "duckdb/main/database.hpp" +#include "duckdb/main/prepared_statement_data.hpp" + namespace duckdb { BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties_p, @@ -78,6 +86,9 @@ const vector &BaseQueryResult::GetNames() const { return names; } +//===--------------------------------------------------------------------===// +// Construction +//===--------------------------------------------------------------------===// QueryResult::QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, vector types_p, vector names_p, ClientProperties client_properties_p) : BaseQueryResult(type, statement_type, std::move(properties), std::move(types_p), std::move(names_p)), @@ -89,7 +100,26 @@ QueryResult::QueryResult(QueryResultType type, ErrorData error) client_properties("UTC", ArrowOffsetSize::REGULAR, false, false, false, ArrowFormatVersion::V1_0, nullptr) { } +QueryResult::QueryResult(shared_ptr context_p, PreparedStatementData &statement, + vector types_p, ClientProperties client_properties_p, + shared_ptr buffer_p) + : BaseQueryResult(QueryResultType::MATERIALIZED_RESULT, statement.statement_type, statement.properties, + std::move(types_p), statement.names), + client_properties(std::move(client_properties_p)), context(std::move(context_p)), buffer(std::move(buffer_p)) { +} + +QueryResult::QueryResult(StatementType statement_type, StatementProperties properties, vector names_p, + unique_ptr collection_p, ClientProperties client_properties_p) + : BaseQueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, std::move(properties), + collection_p->Types(), std::move(names_p)), + client_properties(std::move(client_properties_p)), collection(std::move(collection_p)) { +} + +QueryResult::QueryResult(ErrorData error) : QueryResult(QueryResultType::MATERIALIZED_RESULT, std::move(error)) { +} + QueryResult::~QueryResult() { + Close(); } void QueryResult::DeduplicateColumns(vector &names) { @@ -124,8 +154,246 @@ const Identifier &QueryResult::ColumnName(idx_t index) const { return names[index]; } -string QueryResult::ToBox(BoxRendererContext &context, const BoxRendererConfig &config) { - return ToString(); +//===--------------------------------------------------------------------===// +// Execution +//===--------------------------------------------------------------------===// +unique_ptr QueryResult::LockContext() { + if (!context) { + string error_str = "Attempting to execute an unsuccessful or closed query result"; + if (HasError()) { + error_str += StringUtil::Format("\nError: %s", GetError()); + } + throw InvalidInputException(error_str); + } + return context->LockContext(); +} + +bool QueryResult::IsOpenInternal(ClientContextLock &lock) { + if (HasError() || !context) { + return false; + } + return context->IsActiveResult(lock, *this); +} + +void QueryResult::CheckExecutableInternal(ClientContextLock &lock) { + if (!IsOpenInternal(lock)) { + string error_str = "Attempting to execute an unsuccessful or closed query result"; + if (HasError()) { + error_str += StringUtil::Format("\nError: %s", GetError()); + } + throw InvalidInputException(error_str); + } +} + +bool QueryResult::IsOpen() { + if (HasError() || !context) { + return false; + } + auto lock = LockContext(); + return IsOpenInternal(*lock); +} + +QueryResultState QueryResult::Cancelled() { + if (!HasError()) { + SetError(ErrorData(ExceptionType::INTERRUPT, + "The execution of the query was cancelled before it could finish, likely caused by " + "executing a different query")); + } + return QueryResultState::EXECUTION_ERROR; +} + +QueryResultState QueryResult::Poll() { + if (HasError()) { + return QueryResultState::EXECUTION_ERROR; + } + if (collection || !context) { + // The result was collected, or the query already ended: keep reporting the terminal state + return QueryResultState::FINISHED; + } + auto lock = LockContext(); + if (!IsOpenInternal(*lock)) { + return Cancelled(); + } + return context->PollInternal(*lock, *this); +} + +QueryResultState QueryResult::ExecuteTask() { + auto lock = LockContext(); + CheckExecutableInternal(*lock); + return context->ExecuteTaskInternal(*lock, *this); +} + +void QueryResult::WaitForTask() { + if (!context) { + return; + } + auto lock = LockContext(); + if (!IsOpenInternal(*lock)) { + return; + } + context->WaitForTask(*lock, *this); +} + +void QueryResult::Close() { + if (buffer) { + buffer->Close(); + } + if (context) { + auto lock = context->LockContext(); + if (context->IsActiveResult(*lock, *this)) { + // Abandoned before the result was consumed: release the active-query state now (matching + // InitialCleanup) instead of leaking it until the next query or context teardown + context->CleanupInternal(*lock, this, false); + } + } + context.reset(); +} + +//===--------------------------------------------------------------------===// +// Retention +//===--------------------------------------------------------------------===// +void QueryResult::Materialize() { + if (collection || HasError() || !context) { + return; + } + auto lock = LockContext(); + if (!IsOpenInternal(*lock)) { + Cancelled(); + context.reset(); + return; + } + D_ASSERT(buffer); + buffer->Decide(ResultLifetime::RETAINED); +} + +void QueryResult::Complete() { + if (collection || HasError() || !context) { + return; + } + // The handle may hold the last reference to the context, which the lock below outlives + auto keep_alive = context; + auto lock = keep_alive->LockContext(); + CompleteInternal(*lock); +} + +void QueryResult::CompleteInternal(ClientContextLock &lock) { + if (collection || HasError() || !context) { + return; + } + if (!IsOpenInternal(lock)) { + Cancelled(); + context.reset(); + return; + } + D_ASSERT(buffer); + buffer->Decide(ResultLifetime::RETAINED); + QueryResultState state; + while (!IsTerminal(state = context->ExecuteTaskInternal(lock, *this))) { + if (state == QueryResultState::BLOCKED || state == QueryResultState::READY) { + context->WaitForTask(lock, *this); + } + } + if (state == QueryResultState::FINISHED) { + auto produced = context->GetExecutor().GetResult(); + // Cleanup can fail on an autocommit commit; it records the error on this result + context->CleanupInternal(lock, this, false); + if (!HasError()) { + collection = produced->TakeCollection(); + } + } + context.reset(); +} + +void QueryResult::ThrowNoCollection() const { + throw InvalidInputException("This query result no longer holds a collection: it was taken with TakeCollection, or " + "the result was closed before it was collected"); +} + +ColumnDataCollection &QueryResult::Collection() { + Complete(); + if (HasError()) { + throw InvalidInputException("Attempting to get collection from an unsuccessful query result\n: Error %s", + GetError()); + } + if (!collection) { + ThrowNoCollection(); + } + return *collection; +} + +unique_ptr QueryResult::TakeCollection() { + Complete(); + if (HasError()) { + throw InvalidInputException("Attempting to get collection from an unsuccessful query result\n: Error %s", + GetError()); + } + if (!collection) { + ThrowNoCollection(); + } + return std::move(collection); +} + +Value QueryResult::GetValue(idx_t column_idx, idx_t row_idx) { + Complete(); + if (HasError()) { + ThrowError(); + } + if (!row_collection) { + if (!collection) { + ThrowNoCollection(); + } + row_collection = make_uniq(collection->GetRows()); + } + return row_collection->GetValue(column_idx, row_idx); +} + +idx_t QueryResult::RowCount() { + Complete(); + return collection ? collection->Count() : 0; +} + +//===--------------------------------------------------------------------===// +// Fetch +//===--------------------------------------------------------------------===// +void QueryResult::EndQuery(ClientContextLock &lock, bool invalidate_transaction) { + context->CleanupInternal(lock, this, invalidate_transaction); +} + +void QueryResult::HandleFetchFailure(ClientContextLock &lock, ErrorData error) { + bool invalidate_query = true; + if (!context->ErrorInvalidatesTransaction(error.Type())) { + // standard exceptions do not invalidate the current transaction + invalidate_query = false; + } else if (Exception::InvalidatesDatabase(error.Type())) { + // fatal exceptions invalidate the entire database + auto &db_instance = DatabaseInstance::GetDatabase(*context); + ValidChecker::Invalidate(db_instance, error.RawMessage()); + } + context->ProcessError(error, context->GetCurrentQuery()); + SetError(std::move(error)); + context->CleanupInternal(lock, this, invalidate_query); +} + +unique_ptr QueryResult::FetchInternal() { + Complete(); + if (HasError()) { + throw InvalidInputException("Attempting to fetch from an unsuccessful query result\nError: %s", GetError()); + } + if (!collection) { + ThrowNoCollection(); + } + auto result = make_uniq(); + collection->InitializeScanChunk(*result); + if (!scan_initialized) { + // we disallow zero copy so the chunk is independently usable even after the result is destroyed + collection->InitializeScan(scan_state, ColumnDataScanProperties::DISALLOW_ZERO_COPY); + scan_initialized = true; + } + collection->Scan(scan_state, *result); + if (result->size() == 0) { + return nullptr; + } + return result; } unique_ptr QueryResult::Fetch() { @@ -141,6 +409,39 @@ unique_ptr QueryResult::FetchRaw() { return FetchInternal(); } +//===--------------------------------------------------------------------===// +// Rendering +//===--------------------------------------------------------------------===// +string QueryResult::ToString() { + if (HasError()) { + return GetError() + "\n"; + } + string result = HeaderToString(); + auto &coll = Collection(); + result += "[ Rows: " + to_string(coll.Count()) + "]\n"; + for (auto &row : coll.Rows()) { + for (idx_t col_idx = 0; col_idx < coll.ColumnCount(); col_idx++) { + if (col_idx > 0) { + result += "\t"; + } + auto val = row.GetValue(col_idx); + result += val.IsNull() ? "NULL" : StringUtil::Replace(val.ToString(), string("\0", 1), "\\0"); + } + result += "\n"; + } + result += "\n"; + return result; +} + +string QueryResult::ToBox(BoxRendererContext &context_p, const BoxRendererConfig &config) { + if (HasError()) { + return GetError() + "\n"; + } + BoxRenderer renderer(config); + ColumnDataCollectionWrapper wrapper(Collection()); + return renderer.ToString(context_p, IdentifiersToStrings(GetNames()), wrapper); +} + bool QueryResult::Equals(QueryResult &other, bool compare_names) { // LCOV_EXCL_START // first compare the success state of the results if (HasError() != other.HasError()) { diff --git a/src/duckdb/src/main/query_result_stream.cpp b/src/duckdb/src/main/query_result_stream.cpp new file mode 100644 index 000000000..20971e72b --- /dev/null +++ b/src/duckdb/src/main/query_result_stream.cpp @@ -0,0 +1,224 @@ +#include "duckdb/main/query_result_stream.hpp" + +#include "duckdb/common/string_util.hpp" +#include "duckdb/main/buffered_data/buffered_data.hpp" +#include "duckdb/main/client_context.hpp" +#include "duckdb/main/result_unit.hpp" + +namespace duckdb { + +QueryResultStream::QueryResultStream(unique_ptr result) : handle(std::move(result)) { + if (!handle) { + throw InvalidInputException("Attempting to open a stream on a query result that does not exist"); + } + if (handle->HasError()) { + throw InvalidInputException("Attempting to open a stream on an unsuccessful query result\nError: %s", + handle->GetError()); + } + if (handle->GetStatementProperties().result_eagerness == ResultEagerness::FORCED) { + throw InvalidInputException( + "Attempting to open a stream on a %s statement, which completes before its result is returned", + StatementTypeToString(handle->GetStatementType())); + } + if (!handle->HasBufferedData()) { + throw InvalidInputException("Attempting to open a stream on a query result that has no streaming buffer"); + } + if (handle->GetBufferedData().Decide(ResultLifetime::DRAINING) != ResultLifetime::DRAINING) { + throw InvalidInputException("Attempting to open a stream on a query result that is being retained"); + } +} + +QueryResultStream::~QueryResultStream() { + Close(); +} + +void QueryResultStream::Close() { + handle->Close(); +} + +bool QueryResultStream::IsOpen() { + return handle->IsOpen(); +} + +QueryResultState +QueryResultStream::GuardedInternal(const char *name, + const std::function &call) { + if (!handle->context) { + // The stream already ended. Keep reporting the terminal state + return handle->HasError() ? QueryResultState::EXECUTION_ERROR : QueryResultState::FINISHED; + } + auto lock = handle->LockContext(); + try { + return call(*lock); + } catch (std::exception &ex) { + // A pending interrupt reaches the consumer as an error on the stream, never as a throw + handle->HandleFetchFailure(*lock, ErrorData(ex)); + } catch (...) { // LCOV_EXCL_START + handle->SetError(ErrorData(StringUtil::Format("Unhandled exception in %s", name))); + handle->EndQuery(*lock, true); + } // LCOV_EXCL_STOP + return QueryResultState::EXECUTION_ERROR; +} + +QueryResultState QueryResultStream::Poll() { + auto state = GuardedInternal("Poll", [&](ClientContextLock &lock) { return handle->buffer->Poll(lock, *handle); }); + if (state == QueryResultState::EXECUTION_ERROR) { + Close(); + } + return state; +} + +QueryResultState QueryResultStream::ExecuteTask() { + auto state = GuardedInternal("ExecuteTask", + [&](ClientContextLock &lock) { return handle->buffer->Participate(lock, *handle); }); + if (state == QueryResultState::EXECUTION_ERROR) { + // A finished execution can still hold trailing chunks, so only an error ends the stream here + Close(); + } + return state; +} + +void QueryResultStream::WaitForTask() { + if (!handle->context) { + return; + } + handle->buffer->UnblockSinks(); + handle->WaitForTask(); +} + +QueryResultState QueryResultStream::TryFetch(unique_ptr &out_chunk) { + out_chunk.reset(); + auto state = GuardedInternal("TryFetch", [&](ClientContextLock &lock) { + auto &buffer = *handle->buffer; + auto state = buffer.Poll(lock, *handle); + if (state == QueryResultState::EXECUTION_ERROR) { + return state; + } + if (state == QueryResultState::READY) { + if (auto unit = buffer.Scan()) { + out_chunk = std::move(unit->Cast().chunk); + } + } + if (out_chunk && out_chunk->size() != 0) { + return QueryResultState::READY; + } + out_chunk.reset(); + if (state == QueryResultState::FINISHED) { + // The buffer is drained and execution is done: this is the end of the stream + buffer.AssertNoBlockedSinks(); + handle->EndQuery(lock); + // Cleanup can fail on an autocommit commit. It records the error without throwing + return handle->HasError() ? QueryResultState::EXECUTION_ERROR : QueryResultState::FINISHED; + } + if (state == QueryResultState::READY) { + // A unit was announced but the scan came up empty: the stream has not ended yet + return QueryResultState::NOT_READY; + } + return state; + }); + if (IsTerminal(state)) { + Close(); + } + return state; +} + +unique_ptr QueryResultStream::FetchInternal(ClientContextLock &lock) { + auto &buffer = *handle->buffer; + unique_ptr chunk; + try { + auto state = buffer.ReplenishBuffer(lock, *handle); + if (state == QueryResultState::EXECUTION_ERROR) { + return nullptr; + } + if (auto unit = buffer.Scan()) { + chunk = std::move(unit->Cast().chunk); + } + if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) { + handle->EndQuery(lock); + return nullptr; + } + return chunk; + } catch (std::exception &ex) { + handle->HandleFetchFailure(lock, ErrorData(ex)); + } catch (...) { // LCOV_EXCL_START + handle->SetError(ErrorData("Unhandled exception in Fetch")); + handle->EndQuery(lock, true); + } // LCOV_EXCL_STOP + return nullptr; +} + +unique_ptr QueryResultStream::Fetch() { + if (!handle->context && !handle->HasError()) { + // The stream ended cleanly. Keep reporting the end, the way TryFetch and Poll do + return nullptr; + } + unique_ptr chunk; + { + auto lock = handle->LockContext(); + handle->CheckExecutableInternal(*lock); + chunk = FetchInternal(*lock); + } + if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) { + if (!HasError()) { + handle->buffer->AssertNoBlockedSinks(); + } + Close(); + return nullptr; + } + chunk->Flatten(); + return chunk; +} + +void QueryResultStream::SetError(ErrorData error) { + handle->SetError(std::move(error)); +} + +bool QueryResultStream::HasError() const { + return handle->HasError(); +} + +const string &QueryResultStream::GetError() const { + return handle->GetError(); +} + +const ErrorData &QueryResultStream::GetErrorObject() const { + return handle->GetErrorObject(); +} + +const ExceptionType &QueryResultStream::GetErrorType() const { + return handle->GetErrorType(); +} + +const vector &QueryResultStream::GetTypes() const { + return handle->GetTypes(); +} + +const vector &QueryResultStream::GetNames() const { + return handle->GetNames(); +} + +const Identifier &QueryResultStream::ColumnName(idx_t index) const { + return handle->ColumnName(index); +} + +idx_t QueryResultStream::ColumnCount() const { + return handle->ColumnCount(); +} + +StatementType QueryResultStream::GetStatementType() const { + return handle->GetStatementType(); +} + +const StatementProperties &QueryResultStream::GetStatementProperties() const { + return handle->GetStatementProperties(); +} + +const ClientProperties &QueryResultStream::GetClientProperties() const { + return handle->client_properties; +} + +ClientProperties &QueryResultStream::GetClientProperties() { + return handle->client_properties; +} + +} // namespace duckdb diff --git a/src/duckdb/src/main/relation.cpp b/src/duckdb/src/main/relation.cpp index f496b7636..83991cf04 100644 --- a/src/duckdb/src/main/relation.cpp +++ b/src/duckdb/src/main/relation.cpp @@ -355,7 +355,7 @@ shared_ptr Relation::CreateView(const Identifier &schema_name, const I } unique_ptr Relation::Query(const string &sql) const { - return context->GetContext()->Query(sql, false); + return context->GetContext()->Query(sql, QueryParameters()); } unique_ptr Relation::Query(const Identifier &name, const string &sql) { diff --git a/src/duckdb/src/main/relation/read_csv_relation.cpp b/src/duckdb/src/main/relation/read_csv_relation.cpp index e6dfecff6..90a94de5b 100644 --- a/src/duckdb/src/main/relation/read_csv_relation.cpp +++ b/src/duckdb/src/main/relation/read_csv_relation.cpp @@ -15,7 +15,9 @@ #include "duckdb/parser/tableref/table_function_ref.hpp" #include "duckdb/function/table/read_csv.hpp" #include "duckdb/common/multi_file/multi_file_function.hpp" -#include "duckdb/execution/operator/csv_scanner/csv_multi_file_info.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp" +#include "duckdb/execution/operator/csv_scanner/csv_schema_discovery.hpp" +#include "duckdb/common/multi_file/union_by_name.hpp" namespace duckdb { @@ -37,8 +39,7 @@ CSVReaderOptions ReadCSVRelationBind(const shared_ptr &context, c D_ASSERT(!files.empty()); auto &file_name = files[0]; - CSVFileReaderOptions csv_file_options; - auto &csv_options = csv_file_options.options; + CSVReaderOptions csv_options; csv_options.file_path = file_name.path; vector empty; csv_options.FromNamedParameters(options, *context, file_options); @@ -49,12 +50,14 @@ CSVReaderOptions ReadCSVRelationBind(const shared_ptr &context, c if (file_options.union_by_name) { vector types; vector names; - auto result = make_uniq(); - auto csv_data = make_uniq(); - result->interface = make_uniq(); - - multi_file_reader->BindUnionReader(*context, types, names, multi_file_list, *result, csv_file_options, - file_options); + // sniff every file and unify the columns of the files by name + identifier_map_t union_names_map; + for (auto &file : files) { + auto file_csv_options = csv_options; + file_csv_options.file_path = file.path; + CSVFileScan file_scan(*context, file, file_csv_options, file_options); + UnionByName::CombineUnionTypes(file_scan.GetNames(), file_scan.GetTypes(), types, names, union_names_map); + } if (!csv_options.sql_types_per_column.empty()) { const auto exception = CSVError::ColumnTypesError(csv_options.sql_types_per_column, names); if (!exception.error_message.empty()) { diff --git a/src/duckdb/src/main/relation/table_function_relation.cpp b/src/duckdb/src/main/relation/table_function_relation.cpp index c73cb0218..51ef3ef7b 100644 --- a/src/duckdb/src/main/relation/table_function_relation.cpp +++ b/src/duckdb/src/main/relation/table_function_relation.cpp @@ -30,27 +30,30 @@ void TableFunctionRelation::SetNamedParameters(named_parameter_map_t &&options) TableFunctionRelation::TableFunctionRelation(const shared_ptr &context, string name_p, vector parameters_p, named_parameter_map_t named_parameters, - shared_ptr input_relation_p, bool auto_init) + shared_ptr input_relation_p, bool auto_init, + shared_ptr bind_info_p) : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(std::move(name_p)), parameters(std::move(parameters_p)), named_parameters(std::move(named_parameters)), - input_relation(std::move(input_relation_p)), auto_initialize(auto_init) { + input_relation(std::move(input_relation_p)), bind_info(std::move(bind_info_p)), auto_initialize(auto_init) { InitializeColumns(); } TableFunctionRelation::TableFunctionRelation(const shared_ptr &context, string name_p, vector parameters_p, named_parameter_map_t named_parameters, - shared_ptr input_relation_p, bool auto_init) + shared_ptr input_relation_p, bool auto_init, + shared_ptr bind_info_p) : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(std::move(name_p)), parameters(std::move(parameters_p)), named_parameters(std::move(named_parameters)), - input_relation(std::move(input_relation_p)), auto_initialize(auto_init) { + input_relation(std::move(input_relation_p)), bind_info(std::move(bind_info_p)), auto_initialize(auto_init) { InitializeColumns(); } TableFunctionRelation::TableFunctionRelation(const shared_ptr &context, string name_p, vector parameters_p, shared_ptr input_relation_p, - bool auto_init) + bool auto_init, shared_ptr bind_info_p) : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(std::move(name_p)), - parameters(std::move(parameters_p)), input_relation(std::move(input_relation_p)), auto_initialize(auto_init) { + parameters(std::move(parameters_p)), input_relation(std::move(input_relation_p)), + bind_info(std::move(bind_info_p)), auto_initialize(auto_init) { InitializeColumns(); } @@ -95,6 +98,7 @@ unique_ptr TableFunctionRelation::GetTableRef() { auto table_function = make_uniq(); auto function = make_uniq(name, std::move(children)); table_function->function = std::move(function); + table_function->bind_info = bind_info; return std::move(table_function); } diff --git a/src/duckdb/src/main/result_unit.cpp b/src/duckdb/src/main/result_unit.cpp new file mode 100644 index 000000000..78720be87 --- /dev/null +++ b/src/duckdb/src/main/result_unit.cpp @@ -0,0 +1,15 @@ +#include "duckdb/main/result_unit.hpp" + +namespace duckdb { + +ResultUnit::ResultUnit(idx_t row_count_p, idx_t byte_size_p) : row_count(row_count_p), byte_size(byte_size_p) { +} + +ResultUnit::~ResultUnit() { +} + +ChunkUnit::ChunkUnit(unique_ptr chunk_p) + : ResultUnit(chunk_p->size(), chunk_p->GetDataSize()), chunk(std::move(chunk_p)) { +} + +} // namespace duckdb diff --git a/src/duckdb/src/main/settings/autogenerated_settings.cpp b/src/duckdb/src/main/settings/autogenerated_settings.cpp index 0eefdef63..00e4f4e69 100644 --- a/src/duckdb/src/main/settings/autogenerated_settings.cpp +++ b/src/duckdb/src/main/settings/autogenerated_settings.cpp @@ -126,6 +126,16 @@ void DebugPhysicalTableScanExecutionStrategySetting::OnSet(SettingCallbackInfo & EnumUtil::FromString(StringValue::Get(parameter)); } +//===----------------------------------------------------------------------===// +// Debug Verify Progress +//===----------------------------------------------------------------------===// +void DebugVerifyProgressSetting::OnSet(SettingCallbackInfo &info, Value ¶meter) { + if (parameter.IsNull()) { + throw InvalidInputException("debug_verify_progress setting cannot be NULL"); + } + EnumUtil::FromString(StringValue::Get(parameter)); +} + //===----------------------------------------------------------------------===// // Debug Verify Statement //===----------------------------------------------------------------------===// @@ -209,6 +219,16 @@ void ExplainOutputSetting::OnSet(SettingCallbackInfo &info, Value ¶meter) { EnumUtil::FromString(StringValue::Get(parameter)); } +//===----------------------------------------------------------------------===// +// Fsync Mode +//===----------------------------------------------------------------------===// +void FsyncModeSetting::OnSet(SettingCallbackInfo &info, Value ¶meter) { + if (parameter.IsNull()) { + throw InvalidInputException("fsync_mode setting cannot be NULL"); + } + EnumUtil::FromString(StringValue::Get(parameter)); +} + //===----------------------------------------------------------------------===// // H T T P Proxy //===----------------------------------------------------------------------===// diff --git a/src/duckdb/src/main/settings/custom_settings.cpp b/src/duckdb/src/main/settings/custom_settings.cpp index 64692b2ef..927c85267 100644 --- a/src/duckdb/src/main/settings/custom_settings.cpp +++ b/src/duckdb/src/main/settings/custom_settings.cpp @@ -26,6 +26,7 @@ #include "duckdb/main/config.hpp" #include "duckdb/main/database.hpp" #include "duckdb/main/database_manager.hpp" +#include "duckdb/main/http/http_transport_manager.hpp" #include "duckdb/common/tree_renderer.hpp" #include "duckdb/main/extension_helper.hpp" #include "duckdb/main/extension_callback_manager.hpp" @@ -143,15 +144,16 @@ Value AllocatorBulkDeallocationFlushThresholdSetting::GetSetting(const ClientCon //===----------------------------------------------------------------------===// // Delta Only Variant Legacy Encoding //===----------------------------------------------------------------------===// -void DeltaOnlyVariantEncodingEnabledSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { +void DebugDeltaOnlyVariantEncodingEnabledSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, + const Value &input) { throw InvalidInputException("This setting is not adjustable by a user"); } -void DeltaOnlyVariantEncodingEnabledSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { +void DebugDeltaOnlyVariantEncodingEnabledSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { throw InvalidInputException("This setting is not adjustable by a user"); } -Value DeltaOnlyVariantEncodingEnabledSetting::GetSetting(const ClientContext &context) { +Value DebugDeltaOnlyVariantEncodingEnabledSetting::GetSetting(const ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BOOLEAN(config.options.variant_legacy_encoding); } @@ -316,7 +318,7 @@ void AllowedDirectoriesSetting::ResetGlobal(DatabaseInstance *db, DBConfig &conf Value AllowedDirectoriesSetting::GetSetting(const ClientContext &context) { auto &config = DBConfig::GetConfig(context); vector allowed_directories; - for (auto &dir : config.options.allowed_directories) { + for (auto &dir : config.GetAllowedDirectories()) { allowed_directories.emplace_back(dir); } return Value::LIST(LogicalType::VARCHAR, std::move(allowed_directories)); @@ -350,7 +352,7 @@ void AllowedPathsSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { Value AllowedPathsSetting::GetSetting(const ClientContext &context) { auto &config = DBConfig::GetConfig(context); vector allowed_paths; - for (auto &dir : config.options.allowed_paths) { + for (auto &dir : config.GetAllowedPaths()) { allowed_paths.emplace_back(dir); } return Value::LIST(LogicalType::VARCHAR, std::move(allowed_paths)); @@ -1150,18 +1152,23 @@ void LogQueryPathSetting::OnSet(SettingCallbackInfo &info, Value &input) { //===----------------------------------------------------------------------===// void MaxMemorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { // a percentage is relative to the system memory, since resolving it against maximum_memory would be circular - config.options.maximum_memory = + auto maximum_memory = ParseMemoryLimitOrPercentage(input.ToString(), [&]() { return GetAvailableSystemMemory(config); }); if (db) { - BufferManager::GetBufferManager(*db).SetMemoryLimit(config.options.maximum_memory); + BufferManager::GetBufferManager(*db).SetMemoryLimit(maximum_memory); } + config.options.maximum_memory = maximum_memory; } void MaxMemorySetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + auto old_memory = config.options.maximum_memory; config.SetDefaultMaxMemory(); + auto new_memory = config.options.maximum_memory; + config.options.maximum_memory = old_memory; if (db) { - BufferManager::GetBufferManager(*db).SetMemoryLimit(config.options.maximum_memory); + BufferManager::GetBufferManager(*db).SetMemoryLimit(new_memory); } + config.options.maximum_memory = new_memory; } Value MaxMemorySetting::GetSetting(const ClientContext &context) { @@ -1676,6 +1683,13 @@ Value ThreadsSetting::GetSetting(const ClientContext &context) { return Value::BIGINT(NumericCast(config.options.maximum_threads)); } +static void ResizeAutomaticHTTPClientPool(optional_ptr db, DBConfig &config) { + if (!db || config.options.http_client_pool_capacity != DConstants::INVALID_INDEX) { + return; + } + config.GetHTTPTransportManager().SetCapacity(HTTPTransportManager::AutomaticCapacity(config)); +} + //===----------------------------------------------------------------------===// // Async Threads //===----------------------------------------------------------------------===// @@ -1692,6 +1706,7 @@ void AsyncThreadsSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, cons TaskScheduler::GetScheduler(*db).SetAsyncThreads(new_async_threads); } config.options.async_threads = new_async_threads; + ResizeAutomaticHTTPClientPool(db, config); } void AsyncThreadsSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { @@ -1700,6 +1715,7 @@ void AsyncThreadsSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { TaskScheduler::GetScheduler(*db).SetAsyncThreads(new_async_threads); } config.options.async_threads = new_async_threads; + ResizeAutomaticHTTPClientPool(db, config); } Value AsyncThreadsSetting::GetSetting(const ClientContext &context) { @@ -1707,6 +1723,34 @@ Value AsyncThreadsSetting::GetSetting(const ClientContext &context) { return Value::BIGINT(NumericCast(config.options.async_threads)); } +void HTTPClientPoolCapacitySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + if (input.IsNull()) { + throw InvalidInputException("http_client_pool_capacity must be a positive integer"); + } + auto new_val = input.GetValue(); + if (new_val <= 0) { + throw InvalidInputException( + "http_client_pool_capacity must be a positive integer, RESET it to return to the automatic value"); + } + auto new_capacity = NumericCast(new_val); + if (db) { + config.GetHTTPTransportManager().SetCapacity(new_capacity); + } + config.options.http_client_pool_capacity = new_capacity; +} + +void HTTPClientPoolCapacitySetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + if (db) { + config.GetHTTPTransportManager().SetCapacity(HTTPTransportManager::AutomaticCapacity(config)); + } + config.options.http_client_pool_capacity = DConstants::INVALID_INDEX; +} + +Value HTTPClientPoolCapacitySetting::GetSetting(const ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BIGINT(NumericCast(config.GetHTTPTransportManager().GetCapacity())); +} + //===----------------------------------------------------------------------===// // Warnings As Errors //===----------------------------------------------------------------------===// @@ -1749,7 +1793,7 @@ Value WriteBufferRowGroupMemoryLimitSetting::GetSetting(const ClientContext &con void CurrentTransactionInvalidationPolicySetting::OnSet(SettingCallbackInfo &info, Value &input) { if (!info.context) { throw InvalidInputException( - "current_transaction_invalidaton_policy can only be set when there is an active client context"); + "current_transaction_invalidation_policy can only be set when there is an active client context"); } info.context->transaction.SetInvalidationPolicy( EnumUtil::FromString(input.GetValue())); @@ -1820,7 +1864,8 @@ void ActiveGrammarExtensionsSetting::SetLocal(ClientContext &context, const Valu auto &config = DatabaseInstance::GetDatabase(context).config; auto &callback_manager = config.GetCallbackManager(); - case_insensitive_set_t selected_extensions; + case_insensitive_set_t distinct_names; + vector selected_extensions; if (input.type().id() != LogicalTypeId::LIST) { throw InvalidInputException("'active_grammar_extensions' setting value should be of type VARCHAR[], not %s", input.type().ToString()); @@ -1832,9 +1877,10 @@ void ActiveGrammarExtensionsSetting::SetLocal(ClientContext &context, const Valu val.type().ToString()); } auto val_str = val.GetValue(); - if (!selected_extensions.insert(val_str).second) { + if (!distinct_names.insert(val_str).second) { throw InvalidInputException("'active_grammar_extensions' list contains duplicate value '%s'", val_str); } + selected_extensions.emplace_back(std::move(val_str)); } vector missing; @@ -1912,6 +1958,10 @@ void EnableObjectCacheSetting::OnSet(SettingCallbackInfo &info, Value &) { WarnDeprecatedSetting(info, EnableObjectCacheSetting::Name); } +void ErrorOnDivisionByZeroSetting::OnSet(SettingCallbackInfo &info, Value &) { + WarnDeprecatedSetting(info, ErrorOnDivisionByZeroSetting::Name); +} + void ExperimentalMetadataReuseSetting::OnSet(SettingCallbackInfo &info, Value &) { WarnDeprecatedSetting(info, ExperimentalMetadataReuseSetting::Name); } @@ -1928,10 +1978,6 @@ void LegacyMetricsFormatSetting::OnSet(SettingCallbackInfo &info, Value &) { WarnDeprecatedSetting(info, LegacyMetricsFormatSetting::Name); } -void NullOnDivisionByZeroSetting::OnSet(SettingCallbackInfo &info, Value &) { - WarnDeprecatedSetting(info, NullOnDivisionByZeroSetting::Name); -} - void ProduceArrowStringViewSetting::OnSet(SettingCallbackInfo &info, Value &) { WarnDeprecatedSetting(info, ProduceArrowStringViewSetting::Name); } diff --git a/src/duckdb/src/main/stream_query_result.cpp b/src/duckdb/src/main/stream_query_result.cpp deleted file mode 100644 index c97335b1e..000000000 --- a/src/duckdb/src/main/stream_query_result.cpp +++ /dev/null @@ -1,272 +0,0 @@ -#include "duckdb/main/stream_query_result.hpp" - -#include "duckdb/main/client_context.hpp" -#include "duckdb/main/pending_query_result.hpp" -#include "duckdb/execution/executor.hpp" -#include "duckdb/main/materialized_query_result.hpp" -#include "duckdb/common/box_renderer.hpp" -#include "duckdb/main/database.hpp" - -namespace duckdb { - -StreamQueryResult::StreamQueryResult(StatementType statement_type, StatementProperties properties, - vector types, vector names, - ClientProperties client_properties, shared_ptr data) - : QueryResult(QueryResultType::STREAM_RESULT, statement_type, std::move(properties), std::move(types), - std::move(names), std::move(client_properties)), - buffered_data(std::move(data)) { - context = buffered_data->GetContext(); -} - -StreamQueryResult::StreamQueryResult(ErrorData error) : QueryResult(QueryResultType::STREAM_RESULT, std::move(error)) { -} - -StreamQueryResult::~StreamQueryResult() { -} - -string StreamQueryResult::ToString() { - string result; - if (!HasError()) { - result = HeaderToString(); - result += "[[STREAM RESULT]]"; - } else { - result = GetError() + "\n"; - } - return result; -} - -unique_ptr StreamQueryResult::LockContext() { - if (!context) { - string error_str = "Attempting to execute an unsuccessful or closed pending query result"; - if (HasError()) { - error_str += StringUtil::Format("\nError: %s", GetError()); - } - throw InvalidInputException(error_str); - } - return context->LockContext(); -} - -StreamExecutionResult StreamQueryResult::ExecuteTaskInternal(ClientContextLock &lock) { - return buffered_data->ExecuteTaskInternal(*this, lock); -} - -StreamExecutionResult StreamQueryResult::ExecuteTask() { - auto lock = LockContext(); - return ExecuteTaskInternal(*lock); -} - -void StreamQueryResult::WaitForTask() { - auto lock = LockContext(); - // Nothing to wait for on a result being materialized; ExecuteTask reports it - if (buffered_data->Decide(ResultLifetime::DRAINING) != ResultLifetime::DRAINING) { - return; - } - buffered_data->UnblockSinks(); - context->WaitForTask(*lock, *this); -} - -static bool ExecutionErrorOccurred(StreamExecutionResult result) { - if (result == StreamExecutionResult::EXECUTION_CANCELLED) { - return true; - } - if (result == StreamExecutionResult::EXECUTION_ERROR) { - return true; - } - return false; -} - -unique_ptr StreamQueryResult::FetchNextInternal(ClientContextLock &lock) { - bool invalidate_query = true; - unique_ptr chunk; - try { - // fetch the chunk and return it - auto stream_execution_result = buffered_data->ReplenishBuffer(*this, lock); - if (ExecutionErrorOccurred(stream_execution_result)) { - return chunk; - } - chunk = buffered_data->Scan(); - if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) { - context->CleanupInternal(lock, this); - chunk = nullptr; - } - return chunk; - } catch (std::exception &ex) { - ErrorData error(ex); - if (!Exception::InvalidatesTransaction(error.Type())) { - // standard exceptions do not invalidate the current transaction - invalidate_query = false; - } else if (Exception::InvalidatesDatabase(error.Type())) { - // fatal exceptions invalidate the entire database - auto &db_instance = DatabaseInstance::GetDatabase(*context); - ValidChecker::Invalidate(db_instance, error.RawMessage()); - } - context->ProcessError(error, context->GetCurrentQuery()); - SetError(std::move(error)); - } catch (...) { // LCOV_EXCL_START - SetError(ErrorData("Unhandled exception in FetchInternal")); - } // LCOV_EXCL_STOP - context->CleanupInternal(lock, this, invalidate_query); - return nullptr; -} - -unique_ptr StreamQueryResult::FetchInternal() { - unique_ptr chunk; - { - auto lock = LockContext(); - CheckExecutableInternal(*lock); - chunk = FetchNextInternal(*lock); - } - if (!chunk || chunk->ColumnCount() == 0 || chunk->size() == 0) { - if (!HasError()) { - buffered_data->AssertNoBlockedSinks(); - } - Close(); - return nullptr; - } - return chunk; -} - -#ifdef DUCKDB_ALTERNATIVE_VERIFY -static unique_ptr AlternativeFetch(StreamQueryResult &stream_result) { - // We first use StreamQueryResult::ExecuteTask until IsChunkReady becomes true - // then call Fetch - StreamExecutionResult execution_result; - while (!StreamQueryResult::IsChunkReady(execution_result = stream_result.ExecuteTask())) { - if (execution_result == StreamExecutionResult::BLOCKED) { - stream_result.WaitForTask(); - } - } - if (execution_result == StreamExecutionResult::EXECUTION_CANCELLED) { - throw InvalidInputException("The execution of the query was cancelled before it could finish, likely " - "caused by executing a different query"); - } - if (execution_result == StreamExecutionResult::EXECUTION_ERROR) { - // Mirror Fetch: the error is already on the result, so the drain ends instead of throwing - stream_result.Close(); - return nullptr; - } - return stream_result.Fetch(); -} -#endif - -unique_ptr StreamQueryResult::MaterializeByDraining() { - auto collection = make_uniq(Allocator::DefaultAllocator(), GetTypes()); - - ColumnDataAppendState append_state; - collection->InitializeAppend(append_state); - while (true) { -#ifdef DUCKDB_ALTERNATIVE_VERIFY - auto chunk = AlternativeFetch(*this); -#else - auto chunk = Fetch(); -#endif - if (!chunk || chunk->size() == 0) { - break; - } - collection->Append(append_state, *chunk); - } - if (HasError()) { - return make_uniq(GetErrorObject()); - } - return make_uniq(GetStatementType(), GetStatementProperties(), GetNames(), - std::move(collection), client_properties); -} - -unique_ptr StreamQueryResult::Materialize() { - if (HasError() || !context) { - return make_uniq(GetErrorObject()); - } - bool retained; - unique_ptr result; - { - auto lock = LockContext(); - CheckExecutableInternal(*lock); - retained = buffered_data->Decide(ResultLifetime::RETAINED) == ResultLifetime::RETAINED; - if (retained) { - // Producers append into the sink's collection from here on, so the query runs to - // completion and the collection is taken from the sink instead of copied out of the buffer - PendingExecutionResult execution_result; - while (!PendingQueryResult::IsExecutionFinished(execution_result = - context->ExecuteTaskInternal(*lock, *this))) { - if (execution_result == PendingExecutionResult::BLOCKED || - execution_result == PendingExecutionResult::RESULT_READY) { - context->WaitForTask(*lock, *this); - } - } - if (execution_result == PendingExecutionResult::EXECUTION_FINISHED) { - result = context->GetExecutor().GetResult(); - context->CleanupInternal(*lock, result.get(), false); - } - } - } - if (!retained) { - return MaterializeByDraining(); - } - Close(); - if (HasError()) { - return make_uniq(GetErrorObject()); - } - D_ASSERT(result && result->GetResultType() == QueryResultType::MATERIALIZED_RESULT); - return unique_ptr_cast(std::move(result)); -} - -bool StreamQueryResult::IsOpenInternal(ClientContextLock &lock) { - bool invalidated = HasError() || !context; - if (!invalidated) { - invalidated = !context->IsActiveResult(lock, *this); - } - return !invalidated; -} - -void StreamQueryResult::CheckExecutableInternal(ClientContextLock &lock) { - if (!IsOpenInternal(lock)) { - string error_str = "Attempting to execute an unsuccessful or closed pending query result"; - if (HasError()) { - error_str += StringUtil::Format("\nError: %s", GetError()); - } - throw InvalidInputException(error_str); - } -} - -bool StreamQueryResult::IsOpen() { - if (HasError() || !context) { - return false; - } - auto lock = LockContext(); - return IsOpenInternal(*lock); -} - -void StreamQueryResult::Close() { - buffered_data->Close(); - if (context) { - auto lock = LockContext(); - if (context->IsActiveResult(*lock, *this)) { - // Abandoned before the stream was fully drained: release the active-query state now - // (matching InitialCleanup) instead of leaking it until the next query or context teardown. - context->CleanupInternal(*lock, this, false); - } - } - context.reset(); -} - -bool StreamQueryResult::IsChunkReady(StreamExecutionResult result) { - if (result == StreamExecutionResult::CHUNK_READY) { - // A chunk is ready to be fetched with Fetch() - return true; - } - if (result == StreamExecutionResult::EXECUTION_CANCELLED) { - // Another query execution was started that cancelled this one - return true; - } - if (result == StreamExecutionResult::EXECUTION_ERROR) { - // An error was encountered while executing the final pipeline - return true; - } - if (result == StreamExecutionResult::EXECUTION_FINISHED) { - // The final pipeline completed successfully - return true; - } - return false; -} - -} // namespace duckdb diff --git a/src/duckdb/src/optimizer/aggregate_rewrite_helper.cpp b/src/duckdb/src/optimizer/aggregate_rewrite_helper.cpp index 02c75446c..d6cb8062a 100644 --- a/src/duckdb/src/optimizer/aggregate_rewrite_helper.cpp +++ b/src/duckdb/src/optimizer/aggregate_rewrite_helper.cpp @@ -140,4 +140,18 @@ unique_ptr AggregateRewriteHelper::CreateCTERef(Optimizer &opti return make_uniq(cte_ref_index, cte_index, input_types, input_names); } +unique_ptr AggregateRewriteHelper::PinColumnOrder(Optimizer &optimizer, + unique_ptr definition, + const vector &types, + const vector &bindings) { + vector> expressions; + expressions.reserve(bindings.size()); + for (idx_t col_idx = 0; col_idx < bindings.size(); col_idx++) { + expressions.push_back(make_uniq(types[col_idx], bindings[col_idx])); + } + auto projection = make_uniq(optimizer.binder.GenerateTableIndex(), std::move(expressions)); + projection->children.push_back(std::move(definition)); + return std::move(projection); +} + } // namespace duckdb diff --git a/src/duckdb/src/optimizer/column_binding_replacer.cpp b/src/duckdb/src/optimizer/column_binding_replacer.cpp index 9b462d8e6..aa0261099 100644 --- a/src/duckdb/src/optimizer/column_binding_replacer.cpp +++ b/src/duckdb/src/optimizer/column_binding_replacer.cpp @@ -4,6 +4,7 @@ #include "duckdb/planner/expression/bound_subquery_expression.hpp" #include "duckdb/planner/operator/logical_cte.hpp" #include "duckdb/planner/operator/logical_dependent_join.hpp" +#include "duckdb/planner/operator/logical_secure_view.hpp" #include "duckdb/planner/column_binding_map.hpp" namespace duckdb { @@ -142,6 +143,16 @@ void ColumnBindingReplacer::VisitOperator(LogicalOperator &op) { } void ColumnBindingReplacer::VisitOperatorBindings(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_SECURE_VIEW) { + auto &view = op.Cast(); + for (auto &binding : view.output_bindings) { + for (auto &replacement : replacement_bindings) { + if (binding == replacement.old_binding) { + binding = replacement.new_binding; + } + } + } + } VisitOperatorExpressions(op); } diff --git a/src/duckdb/src/optimizer/common_subplan_optimizer.cpp b/src/duckdb/src/optimizer/common_subplan_optimizer.cpp index 6fdbfe263..ff0557cfe 100644 --- a/src/duckdb/src/optimizer/common_subplan_optimizer.cpp +++ b/src/duckdb/src/optimizer/common_subplan_optimizer.cpp @@ -250,6 +250,9 @@ class PlanSignatureTableIndexMap { auto &get = op.Cast(); switch (TYPE) { case ConversionType::TO_CANONICAL: { + // Source ordinality is represented by the bound operators. + source_ordinality = get.source_ordinality; + get.source_ordinality = OrdinalityType::WITHOUT_ORDINALITY; D_ASSERT(column_ids.empty()); // Grab selected GET columns and populate with all possible columns column_ids = std::move(get.GetMutableColumnIds()); @@ -327,6 +330,7 @@ class PlanSignatureTableIndexMap { break; } case ConversionType::RESTORE_ORIGINAL: + get.source_ordinality = source_ordinality; D_ASSERT(!column_ids.empty()); get.GetMutableColumnIds() = std::move(column_ids); D_ASSERT(get.projection_ids.empty()); @@ -480,6 +484,7 @@ class PlanSignatureTableIndexMap { vector> projection_maps; //! Utility to temporarily store column ids, projection_ids, table indices, expression info and children + OrdinalityType source_ordinality = OrdinalityType::WITHOUT_ORDINALITY; vector column_ids; vector chunk_column_ids; vector projection_ids; diff --git a/src/duckdb/src/optimizer/compressed_materialization.cpp b/src/duckdb/src/optimizer/compressed_materialization.cpp index 72f0ca379..d8074437f 100644 --- a/src/duckdb/src/optimizer/compressed_materialization.cpp +++ b/src/duckdb/src/optimizer/compressed_materialization.cpp @@ -138,6 +138,7 @@ unique_ptr CMHelper::CreateDefaultStatsAwareCast(ClientContext &cont throw InternalException("Expected a cast in CMHelper::CreateDefaultStatsAwareCast"); } // LCOV_EXCL_STOP auto &cast = result->Cast(); + CMUtils::MarkCast(cast); result_stats = BoundCastExpression::PropagateStatistics(cast, input_stats, context); if (!result_stats) { // LCOV_EXCL_START throw InternalException("Could not propagate cast statistics in compressed materialization"); @@ -992,7 +993,8 @@ unique_ptr CompressedMaterialization::GetGeometryDecompress(unique_p BoundScalarFunction bound_function(decompress_function); bound_function.SetReturnType(result_type); - return make_uniq(std::move(bound_function), std::move(arguments), nullptr); + auto result = make_uniq(std::move(bound_function), std::move(arguments), nullptr); + return std::move(result); } unique_ptr CompressedMaterialization::GetIntegralDecompress(unique_ptr input, @@ -1008,7 +1010,8 @@ unique_ptr CompressedMaterialization::GetIntegralDecompress(unique_p BoundScalarFunction bound_function(decompress_function); bound_function.SetReturnType(result_type); - return make_uniq(std::move(bound_function), std::move(arguments), nullptr); + auto result = make_uniq(std::move(bound_function), std::move(arguments), nullptr); + return std::move(result); } unique_ptr CompressedMaterialization::GetStringDecompress(unique_ptr input, @@ -1022,7 +1025,8 @@ unique_ptr CompressedMaterialization::GetStringDecompress(unique_ptr BoundScalarFunction bound_function(decompress_function); bound_function.SetReturnType(result_type); - return make_uniq(std::move(bound_function), std::move(arguments), nullptr); + auto result = make_uniq(std::move(bound_function), std::move(arguments), nullptr); + return std::move(result); } unique_ptr CompressedMaterialization::GetVariantDecompress(unique_ptr input, diff --git a/src/duckdb/src/optimizer/cte_filter_pusher.cpp b/src/duckdb/src/optimizer/cte_filter_pusher.cpp index f1ddf640e..c5e7081d1 100644 --- a/src/duckdb/src/optimizer/cte_filter_pusher.cpp +++ b/src/duckdb/src/optimizer/cte_filter_pusher.cpp @@ -4,6 +4,7 @@ #include "duckdb/optimizer/column_binding_replacer.hpp" #include "duckdb/optimizer/filter_pushdown.hpp" #include "duckdb/planner/expression/bound_conjunction_expression.hpp" +#include "duckdb/planner/expression/expression_barrier.hpp" #include "duckdb/planner/operator/logical_cteref.hpp" #include "duckdb/planner/operator/logical_filter.hpp" #include "duckdb/planner/operator/logical_materialized_cte.hpp" @@ -11,7 +12,8 @@ namespace duckdb { CTEFilterPusher::MaterializedCTEInfo::MaterializedCTEInfo(LogicalOperator &materialized_cte_p) - : materialized_cte(materialized_cte_p), all_cte_refs_are_filtered(true) { + : materialized_cte(materialized_cte_p), all_cte_refs_are_filtered(true), + has_filter_dependency(materialized_cte_p.Cast().filter_dependency != nullptr) { } CTEFilterPusher::CTEFilterPusher(Optimizer &optimizer_p) : optimizer(optimizer_p) { @@ -23,7 +25,8 @@ unique_ptr CTEFilterPusher::Optimize(unique_ptrsecond->all_cte_refs_are_filtered) { + if (it->second->filters.empty() || + (!it->second->all_cte_refs_are_filtered && !it->second->has_filter_dependency)) { continue; } @@ -32,11 +35,43 @@ unique_ptr CTEFilterPusher::Optimize(unique_ptr>(); FindCandidates(*op); - PushFilterIntoCTE(*cte_info_map[it->first]); + auto &info = *cte_info_map[it->first]; + if (CanPushFilter(info)) { + PushFilterIntoCTE(info); + } } return op; } +void CTEFilterPusher::ClearDependencies(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) { + op.Cast().filter_dependency.reset(); + } + for (auto &child : op.children) { + ClearDependencies(*child); + } +} + +bool CTEFilterPusher::CanPushFilter(const MaterializedCTEInfo &info) { + if (info.all_cte_refs_are_filtered) { + return true; + } + auto &cte = info.materialized_cte.Cast(); + if (!cte.filter_dependency || info.references.size() != 2 || info.filters.size() != 1) { + return false; + } + auto &dependency = *cte.filter_dependency; + idx_t row_scans = 0; + idx_t domain_scans = 0; + for (auto &ref : info.references) { + row_scans += ref.get().table_index == dependency.row_scan; + domain_scans += ref.get().table_index == dependency.domain_scan; + } + D_ASSERT(info.filters[0].get().children[0]->type == LogicalOperatorType::LOGICAL_CTE_REF); + auto &filtered_ref = info.filters[0].get().children[0]->Cast(); + return row_scans == 1 && domain_scans == 1 && filtered_ref.table_index == dependency.row_scan; +} + void CTEFilterPusher::FindCandidates(LogicalOperator &op) { if (op.type == LogicalOperatorType::LOGICAL_MATERIALIZED_CTE) { // We encountered a new CTE, add it to the map @@ -51,6 +86,7 @@ void CTEFilterPusher::FindCandidates(LogicalOperator &op) { auto it = cte_info_map.find(to_string(cte_ref.cte_index.index)); if (it != cte_info_map.end()) { it->second->filters.push_back(op); + it->second->references.push_back(cte_ref); } return; } else if (op.type == LogicalOperatorType::LOGICAL_CTE_REF) { @@ -59,6 +95,7 @@ void CTEFilterPusher::FindCandidates(LogicalOperator &op) { auto it = cte_info_map.find(to_string(cte_ref.cte_index.index)); if (it != cte_info_map.end()) { it->second->all_cte_refs_are_filtered = false; + it->second->references.push_back(cte_ref); } return; } @@ -88,9 +125,19 @@ void CTEFilterPusher::PushFilterIntoCTE(MaterializedCTEInfo &info) { replacer.replacement_bindings.emplace_back(old_bindings[i], new_bindings[i]); } + bool all_conjuncts_repeatable = true; + for (auto &expr : filter.get().expressions) { + all_conjuncts_repeatable &= !expr->IsVolatile() && !ExpressionBarrier::Contains(*expr); + } + // We copy the filters and replace the CTE reference bindings with the bindings in the CTE definition unique_ptr inner_expr; for (auto &filter_expr : filter.get().expressions) { + // Dropping a conjunct must not expose errors it previously short-circuited. + if (filter_expr->IsVolatile() || ExpressionBarrier::Contains(*filter_expr) || + (!all_conjuncts_repeatable && filter_expr->CanThrow())) { + continue; + } auto filter_expr_copy = filter_expr->Copy(); replacer.VisitExpression(&filter_expr_copy); if (inner_expr) { @@ -101,6 +148,11 @@ void CTEFilterPusher::PushFilterIntoCTE(MaterializedCTEInfo &info) { } } + // An unrestricted consumer makes the disjunction true. + if (!inner_expr) { + return; + } + if (outer_expr) { outer_expr = make_uniq(ExpressionType::CONJUNCTION_OR, std::move(outer_expr), std::move(inner_expr)); diff --git a/src/duckdb/src/optimizer/expression_rewriter.cpp b/src/duckdb/src/optimizer/expression_rewriter.cpp index 9b9bee511..2b20327ff 100644 --- a/src/duckdb/src/optimizer/expression_rewriter.cpp +++ b/src/duckdb/src/optimizer/expression_rewriter.cpp @@ -25,8 +25,13 @@ static unique_ptr ApplyRule(LogicalOperator &op, const vectorGetAlias(); +#ifdef D_ASSERT_IS_ENABLED + auto return_type = expr->GetReturnType(); +#endif auto result = rule.get().Apply(op, bindings, rule_made_change, is_root); if (result) { + D_ASSERT(result->GetReturnType() != return_type || + result->GetReturnType().EqualsIncludingCollation(return_type)); changes_made = true; // the base node changed: the rule applied changes if (!alias.empty()) { diff --git a/src/duckdb/src/optimizer/grouping_sets_optimizer.cpp b/src/duckdb/src/optimizer/grouping_sets_optimizer.cpp index bd0a493d5..6b625fea5 100644 --- a/src/duckdb/src/optimizer/grouping_sets_optimizer.cpp +++ b/src/duckdb/src/optimizer/grouping_sets_optimizer.cpp @@ -192,9 +192,10 @@ bool GroupingSetsOptimizer::TryExpandGroupingSets(unique_ptr &o } auto cte_name = Identifier(StringUtil::Format("__grouping_sets_input_cte_%llu", cte_index.index)); - result = make_uniq(std::move(cte_name), cte_index, input_types.size(), - std::move(op->children[0]), std::move(result), - CTEMaterialize::CTE_MATERIALIZE_DEFAULT); + auto input = + AggregateRewriteHelper::PinColumnOrder(optimizer, std::move(op->children[0]), input_types, input_bindings); + result = make_uniq(std::move(cte_name), cte_index, input_types.size(), std::move(input), + std::move(result), CTEMaterialize::CTE_MATERIALIZE_DEFAULT); if (aggr.has_estimated_cardinality) { result->SetEstimatedCardinality(aggr.estimated_cardinality); } diff --git a/src/duckdb/src/optimizer/multi_stage_aggregate_rewriter.cpp b/src/duckdb/src/optimizer/multi_stage_aggregate_rewriter.cpp index bd4eac573..fc79f80db 100644 --- a/src/duckdb/src/optimizer/multi_stage_aggregate_rewriter.cpp +++ b/src/duckdb/src/optimizer/multi_stage_aggregate_rewriter.cpp @@ -346,6 +346,7 @@ static BranchResult CreateRewriteBranch(Optimizer &optimizer, LogicalAggregate & optional_idx input_cte_index; if (input_consumers > 1) { input_cte_index = optimizer.binder.GenerateTableIndex().index; + input = AggregateRewriteHelper::PinColumnOrder(optimizer, std::move(input), input_types, input_bindings); } struct StageOutput { @@ -369,7 +370,8 @@ static BranchResult CreateRewriteBranch(Optimizer &optimizer, LogicalAggregate & AggregateRewriteHelper::CreateCTERef(optimizer, TableIndex(input_cte_index.GetIndex()), input_types, input_names, input_bindings, replacements)); } else { - sources.push_back(std::move(input)); + // The validation above guarantees that the input is moved exactly once when no CTE is needed. + sources.push_back(std::move(input)); // NOLINT(bugprone-use-after-move) } } else { auto &source_stage = set.plan->stages[source.stage_index]; @@ -717,6 +719,8 @@ bool MultiStageAggregateRewriter::TryRewrite(unique_ptr &op) { input_names = AggregateRewriteHelper::GenerateColumnNames("__aggregate_input", input_types.size()); input_bindings = op->children[0]->GetColumnBindings(); cte_index = optimizer.binder.GenerateTableIndex(); + op->children[0] = + AggregateRewriteHelper::PinColumnOrder(optimizer, std::move(op->children[0]), input_types, input_bindings); } vector branches; diff --git a/src/duckdb/src/optimizer/optimizer.cpp b/src/duckdb/src/optimizer/optimizer.cpp index 26408f9bd..bd023c585 100644 --- a/src/duckdb/src/optimizer/optimizer.cpp +++ b/src/duckdb/src/optimizer/optimizer.cpp @@ -61,6 +61,7 @@ #include "duckdb/planner/logical_plan_verifier.hpp" #include "duckdb/planner/planner.hpp" #include "duckdb/planner/operator/logical_prepare.hpp" +#include "duckdb/planner/operator/logical_secure_view.hpp" #include "duckdb/optimizer/remote_pushdown_optimizer.hpp" #include "duckdb/main/database_manager.hpp" #include "duckdb/main/settings.hpp" @@ -243,6 +244,10 @@ void Optimizer::RunBuiltInOptimizers() { default: break; } + // determine which secure views may expose the statistics of their contents - this runs before any rewrites so + // that the filters the optimizer pushes into a view are not mistaken for the view restricting its own rows + LogicalSecureView::AnalyzeStatistics(*plan); + // first we perform expression rewrites using the ExpressionRewriter // this does not change the logical plan structure, but only simplifies the expression trees RunOptimizer(OptimizerType::EXPRESSION_REWRITER, [&]() { @@ -287,6 +292,7 @@ void Optimizer::RunBuiltInOptimizers() { CTEFilterPusher cte_filter_pusher(*this); plan = cte_filter_pusher.Optimize(std::move(plan)); }); + CTEFilterPusher::ClearDependencies(*plan); RunOptimizer(OptimizerType::REGEX_RANGE, [&]() { RegexRangeFilter regex_opt; @@ -555,6 +561,7 @@ unique_ptr Optimizer::LowerMandatoryAggregateRewrites(unique_pt unique_ptr Optimizer::Optimize(unique_ptr plan_p) { plan_p = LowerMandatoryAggregateRewrites(std::move(plan_p)); if (!Settings::Get(context)) { + CTEFilterPusher::ClearDependencies(*plan_p); return plan_p; } Verify(*plan_p); @@ -572,6 +579,7 @@ unique_ptr Optimizer::Optimize(unique_ptr plan RunOptimizer(OptimizerType::EXTENSION, [&]() { OptimizerExtensionInput input {GetContext(), *this, pre_optimizer_extension.optimizer_info.get()}; if (pre_optimizer_extension.pre_optimize_function) { + CTEFilterPusher::ClearDependencies(*plan); pre_optimizer_extension.pre_optimize_function(input, plan); } }); diff --git a/src/duckdb/src/optimizer/pushdown/pushdown_secure_view.cpp b/src/duckdb/src/optimizer/pushdown/pushdown_secure_view.cpp index 301c05da7..e2f971af6 100644 --- a/src/duckdb/src/optimizer/pushdown/pushdown_secure_view.cpp +++ b/src/duckdb/src/optimizer/pushdown/pushdown_secure_view.cpp @@ -1,28 +1,57 @@ #include "duckdb/optimizer/filter_pushdown.hpp" #include "duckdb/optimizer/optimizer.hpp" #include "duckdb/planner/expression/expression_barrier.hpp" +#include "duckdb/planner/expression/bound_columnref_expression.hpp" +#include "duckdb/planner/expression_iterator.hpp" #include "duckdb/planner/operator/logical_empty_result.hpp" #include "duckdb/planner/operator/logical_secure_view.hpp" namespace duckdb { +static bool RetainSecureViewFilter(unique_ptr &expression, const LogicalSecureView &view) { + if (expression->GetExpressionClass() == ExpressionClass::BOUND_COLUMN_REF) { + auto &column = expression->Cast(); + if (column.Depth() != 0 || view.output_bindings.size() != view.output_expressions.size()) { + return false; + } + for (idx_t i = 0; i < view.output_bindings.size(); i++) { + if (column.Binding() == view.output_bindings[i]) { + expression = view.output_expressions[i]->Copy(); + return true; + } + } + return false; + } + bool valid = true; + ExpressionIterator::EnumerateChildren( + *expression, [&](unique_ptr &child) { valid = RetainSecureViewFilter(child, view) && valid; }); + return valid; +} + unique_ptr FilterPushdown::PushdownSecureView(unique_ptr op) { D_ASSERT(op->type == LogicalOperatorType::LOGICAL_SECURE_VIEW); // filters can be pushed into a secure view, but only if evaluating them on rows that the view does not emit // cannot be observed from the outside. Expressions that can throw an error or have side effects are wrapped in // a barrier: those are never pushed past an operator inside the view that removes rows, and are always // evaluated after the filters they end up next to. - // + auto &secure_view = op->Cast(); // freeze the cardinality estimate of the view before anything is pushed into it - otherwise the estimate of the - // boundary node reports what the statistics of the view contents say about the caller's predicate - if (!filters.empty() && !op->has_estimated_cardinality) { + // boundary node reports what the statistics of the view contents say about the caller's predicate. Views whose + // statistics are exposed anyway do not need this - the caller can derive the same estimate above the boundary + if (!filters.empty() && !secure_view.propagate_statistics && !op->has_estimated_cardinality) { op->SetEstimatedCardinality(op->children[0]->EstimateCardinality(optimizer.GetContext())); } - auto &secure_view = op->Cast(); FilterPushdown child_pushdown(optimizer, convert_mark_joins, projection_mode); for (auto &f : filters) { auto expr = std::move(f->filter); + if (secure_view.has_source) { + auto source_filter = expr->Copy(); + if (!RetainSecureViewFilter(source_filter, secure_view)) { + source_filter.reset(); + } + secure_view.source_filters.push_back(std::move(source_filter)); + } // the operators inside the view are never shown - report the filter as part of the boundary node instead secure_view.pushed_filters.push_back(expr->ToString()); if (ExpressionBarrier::Required(*expr) && !ExpressionBarrier::Contains(*expr)) { diff --git a/src/duckdb/src/optimizer/remove_unused_columns.cpp b/src/duckdb/src/optimizer/remove_unused_columns.cpp index a59db825d..ab3c4dfbd 100644 --- a/src/duckdb/src/optimizer/remove_unused_columns.cpp +++ b/src/duckdb/src/optimizer/remove_unused_columns.cpp @@ -25,8 +25,10 @@ #include "duckdb/planner/operator/logical_projection.hpp" #include "duckdb/planner/operator/logical_recursive_cte.hpp" #include "duckdb/planner/operator/logical_set_operation.hpp" +#include "duckdb/planner/operator/logical_secure_view.hpp" #include "duckdb/planner/operator/logical_cte.hpp" #include "duckdb/planner/operator/logical_cteref.hpp" +#include "duckdb/planner/operator/logical_window.hpp" #include "duckdb/function/scalar/struct_utils.hpp" #include "duckdb/function/scalar/variant_utils.hpp" #include "duckdb/function/scalar/nested_functions.hpp" @@ -34,6 +36,8 @@ #include "duckdb/optimizer/optimizer.hpp" #include "duckdb/planner/logical_operator_repeatability.hpp" #include "duckdb/planner/subquery/column_binding_layout.hpp" +#include "duckdb/planner/sql_export_helpers.hpp" +#include "duckdb/planner/expression_iterator.hpp" #include namespace duckdb { @@ -135,6 +139,7 @@ void RemoveUnusedColumns::ApplyRecursiveProjections(LogicalRecursiveCTE &rec, entries.push_back(i); } ClearUnusedExpressions(entries, rec.table_index); + ApplySecureViewReplacements(); for (auto &child : rec.children) { child->ResolveOperatorTypes(); @@ -192,7 +197,9 @@ bool RemoveUnusedColumns::TryPruneRecursiveCTE(LogicalRecursiveCTE &rec) { } for (auto &replacement : reference_replacements) { root.projection_map_replacements[replacement.old_binding] = {replacement.new_binding}; + RecordSecureViewReplacement(replacement.old_binding, replacement.new_binding); } + ApplySecureViewReplacements(); return true; } @@ -228,6 +235,9 @@ void RemoveUnusedColumns::ClearUnusedExpressions(vector &list, TableIndex tab idx_t new_col_idx = 0; for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { auto current_binding = ColumnBinding(table_idx, ProjectionIndex(col_idx + offset)); + if (replace && !root.active_secure_views.empty()) { + root.secure_view_replacements[current_binding].clear(); + } auto entry = column_references.find(current_binding); if (entry == column_references.end()) { if (replace) { @@ -260,8 +270,13 @@ void RemoveUnusedColumns::ClearUnusedExpressions(vector &list, TableIndex tab for (idx_t binding_idx = 0; binding_idx < created_bindings; binding_idx++) { map_replacements.emplace_back(table_idx, ProjectionIndex(new_col_idx + binding_idx)); } + if (entry->second.child_columns.empty() || + entry->second.supports_pushdown_extract != PushdownExtractSupport::ENABLED) { + RecordSecureViewReplacement(current_binding, new_binding); + } new_col_idx += created_bindings; } else { + RecordSecureViewReplacement(current_binding, current_binding); new_col_idx++; } } @@ -349,10 +364,182 @@ void RemoveUnusedColumns::VisitPrunableChildren(LogicalOperator &op) { } } +static idx_t ReplaceSecureViewSource(unique_ptr &expression, const ColumnBinding &binding, + const Expression &source_expression, bool &has_other_binding) { + if (expression->GetExpressionClass() == ExpressionClass::BOUND_COLUMN_REF) { + auto &column = expression->Cast(); + if (column.Binding() != binding || column.Depth() != 0) { + has_other_binding = true; + return 0; + } + expression = source_expression.Copy(); + return 1; + } + idx_t replacements = 0; + ExpressionIterator::EnumerateChildren(*expression, [&](unique_ptr &child) { + replacements += ReplaceSecureViewSource(child, binding, source_expression, has_other_binding); + }); + return replacements; +} + +static unique_ptr ComposeSecureViewSource(const Expression &expression, const ColumnBinding &binding, + const Expression &source_expression) { + auto result = expression.Copy(); + bool has_other_binding = false; + auto replacements = ReplaceSecureViewSource(result, binding, source_expression, has_other_binding); + if (has_other_binding || + (replacements != 1 && expression.GetExpressionClass() != ExpressionClass::BOUND_CONSTANT)) { + return nullptr; + } + return result; +} + +void RemoveUnusedColumns::RecordSecureViewReplacement(ColumnBinding old_binding, ColumnBinding new_binding, + unique_ptr expression) { + if (root.active_secure_views.empty()) { + return; + } + auto &columns = root.secure_view_replacements[old_binding]; + for (auto &column : columns) { + if (column.binding == new_binding && + ((!column.expression && !expression) || + (column.expression && expression && column.expression->Equals(*expression)))) { + return; + } + } + columns.push_back({new_binding, std::move(expression)}); +} + +void RemoveUnusedColumns::ApplySecureViewReplacements() { + if (root.secure_view_replacements.empty()) { + return; + } + for (auto &view_ref : root.active_secure_views) { + auto &view = view_ref.get(); + vector bindings; + vector> expressions; + bool valid = true; + for (idx_t i = 0; valid && i < view.output_bindings.size(); i++) { + auto binding = view.output_bindings[i]; + auto replacement = root.secure_view_replacements.find(binding); + if (replacement == root.secure_view_replacements.end()) { + bindings.push_back(binding); + expressions.push_back(std::move(view.output_expressions[i])); + continue; + } + for (auto &column : replacement->second) { + auto source = column.expression + ? ComposeSecureViewSource(*column.expression, binding, *view.output_expressions[i]) + : view.output_expressions[i]->Copy(); + if (!source) { + valid = false; + break; + } + bindings.push_back(column.binding); + expressions.push_back(std::move(source)); + } + } + if (!valid) { + bindings.clear(); + expressions.clear(); + } + view.output_bindings = std::move(bindings); + view.output_expressions = std::move(expressions); + } + root.secure_view_replacements.clear(); +} + +void RemoveUnusedColumns::VisitSecureView(LogicalSecureView &view) { + D_ASSERT(mode == RemoveUnusedColumnsMode::APPLY); + D_ASSERT(!everything_referenced); + D_ASSERT(view.children.size() == 1); + D_ASSERT(view.output_bindings.size() == view.output_expressions.size()); + + root.active_secure_views.push_back(view); + VisitPrunableChildren(view); + root.active_secure_views.pop_back(); + view.ResolveOperatorTypes(); + + auto new_bindings = view.children[0]->GetColumnBindings(); + auto &new_types = view.children[0]->types; + vector> new_expressions; + new_expressions.reserve(new_bindings.size()); + for (idx_t output_idx = 0; output_idx < new_bindings.size(); output_idx++) { + unique_ptr source_expression; + for (idx_t i = 0; i < view.output_bindings.size(); i++) { + if (view.output_bindings[i] != new_bindings[output_idx] || + !SQLExportHelpers::SQLTypesMatch(view.output_expressions[i]->GetReturnType(), new_types[output_idx])) { + continue; + } + if (source_expression && !source_expression->Equals(*view.output_expressions[i])) { + view.output_bindings.clear(); + view.output_expressions.clear(); + return; + } + source_expression = view.output_expressions[i]->Copy(); + } + if (!source_expression) { + view.output_bindings.clear(); + view.output_expressions.clear(); + return; + } + new_expressions.push_back(std::move(source_expression)); + } + view.output_bindings = std::move(new_bindings); + view.output_expressions = std::move(new_expressions); +} + void RemoveUnusedColumns::VisitOperator(unique_ptr &op_ref) { const bool analyze = mode == RemoveUnusedColumnsMode::ANALYZE; auto &op = *op_ref; switch (op.type) { + case LogicalOperatorType::LOGICAL_WINDOW: { + auto &window = op.Cast(); + // Preserve volatile evaluation within the window expression, even when its output is unused. + // Column references do not propagate volatility from their producers. + if (!everything_referenced) { + for (idx_t i = 0; i < window.expressions.size(); i++) { + if (window.expressions[i]->IsVolatile()) { + column_references.emplace(ColumnBinding(window.window_index, ProjectionIndex(i)), + ReferencedColumn()); + } + } + } + if (analyze) { + // Windows also pass through child columns, so retain the existing references. + for (idx_t i = 0; i < window.expressions.size(); i++) { + auto binding = ColumnBinding(window.window_index, ProjectionIndex(i)); + if (everything_referenced || column_references.find(binding) != column_references.end()) { + VisitExpression(&window.expressions[i]); + } + } + VisitOperator(window.children[0]); + return; + } + if (!everything_referenced) { + ClearUnusedExpressions(window.expressions, window.window_index); + ApplySecureViewReplacements(); + } + if (window.expressions.empty()) { + // A window with no remaining outputs preserves its child's rows and bindings. + auto child = std::move(window.children[0]); + op_ref = std::move(child); + VisitOperator(op_ref); + return; + } + VisitOperatorExpressions(window); + VisitPrunableChildren(window); + return; + } + case LogicalOperatorType::LOGICAL_SECURE_VIEW: { + auto &view = op.Cast(); + if (!analyze && !everything_referenced && view.has_source && + view.output_bindings.size() == view.output_expressions.size()) { + VisitSecureView(view); + return; + } + break; + } case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: { // aggregate auto &aggr = op.Cast(); @@ -373,6 +560,7 @@ void RemoveUnusedColumns::VisitOperator(unique_ptr &op_ref) { if (!everything_referenced) { // FIXME: groups that are not referenced need to stay -> but they don't need to be scanned and output! ClearUnusedExpressions(aggr.expressions, aggr.aggregate_index); + ApplySecureViewReplacements(); if (aggr.expressions.empty() && aggr.groups.empty()) { // removed all expressions from the aggregate: push a COUNT(*) auto count_star_fun = GetBuiltinAggregateFunction(context, CountStarFun::Name, {}); @@ -486,6 +674,7 @@ void RemoveUnusedColumns::VisitOperator(unique_ptr &op_ref) { } ClearUnusedExpressions(entries, setop.table_index); if (entries.size() >= setop.column_count) { + ApplySecureViewReplacements(); // We still need to recurse into the children to populate CTE info, etc. for (auto &child : op.children) { RemoveUnusedColumns remove(*this, true); @@ -498,7 +687,10 @@ void RemoveUnusedColumns::VisitOperator(unique_ptr &op_ref) { // no columns referenced: this happens in the case of a COUNT(*) // extract the first column entries.push_back(0); + auto binding = ColumnBinding(setop.table_index, ProjectionIndex(0)); + RecordSecureViewReplacement(binding, binding); } + ApplySecureViewReplacements(); for (idx_t child_idx = 0; child_idx < op.children.size(); child_idx++) { RemoveUnusedColumns remove(*this, true); auto &child = op.children[child_idx]; @@ -568,7 +760,10 @@ void RemoveUnusedColumns::VisitOperator(unique_ptr &op_ref) { // this happens in the case of e.g. EXISTS(SELECT * FROM ...) // in this case we only need to project a single constant proj.expressions.push_back(make_uniq(Value::INTEGER(42))); + auto binding = ColumnBinding(proj.table_index, ProjectionIndex(0)); + RecordSecureViewReplacement(binding, binding, proj.expressions[0]->Copy()); } + ApplySecureViewReplacements(); } // then recurse into the children of this projection RemoveUnusedColumns remove(*this, false); @@ -748,8 +943,11 @@ void RemoveUnusedColumns::VisitOperator(unique_ptr &op_ref) { cte_ref_pruner.VisitOperator(*cte.children[1]); for (auto &replacement : cte_ref_pruner.binding_replacements) { root.projection_map_replacements[replacement.old_binding] = {replacement.new_binding}; + RecordSecureViewReplacement(replacement.old_binding, replacement.new_binding); } + ApplySecureViewReplacements(); + // We also need to rewrite the column bindings in the right-hand side of the CTE to account for the removed // columns on the left-hand side. Conveniently, the CTERefPruner already has the information about which // columns were removed, so we can reuse it for the column binding replacement. @@ -898,6 +1096,8 @@ void RemoveUnusedColumns::WritePushdownExtractColumns( auto return_type = expr->GetReturnType(); auto &colref = col.bindings[struct_extract.bindings_idx]; + auto old_binding = colref.get().Binding(); + auto source = root.active_secure_views.empty() ? nullptr : expr->Copy(); auto colref_copy = colref.get().Copy(); expr = std::move(colref_copy); auto &new_expr = expr->Cast(); @@ -905,6 +1105,7 @@ void RemoveUnusedColumns::WritePushdownExtractColumns( auto column_index = callback(*entry, component.cast ? &(*component.cast)->GetReturnType() : nullptr); new_expr.BindingMutable().column_index = column_index; + RecordSecureViewReplacement(old_binding, new_expr.Binding(), std::move(source)); } } @@ -1083,6 +1284,7 @@ void RemoveUnusedColumns::RemoveColumnsFromLogicalColumnDataGet(LogicalColumnDat auto column_ids = get.GetColumnIds(); ClearUnusedExpressions(column_ids, get.table_index); + ApplySecureViewReplacements(); get.SetColumnIds(std::move(column_ids)); } @@ -1142,17 +1344,20 @@ void RemoveUnusedColumns::RemoveColumnsFromLogicalGet(LogicalGet &get, unique_pt //! Now visit the filter to add to the 'column_references' VisitExpression(&filter_expression); } + //! The 'column_references' hold references to these expressions, so they have to stay alive + vector> multi_filter_columns; for (const auto &filter : get.table_filters.GetMultiColumnFilters()) { const auto &expression_filter = ExpressionFilter::GetExpressionFilter(*filter, "RemoveUnusedColumns::VisitGet"); for (const auto &filter_idx : expression_filter.column_indexes) { const auto &col_id = get.GetColumnIndex(filter_idx); auto column_type = get.GetColumnType(col_id); ColumnBinding filter_binding(get.table_index, filter_idx); - unique_ptr column_ref = - make_uniq(std::move(column_type), filter_binding); - VisitExpression(&column_ref); + multi_filter_columns.push_back(make_uniq(std::move(column_type), filter_binding)); } } + for (auto &column_ref : multi_filter_columns) { + VisitExpression(&column_ref); + } //! Check with the LogicalGet whether pushdown-extract is supported CheckPushdownExtract(get); @@ -1215,6 +1420,7 @@ void RemoveUnusedColumns::RemoveColumnsFromLogicalGet(LogicalGet &get, unique_pt original_ids.emplace_back(any_column); new_column_ids.emplace_back(any_column); } + ApplySecureViewReplacements(); get.SetColumnIds(std::move(new_column_ids)); // remap table filters so they point towards the new set of ids diff --git a/src/duckdb/src/optimizer/row_group_pruner.cpp b/src/duckdb/src/optimizer/row_group_pruner.cpp index 9488dbd21..a93b90e9d 100644 --- a/src/duckdb/src/optimizer/row_group_pruner.cpp +++ b/src/duckdb/src/optimizer/row_group_pruner.cpp @@ -188,6 +188,9 @@ RowGroupPruner::CreateRowGroupReordererOptions(const optional_idx row_limit, con order_by, column_type, order_type, null_order, storage_index, row_offset.GetIndex(), partition_stats); if (offset_puning_result.pruned_row_group_count > 0 || offset_puning_result.leading_null_group_offset > 0) { // We can prune row groups and/or reduce the offset by consuming definite NULL-only groups + if (!logical_limit.unpruned_offset.IsValid()) { + logical_limit.unpruned_offset = row_offset; + } logical_limit.offset_val = BoundLimitNode::ConstantValue(NumericCast(offset_puning_result.offset_remainder)); diff --git a/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp b/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp index 64e59b445..12424950f 100644 --- a/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp +++ b/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp @@ -40,18 +40,21 @@ unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, if (constant.GetValue() == 0) { // addition with 0 // we can remove the entire operator and replace it with the non-constant child - return std::move(root.GetChildrenMutable()[1 - constant_child]); + return Expression::PreserveReturnType(root.GetReturnType(), + std::move(root.GetChildrenMutable()[1 - constant_child])); } } else if (func_name == "-") { if (constant_child == 1 && constant.GetValue() == 0) { // subtraction by 0 // we can remove the entire operator and replace it with the non-constant child - return std::move(root.GetChildrenMutable()[1 - constant_child]); + return Expression::PreserveReturnType(root.GetReturnType(), + std::move(root.GetChildrenMutable()[1 - constant_child])); } } else if (func_name == "*") { if (constant.GetValue() == 1) { // multiply with 1, replace with non-constant child - return std::move(root.GetChildrenMutable()[1 - constant_child]); + return Expression::PreserveReturnType(root.GetReturnType(), + std::move(root.GetChildrenMutable()[1 - constant_child])); } else if (constant.GetValue() == 0) { // multiply by zero: replace with constant or null return ExpressionRewriter::ConstantOrNull(GetContext(), @@ -62,8 +65,9 @@ unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, if (constant_child == 1) { if (constant.GetValue() == 1) { // divide by 1, replace with non-constant child - return std::move(root.GetChildrenMutable()[1 - constant_child]); - } else if (constant.GetValue() == 0 && Settings::Get(rewriter.context)) { + return Expression::PreserveReturnType(root.GetReturnType(), + std::move(root.GetChildrenMutable()[1 - constant_child])); + } else if (constant.GetValue() == 0 && !Settings::Get(rewriter.context)) { // divide by 0, replace with NULL return make_uniq(Value(root.GetReturnType())); } diff --git a/src/duckdb/src/optimizer/rule/case_simplification.cpp b/src/duckdb/src/optimizer/rule/case_simplification.cpp index 4e2568a3c..0fdaff5b7 100644 --- a/src/duckdb/src/optimizer/rule/case_simplification.cpp +++ b/src/duckdb/src/optimizer/rule/case_simplification.cpp @@ -40,7 +40,7 @@ unique_ptr CaseSimplificationRule::Apply(LogicalOperator &op, vector } if (root.CaseChecksMutable().empty()) { // no case checks left: return the ELSE expression - return std::move(root.ElseMutable()); + return Expression::PreserveReturnType(root.GetReturnType(), std::move(root.ElseMutable())); } return nullptr; } diff --git a/src/duckdb/src/optimizer/rule/constant_order_normalization.cpp b/src/duckdb/src/optimizer/rule/constant_order_normalization.cpp index 4768b8a3b..929b2d4d8 100644 --- a/src/duckdb/src/optimizer/rule/constant_order_normalization.cpp +++ b/src/duckdb/src/optimizer/rule/constant_order_normalization.cpp @@ -141,7 +141,7 @@ unique_ptr ConstantOrderNormalizationRule::Apply(LogicalOperator &op D_ASSERT(children.size() == 1); D_ASSERT(children[0]->GetReturnType() == root.GetReturnType()); - return std::move(children[0]); + return Expression::PreserveReturnType(root.GetReturnType(), std::move(children[0])); } } // namespace duckdb diff --git a/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp b/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp index ae6732eb2..12ab18a4d 100644 --- a/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp +++ b/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp @@ -23,7 +23,7 @@ static unique_ptr TryRemoveEmptyStringConcat(ClientContext &context, if (value.IsNull() || value.type().id() != LogicalTypeId::VARCHAR || !StringValue::Get(value).empty()) { continue; } - return std::move(children[1 - child_idx]); + return Expression::PreserveReturnType(root.GetReturnType(), std::move(children[1 - child_idx])); } return nullptr; } @@ -110,7 +110,7 @@ unique_ptr NoopReplaceRemovalRule::Apply(LogicalOperator &op, vector if (StringValue::Get(needle) != StringValue::Get(replacement)) { return nullptr; } - return std::move(root.GetChildrenMutable()[0]); + return Expression::PreserveReturnType(root.GetReturnType(), std::move(root.GetChildrenMutable()[0])); } } // namespace duckdb diff --git a/src/duckdb/src/optimizer/rule/least_greatest_simplification.cpp b/src/duckdb/src/optimizer/rule/least_greatest_simplification.cpp index 7f7595808..26b82cab9 100644 --- a/src/duckdb/src/optimizer/rule/least_greatest_simplification.cpp +++ b/src/duckdb/src/optimizer/rule/least_greatest_simplification.cpp @@ -23,7 +23,7 @@ unique_ptr LeastGreatestSimplificationRule::Apply(LogicalOperator &o if (children[0]->IsVolatile() || !children[0]->Equals(*children[1])) { return nullptr; } - return std::move(children[0]); + return Expression::PreserveReturnType(root.GetReturnType(), std::move(children[0])); } } // namespace duckdb diff --git a/src/duckdb/src/optimizer/rule/move_constants.cpp b/src/duckdb/src/optimizer/rule/move_constants.cpp index fc5cac60c..db16d0126 100644 --- a/src/duckdb/src/optimizer/rule/move_constants.cpp +++ b/src/duckdb/src/optimizer/rule/move_constants.cpp @@ -91,7 +91,7 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vector MoveConstantsRule::Apply(LogicalOperator &op, vector MoveConstantsRule::Apply(LogicalOperator &op, vector 2] BoundComparisonExpression::FlipType(comparison); @@ -180,7 +180,7 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vector MoveUnaryMinusRule::Apply(LogicalOperator &op, vector MoveUnaryMinusRule::Apply(LogicalOperator &op, vector(negated_value), width, scale); + outer_constant.SetValue(Value::DECIMAL(Cast::Operation(negated_value), width, scale)); break; case PhysicalType::INT32: - outer_constant.GetValueMutable() = - Value::DECIMAL(Cast::Operation(negated_value), width, scale); + outer_constant.SetValue(Value::DECIMAL(Cast::Operation(negated_value), width, scale)); break; case PhysicalType::INT64: - outer_constant.GetValueMutable() = - Value::DECIMAL(Cast::Operation(negated_value), width, scale); + outer_constant.SetValue(Value::DECIMAL(Cast::Operation(negated_value), width, scale)); break; case PhysicalType::INT128: - outer_constant.GetValueMutable() = Value::DECIMAL(negated_value, width, scale); + outer_constant.SetValue(Value::DECIMAL(negated_value, width, scale)); break; default: throw InternalException("Unknown DECIMAL physical type"); @@ -347,7 +344,7 @@ unique_ptr MoveUnaryMinusRule::Apply(LogicalOperator &op, vector [x FLIPPED_COMP -c] auto inner_expr = std::move(negation.GetChildrenMutable()[0]); diff --git a/src/duckdb/src/optimizer/scalar_fn_pushdown.cpp b/src/duckdb/src/optimizer/scalar_fn_pushdown.cpp index 9cb58267c..ea8b12da7 100644 --- a/src/duckdb/src/optimizer/scalar_fn_pushdown.cpp +++ b/src/duckdb/src/optimizer/scalar_fn_pushdown.cpp @@ -71,12 +71,12 @@ unique_ptr ScalarFnReplace::VisitReplace(BoundColumnRefExpression &e return std::move(*ptr); } - const auto &[analysis, column_index, projection] = *binding; + const auto &[analysis, column_index, projection, projection_column_index] = *binding; if (CanPushdownColumn(analysis, column_index)) { const LogicalType return_type = analysis.get.returned_types[analysis.StorageIndex(column_index)]; expr.SetReturnType(return_type); if (projection != nullptr && !projection->types.empty()) { - projection->types[column_index] = return_type; + projection->types[projection_column_index] = return_type; } } @@ -99,7 +99,7 @@ unique_ptr ScalarFnReplace::VisitReplace(BoundFunctionExpression &ex return nullptr; } - const auto &[analysis, column_index, projection] = *binding; + const auto &[analysis, column_index, projection, projection_column_index] = *binding; if (!CanPushdownColumn(analysis, column_index)) { return std::move(*ptr); } @@ -107,7 +107,7 @@ unique_ptr ScalarFnReplace::VisitReplace(BoundFunctionExpression &ex const LogicalType return_type = analysis.get.returned_types[analysis.StorageIndex(column_index)]; bound_col_base->SetReturnType(return_type); if (projection != nullptr && !projection->types.empty()) { - projection->types[column_index] = return_type; + projection->types[projection_column_index] = return_type; } return std::move(bound_col_base); } diff --git a/src/duckdb/src/optimizer/statistics/expression/propagate_function.cpp b/src/duckdb/src/optimizer/statistics/expression/propagate_function.cpp index 6aadff67a..597c8cea4 100644 --- a/src/duckdb/src/optimizer/statistics/expression/propagate_function.cpp +++ b/src/duckdb/src/optimizer/statistics/expression/propagate_function.cpp @@ -40,6 +40,10 @@ bool CanInferConstantFromNumericBounds(const Value &value) { } bool TryInferConstantBounds(const BaseStatistics &stats, Value &constant) { + if (stats.CanHaveNull() && !stats.CanHaveNoNull()) { + constant = Value(stats.GetType()); + return true; + } if (stats.CanHaveNull()) { return false; } diff --git a/src/duckdb/src/optimizer/statistics/expression/propagate_operator.cpp b/src/duckdb/src/optimizer/statistics/expression/propagate_operator.cpp index cccf58edb..94f99ff34 100644 --- a/src/duckdb/src/optimizer/statistics/expression/propagate_operator.cpp +++ b/src/duckdb/src/optimizer/statistics/expression/propagate_operator.cpp @@ -50,7 +50,7 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundOperat D_ASSERT(expr.GetChildrenMutable().size() == child_stats.size()); if (expr.GetChildrenMutable().size() == 1) { // coalesce of one entry: simply return that entry - expr_ptr = std::move(expr.GetChildrenMutable()[0]); + expr_ptr = Expression::PreserveReturnType(expr.GetReturnType(), std::move(expr.GetChildrenMutable()[0])); } else { // coalesce of multiple entries // merge the stats diff --git a/src/duckdb/src/optimizer/statistics/operator/propagate_secure_view.cpp b/src/duckdb/src/optimizer/statistics/operator/propagate_secure_view.cpp index 18da8cf93..b33985f10 100644 --- a/src/duckdb/src/optimizer/statistics/operator/propagate_secure_view.cpp +++ b/src/duckdb/src/optimizer/statistics/operator/propagate_secure_view.cpp @@ -11,24 +11,37 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalSecu bindings_before.insert(entry.first); } - // propagate into the view - the view definition itself is still optimized using its own statistics - PropagateChildren(op, node_ptr); + // propagate into the view - the view definition itself is always optimized using its own statistics + auto child_stats = PropagateStatistics(op.children[0]); - // discard every statistic that was derived from the contents of the view. Statistics describe the data itself - // (min/max, null counts, distinct counts) - leaking them past a secure view would expose values from rows that - // the view does not return, both through stats() and by allowing filters on top of the view to be pruned. + // statistics describe the data itself (min/max, null counts, distinct counts). Only the statistics of the columns + // that the view emits may cross the boundary, and only if the view emits every row it reads - otherwise they would + // expose values from rows that the view does not return, both through stats() and by allowing filters on top of + // the view to be pruned. + column_binding_set_t exposed_bindings; + if (op.propagate_statistics) { + for (auto &binding : op.GetColumnBindings()) { + exposed_bindings.insert(binding); + } + } vector leaked_bindings; for (auto &entry : statistics_map) { - if (bindings_before.find(entry.first) == bindings_before.end()) { - leaked_bindings.push_back(entry.first); + if (bindings_before.find(entry.first) != bindings_before.end()) { + continue; + } + if (exposed_bindings.find(entry.first) != exposed_bindings.end()) { + continue; } + leaked_bindings.push_back(entry.first); } for (auto &binding : leaked_bindings) { statistics_map.erase(binding); } - - // no cardinality information escapes the view either - return nullptr; + if (!op.propagate_statistics) { + // no cardinality information escapes the view either + return nullptr; + } + return child_stats; } } // namespace duckdb diff --git a/src/duckdb/src/optimizer/statistics_propagator.cpp b/src/duckdb/src/optimizer/statistics_propagator.cpp index 8d200e6f4..86d062c3e 100644 --- a/src/duckdb/src/optimizer/statistics_propagator.cpp +++ b/src/duckdb/src/optimizer/statistics_propagator.cpp @@ -161,7 +161,11 @@ unique_ptr StatisticsPropagator::PropagateExpression(Expression } unique_ptr StatisticsPropagator::PropagateExpression(unique_ptr &expr) { +#ifdef D_ASSERT_IS_ENABLED + auto return_type = expr->GetReturnType(); +#endif auto stats = PropagateExpression(*expr, expr); + D_ASSERT(expr->GetReturnType() != return_type || expr->GetReturnType().EqualsIncludingCollation(return_type)); if (Settings::Get(context) && stats) { expr->SetVerificationStats(stats->ToUnique()); } diff --git a/src/duckdb/src/optimizer/topn_optimizer.cpp b/src/duckdb/src/optimizer/topn_optimizer.cpp index 6816757dc..a2c9f805b 100644 --- a/src/duckdb/src/optimizer/topn_optimizer.cpp +++ b/src/duckdb/src/optimizer/topn_optimizer.cpp @@ -184,6 +184,7 @@ unique_ptr TopN::Optimize(unique_ptr op) { offset_val = limit.offset_val.GetConstantValue(); } auto topn = make_uniq(std::move(order_by.orders), limit_val, offset_val); + topn->unpruned_offset = limit.unpruned_offset; topn->AddChild(std::move(order_by.children[0])); auto cardinality = limit_val; if (topn->children[0]->has_estimated_cardinality && topn->children[0]->estimated_cardinality < limit_val) { diff --git a/src/duckdb/src/optimizer/type_pushdown.cpp b/src/duckdb/src/optimizer/type_pushdown.cpp index 2e36ffe2b..8ebbbb215 100644 --- a/src/duckdb/src/optimizer/type_pushdown.cpp +++ b/src/duckdb/src/optimizer/type_pushdown.cpp @@ -92,7 +92,7 @@ optional Resolve(ColumnBinding binding, Analyses &analyses, const Pr return nullopt; } if (const auto it = analyses.find(binding.table_index); it != analyses.end()) { - return {{it->second, binding.column_index, nullptr}}; + return {{it->second, binding.column_index, nullptr, binding.column_index}}; } const auto projection_it = projections.find(binding.table_index); @@ -110,7 +110,7 @@ optional Resolve(ColumnBinding binding, Analyses &analyses, const Pr return nullopt; } if (const auto it = analyses.find(get_binding.table_index); it != analyses.end()) { - return {{it->second, get_binding.column_index, &projection}}; + return {{it->second, get_binding.column_index, &projection, binding.column_index}}; } return nullopt; } @@ -236,7 +236,7 @@ unique_ptr CastReplace::VisitReplace(BoundColumnRefExpression &expr, return std::move(*ptr); } - const auto &[analysis, column_index, projection] = *binding; + const auto &[analysis, column_index, projection, projection_column_index] = *binding; if (CanPushdownColumn(analysis, column_index)) { const LogicalType return_type = analysis.get.returned_types[analysis.StorageIndex(column_index)]; expr.SetReturnType(return_type); @@ -244,7 +244,7 @@ unique_ptr CastReplace::VisitReplace(BoundColumnRefExpression &expr, // LogicalProjection::ResolveTypes, so we need to check whether types in // projection have been resolved, and updated them only if needed. if (projection != nullptr && !projection->types.empty()) { - projection->types[column_index] = return_type; + projection->types[projection_column_index] = return_type; } } @@ -265,7 +265,7 @@ unique_ptr CastReplace::VisitReplace(BoundFunctionExpression &expr, return nullptr; } - const auto &[analysis, column_index, projection] = *binding; + const auto &[analysis, column_index, projection, projection_column_index] = *binding; if (!CanPushdownColumn(analysis, column_index)) { return std::move(*ptr); } @@ -274,7 +274,7 @@ unique_ptr CastReplace::VisitReplace(BoundFunctionExpression &expr, bound_col_base->SetReturnType(return_type); // Same as in CastReplace::VisitReplace(BoundColumnRefExpression) if (projection != nullptr && !projection->types.empty()) { - projection->types[column_index] = return_type; + projection->types[projection_column_index] = return_type; } return std::move(bound_col_base); } diff --git a/src/duckdb/src/parallel/executor.cpp b/src/duckdb/src/parallel/executor.cpp index 03953951e..14b8e78b8 100644 --- a/src/duckdb/src/parallel/executor.cpp +++ b/src/duckdb/src/parallel/executor.cpp @@ -7,6 +7,7 @@ #include "duckdb/execution/operator/set/physical_cte.hpp" #include "duckdb/execution/operator/set/physical_recursive_cte.hpp" #include "duckdb/execution/physical_operator.hpp" +#include "duckdb/main/buffered_data/buffered_data.hpp" #include "duckdb/main/client_context.hpp" #include "duckdb/main/client_data.hpp" #include "duckdb/main/settings.hpp" @@ -18,6 +19,7 @@ #include "duckdb/parallel/pipeline_initialize_event.hpp" #include "duckdb/parallel/pipeline_prepare_finish_event.hpp" #include "duckdb/parallel/pipeline_schedule.hpp" +#include "duckdb/parallel/progress_verifier.hpp" #include "duckdb/parallel/task_scheduler.hpp" #include "duckdb/parallel/thread_context.hpp" @@ -240,6 +242,12 @@ void Executor::InitializeInternal(PhysicalOperator &plan) { this->profiler = ClientData::Get(context).profiler; this->producer = scheduler.CreateProducer(); + auto verify_progress = Settings::Get(context); + if (verify_progress != DebugProgressVerification::NONE) { + progress_verifier = make_uniq(context, verify_progress, + Settings::Get(context)); + } + // build and ready the pipelines PipelineBuildState state; auto root_pipeline = make_shared_ptr(*this, state, nullptr); @@ -277,6 +285,10 @@ void Executor::InitializeInternal(PhysicalOperator &plan) { void Executor::CancelTasks() { task.reset(); + { + lock_guard guard(result_buffer_lock); + result_buffer.reset(); + } reference_map_t> to_destroy; { lock_guard elock(executor_lock); @@ -372,7 +384,7 @@ void Executor::WaitForTask() { return; } if (ResultCollectorIsBlocked()) { - // If the result collector is blocked, it won't get unblocked until the connection calls Fetch + // Only the consumer's decision or pop lets the query progress, so waiting here is pointless blocked_thread_time += blocked_micros; return; } @@ -419,8 +431,8 @@ void Executor::AddToBeRescheduled(shared_ptr &task_p) { // Save the reference before move — evaluation order of operator[] key and assignment value is unspecified pre-C++17 auto &task_ref = *task_p; to_be_rescheduled_tasks[task_ref] = std::move(task_p); - // Only a result-sink park needs the consumer, so only a streaming plan wakes the waiting consumer - if (HasStreamingResultCollector()) { + // Only a result-sink park needs the consumer, so only a store that can park wakes it + if (ResultStoreCanPark()) { task_reschedule.notify_all(); } } @@ -429,48 +441,26 @@ bool Executor::ExecutionIsFinished() { return completed_pipelines >= total_pipelines || HasError(); } -PendingExecutionResult Executor::ExecuteTask(bool dry_run) { +QueryResultState Executor::ExecuteTask() { // Only executor should return NO_TASKS_AVAILABLE - D_ASSERT(execution_result != PendingExecutionResult::NO_TASKS_AVAILABLE); - if (execution_result != PendingExecutionResult::RESULT_NOT_READY && ExecutionIsFinished()) { + D_ASSERT(execution_result != QueryResultState::NO_TASKS_AVAILABLE); + if (execution_result != QueryResultState::NOT_READY && ExecutionIsFinished()) { return execution_result; } - // check if there are any incomplete pipelines - auto &scheduler = TaskScheduler::GetScheduler(context); if (completed_pipelines < total_pipelines) { - // there are! if we don't already have a task, fetch one - auto current_task = task.get(); - if (dry_run) { - // Pretend we have no task, we don't want to execute anything - current_task = nullptr; - } else { - if (!task) { - scheduler.GetTaskFromProducer(*producer, task); - } - current_task = task.get(); + if (!task) { + TaskScheduler::GetScheduler(context).GetTaskFromProducer(*producer, task); } - - if (!current_task && !HasError()) { - // there are no tasks to be scheduled and there are tasks blocked - lock_guard l(executor_lock); - if (to_be_rescheduled_tasks.empty()) { - return PendingExecutionResult::NO_TASKS_AVAILABLE; - } - // At least one task is blocked - if (ResultCollectorIsBlocked()) { - return PendingExecutionResult::RESULT_READY; - } - return PendingExecutionResult::BLOCKED; + if (!task && !HasError()) { + return IdleState(); } - - if (current_task) { - // if we have a task, partially process it + if (task) { + // partially process the task auto result = task->Execute(TaskExecutionMode::PROCESS_PARTIAL); if (result == TaskExecutionResult::TASK_BLOCKED) { task->Deschedule(); task.reset(); } else if (result == TaskExecutionResult::TASK_FINISHED) { - // if the task is finished, clean it up task.reset(); } else if (result == TaskExecutionResult::TASK_ERROR) { if (!HasError()) { @@ -488,26 +478,64 @@ PendingExecutionResult Executor::ExecuteTask(bool dry_run) { TaskScheduler::GetScheduler(context).ScheduleTask(token, task); task.reset(); } - return PendingExecutionResult::RESULT_NOT_READY; + return QueryResultState::NOT_READY; } - execution_result = PendingExecutionResult::EXECUTION_ERROR; + FailExecution(); + } + return FinishExecution(); +} - // an exception has occurred executing one of the pipelines - // we need to cancel all tasks associated with this executor - CancelTasks(); - ThrowException(); +QueryResultState Executor::Poll() { + D_ASSERT(execution_result != QueryResultState::NO_TASKS_AVAILABLE); + if (execution_result != QueryResultState::NOT_READY && ExecutionIsFinished()) { + return execution_result; } - D_ASSERT(!task); + if (completed_pipelines < total_pipelines) { + if (!HasError()) { + return IdleState(); + } + FailExecution(); + } + return FinishExecution(); +} +QueryResultState Executor::IdleState() { + lock_guard l(executor_lock); + if (to_be_rescheduled_tasks.empty()) { + return QueryResultState::NO_TASKS_AVAILABLE; + } + // At least one task is blocked + if (ResultCollectorIsBlocked()) { + return QueryResultState::READY; + } + return QueryResultState::BLOCKED; +} + +void Executor::FailExecution() { + execution_result = QueryResultState::EXECUTION_ERROR; + // an exception has occurred executing one of the pipelines + // we need to cancel all tasks associated with this executor + CancelTasks(); + ThrowException(); +} + +QueryResultState Executor::FinishExecution() { + D_ASSERT(!task); lock_guard elock(executor_lock); + if (progress_verifier && !HasError()) { + auto progress_error = progress_verifier->Finalize(pipelines); + if (!progress_error.empty()) { + error_manager.PushError(ErrorData(ExceptionType::INVALID_INPUT, progress_error)); + } + } pipelines.clear(); NextExecutor(); if (HasError()) { // LCOV_EXCL_START // an exception has occurred executing one of the pipelines - execution_result = PendingExecutionResult::EXECUTION_ERROR; + execution_result = QueryResultState::EXECUTION_ERROR; ThrowException(); } // LCOV_EXCL_STOP - execution_result = PendingExecutionResult::EXECUTION_FINISHED; + execution_result = QueryResultState::FINISHED; return execution_result; } @@ -521,10 +549,11 @@ void Executor::Reset() { completed_pipelines = 0; total_pipelines = 0; error_manager.Reset(); + progress_verifier.reset(); pipelines.clear(); events.clear(); to_be_rescheduled_tasks.clear(); - execution_result = PendingExecutionResult::RESULT_NOT_READY; + execution_result = QueryResultState::NOT_READY; } shared_ptr Executor::CreateChildPipeline(Pipeline ¤t, PhysicalOperator &op) { @@ -614,20 +643,44 @@ bool Executor::HasStreamingResultCollector() { return result_collector.IsStreaming(); } -bool Executor::ResultCollectorIsBlocked() { - // A sink retained by the plan never parks, so the materialized hot path skips the lock +void Executor::SetResultBuffer(shared_ptr result_buffer_p) { + lock_guard guard(result_buffer_lock); + result_buffer = std::move(result_buffer_p); +} + +shared_ptr Executor::GetResultBuffer() { + lock_guard guard(result_buffer_lock); + return result_buffer; +} + +bool Executor::ResultStoreCanPark() { if (!HasStreamingResultCollector()) { return false; } + auto buffer = GetResultBuffer(); + // The store was settled on retained at submission: producers append and never park + return !buffer || buffer->Lifetime() != ResultLifetime::RETAINED; +} + +bool Executor::ResultCollectorIsBlocked() { + // A store that cannot park never waits on the consumer, so the retained hot path skips the rest + if (!ResultStoreCanPark()) { + return false; + } + auto buffer = GetResultBuffer(); + if (buffer) { + return buffer->WaitsOnConsumer(); + } auto &result_collector = physical_plan->Cast(); // The sink state is published by a pipeline initialize task on a worker, under the - // operator lock. Read it under the same lock, or the client can observe the pointer - // before the pointee is visible + // operator lock. Read it under the same lock, or readiness is reported before GetResult + // has a state to fetch from lock_guard guard(result_collector.lock); if (!result_collector.sink_state) { return false; } - return result_collector.HasBlockedResultProducer(*result_collector.sink_state); + // A custom streaming collector has no parked-producer notion, and must never be waited on forever + return result_collector.IsStreaming(); } unique_ptr Executor::GetResult() { diff --git a/src/duckdb/src/parallel/pipeline.cpp b/src/duckdb/src/parallel/pipeline.cpp index cc6d0d44f..40232b81d 100644 --- a/src/duckdb/src/parallel/pipeline.cpp +++ b/src/duckdb/src/parallel/pipeline.cpp @@ -17,6 +17,7 @@ #include "duckdb/parallel/pipeline_event.hpp" #include "duckdb/parallel/pipeline_executor.hpp" #include "duckdb/parallel/pipeline_schedule.hpp" +#include "duckdb/parallel/progress_verifier.hpp" #include "duckdb/parallel/task_scheduler.hpp" #include "duckdb/main/settings.hpp" #include "duckdb/storage/buffer_manager.hpp" @@ -80,33 +81,41 @@ ClientContext &Pipeline::GetClientContext() { } bool Pipeline::GetProgress(ProgressData &progress) { + PipelineProgress detailed_progress; + GetDetailedProgress(detailed_progress); + progress = detailed_progress.pipeline; + return progress.IsValid(); +} + +void Pipeline::GetDetailedProgress(PipelineProgress &progress) { D_ASSERT(source); idx_t source_cardinality = MinValue(source->estimated_cardinality, 1ULL << 48ULL); if (source_cardinality < 1) { source_cardinality = 1; } if (!initialized) { - progress.done = 0; - progress.total = double(source_cardinality); - return true; + progress.source.done = 0; + progress.source.total = double(source_cardinality); + progress.pipeline = progress.source; + return; } auto &client = executor.context; auto state = GetSourceState(); if (state) { - progress = source->GetProgress(client, *state); + progress.source = source->GetProgress(client, *state); } else { - progress.done = 0; - progress.total = double(source_cardinality); + progress.source.done = 0; + progress.source.total = double(source_cardinality); } - progress.Normalize(double(source_cardinality)); + progress.pipeline = progress.source; + progress.pipeline.Normalize(double(source_cardinality)); if (sink) { lock_guard guard(sink->lock); if (sink->sink_state) { - progress = sink->GetSinkProgress(client, *sink->sink_state, progress); + progress.pipeline = sink->GetSinkProgress(client, *sink->sink_state, progress.pipeline); } } - return progress.IsValid(); } void Pipeline::ScheduleSequentialTask(shared_ptr &event) { @@ -353,6 +362,7 @@ void Pipeline::ResetSinkForReschedule() { if (!sink->IsSink()) { throw InternalException("Sink of pipeline does not have IsSink set"); } + NotifyProgressReset(); lock_guard guard(sink->lock); auto &client = GetClientContext(); auto allow_reuse = Settings::Get(client); @@ -394,6 +404,7 @@ void Pipeline::Reset() { } void Pipeline::ResetForReschedule(bool reset_sink) { + NotifyProgressReset(); if (reset_sink) { ResetSinkForReschedule(); } @@ -423,12 +434,20 @@ void Pipeline::ResetForReschedule(bool reset_sink) { initialized = true; } +void Pipeline::NotifyProgressReset() { + auto progress_verifier = executor.GetProgressVerifier(); + if (progress_verifier) { + progress_verifier->OnReset(*this); + } +} + void Pipeline::ResetSource(bool force) { if (source && !source->IsSource()) { throw InternalException("Source of pipeline does not have IsSource set"); } auto source_state = GetSourceState(); if (force || !source_state) { + NotifyProgressReset(); auto partition_info = sink ? sink->RequiredPartitionInfo() : OperatorPartitionInfo::NoPartitionInfo(); SetSourceState(ToSharedSourceState(source->GetGlobalSourceState(GetClientContext(), partition_info))); } diff --git a/src/duckdb/src/parallel/pipeline_executor.cpp b/src/duckdb/src/parallel/pipeline_executor.cpp index b73e3b689..3f4cfbc3d 100644 --- a/src/duckdb/src/parallel/pipeline_executor.cpp +++ b/src/duckdb/src/parallel/pipeline_executor.cpp @@ -5,6 +5,7 @@ #include "duckdb/main/client_context.hpp" #include "duckdb/main/settings.hpp" +#include "duckdb/parallel/progress_verifier.hpp" #ifdef DUCKDB_DEBUG_ASYNC_SINK_SOURCE #include @@ -92,6 +93,7 @@ void PipelineExecutor::Reset() { source_profiling_finalized = false; source_finish_notification_state = SourceFinishNotificationState::PENDING; should_flush_current_idx = true; + unsampled_progress_rows = 0; while (!in_process_operators.empty()) { in_process_operators.pop(); } @@ -706,6 +708,12 @@ PipelineExecuteResult PipelineExecutor::PushFinalize() { finalized = true; NotifySourceFinished(); + SampleProgress(); + auto progress_verifier = pipeline.executor.GetProgressVerifier(); + if (progress_verifier && !exhausted_source && !pipeline.IsExternalInput()) { + progress_verifier->OnEarlyExit(pipeline); + } + // If source was not exhausted (e.g. LIMIT stopped the pipeline), collect exact metrics now if (!source_profiling_finalized && local_source_state && global_source_state) { context.thread.profiler.FinishSource(*pipeline.source, *global_source_state, *local_source_state); @@ -851,6 +859,8 @@ PipelineExecutor::SourceFetchResult PipelineExecutor::FetchFromSource(DataChunk D_ASSERT(!pipeline.IsExternalInput()); D_ASSERT(global_source_state); D_ASSERT(local_source_state); + // the previous chunk has been pushed through the pipeline + SampleProgress(); StartOperator(*pipeline.source); OperatorSourceInput source_input = {*global_source_state, *local_source_state, interrupt_state}; @@ -869,9 +879,21 @@ PipelineExecutor::SourceFetchResult PipelineExecutor::FetchFromSource(DataChunk } EndOperator(*pipeline.source, &result); + if (pipeline.executor.GetProgressVerifier()) { + unsampled_progress_rows = result.size(); + } return fetch_result; } +void PipelineExecutor::SampleProgress() { + auto progress_verifier = pipeline.executor.GetProgressVerifier(); + if (!progress_verifier || unsampled_progress_rows == 0) { + return; + } + progress_verifier->OnSourceChunk(pipeline, unsampled_progress_rows); + unsampled_progress_rows = 0; +} + void PipelineExecutor::InitializeChunk(DataChunk &chunk) { auto &last_op = pipeline.operators.empty() ? *pipeline.source : pipeline.operators.back().get(); chunk.Initialize(BufferAllocator::Get(context.client), last_op.GetTypes()); diff --git a/src/duckdb/src/parallel/progress_verifier.cpp b/src/duckdb/src/parallel/progress_verifier.cpp new file mode 100644 index 000000000..cfb715ed0 --- /dev/null +++ b/src/duckdb/src/parallel/progress_verifier.cpp @@ -0,0 +1,374 @@ +#include "duckdb/parallel/progress_verifier.hpp" + +#include "duckdb/common/enum_util.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/execution/operator/scan/physical_table_scan.hpp" +#include "duckdb/logging/logger.hpp" +#include "duckdb/main/client_context.hpp" +#include "duckdb/parallel/pipeline.hpp" + +#include + +namespace duckdb { + +//! Tolerance used when comparing progress fractions +static constexpr double PROGRESS_EPSILON = 1e-6; +//! Tolerance for a completed pipeline to count as 100% done +static constexpr double COMPLETION_EPSILON = 1e-3; +//! Minimum number of chunks before invalid progress or a missing 100% is flagged +static constexpr idx_t MIN_CHUNKS_SUPPORTED = 2; +//! Minimum number of rows before non-moving or inaccurate progress is flagged +static constexpr idx_t MIN_ROWS_GRANULARITY = 16384; +//! Maximum deviation between the source progress and the fraction of rows produced +static constexpr double MAX_INACCURACY = 0.5; + +ProgressVerifier::ProgressVerifier(ClientContext &context, DebugProgressVerification mode, const string &ignore_str) + : context(context), mode(mode) { + for (auto &entry : StringUtil::Split(ignore_str, ',')) { + auto trimmed = entry; + StringUtil::Trim(trimmed); + if (!trimmed.empty()) { + ignore_list.insert(StringUtil::Upper(trimmed)); + } + } +} + +string ProgressVerifier::OperatorName(const PhysicalOperator &op) { + if (op.type == PhysicalOperatorType::TABLE_SCAN) { + // table functions implement progress individually - attribute to the function + return StringUtil::Upper(op.Cast().function.name.GetIdentifierName()); + } + return PhysicalOperatorToString(op.type); +} + +bool ProgressVerifier::FailsQuery(ProgressInvariant invariant) { + // selective filters and skewed data legitimately make source progress deviate from the rows produced + return invariant != ProgressInvariant::INACCURATE; +} + +static bool IsWellFormed(const ProgressData &progress) { + return std::isfinite(progress.done) && std::isfinite(progress.total) && progress.done >= 0 && progress.total >= 0 && + progress.done <= progress.total * (1 + PROGRESS_EPSILON) + PROGRESS_EPSILON; +} + +static double ProgressFraction(const ProgressData &progress) { + if (progress.total <= 0) { + return 0; + } + return MinValue(progress.done / progress.total, 1.0); +} + +static string FormatPercentage(double fraction) { + return StringUtil::Format("%.1f%%", fraction * 100); +} + +static string FormatProgress(const ProgressData &progress) { + return StringUtil::Format("done=%g, total=%g", progress.done, progress.total); +} + +ProgressVerifier::PipelineTrace &ProgressVerifier::GetTrace(Pipeline &pipeline) { + lock_guard guard(lock); + auto entry = traces.find(&pipeline); + if (entry != traces.end()) { + return *entry->second; + } + auto trace = make_uniq(); + trace->source_name = OperatorName(*pipeline.GetSource()); + trace->sink_name = pipeline.GetSink() ? OperatorName(*pipeline.GetSink()) : "NONE"; + auto &result = *trace; + traces[&pipeline] = std::move(trace); + return result; +} + +void ProgressVerifier::Sample(Pipeline &pipeline, PipelineTrace &trace, bool is_final) { + PipelineProgress progress; + pipeline.GetDetailedProgress(progress); + + auto &run = trace.run; + const auto sample_idx = run.samples.size(); + ProgressSample sample; + sample.source_fraction = std::nan(""); + sample.fraction = std::nan(""); + sample.rows = run.rows; + + // invalid progress after completion never reaches the user - only flag it while the pipeline is running + if (progress.source.invalid) { + if (!is_final && !run.first_unsupported_source.IsValid()) { + run.first_unsupported_source = sample_idx; + } + } else if (!IsWellFormed(progress.source)) { + AddViolation(trace, ProgressInvariant::MALFORMED_SOURCE, trace.source_name, FormatProgress(progress.source)); + } else { + sample.source_fraction = ProgressFraction(progress.source); + if (progress.pipeline.invalid) { + if (!is_final && !run.first_unsupported_sink.IsValid()) { + run.first_unsupported_sink = sample_idx; + } + } else if (!IsWellFormed(progress.pipeline)) { + AddViolation(trace, ProgressInvariant::MALFORMED_SINK, trace.sink_name, + StringUtil::Format("%s (source %s)", FormatProgress(progress.pipeline), + FormatProgress(progress.source))); + } else { + sample.fraction = ProgressFraction(progress.pipeline); + } + } + run.samples.push_back(sample); + run.has_final_sample = is_final; +} + +void ProgressVerifier::OnSourceChunk(Pipeline &pipeline, idx_t count) { + auto &trace = GetTrace(pipeline); + lock_guard guard(trace.lock); + trace.run.rows += count; + trace.run.chunks++; + Sample(pipeline, trace, false); +} + +void ProgressVerifier::OnEarlyExit(Pipeline &pipeline) { + auto &trace = GetTrace(pipeline); + lock_guard guard(trace.lock); + trace.run.early_exit = true; +} + +void ProgressVerifier::OnReset(Pipeline &pipeline) { + optional_ptr trace; + { + lock_guard guard(lock); + auto entry = traces.find(&pipeline); + if (entry == traces.end()) { + return; + } + trace = entry->second.get(); + } + lock_guard guard(trace->lock); + if (trace->run.samples.empty() && !trace->run.early_exit) { + return; + } + VerifyRun(*trace); + trace->run = PipelineRun(); +} + +static optional_idx FindDecrease(const vector &fractions) { + double previous = -1; + for (idx_t i = 0; i < fractions.size(); i++) { + if (std::isnan(fractions[i])) { + continue; + } + if (previous >= 0 && fractions[i] < previous - PROGRESS_EPSILON) { + return i; + } + previous = fractions[i]; + } + return optional_idx(); +} + +static double PreviousValid(const vector &fractions, idx_t idx) { + for (idx_t i = idx; i > 0; i--) { + if (!std::isnan(fractions[i - 1])) { + return fractions[i - 1]; + } + } + return 0; +} + +//! Returns the number of valid fractions, and whether they all have the same value +static idx_t CountConstant(const vector &fractions, bool &constant, double &value) { + idx_t count = 0; + double min_value = 2; + double max_value = -1; + for (auto fraction : fractions) { + if (std::isnan(fraction)) { + continue; + } + count++; + min_value = MinValue(min_value, fraction); + max_value = MaxValue(max_value, fraction); + } + constant = count > 0 && max_value - min_value < PROGRESS_EPSILON; + value = min_value; + return count; +} + +void ProgressVerifier::VerifyRun(PipelineTrace &trace) { + auto &run = trace.run; + if (run.samples.empty()) { + return; + } + vector source_fractions; + vector fractions; + for (auto &sample : run.samples) { + source_fractions.push_back(sample.source_fraction); + fractions.push_back(sample.fraction); + } + + // progress must be reported while the pipeline is producing data + if (run.chunks >= MIN_CHUNKS_SUPPORTED) { + if (run.first_unsupported_source.IsValid()) { + AddViolation(trace, ProgressInvariant::UNSUPPORTED_SOURCE, trace.source_name, + StringUtil::Format("invalid progress after %llu of %llu chunks", + run.first_unsupported_source.GetIndex() + 1, run.chunks)); + } + if (run.first_unsupported_sink.IsValid()) { + AddViolation(trace, ProgressInvariant::UNSUPPORTED_SINK, trace.sink_name, + StringUtil::Format("invalid progress after %llu of %llu chunks", + run.first_unsupported_sink.GetIndex() + 1, run.chunks)); + } + } + + // progress must never decrease - attribute to the source if its own progress decreased + auto source_decrease = FindDecrease(source_fractions); + if (source_decrease.IsValid()) { + auto idx = source_decrease.GetIndex(); + AddViolation(trace, ProgressInvariant::NON_MONOTONIC, trace.source_name, + StringUtil::Format("source progress decreased from %s to %s at sample %llu", + FormatPercentage(PreviousValid(source_fractions, idx)), + FormatPercentage(source_fractions[idx]), idx + 1)); + } else { + auto decrease = FindDecrease(fractions); + if (decrease.IsValid()) { + auto idx = decrease.GetIndex(); + AddViolation(trace, ProgressInvariant::NON_MONOTONIC, trace.sink_name, + StringUtil::Format("pipeline progress decreased from %s to %s at sample %llu", + FormatPercentage(PreviousValid(fractions, idx)), + FormatPercentage(fractions[idx]), idx + 1)); + } + } + + auto ran_to_completion = run.has_final_sample && !run.early_exit; + // a pipeline that ran to completion must report 100% + if (ran_to_completion && run.chunks >= MIN_CHUNKS_SUPPORTED) { + auto &final_sample = run.samples.back(); + if (!std::isnan(final_sample.fraction) && final_sample.fraction < 1 - COMPLETION_EPSILON) { + auto source_incomplete = final_sample.source_fraction < 1 - COMPLETION_EPSILON; + AddViolation(trace, ProgressInvariant::INCOMPLETE, source_incomplete ? trace.source_name : trace.sink_name, + StringUtil::Format("finished at %s (source %s) after %llu chunks", + FormatPercentage(final_sample.fraction), + FormatPercentage(final_sample.source_fraction), run.chunks)); + } + } + + if (run.rows < MIN_ROWS_GRANULARITY) { + return; + } + // progress must move while the source produces data + auto chunk_sample_count = run.has_final_sample ? run.samples.size() - 1 : run.samples.size(); + source_fractions.resize(chunk_sample_count); + fractions.resize(chunk_sample_count); + bool source_constant, constant; + double source_value, value; + auto source_count = CountConstant(source_fractions, source_constant, source_value); + auto count = CountConstant(fractions, constant, value); + // progress that reaches 100% too early is not stalled, but inaccurate + source_constant = source_constant && source_value < 1 - COMPLETION_EPSILON; + constant = constant && value < 1 - COMPLETION_EPSILON; + if (source_count > 1 && source_constant) { + AddViolation(trace, ProgressInvariant::STALLED, trace.source_name, + StringUtil::Format("source progress stuck at %s for %llu chunks", FormatPercentage(source_value), + source_count)); + } else if (count > 1 && constant) { + AddViolation( + trace, ProgressInvariant::STALLED, trace.sink_name, + StringUtil::Format("pipeline progress stuck at %s for %llu chunks", FormatPercentage(value), count)); + } + + // source progress should roughly follow the fraction of rows produced + if (ran_to_completion && run.rows > 0) { + double max_error = 0; + idx_t max_idx = 0; + for (idx_t i = 0; i < chunk_sample_count; i++) { + auto &sample = run.samples[i]; + if (std::isnan(sample.source_fraction)) { + continue; + } + auto actual = static_cast(sample.rows) / static_cast(run.rows); + auto error = std::fabs(sample.source_fraction - actual); + if (error > max_error) { + max_error = error; + max_idx = i; + } + } + if (max_error > MAX_INACCURACY) { + auto &sample = run.samples[max_idx]; + AddViolation( + trace, ProgressInvariant::INACCURATE, trace.source_name, + StringUtil::Format("source reported %s after %s of the rows (%llu of %llu)", + FormatPercentage(sample.source_fraction), + FormatPercentage(static_cast(sample.rows) / static_cast(run.rows)), + sample.rows, run.rows)); + } + } +} + +void ProgressVerifier::AddViolation(const PipelineTrace &trace, ProgressInvariant invariant, + const string &operator_name, const string &detail) { + lock_guard guard(lock); + auto key = EnumUtil::ToString(invariant) + ":" + operator_name; + if (reported.find(key) != reported.end()) { + return; + } + reported.insert(key); + Violation violation; + violation.invariant = invariant; + violation.operator_name = operator_name; + violation.pipeline = trace.source_name + " -> " + trace.sink_name; + violation.detail = detail; + violations.push_back(std::move(violation)); +} + +bool ProgressVerifier::IsIgnored(const Violation &violation) const { + auto invariant = EnumUtil::ToString(violation.invariant); + return ignore_list.count(invariant) > 0 || ignore_list.count(invariant + ":" + violation.operator_name) > 0 || + ignore_list.count("*:" + violation.operator_name) > 0; +} + +string ProgressVerifier::Finalize(const vector> &pipelines) { + for (auto &pipeline : pipelines) { + optional_ptr trace; + { + lock_guard guard(lock); + auto entry = traces.find(pipeline.get()); + if (entry == traces.end()) { + // the source of this pipeline never produced any data + continue; + } + trace = entry->second.get(); + } + lock_guard guard(trace->lock); + Sample(*pipeline, *trace, true); + } + vector> all_traces; + { + lock_guard guard(lock); + for (auto &entry : traces) { + all_traces.push_back(*entry.second); + } + } + for (auto &trace : all_traces) { + lock_guard guard(trace.get().lock); + VerifyRun(trace.get()); + trace.get().run = PipelineRun(); + } + + lock_guard guard(lock); + string error; + vector failing_keys; + for (auto &violation : violations) { + auto invariant = EnumUtil::ToString(violation.invariant); + if (mode != DebugProgressVerification::ERROR || !FailsQuery(violation.invariant) || IsIgnored(violation)) { + DUCKDB_LOG(context, ProgressVerificationLogType, invariant, violation.operator_name, violation.pipeline, + violation.detail); + continue; + } + error += StringUtil::Format("\n- %s [%s] in pipeline %s: %s", invariant, violation.operator_name, + violation.pipeline, violation.detail); + failing_keys.push_back(invariant + ":" + violation.operator_name); + } + violations.clear(); + if (error.empty()) { + return error; + } + return "Progress verification failed:" + error + "\nIgnore with SET debug_verify_progress_ignore='" + + StringUtil::Join(failing_keys, ",") + "'"; +} + +} // namespace duckdb diff --git a/src/duckdb/src/parallel/scan_read_ahead.cpp b/src/duckdb/src/parallel/scan_read_ahead.cpp index 86f2507b8..4ad044a57 100644 --- a/src/duckdb/src/parallel/scan_read_ahead.cpp +++ b/src/duckdb/src/parallel/scan_read_ahead.cpp @@ -132,6 +132,10 @@ ScanReadAhead::ScanReadAhead(ClientContext &context, idx_t read_ahead_depth_p, } ScanReadAhead::~ScanReadAhead() { + CancelAndDrain(); +} + +void ScanReadAhead::CancelAndDrain() { executor->CancelAndDrain(); } diff --git a/src/duckdb/src/parser/keyword_helper.cpp b/src/duckdb/src/parser/keyword_helper.cpp index 61ef32119..322d7d26f 100644 --- a/src/duckdb/src/parser/keyword_helper.cpp +++ b/src/duckdb/src/parser/keyword_helper.cpp @@ -5,29 +5,12 @@ namespace duckdb { -static KeywordCategory GetPEGKeywordCategory(const string &text) { - auto &helper = DuckDBKeywordHelper::Instance(); - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_RESERVED)) { - return KeywordCategory::KEYWORD_RESERVED; - } - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_UNRESERVED)) { - return KeywordCategory::KEYWORD_UNRESERVED; - } - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_TYPE_FUNC)) { - return KeywordCategory::KEYWORD_TYPE_FUNC; - } - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_COL_NAME)) { - return KeywordCategory::KEYWORD_COL_NAME; - } - return KeywordCategory::KEYWORD_NONE; -} - bool KeywordHelper::IsKeyword(const string &text, KeywordCategory category) { - return GetPEGKeywordCategory(text) != category; + return DuckDBKeywordHelper::Instance().GetKeywordCategory(text) != category; } KeywordCategory KeywordHelper::KeywordCategoryType(const string &text) { - return GetPEGKeywordCategory(text); + return DuckDBKeywordHelper::Instance().GetKeywordCategory(text); } bool KeywordHelper::RequiresQuotes(const string &text, bool allow_caps) { diff --git a/src/duckdb/src/parser/parsed_data/alter_table_info.cpp b/src/duckdb/src/parser/parsed_data/alter_table_info.cpp index b3719487a..161c9c3d1 100644 --- a/src/duckdb/src/parser/parsed_data/alter_table_info.cpp +++ b/src/duckdb/src/parser/parsed_data/alter_table_info.cpp @@ -211,10 +211,10 @@ AddColumnInfo::AddColumnInfo(ColumnDefinition new_column_p) : AlterTableInfo(AlterTableType::ADD_COLUMN), new_column(std::move(new_column_p)) { } -AddColumnInfo::AddColumnInfo(const AlterEntryData &data, ColumnDefinition new_column, bool if_column_not_exists, - bool add_not_null) - : AlterTableInfo(AlterTableType::ADD_COLUMN, data), new_column(std::move(new_column)), - if_column_not_exists(if_column_not_exists), add_not_null(add_not_null) { +AddColumnInfo::AddColumnInfo(const AlterEntryData &data, ColumnDefinition new_column_p, bool if_column_not_exists_p, + AddColumnConstraints add_column_constraints_p) + : AlterTableInfo(AlterTableType::ADD_COLUMN, data), new_column(std::move(new_column_p)), + if_column_not_exists(if_column_not_exists_p), add_column_constraints(add_column_constraints_p) { } AddColumnInfo::~AddColumnInfo() { @@ -222,7 +222,7 @@ AddColumnInfo::~AddColumnInfo() { unique_ptr AddColumnInfo::Copy() const { return make_uniq_base(GetAlterEntryData(), new_column.Copy(), if_column_not_exists, - add_not_null); + add_column_constraints); } string AddColumnInfo::ToString() const { @@ -238,9 +238,12 @@ string AddColumnInfo::ToString() const { } result += " " + SQLIdentifier(this->new_column.GetName()); result += " " + this->new_column.GetType().ToString(); - if (add_not_null) { + if (add_column_constraints.add_not_null) { result += " NOT NULL"; } + if (add_column_constraints.add_unique) { + result += " UNIQUE"; + } if (this->new_column.HasDefaultValue()) { result += " DEFAULT "; result += this->new_column.DefaultValue().ToString(); diff --git a/src/duckdb/src/parser/parsed_data/attach_info.cpp b/src/duckdb/src/parser/parsed_data/attach_info.cpp index c4a0251ce..0fd12023c 100644 --- a/src/duckdb/src/parser/parsed_data/attach_info.cpp +++ b/src/duckdb/src/parser/parsed_data/attach_info.cpp @@ -18,11 +18,26 @@ unique_ptr AttachInfo::Copy() const { result->parsed_options[entry.first] = entry.second->Copy(); } result->on_conflict = on_conflict; + if (external_resource) { + result->external_resource = external_resource->Copy(); + } return result; } string AttachInfo::ToString() const { string result = ""; + // `ATTACH TO [NEW TEMPORARY] EXTERNAL RESOURCE [(create opts)] AS name [(attach opts)]` + if (external_resource) { + // No IF NOT EXISTS / OR REPLACE: AttachToExternalResource has no slot for either, so rendering + // one would produce SQL that cannot be parsed back. + result += "ATTACH TO " + external_resource->ToString(); + if (!name.empty()) { + result += " AS " + SQLIdentifier(name); + } + result += RenderOptionList(parsed_options, options); + result += ";"; + return result; + } result += "ATTACH"; if (on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT) { result += " IF NOT EXISTS"; @@ -38,18 +53,7 @@ string AttachInfo::ToString() const { if (!name.empty()) { result += " AS " + SQLIdentifier(name); } - if (!parsed_options.empty() || !options.empty()) { - vector stringified; - for (auto &opt : parsed_options) { - stringified.push_back( - StringUtil::Format("%s %s", SQLIdentifier::ToString(opt.first), opt.second->ToString())); - } - for (auto &opt : options) { - stringified.push_back( - StringUtil::Format("%s %s", SQLIdentifier::ToString(opt.first), opt.second.ToSQLString())); - } - result += " (" + StringUtil::Join(stringified, ", ") + ")"; - } + result += RenderOptionList(parsed_options, options); result += ";"; return result; } diff --git a/src/duckdb/src/parser/parsed_data/connect_info.cpp b/src/duckdb/src/parser/parsed_data/connect_info.cpp index 153e13166..5bea79484 100644 --- a/src/duckdb/src/parser/parsed_data/connect_info.cpp +++ b/src/duckdb/src/parser/parsed_data/connect_info.cpp @@ -15,10 +15,17 @@ unique_ptr ConnectInfo::Copy() const { result->parsed_options[entry.first] = entry.second->Copy(); } result->options = options; + if (external_resource) { + result->external_resource = external_resource->Copy(); + } return result; } string ConnectInfo::ToString() const { + if (external_resource) { + // Only the borrow form can carry connect options; provisioning gives its one list to the recipe. + return "CONNECT TO " + external_resource->ToString() + RenderOptionList(parsed_options, options) + ";"; + } if (target_is_local) { return "CONNECT LOCAL;"; } @@ -31,18 +38,7 @@ string ConnectInfo::ToString() const { } else { result += SQLIdentifier(name); } - if (!parsed_options.empty() || !options.empty()) { - vector stringified; - for (auto &opt : parsed_options) { - stringified.push_back( - StringUtil::Format("%s %s", SQLIdentifier::ToString(opt.first), opt.second->ToString())); - } - for (auto &opt : options) { - stringified.push_back( - StringUtil::Format("%s %s", SQLIdentifier::ToString(opt.first), opt.second.ToSQLString())); - } - result += " (" + StringUtil::Join(stringified, ", ") + ")"; - } + result += RenderOptionList(parsed_options, options); result += ";"; return result; } diff --git a/src/duckdb/src/parser/parsed_data/external_resource_options.cpp b/src/duckdb/src/parser/parsed_data/external_resource_options.cpp new file mode 100644 index 000000000..28699c725 --- /dev/null +++ b/src/duckdb/src/parser/parsed_data/external_resource_options.cpp @@ -0,0 +1,49 @@ +#include "duckdb/parser/parsed_data/external_resource_options.hpp" + +#include "duckdb/parser/parsed_data/parse_info.hpp" + +#include "duckdb/common/serializer/deserializer.hpp" +#include "duckdb/common/sql_identifier.hpp" +#include "duckdb/common/serializer/serializer.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/parser/keyword_helper.hpp" + +namespace duckdb { + +unique_ptr ExternalResourceOptions::Copy() const { + auto result = make_uniq(); + for (auto &entry : parsed_params) { + result->parsed_params[entry.first] = entry.second->Copy(); + } + result->provider = provider; + result->params = params; + result->reference_name = reference_name; + return result; +} + +string ExternalResourceOptions::ToString() const { + // Reference form: a bare identifier naming an already-registered resource. + if (!reference_name.empty()) { + return "EXTERNAL RESOURCE " + SQLIdentifier(reference_name); + } + // Create form: NEW TEMPORARY EXTERNAL RESOURCE '' [(create opts)]. + string result = "NEW TEMPORARY EXTERNAL RESOURCE " + SQLString(provider); + result += RenderOptionList(parsed_params, params); + return result; +} + +void ExternalResourceOptions::Serialize(Serializer &serializer) const { + serializer.WritePropertyWithDefault(101, "provider", provider); + serializer.WritePropertyWithDefault>(102, "params", params); + serializer.WritePropertyWithDefault(103, "reference_name", reference_name); +} + +unique_ptr ExternalResourceOptions::Deserialize(Deserializer &deserializer) { + auto result = make_uniq(); + deserializer.ReadPropertyWithDefault(101, "provider", result->provider); + deserializer.ReadPropertyWithDefault>(102, "params", result->params); + deserializer.ReadPropertyWithDefault(103, "reference_name", result->reference_name); + return result; +} + +} // namespace duckdb diff --git a/src/duckdb/src/parser/parsed_data/parse_info.cpp b/src/duckdb/src/parser/parsed_data/parse_info.cpp index 4976b9b1c..69b02fe34 100644 --- a/src/duckdb/src/parser/parsed_data/parse_info.cpp +++ b/src/duckdb/src/parser/parsed_data/parse_info.cpp @@ -1,4 +1,7 @@ #include "duckdb/parser/parsed_data/parse_info.hpp" +#include "duckdb/parser/parsed_expression.hpp" +#include "duckdb/common/sql_identifier.hpp" +#include "duckdb/common/string_util.hpp" #include "duckdb/common/enums/catalog_type.hpp" #include "duckdb/common/enum_util.hpp" #include "duckdb/parser/keyword_helper.hpp" @@ -35,4 +38,20 @@ string ParseInfo::TypeToString(CatalogType type) { } } +string RenderOptionList(const case_insensitive_map_t> &parsed_options, + const unordered_map &options) { + if (parsed_options.empty() && options.empty()) { + return string(); + } + vector stringified; + for (auto &opt : parsed_options) { + stringified.push_back(StringUtil::Format("%s %s", SQLIdentifier::ToString(opt.first), opt.second->ToString())); + } + for (auto &opt : options) { + stringified.push_back( + StringUtil::Format("%s %s", SQLIdentifier::ToString(opt.first), opt.second.ToSQLString())); + } + return " (" + StringUtil::Join(stringified, ", ") + ")"; +} + } // namespace duckdb diff --git a/src/duckdb/src/parser/parser.cpp b/src/duckdb/src/parser/parser.cpp index 28c4b5425..3b72ff2ec 100644 --- a/src/duckdb/src/parser/parser.cpp +++ b/src/duckdb/src/parser/parser.cpp @@ -543,21 +543,7 @@ vector Parser::TokenizeError(const string &error_msg) { } KeywordCategory Parser::ToKeywordCategory(const string &text) { - auto &helper = DuckDBKeywordHelper::Instance(); - - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_RESERVED)) { - return KeywordCategory::KEYWORD_RESERVED; - } - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_UNRESERVED)) { - return KeywordCategory::KEYWORD_UNRESERVED; - } - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_TYPE_FUNC)) { - return KeywordCategory::KEYWORD_TYPE_FUNC; - } - if (helper.KeywordCategoryType(text, PEGKeywordCategory::KEYWORD_COL_NAME)) { - return KeywordCategory::KEYWORD_COL_NAME; - } - return KeywordCategory::KEYWORD_NONE; + return DuckDBKeywordHelper::Instance().GetKeywordCategory(text); } KeywordCategory Parser::IsKeyword(const string &text) { diff --git a/src/duckdb/src/parser/peg/autocomplete_core.cpp b/src/duckdb/src/parser/peg/autocomplete_core.cpp index e0c16bafe..076aad940 100644 --- a/src/duckdb/src/parser/peg/autocomplete_core.cpp +++ b/src/duckdb/src/parser/peg/autocomplete_core.cpp @@ -215,8 +215,7 @@ vector GenerateAutoCompleteSuggestions(AutoCompleteCatal TokenIterator token_iterator(tokens); ArenaAllocator process_allocator(Allocator::DefaultAllocator()); MatchContext match_context(suggestions, parse_allocator, process_allocator, max_token_index, - MatchMode::RECOGNIZE_ONLY, IdentifierCaseMode::PRESERVE_CASE, - parameters.use_heap_based_parser); + MatchMode::RECOGNIZE_ONLY, IdentifierCaseMode::PRESERVE_CASE); MatchState state(token_iterator, match_context); compiled_grammar->ProgramMatcher().MatchParseResult(state); } diff --git a/src/duckdb/src/parser/peg/compiled_grammar.cpp b/src/duckdb/src/parser/peg/compiled_grammar.cpp index 463b2384b..03f72e0ed 100644 --- a/src/duckdb/src/parser/peg/compiled_grammar.cpp +++ b/src/duckdb/src/parser/peg/compiled_grammar.cpp @@ -120,6 +120,8 @@ terminal_rule_overrides_t ParsedGrammar::BuildTerminalRuleOverrides(const PEGKey AddTerminalRuleOverride(overrides, "NumberLiteral", make_uniq()); AddTerminalRuleOverride(overrides, "StringLiteral", make_uniq()); AddTerminalRuleOverride(overrides, "OperatorLiteral", make_uniq()); + AddTerminalRuleOverride(overrides, "AnyOperatorLiteral", + make_uniq(OperatorMatcherMode::ALL_OPERATORS)); //===--------------------------------------------------------------------===// // END GENERATED RULE OVERRIDES //===--------------------------------------------------------------------===// @@ -131,10 +133,9 @@ terminal_rule_overrides_t ParsedGrammar::BuildTerminalRuleOverrides(const PEGKey return overrides; } -shared_ptr -CompiledGrammar::Create(const case_insensitive_map_t> &grammar_extensions) { +shared_ptr CompiledGrammar::Create(const vector> &grammar_extensions) { auto grammar = ParsedGrammar::CreateDefault(); - for (auto &[_, extension] : grammar_extensions) { + for (auto &extension : grammar_extensions) { auto changes = extension.get().GetChanges(); for (auto &change : changes) { change.Apply(grammar); @@ -157,7 +158,7 @@ CompiledGrammar::Create(const case_insensitive_map_t MatcherAllocator allocator; auto terminal_rule_overrides = grammar.BuildTerminalRuleOverrides(*keyword_helper); - MatcherFactory factory(allocator, grammar, rules, std::move(terminal_rule_overrides)); + MatcherFactory factory(allocator, grammar, rules, *keyword_helper, std::move(terminal_rule_overrides)); auto &program_matcher = factory.CreateRootMatcher("Program"); auto &top_level_statement_matcher = factory.GetMatcher("TopLevelStatement"); @@ -173,13 +174,13 @@ shared_ptr CompiledGrammar::Create() { } shared_ptr CompiledGrammar::Create(const ClientContext &context, - const case_insensitive_set_t &active_extensions) { - case_insensitive_map_t> selected_extensions; + const vector &active_extensions) { + vector> selected_extensions; auto &callback_manager = ExtensionCallbackManager::Get(context); for (auto &name : active_extensions) { auto grammar_extension = callback_manager.FindGrammarExtension(name); if (grammar_extension) { - selected_extensions.emplace(name, *grammar_extension); + selected_extensions.emplace_back(*grammar_extension); } } return Create(selected_extensions); diff --git a/src/duckdb/src/parser/peg/dialect_extension.cpp b/src/duckdb/src/parser/peg/dialect_extension.cpp index 959bd87e7..cfd4d65fd 100644 --- a/src/duckdb/src/parser/peg/dialect_extension.cpp +++ b/src/duckdb/src/parser/peg/dialect_extension.cpp @@ -66,7 +66,7 @@ void DialectExtension::ApplyGrammarChanges(GrammarChangesInput &) { } unique_ptr DialectExtension::CreateMatcherFactory(CreateMatcherFactoryInput &input) { - return make_uniq(input.allocator, input.parsed_grammar, input.rules, + return make_uniq(input.allocator, input.parsed_grammar, input.rules, input.keyword_helper, std::move(input.terminal_rules)); } diff --git a/src/duckdb/src/parser/peg/keyword_helper/default_keyword_maps.cpp b/src/duckdb/src/parser/peg/keyword_helper/default_keyword_maps.cpp index 20ec6622a..732eb3d66 100644 --- a/src/duckdb/src/parser/peg/keyword_helper/default_keyword_maps.cpp +++ b/src/duckdb/src/parser/peg/keyword_helper/default_keyword_maps.cpp @@ -1,43 +1,102 @@ #include "duckdb/parser/peg/keyword_helper/default_keyword_maps.hpp" +#include "duckdb/parser/peg/matcher.hpp" namespace duckdb { -bool DefaultKeywordMaps::IsKeywordOfCategory(const string &text, PEGKeywordCategory category) const { - switch (category) { - case PEGKeywordCategory::KEYWORD_RESERVED: - return reserved_keyword_map.count(text) != 0; - case PEGKeywordCategory::KEYWORD_UNRESERVED: - return unreserved_keyword_map.count(text) != 0; - case PEGKeywordCategory::KEYWORD_TYPE_FUNC: - return typefunc_keyword_map.count(text) != 0; - case PEGKeywordCategory::KEYWORD_COL_NAME: - return colname_keyword_map.count(text) != 0; - case PEGKeywordCategory::KEYWORD_TYPE_NAME: - return typename_keyword_map.count(text) != 0; +static constexpr keyword_categories_t KEYWORD_UNRESERVED = keyword_categories_t::CreateCategory(0); +static constexpr keyword_categories_t KEYWORD_RESERVED = keyword_categories_t::CreateCategory(1); +static constexpr keyword_categories_t KEYWORD_TYPE_FUNC = keyword_categories_t::CreateCategory(2); +static constexpr keyword_categories_t KEYWORD_COL_NAME = keyword_categories_t::CreateCategory(3); +static constexpr keyword_categories_t KEYWORD_TYPE_NAME = keyword_categories_t::CreateCategory(4); + +LiteralInfo DefaultKeywordMaps::LookupKeyword(const string &text, uint16_t literal_id) const { + keyword_categories_t flags; + if (unreserved_keyword_map.count(text)) { + flags |= KEYWORD_UNRESERVED; + } + if (reserved_keyword_map.count(text)) { + flags |= KEYWORD_RESERVED; + } + if (typefunc_keyword_map.count(text)) { + flags |= KEYWORD_TYPE_FUNC; + } + if (colname_keyword_map.count(text)) { + flags |= KEYWORD_COL_NAME; + } + if (typename_keyword_map.count(text)) { + flags |= KEYWORD_TYPE_NAME; + } + return LiteralInfo(literal_id, flags); +} + +keyword_categories_t DefaultKeywordMaps::GetIdentifierMask(SuggestionState type) { + switch (type) { + case SuggestionState::SUGGEST_TYPE_NAME: + return KEYWORD_UNRESERVED | KEYWORD_TYPE_NAME; + case SuggestionState::SUGGEST_SCALAR_FUNCTION_NAME: + case SuggestionState::SUGGEST_TABLE_FUNCTION_NAME: + return KEYWORD_UNRESERVED | KEYWORD_TYPE_FUNC; default: - return false; + return KEYWORD_UNRESERVED | KEYWORD_COL_NAME; + } +} + +KeywordCategory DefaultKeywordMaps::GetKeywordCategory(LiteralInfo info) { + auto categories = GetKeywordCategories(info); + if (categories.empty()) { + return KeywordCategory::KEYWORD_NONE; + } + return categories[0]; +} + +vector DefaultKeywordMaps::GetKeywordCategories(LiteralInfo info) { + vector result; + if (info.HasAnyFlags(KEYWORD_RESERVED)) { + result.push_back(KeywordCategory::KEYWORD_RESERVED); + } + if (info.HasAnyFlags(KEYWORD_UNRESERVED)) { + result.push_back(KeywordCategory::KEYWORD_UNRESERVED); } + if (info.HasAnyFlags(KEYWORD_TYPE_FUNC)) { + result.push_back(KeywordCategory::KEYWORD_TYPE_FUNC); + } + if (info.HasAnyFlags(KEYWORD_COL_NAME)) { + result.push_back(KeywordCategory::KEYWORD_COL_NAME); + } + if (info.HasAnyFlags(KEYWORD_TYPE_NAME)) { + result.push_back(KeywordCategory::KEYWORD_TYPE_NAME); + } + return result; } -bool DefaultKeywordMaps::IsKeyword(const string &text) const { - return reserved_keyword_map.count(text) != 0 || unreserved_keyword_map.count(text) != 0 || - colname_keyword_map.count(text) != 0 || typefunc_keyword_map.count(text) != 0 || - typename_keyword_map.count(text) != 0; +case_insensitive_map_t DefaultKeywordMaps::ToLiteralMap() const { + case_insensitive_map_t result; + auto add_keywords = [&](const case_insensitive_set_t &words) { + for (auto &word : words) { + result.emplace(word, LookupKeyword(word)); + } + }; + add_keywords(reserved_keyword_map); + add_keywords(unreserved_keyword_map); + add_keywords(colname_keyword_map); + add_keywords(typefunc_keyword_map); + add_keywords(typename_keyword_map); + return result; } vector DefaultKeywordMaps::ToList() const { vector result; for (auto &kw : reserved_keyword_map) { - result.push_back({kw, KeywordCategory::KEYWORD_RESERVED}); + result.push_back({kw, "reserved"}); } for (auto &kw : unreserved_keyword_map) { - result.push_back({kw, KeywordCategory::KEYWORD_UNRESERVED}); + result.push_back({kw, "unreserved"}); } for (auto &kw : typefunc_keyword_map) { - result.push_back({kw, KeywordCategory::KEYWORD_TYPE_FUNC}); + result.push_back({kw, "type_function"}); } for (auto &kw : colname_keyword_map) { - result.push_back({kw, KeywordCategory::KEYWORD_COL_NAME}); + result.push_back({kw, "column_name"}); } return result; } diff --git a/src/duckdb/src/parser/peg/keyword_helper/duckdb_keyword_helper.cpp b/src/duckdb/src/parser/peg/keyword_helper/duckdb_keyword_helper.cpp index 6421801fb..45f57c8cb 100644 --- a/src/duckdb/src/parser/peg/keyword_helper/duckdb_keyword_helper.cpp +++ b/src/duckdb/src/parser/peg/keyword_helper/duckdb_keyword_helper.cpp @@ -1,9 +1,11 @@ #include "duckdb/parser/peg/keyword_helper/duckdb_keyword_helper.hpp" +#include "duckdb/parser/peg/parsed_grammar.hpp" namespace duckdb { -DuckDBKeywordHelper::DuckDBKeywordHelper() : initialized(false) { - InitializeKeywordMaps(); +DuckDBKeywordHelper::DuckDBKeywordHelper() + : keyword_maps(InitializeKeywordMaps()), + literal_table(ParsedGrammar::CreateDefault(), keyword_maps.ToLiteralMap()) { } const DuckDBKeywordHelper &DuckDBKeywordHelper::Instance() { @@ -11,13 +13,13 @@ const DuckDBKeywordHelper &DuckDBKeywordHelper::Instance() { return instance; } -bool DuckDBKeywordHelper::KeywordCategoryType(const std::string &text, const PEGKeywordCategory category) const { - return keyword_maps.IsKeywordOfCategory(text, category); +keyword_categories_t DuckDBKeywordHelper::GetIdentifierMask(SuggestionState type) const { + return DefaultKeywordMaps::GetIdentifierMask(type); } -bool DuckDBKeywordHelper::IsKeyword(const string &text) const { - return keyword_maps.IsKeyword(text); -}; +KeywordCategory DuckDBKeywordHelper::GetKeywordCategory(const string &text) const { + return DefaultKeywordMaps::GetKeywordCategory(LookupKeyword(text)); +} vector DuckDBKeywordHelper::KeywordList() const { return keyword_maps.ToList(); diff --git a/src/duckdb/src/parser/peg/keyword_helper/grammar_literal_table.cpp b/src/duckdb/src/parser/peg/keyword_helper/grammar_literal_table.cpp new file mode 100644 index 000000000..dfec0c26a --- /dev/null +++ b/src/duckdb/src/parser/peg/keyword_helper/grammar_literal_table.cpp @@ -0,0 +1,50 @@ +#include "duckdb/parser/peg/grammar_literal_table.hpp" + +#include "duckdb/common/atomic.hpp" +#include "duckdb/common/exception.hpp" +#include "duckdb/parser/peg/parsed_grammar.hpp" + +namespace duckdb { + +static uint64_t NextLiteralTableId() { + static atomic next_id {1}; + auto result = next_id.fetch_add(1, std::memory_order_relaxed); + D_ASSERT(result != 0); + return result; +} + +GrammarLiteralTable::GrammarLiteralTable(const ParsedGrammar &grammar, + const case_insensitive_map_t &keywords) + : cache_id(NextLiteralTableId()) { + vector> pending; + for (auto &entry : grammar.rules) { + pending.push_back(entry.second->recipe.expression); + } + while (!pending.empty()) { + auto &expression = pending.back().get(); + pending.pop_back(); + if (expression.type == PEGExpression::Type::LITERAL) { + Register(expression.text.GetString()); + } + for (auto &child : expression.children) { + pending.push_back(child); + } + } + for (auto &entry : keywords) { + Register(entry.first, entry.second.CategoryFlags()); + } +} + +void GrammarLiteralTable::Register(const string &text, keyword_categories_t categories) { + auto entry = literals.find(text); + if (entry == literals.end()) { + if (literals.size() >= LiteralInfo::MAX_LITERAL_ID) { + throw InvalidInputException("Grammar has too many distinct literals"); + } + auto id = static_cast(literals.size() + 1); + entry = literals.emplace(text, LiteralInfo(id)).first; + } + entry->second.AddCategories(categories); +} + +} // namespace duckdb diff --git a/src/duckdb/src/parser/peg/keyword_helper/parsed_grammar_keyword_helper.cpp b/src/duckdb/src/parser/peg/keyword_helper/parsed_grammar_keyword_helper.cpp index 5d75b5bab..528d26657 100644 --- a/src/duckdb/src/parser/peg/keyword_helper/parsed_grammar_keyword_helper.cpp +++ b/src/duckdb/src/parser/peg/keyword_helper/parsed_grammar_keyword_helper.cpp @@ -46,7 +46,8 @@ static void PopulateKeywordMap(const ParsedGrammar &grammar, const string &root_ active_rules.erase(rule_name); } -ParsedGrammarKeywordHelper::ParsedGrammarKeywordHelper(const ParsedGrammar &grammar) { +static DefaultKeywordMaps BuildKeywordMaps(const ParsedGrammar &grammar) { + DefaultKeywordMaps keyword_maps; unordered_map> mapping { {"ReservedKeyword", keyword_maps.reserved_keyword_map}, {"UnreservedKeyword", keyword_maps.unreserved_keyword_map}, @@ -58,14 +59,15 @@ ParsedGrammarKeywordHelper::ParsedGrammarKeywordHelper(const ParsedGrammar &gram case_insensitive_set_t active_rules; PopulateKeywordMap(grammar, entry.first, entry.first, entry.second.get(), active_rules); } + return keyword_maps; } -bool ParsedGrammarKeywordHelper::KeywordCategoryType(const string &text, PEGKeywordCategory category) const { - return keyword_maps.IsKeywordOfCategory(text, category); +ParsedGrammarKeywordHelper::ParsedGrammarKeywordHelper(const ParsedGrammar &grammar) + : keyword_maps(BuildKeywordMaps(grammar)), literal_table(grammar, keyword_maps.ToLiteralMap()) { } -bool ParsedGrammarKeywordHelper::IsKeyword(const string &text) const { - return keyword_maps.IsKeyword(text); +keyword_categories_t ParsedGrammarKeywordHelper::GetIdentifierMask(SuggestionState type) const { + return DefaultKeywordMaps::GetIdentifierMask(type); } vector ParsedGrammarKeywordHelper::KeywordList() const { diff --git a/src/duckdb/src/parser/peg/keyword_map.cpp b/src/duckdb/src/parser/peg/keyword_map.cpp index d5f235b1b..1ac505c63 100644 --- a/src/duckdb/src/parser/peg/keyword_map.cpp +++ b/src/duckdb/src/parser/peg/keyword_map.cpp @@ -2,11 +2,8 @@ #include "duckdb/parser/peg/keyword_helper/duckdb_keyword_helper.hpp" namespace duckdb { -void DuckDBKeywordHelper::InitializeKeywordMaps() { // Renamed for clarity - if (initialized) { - return; - }; - initialized = true; +DefaultKeywordMaps DuckDBKeywordHelper::InitializeKeywordMaps() { + DefaultKeywordMaps keyword_maps; auto &reserved_keyword_map = keyword_maps.reserved_keyword_map; auto &unreserved_keyword_map = keyword_maps.unreserved_keyword_map; @@ -560,5 +557,6 @@ void DuckDBKeywordHelper::InitializeKeywordMaps() { // Renamed for clarity typename_keyword_map.insert("try_cast"); typename_keyword_map.insert("unpack"); typename_keyword_map.insert("verbose"); + return keyword_maps; } } // namespace duckdb diff --git a/src/duckdb/src/parser/peg/matcher.cpp b/src/duckdb/src/parser/peg/matcher.cpp index 46e0b2407..e3c48c950 100644 --- a/src/duckdb/src/parser/peg/matcher.cpp +++ b/src/duckdb/src/parser/peg/matcher.cpp @@ -18,40 +18,10 @@ namespace duckdb { -static MatcherResult ExecuteRecursive(MatchInput input) { - auto &matcher = input.matcher; - auto &state = input.state; - state.rule = matcher.GetRule(); - PackratMatchState packrat_state; - if (PackratMatchState::IsEnabled(matcher, state)) { - auto cached_result = packrat_state.TryLoadCachedResult(matcher, state); - if (cached_result) { - return *cached_result; - } - } - - auto process = matcher.StartMatch(state); - optional child_result; - while (true) { - auto step = process->Resume(child_result); - child_result.reset(); - auto child = step.GetChild(); - if (!child) { - auto result = step.GetResult(); - packrat_state.StoreResult(matcher, state, result); - return result; - } - child_result = ExecuteRecursive(*child); - } -} - MatcherResult Matcher::MatchParseResult(MatchState &state) const { MatchInput input {*this, state}; - if (state.context.use_heap_based_parser) { - MatchStack stack; - return stack.Execute(input); - } - return ExecuteRecursive(input); + MatchStack stack; + return stack.Execute(input); } SuggestionType Matcher::AddSuggestion(MatchState &state) const { diff --git a/src/duckdb/src/parser/peg/matcher_factory.cpp b/src/duckdb/src/parser/peg/matcher_factory.cpp index 73d56ce75..fafdc6388 100644 --- a/src/duckdb/src/parser/peg/matcher_factory.cpp +++ b/src/duckdb/src/parser/peg/matcher_factory.cpp @@ -2,9 +2,24 @@ #include "duckdb/parser/peg/peg_parser.hpp" #include "duckdb/parser/peg/matcher/list.hpp" #include "duckdb/parser/peg/compiled_grammar.hpp" +#include "duckdb/parser/peg/matcher/literal_choice_matcher.hpp" namespace duckdb { +class CompiledKeywordMatcher final : public KeywordMatcher { +public: + CompiledKeywordMatcher(const string &keyword, const KeywordInfo &info, const PEGKeywordHelper &helper) + : KeywordMatcher(keyword, info, helper) { + } + + optional_idx GetDispatchLiteral(const GrammarLiteralTable &table) const override { + if (literal_table.get() != &table || !literal_info.LiteralId()) { + return optional_idx(); + } + return optional_idx(literal_info.LiteralId()); + } +}; + void MatcherFactory::MatcherConstructionState::Register(string_t rule_name) { unconstructed.insert(rule_name); } @@ -186,8 +201,9 @@ void MatcherFactory::SuppressSuggestions(const char *name) { } MatcherFactory::MatcherFactory(MatcherAllocator &allocator, const ParsedGrammar &grammar_p, - const compiled_rules_map_t &rules, terminal_rule_overrides_t terminal_rule_overrides_p) - : allocator(allocator), grammar(grammar_p), rules(rules), + const compiled_rules_map_t &rules, const PEGKeywordHelper &keyword_helper_p, + terminal_rule_overrides_t terminal_rule_overrides_p) + : allocator(allocator), grammar(grammar_p), rules(rules), keyword_helper(keyword_helper_p), terminal_rule_overrides(std::move(terminal_rule_overrides_p)) { } @@ -265,7 +281,7 @@ Matcher &MatcherFactory::CreateRootMatcher(const string &root_rule) { } unique_ptr MatcherFactory::CreateKeyword(const string &keyword, const KeywordInfo &info) const { - return make_uniq(keyword, info); + return make_uniq(keyword, info, keyword_helper); } unique_ptr MatcherFactory::CreateList() const { @@ -273,6 +289,23 @@ unique_ptr MatcherFactory::CreateList() const { } unique_ptr MatcherFactory::CreateChoice(vector> &&matchers) const { + auto &table = keyword_helper.GetLiteralTable(); + if (matchers.size() > 1) { + unordered_map literal_children; + for (idx_t i = 0; i < matchers.size(); i++) { + auto &matcher = matchers[i].get(); + if (matcher.Type() != MatcherType::KEYWORD) { + return make_uniq(std::move(matchers)); + } + auto literal = matcher.Cast().GetDispatchLiteral(table); + if (!literal.IsValid()) { + return make_uniq(std::move(matchers)); + } + // Preserve the first alternative when spellings share an ID. + literal_children.emplace(static_cast(literal.GetIndex()), i); + } + return make_uniq(std::move(matchers), table, std::move(literal_children)); + } return make_uniq(std::move(matchers)); } diff --git a/src/duckdb/src/parser/peg/matcher_process.cpp b/src/duckdb/src/parser/peg/matcher_process.cpp index b1511f31f..078994cac 100644 --- a/src/duckdb/src/parser/peg/matcher_process.cpp +++ b/src/duckdb/src/parser/peg/matcher_process.cpp @@ -1,5 +1,6 @@ #include "duckdb/parser/peg/matcher.hpp" #include "duckdb/parser/peg/matcher/choice_matcher.hpp" +#include "duckdb/parser/peg/matcher/literal_choice_matcher.hpp" #include "duckdb/parser/peg/matcher/list_matcher.hpp" #include "duckdb/parser/peg/matcher/optional_matcher.hpp" #include "duckdb/parser/peg/matcher/repeat_matcher.hpp" @@ -21,7 +22,7 @@ optional MatchStep::GetChild() { MatcherResult MatchStep::GetResult() const { D_ASSERT(!child); D_ASSERT(result); - return *result; + return result.value(); } class AtomicMatchProcess : public MatchProcess { @@ -119,9 +120,11 @@ arena_ptr ListMatcher::StartMatch(MatchState &state) const { return state.Make(*this, state); } +template class ChoiceMatchProcess : public MatchProcess { public: - ChoiceMatchProcess(const ChoiceMatcher &matcher_p, MatchState &state_p) : matcher(matcher_p), state(state_p) { + ChoiceMatchProcess(const ChoiceMatcher &matcher_p, MatchState &state_p, idx_t child_index_p = 0) + : matcher(matcher_p), state(state_p), child_index(child_index_p) { if (auto current = state.token_iterator.Current()) { start_offset = optional_idx(current->offset); } @@ -133,13 +136,16 @@ class ChoiceMatchProcess : public MatchProcess { awaiting_child = false; D_ASSERT(child_state); if (child_result->IsSuccess()) { - state.token_iterator.SetPosition(child_state->token_iterator); + state.token_iterator.SetPosition(child_state.value().token_iterator); if (!child_result->HasParseResult()) { return MatchStep::Complete(MatcherResult::Success()); } return MatchStep::Complete(state.AllocateParseResult(*child_result->GetParseResult(), child_index, start_offset)); } + if (SINGLE_CHILD) { + return MatchStep::Complete(MatcherResult::Failure()); + } child_index++; child_state.reset(); } @@ -161,7 +167,14 @@ class ChoiceMatchProcess : public MatchProcess { }; arena_ptr ChoiceMatcher::StartMatch(MatchState &state) const { - return state.Make(*this, state); + return state.Make>(*this, state); +} + +arena_ptr LiteralChoiceMatcher::StartMatch(MatchState &state) const { + auto literal = state.token_iterator.CurrentLiteralInfo(table); + auto entry = literal_children.find(literal.LiteralId()); + auto child_index = entry == literal_children.end() ? matchers.size() : entry->second; + return state.Make>(*this, state, child_index); } class OptionalMatchProcess : public MatchProcess { diff --git a/src/duckdb/src/parser/peg/operator_matcher.cpp b/src/duckdb/src/parser/peg/operator_matcher.cpp new file mode 100644 index 000000000..d6fe001ee --- /dev/null +++ b/src/duckdb/src/parser/peg/operator_matcher.cpp @@ -0,0 +1,30 @@ +#include "duckdb/parser/peg/matcher/operator_matcher.hpp" + +namespace duckdb { + +bool OperatorMatcher::HasSpecialPrecedence(const string &operator_name) { + switch (operator_name.size()) { + case 1: + switch (operator_name[0]) { + case '=': + case '<': + case '>': + case '~': + return true; + default: + return false; + } + case 2: + return operator_name == "->" || operator_name == "<=" || operator_name == ">=" || operator_name == "!=" || + operator_name == "==" || operator_name == "<>" || operator_name == "~~" || operator_name == "~*" || + operator_name == "!~"; + case 3: + return operator_name == "~~*" || operator_name == "~~~" || operator_name == "!~~" || operator_name == "!~*"; + case 4: + return operator_name == "!~~*"; + default: + return false; + } +} + +} // namespace duckdb diff --git a/src/duckdb/src/parser/peg/peg_parser.cpp b/src/duckdb/src/parser/peg/peg_parser.cpp index 0d4d95bcd..4731b732b 100644 --- a/src/duckdb/src/parser/peg/peg_parser.cpp +++ b/src/duckdb/src/parser/peg/peg_parser.cpp @@ -199,6 +199,7 @@ void PEGParser::ParseRules(const char *grammar) { // if we see a newline while we are parsing a rule definition we can complete the rule auto new_rule = PEGRule(std::move(parameters), BuildExpression(tokens)); AddRule(rule_name, std::move(new_rule)); + parameters = string_map_t(); rule_name = string_t(); // look for the subsequent rule parse_state = PEGParseState::RULE_NAME; diff --git a/src/duckdb/src/parser/peg/tokenizer/base_tokenizer.cpp b/src/duckdb/src/parser/peg/tokenizer/base_tokenizer.cpp index d2d743b28..408f6e212 100644 --- a/src/duckdb/src/parser/peg/tokenizer/base_tokenizer.cpp +++ b/src/duckdb/src/parser/peg/tokenizer/base_tokenizer.cpp @@ -24,46 +24,15 @@ void Tokenizer::HandleLastToken(TokenizerBehavior &behavior, TokenizeState state behavior.OnLastToken(*this, state, last_word, last_pos); } -static bool OperatorEquals(const char *str, const char *op, idx_t len, idx_t &op_len) { - for (idx_t i = 0; i < len; i++) { - if (str[i] != op[i]) { - return false; - } - } - op_len = len; - return true; -} - -bool Tokenizer::IsSpecialOperator(const string &sql, idx_t pos, idx_t &op_len) const { - const char *op_start = sql.c_str() + pos; - if (pos + 2 < sql.size()) { - if (OperatorEquals(op_start, "<->", 3, op_len)) { - return true; - } - if (OperatorEquals(op_start, "->>", 3, op_len)) { - return true; - } - } - if (pos + 1 >= sql.size()) { - // 2-byte operators are out-of-bounds +bool Tokenizer::IsCompoundColonToken(const string &sql, idx_t pos, idx_t &token_length) const { + if (pos + 1 >= sql.size() || sql[pos] != ':') { return false; } - if (OperatorEquals(op_start, "::", 2, op_len)) { - return true; - } - if (OperatorEquals(op_start, ":=", 2, op_len)) { - return true; - } - if (OperatorEquals(op_start, "->", 2, op_len)) { - return true; - } - if (OperatorEquals(op_start, "**", 2, op_len)) { - return true; - } - if (OperatorEquals(op_start, "//", 2, op_len)) { - return true; + if (sql[pos + 1] != ':' && sql[pos + 1] != '=') { + return false; } - return false; + token_length = 2; + return true; } bool Tokenizer::IsSingleByteOperator(char c) { @@ -75,9 +44,9 @@ bool Tokenizer::IsSingleByteOperator(char c) { case '[': case ']': case ',': + case ':': case '?': case '$': - case '-': case '#': return true; default: @@ -135,7 +104,6 @@ bool Tokenizer::CharacterIsScientific(char c) { bool Tokenizer::CharacterIsControlFlow(char c) { switch (c) { case '\'': - case '-': case ';': case '"': case '.': @@ -162,13 +130,25 @@ bool Tokenizer::CharacterIsKeyword(char c) { } bool Tokenizer::CharacterIsOperator(char c) { - if (IsSingleByteOperator(c)) { - return false; - } - if (CharacterIsControlFlow(c)) { + switch (c) { + case '+': + case '-': + case '*': + case '/': + case '%': + case '^': + case '<': + case '>': + case '=': + case '~': + case '!': + case '@': + case '&': + case '|': + return true; + default: return false; } - return StringUtil::CharacterIsOperator(c); } TokenType Tokenizer::TokenizeStateToType(TokenizeState state) { @@ -276,7 +256,7 @@ bool Tokenizer::TokenizeInput(TokenizerBehavior &behavior) const { void Tokenizer::PushOperatorToken(TokenizerBehavior &behavior, idx_t start, idx_t end) const { auto &sql = behavior.sql; auto &tokens = behavior.tokens; - // Apply PostgreSQL trimming rule: an operator cannot end in '+' unless + // Apply PostgreSQL trimming rule: an operator cannot end in '+' or '-' unless // it contains at least one of: ~ ! @ # % ^ & | ` ? idx_t end_pos = end; bool has_special = false; @@ -290,12 +270,12 @@ void Tokenizer::PushOperatorToken(TokenizerBehavior &behavior, idx_t start, idx_ } } if (!has_special) { - while (end_pos > start && sql[end_pos - 1] == '+') { + while (end_pos > start + 1 && (sql[end_pos - 1] == '+' || sql[end_pos - 1] == '-')) { end_pos--; } } behavior.PushToken(start, end_pos, TokenType::OPERATOR); - // Push any trimmed '+' characters as individual tokens + // Push any trimmed '+' or '-' characters as individual tokens for (idx_t pos = end_pos; pos < end; pos++) { tokens.emplace_back(string(1, sql[pos]), pos, TokenType::OPERATOR); } @@ -388,16 +368,16 @@ bool Tokenizer::TokenizeInputInternal(TokenizerBehavior &behavior) const { last_pos = i + 1; break; } - idx_t op_len; - if (IsSpecialOperator(sql, i, op_len)) { - if (i + op_len < sql.size() && CharacterIsOperator(sql[i + op_len])) { + idx_t token_length; + if (IsCompoundColonToken(sql, i, token_length)) { + if (i + token_length < sql.size() && CharacterIsOperator(sql[i + token_length])) { state = TokenizeState::OPERATOR; last_pos = i; break; } - // special operator - push the special operator - tokens.emplace_back(sql.substr(i, op_len), last_pos, TokenType::OPERATOR); - i += op_len - 1; + // Push the compound colon token + tokens.emplace_back(sql.substr(i, token_length), last_pos, TokenType::OPERATOR); + i += token_length - 1; last_pos = i + 1; break; } @@ -477,6 +457,13 @@ bool Tokenizer::TokenizeInputInternal(TokenizerBehavior &behavior) const { i--; break; case TokenizeState::OPERATOR: + if (c == '-' && i + 1 < sql.size() && sql[i + 1] == '-') { + PushOperatorToken(behavior, last_pos, i); + state = TokenizeState::STANDARD; + last_pos = i; + i--; + break; + } if (c == '/' && i + 1 < sql.size() && sql[i + 1] == '*') { PushOperatorToken(behavior, last_pos, i); // Go back to STANDARD state so it tokenizes as a block comment diff --git a/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp b/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp index 7f594a110..e5793b850 100644 --- a/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp +++ b/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp @@ -190,36 +190,14 @@ string TransformStack::FormatStack() const { } #endif -unique_ptr PEGTransformer::ExecuteRecursive(TransformInput input) { - auto rule = input.GetRule(); - if (!rule) { - throw InternalException("No registered data exists for rule '%s'", input.parse_result.name); - } - auto process = rule->StartTransform(*this, input.parse_result); - unique_ptr child_result; - while (true) { - auto step = process->Resume(std::move(child_result)); - auto child = step.GetChild(); - if (!child) { - auto result = step.TakeResult(); - SetResultLocation(input.parse_result, *result); - return result; - } - child_result = ExecuteRecursive(*child); - } -} - unique_ptr PEGTransformer::TransformInternal(ParseResult &parse_result) { auto rule = parse_result.GetRule(); if (!rule) { throw InternalException("No registered data exists for rule '%s'", parse_result.name); } TransformInput input {*rule, parse_result}; - if (options.heap_based_parser) { - TransformStack stack(*this); - return stack.Execute(input); - } - return ExecuteRecursive(input); + TransformStack stack(*this); + return stack.Execute(input); } const CompiledGrammarRule &PEGTransformer::GetRule(const string &rule_name) const { diff --git a/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp b/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp index 4ffb71a24..f390b093f 100644 --- a/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp +++ b/src/duckdb/src/parser/peg/transformer/peg_transformer_factory.cpp @@ -20,19 +20,6 @@ namespace duckdb { -unique_ptr PEGTransformerFactory::TransformStatement(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - if (!transformer.named_parameter_map.empty()) { - // Avoid overriding a previous move with nothing - result->named_param_map = transformer.named_parameter_map; - } - result->has_anonymous_parameters = transformer.has_anonymous_parameters; - return result; -} - static unique_ptr ExtractAndTransformStatement(PEGTransformer &transformer, const TokenIterator &token_iterator, ParseResult &stmt_pr, optional_idx terminator_offset) { @@ -70,8 +57,7 @@ unique_ptr PEGTransformerFactory::TransformTopLevelStatement(Token idx_t max_token_index = token_iterator.Position(); ArenaAllocator process_allocator(Allocator::DefaultAllocator()); MatchContext match_context(suggestions, parse_result_allocator, process_allocator, max_token_index, - MatchMode::BUILD_PARSE_RESULT, options.identifier_case_mode, options.heap_based_parser, - &packrat_cache); + MatchMode::BUILD_PARSE_RESULT, options.identifier_case_mode, &packrat_cache); MatchState state(token_iterator, match_context); auto match_result = grammar.TopLevelStatementMatcher().MatchParseResult(state); process_allocator.FreeAll(); @@ -123,64 +109,7 @@ unique_ptr PEGTransformerFactory::TransformTopLevelStatement(Token return ExtractAndTransformStatement(transformer, token_iterator, stmt_opt.GetResult(), terminator_offset); } -#define REGISTER_TRANSFORM(FUNCTION) Register(string(#FUNCTION).substr(9), &FUNCTION) - -void PEGTransformerFactory::RegisterCommon() { - // common.gram - REGISTER_TRANSFORM(TransformNumberLiteral); - REGISTER_TRANSFORM(TransformStringLiteral); - REGISTER_TRANSFORM(TransformIntervalToIntervalAsType); -} - -void PEGTransformerFactory::RegisterCreateTable() { - // create_table.gram - REGISTER_TRANSFORM(TransformIdentifier); -} - -void PEGTransformerFactory::RegisterExpression() { - // expression.gram - REGISTER_TRANSFORM(TransformPrefixExpression); - REGISTER_TRANSFORM(TransformOverClause); -} - -void PEGTransformerFactory::RegisterPivot() { - // PivotStatement and UnpivotStatement measure parameter usage while transforming - // the source table, so their top-level wrappers remain manual. - REGISTER_TRANSFORM(TransformPivotStatement); - REGISTER_TRANSFORM(TransformUnpivotStatement); -} - -void PEGTransformerFactory::RegisterSelect() { - // select.gram rules that remain manual after generated wrappers are registered. - Register("SelectStatementInternal", &TransformSelectStatementInternalRule); - REGISTER_TRANSFORM(TransformSimpleSelect); - REGISTER_TRANSFORM(TransformTableRef); - REGISTER_TRANSFORM(TransformWithClause); - REGISTER_TRANSFORM(TransformWindowDefinition); -} - -void PEGTransformerFactory::RegisterKeywordsAndIdentifiers() { - Register("PragmaName", &TransformIdentifierOrKeyword); - Register("TypeName", &TransformIdentifierOrKeyword); - Register("PlainIdentifier", &TransformIdentifierOrKeyword); - Register("QuotedIdentifier", &TransformIdentifierOrKeyword); - Register("ReservedKeyword", &TransformIdentifierOrKeyword); - Register("UnreservedKeyword", &TransformIdentifierOrKeyword); - Register("ColumnNameKeyword", &TransformIdentifierOrKeyword); - Register("FuncNameKeyword", &TransformIdentifierOrKeyword); - Register("TypeNameKeyword", &TransformIdentifierOrKeyword); - Register("SettingName", &TransformIdentifierOrKeyword); -} - PEGTransformerFactory::PEGTransformerFactory(ParsedGrammar &grammar_p) : grammar(grammar_p) { - RegisterGenerated(); - REGISTER_TRANSFORM(TransformStatement); - RegisterCommon(); - RegisterCreateTable(); - RegisterExpression(); - RegisterPivot(); - RegisterSelect(); - RegisterKeywordsAndIdentifiers(); for (auto &entry : GeneratedTransformFrameOps()) { auto process_info = entry.second; grammar.SetTransformProcess( @@ -222,10 +151,19 @@ bool PEGTransformerFactory::ExpressionIsEmptyStar(const ParsedExpression &expr) return false; } auto &star = expr.Cast(); - if (!star.IsColumns() && star.ExcludeList().empty() && star.ReplaceList().empty()) { - return true; + if (star.IsColumns()) { + return false; + } + if (!star.ExcludeList().empty()) { + return false; + } + if (!star.ReplaceList().empty()) { + return false; + } + if (!star.RenameList().empty()) { + return false; } - return false; + return true; } QualifiedName PEGTransformerFactory::StringToQualifiedName(vector input) { diff --git a/src/duckdb/src/parser/peg/transformer/transform_alter.cpp b/src/duckdb/src/parser/peg/transformer/transform_alter.cpp index 5a3053e6c..386dd14ac 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_alter.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_alter.cpp @@ -1,3 +1,4 @@ +#include "duckdb/parser/constraints/unique_constraint.hpp" #include "duckdb/parser/peg/ast/add_column_entry.hpp" #include "duckdb/parser/expression/columnref_expression.hpp" #include "duckdb/parser/peg/ast/column_constraint_entry.hpp" @@ -40,17 +41,20 @@ unique_ptr PEGTransformerFactory::TransformAlterStatement(PEGTrans } auto &add_column = alter_table.Cast(); auto &column_entry = add_column.new_column; - const bool add_not_null = add_column.add_not_null; + const auto follow_ups = add_column.add_column_constraints; const bool materialize_default = column_entry.HasDefaultValue() && !IsSimpleDefaultValue(column_entry.DefaultValue()); - if (!add_not_null && !materialize_default) { + if (!follow_ups.add_not_null && !follow_ups.add_unique && !materialize_default) { return std::move(result); } if (add_column.if_column_not_exists) { - if (add_not_null) { + if (follow_ups.add_not_null) { throw NotImplementedException("Adding a NOT NULL column with IF NOT EXISTS is not supported"); } + if (follow_ups.add_unique) { + throw NotImplementedException("Adding a UNIQUE column with IF NOT EXISTS is not supported"); + } // IF NOT EXISTS is not supported by the multi-statement rewrite - keep the plain ALTER return std::move(result); } @@ -64,16 +68,23 @@ unique_ptr PEGTransformerFactory::TransformAlterStatement(PEGTrans multi_statement = TransformAndMaterializeAlter( alter_entry_data, make_uniq(add_column.GetAlterEntryData(), std::move(null_column), - add_column.if_column_not_exists, /*add_not_null=*/false), + add_column.if_column_not_exists, AddColumnConstraints()), column_name.GetIdentifierName(), column_entry.DefaultValue().Copy()); } else { multi_statement = make_uniq(); - add_column.add_not_null = false; + add_column.add_column_constraints = AddColumnConstraints(); AddToMultiStatement(multi_statement, std::move(result->info)); } - if (add_not_null) { + if (follow_ups.add_not_null) { AddToMultiStatement(multi_statement, make_uniq(alter_entry_data, column_name)); } + if (follow_ups.add_unique) { + vector unique_columns; + unique_columns.push_back(column_name); + auto unique_constraint = make_uniq(std::move(unique_columns), /*is_primary_key=*/false); + AddToMultiStatement(multi_statement, + make_uniq(alter_entry_data, std::move(unique_constraint))); + } return std::move(multi_statement); } @@ -251,11 +262,14 @@ unique_ptr PEGTransformerFactory::TransformAddColumn(PEGTransfor if (add_column_entry.column_path.size() == 1) { result = make_uniq(AlterEntryData(), std::move(column_definition), if_not_exists_value, - add_column_entry.is_not_null); + add_column_entry.add_column_constraints); } else { - if (add_column_entry.is_not_null) { + if (add_column_entry.add_column_constraints.add_not_null) { throw NotImplementedException("Adding NOT NULL constraints to nested fields is not supported"); } + if (add_column_entry.add_column_constraints.add_unique) { + throw NotImplementedException("Adding UNIQUE constraints to nested fields is not supported"); + } if (add_column_entry.compression_type != CompressionType::COMPRESSION_AUTO) { throw NotImplementedException("Adding compression to nested fields is not supported"); } @@ -286,14 +300,23 @@ AddColumnEntry PEGTransformerFactory::TransformAddColumnEntry( } if (column_constraint) { for (auto &constraint : *column_constraint) { + auto constraint_type = + constraint.constraint ? constraint.constraint->type : constraint.constraint_type_info.second; if (constraint.constraint_name == "DefaultValue") { if (new_column.default_value) { throw ParserException("Cannot define a default value twice"); } new_column.default_value = std::move(constraint.expression); - } else if (constraint.constraint_name == "NotNullConstraint" && - constraint.constraint_type_info.second == ConstraintType::NOT_NULL) { - new_column.is_not_null = true; + } else if (constraint_type == ConstraintType::NOT_NULL) { + new_column.add_column_constraints.add_not_null = true; + } else if (constraint_type == ConstraintType::UNIQUE && !constraint.constraint_type_info.first) { + new_column.add_column_constraints.add_unique = true; + } else if (constraint_type == ConstraintType::UNIQUE) { + throw ParserException("Adding columns with PRIMARY KEY constraints is not supported yet"); + } else if (constraint_type == ConstraintType::CHECK) { + throw ParserException("Adding columns with CHECK constraints is not supported yet"); + } else if (constraint_type == ConstraintType::FOREIGN_KEY) { + throw ParserException("Adding columns with FOREIGN KEY constraints is not supported yet"); } else if (constraint.constraint_name == "ColumnCompression") { new_column.compression_type = constraint.compression_type; if (new_column.compression_type == CompressionType::COMPRESSION_AUTO) { diff --git a/src/duckdb/src/parser/peg/transformer/transform_comment.cpp b/src/duckdb/src/parser/peg/transformer/transform_comment.cpp index 5dbafc09c..f5cbe424b 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_comment.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_comment.cpp @@ -4,9 +4,15 @@ namespace duckdb { +vector +PEGTransformerFactory::TransformCommentStringLiteralIdentifier(PEGTransformer &transformer, + const Identifier &string_literal_identifier) { + return {string_literal_identifier.GetIdentifierName()}; +} + unique_ptr PEGTransformerFactory::TransformCommentStatement(PEGTransformer &transformer, const CatalogType &comment_on_type, - const vector &dotted_identifier, + const vector &comment_target, const Value &comment_value) { auto result = make_uniq(); unique_ptr info; @@ -14,7 +20,7 @@ unique_ptr PEGTransformerFactory::TransformCommentStatement(PEGTra Identifier column_name; if (comment_on_type == CatalogType::INVALID) { // Column type returned - auto identifier = dotted_identifier; + auto identifier = comment_target; column_name = Identifier(identifier.back()); identifier.pop_back(); if (identifier.empty()) { @@ -28,7 +34,7 @@ unique_ptr PEGTransformerFactory::TransformCommentStatement(PEGTra } else if (comment_on_type == CatalogType::SCHEMA_ENTRY) { throw NotImplementedException("Adding comments to schemas is not implemented"); } else { - auto qualified_name = StringToQualifiedName(dotted_identifier); + auto qualified_name = StringToQualifiedName(comment_target); info = make_uniq(comment_on_type, qualified_name.Catalog(), qualified_name.Schema(), qualified_name.Name(), comment_value, OnEntryNotFound::THROW_EXCEPTION); } diff --git a/src/duckdb/src/parser/peg/transformer/transform_copy.cpp b/src/duckdb/src/parser/peg/transformer/transform_copy.cpp index 93107fa0f..3b1f0e552 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_copy.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_copy.cpp @@ -184,11 +184,12 @@ PEGTransformerFactory::TransformCopyFileNameIdentifierColId(PEGTransformer &tran } Identifier PEGTransformerFactory::TransformIdentifierColId(PEGTransformer &transformer, const Identifier &identifier, - const Identifier &col_id) { - string result; - result += identifier.GetIdentifierName(); - result += "."; - result += col_id.GetIdentifierName(); + const vector ©_file_name_suffix) { + string result = identifier.GetIdentifierName(); + for (const auto &suffix : copy_file_name_suffix) { + result += "."; + result += suffix.GetIdentifierName(); + } return Identifier(result); } diff --git a/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp b/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp index 7b5611cbe..7e243482d 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp @@ -210,11 +210,6 @@ Identifier PEGTransformerFactory::TransformStringLiteralIdentifier(PEGTransforme return Identifier(string_literal); } -string PEGTransformerFactory::TransformIdentifier(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - return list_pr.Child(0).identifier.GetIdentifierName(); -} - vector PEGTransformerFactory::TransformDottedIdentifier(PEGTransformer &transformer, const Identifier &identifier, const optional> &dot_col_label) { diff --git a/src/duckdb/src/parser/peg/transformer/transform_expression.cpp b/src/duckdb/src/parser/peg/transformer/transform_expression.cpp index 9c1562f42..13fed081d 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_expression.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_expression.cpp @@ -18,10 +18,17 @@ #include "duckdb/parser/tableref/subqueryref.hpp" #include "duckdb/parser/tableref/emptytableref.hpp" #include "duckdb/parser/parsed_expression_iterator.hpp" +#include "duckdb/parser/expression/star_expression.hpp" #include "duckdb/common/string_util.hpp" namespace duckdb { +//! Only an unqualified star (e.g. COUNT(*)) refers to the rows themselves - a qualified star (e.g. COUNT(tbl.*)) +//! refers to the columns of that relation and is expanded by the binder +static bool ExpressionIsUnqualifiedStar(const ParsedExpression &expr) { + return PEGTransformerFactory::ExpressionIsEmptyStar(expr) && expr.Cast().RelationName().empty(); +} + unique_ptr PEGTransformerFactory::TransformExpressionStatement(PEGTransformer &transformer, vector> expression_alias) { @@ -187,7 +194,7 @@ unique_ptr PEGTransformerFactory::TransformFunctionExpression( if (filter_clause) { filter_expr = std::move(*filter_clause); } - if (function_children.size() == 1 && ExpressionIsEmptyStar(*function_children[0].GetExpressionMutable()) && + if (function_children.size() == 1 && ExpressionIsUnqualifiedStar(function_children[0].GetExpression()) && !distinct && order_modifier->orders.empty()) { // COUNT(*) gets converted into COUNT() function_children.clear(); @@ -570,20 +577,6 @@ PEGTransformerFactory::TransformBoundedListExpression(PEGTransformer &transforme return vector>(); } -// Expression <- LambdaArrowExpression -unique_ptr PEGTransformerFactory::TransformExpression(PEGTransformer &transformer, - ParseResult &parse_result) { - auto stack_check = transformer.StackCheck(); - auto &list_pr = parse_result.Cast(); - return transformer.Transform>(list_pr.Child(0)); -} - -unique_ptr -PEGTransformerFactory::TransformExpression(PEGTransformer &transformer, - unique_ptr lambda_arrow_expression) { - return lambda_arrow_expression; -} - unique_ptr PEGTransformerFactory::TransformColumnDefaultExpr(PEGTransformer &transformer, unique_ptr col_def_or_expr) { @@ -1319,18 +1312,19 @@ string PEGTransformerFactory::TransformQualifiedOperator(PEGTransformer &transfo string PEGTransformerFactory::TransformQualifiedOperatorContents(PEGTransformer &transformer, const optional> &col_id_dot, - const string &any_op) { + const string &any_operator_literal) { vector result; if (col_id_dot) { result = *col_id_dot; } - result.push_back(any_op); + result.push_back(any_operator_literal); return StringUtil::Join(result, "."); } -pair PEGTransformerFactory::TransformAnyAllOperator(PEGTransformer &transformer, const string &any_op, +pair PEGTransformerFactory::TransformAnyAllOperator(PEGTransformer &transformer, + const string &any_operator_literal, const bool &any_or_all) { - return make_pair(any_op, any_or_all); + return make_pair(any_operator_literal, any_or_all); } bool PEGTransformerFactory::TransformSubqueryAny(PEGTransformer &transformer) { @@ -1504,46 +1498,6 @@ PEGTransformerFactory::TransformAtTimeZoneExpressionTail(PEGTransformer &transfo return prefix_expression; } -// PrefixExpression <- PrefixOperator* BaseExpression -unique_ptr PEGTransformerFactory::TransformPrefixExpression(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &prefix_opt = list_pr.Child(0); - auto &base_expr_pr = list_pr.Child(1); - - if (!prefix_opt.HasResult()) { - return transformer.Transform>(base_expr_pr); - } - - auto &prefix_repeat = prefix_opt.GetResult().Cast(); - auto expr = transformer.Transform>(base_expr_pr); - - vector prefixes; - for (auto &child_ref : prefix_repeat.GetChildren()) { - prefixes.push_back(transformer.Transform(child_ref)); - } - - for (auto it = prefixes.rbegin(); it != prefixes.rend(); ++it) { - const string &prefix = *it; - - if (prefix == "-" && expr->GetExpressionType() == ExpressionType::VALUE_CONSTANT) { - // fold the sign into the number text so -9223372036854775808 stays exact - auto &literal = expr->Cast().GetLiteral(); - if (literal.IsNumeric()) { - expr = make_uniq(literal.Negate()); - continue; - } - } - - vector> children; - children.push_back(std::move(expr)); - auto func_expr = make_uniq(Identifier(prefix), std::move(children)); - func_expr->IsOperatorMutable() = true; - expr = std::move(func_expr); - } - return expr; -} - void PEGTransformerFactory::InitializePrefixExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -1807,7 +1761,7 @@ unique_ptr PEGTransformerFactory::TransformMethodExpression(PEGTransformer &transformer, const string &col_label, MethodArguments method_expression_arguments) { if (method_expression_arguments.arguments.size() == 1 && - ExpressionIsEmptyStar(method_expression_arguments.arguments[0].GetExpression())) { + ExpressionIsUnqualifiedStar(method_expression_arguments.arguments[0].GetExpression())) { // COUNT(*) gets converted into COUNT() method_expression_arguments.arguments.clear(); } @@ -2018,18 +1972,6 @@ QualifiedColumnName PEGTransformerFactory::TransformExcludeColumnName(PEGTransfo return QualifiedColumnName(col_id_or_string); } -unique_ptr PEGTransformerFactory::TransformOverClause(PEGTransformer &transformer, - ParseResult &parse_result) { - if (transformer.in_window_definition) { - throw ParserException("window functions are not allowed in window definitions"); - } - auto &list_pr = parse_result.Cast(); - transformer.in_window_definition = true; - auto window_frame = transformer.Transform>(list_pr.GetChild(1)); - transformer.in_window_definition = false; - return window_frame; -} - void PEGTransformerFactory::InitializeOverClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { if (transformer.in_window_definition) { diff --git a/src/duckdb/src/parser/peg/transformer/transform_external_resource.cpp b/src/duckdb/src/parser/peg/transformer/transform_external_resource.cpp index b31fa23b1..08a011847 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_external_resource.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_external_resource.cpp @@ -5,19 +5,12 @@ namespace duckdb { -//! Fold `(k v, ...)` create params onto the statement. A bare flag binds to boolean true, mirroring -//! ATTACH/CONNECT TO EXTERNAL RESOURCE option handling. +//! Fold `(k v, ...)` create params onto the statement; they are resolved at bind time. static void ApplyOptions(const optional> &options, ExternalResourceStatement &stmt) { if (!options) { return; } - for (const auto &opt : *options) { - if (!opt.expression && opt.children.empty()) { - stmt.options[opt.name.GetIdentifierName()] = ConstantExpression::Boolean(true); - } else { - stmt.options[opt.name.GetIdentifierName()] = opt.GetFirstChildOrExpression(); - } - } + PEGTransformerFactory::CollectGenericOptions(*options, stmt.options, "EXTERNAL RESOURCE"); } unique_ptr PEGTransformerFactory::TransformCreateExternalResourceStmt( diff --git a/src/duckdb/src/parser/peg/transformer/transform_external_resource_source.cpp b/src/duckdb/src/parser/peg/transformer/transform_external_resource_source.cpp new file mode 100644 index 000000000..a42b643a9 --- /dev/null +++ b/src/duckdb/src/parser/peg/transformer/transform_external_resource_source.cpp @@ -0,0 +1,70 @@ +#include "duckdb/parser/expression/constant_expression.hpp" +#include "duckdb/parser/peg/ast/generic_copy_option.hpp" +#include "duckdb/parser/peg/transformer/peg_transformer.hpp" +#include "duckdb/parser/parsed_data/external_resource_options.hpp" +#include "duckdb/parser/statement/attach_statement.hpp" +#include "duckdb/parser/statement/connect_statement.hpp" + +namespace duckdb { + +// Both statements produce a normal ATTACH/CONNECT carrying an ExternalResourceOptions. `NEW TEMPORARY` +// provisions a resource the statement owns; a bare `` borrows a registered one. + +//! NEW TEMPORARY EXTERNAL RESOURCE '' [(create opts)] — provision a fresh resource. +unique_ptr PEGTransformerFactory::TransformExternalResourceCreateClause( + PEGTransformer &transformer, const string &string_literal, + const optional> &external_resource_creation_options) { + auto result = make_uniq(); + result->provider = string_literal; + if (external_resource_creation_options) { + CollectGenericOptions(*external_resource_creation_options, result->parsed_params, "EXTERNAL RESOURCE"); + } + return result; +} + +//! EXTERNAL RESOURCE — reference an already-registered resource. +unique_ptr +PEGTransformerFactory::TransformExternalResourceReferenceClause(PEGTransformer &transformer, const Identifier &col_id) { + auto result = make_uniq(); + result->reference_name = col_id.GetIdentifierName(); + return result; +} + +unique_ptr PEGTransformerFactory::TransformAttachToExternalResource( + PEGTransformer &transformer, unique_ptr external_resource_source, + const Identifier &attach_alias, const optional> &attach_options) { + auto result = make_uniq(); + auto info = make_uniq(); + info->on_conflict = OnCreateConflict::ERROR_ON_CONFLICT; + // The alias is mandatory in the grammar: it separates the create params from the attach options. + info->name = Identifier(attach_alias); + info->external_resource = std::move(external_resource_source); + if (attach_options) { + SplitGenericOptions(*attach_options, info->parsed_options, info->options, "ATTACH"); + } + result->info = std::move(info); + return std::move(result); +} + +//! CONNECT has no alias separating its options from the recipe's. Borrowing takes no create params, so +//! a list there is the connection's; provisioning claims the first, and a second is refused. +unique_ptr +PEGTransformerFactory::TransformConnectToExternalResource(PEGTransformer &transformer, + unique_ptr external_resource_source, + const optional> &attach_options) { + auto result = make_uniq(); + auto info = make_uniq(); + if (attach_options && external_resource_source->reference_name.empty()) { + throw ParserException("CONNECT TO NEW TEMPORARY EXTERNAL RESOURCE: the option list belongs to the resource, so " + "the connection cannot take one of its own. Use `ATTACH TO NEW TEMPORARY EXTERNAL " + "RESOURCE ... AS (options); CONNECT ;` instead"); + } + info->external_resource = std::move(external_resource_source); + if (attach_options) { + SplitGenericOptions(*attach_options, info->parsed_options, info->options, "CONNECT"); + } + result->info = std::move(info); + return std::move(result); +} + +} // namespace duckdb diff --git a/src/duckdb/src/parser/peg/transformer/transform_generated.cpp b/src/duckdb/src/parser/peg/transformer/transform_generated.cpp deleted file mode 100644 index 0b7de2aa4..000000000 --- a/src/duckdb/src/parser/peg/transformer/transform_generated.cpp +++ /dev/null @@ -1,12045 +0,0 @@ -// AUTO-GENERATED by scripts/parser/generate_transformer.py -- DO NOT EDIT -#include "duckdb/parser/peg/transformer/peg_transformer.hpp" -#include "duckdb/parser/expression/star_expression.hpp" -#include "duckdb/parser/expression/columnref_expression.hpp" - -namespace duckdb { - -unique_ptr PEGTransformerFactory::TransformAlterStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto alter_options = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformAlterStatement(transformer, std::move(alter_options)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterTableStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto base_table_name = transformer.Transform>(list_pr.GetChild(2)); - vector> alter_table_options; - auto alter_table_options_items = ExtractParseResultsFromList(list_pr.GetChild(3)); - for (auto &alter_table_options_item : alter_table_options_items) { - auto alter_table_options_value = - transformer.Transform>(alter_table_options_item.get()); - alter_table_options.push_back(std::move(alter_table_options_value)); - } - auto result = - TransformAlterTableStmt(transformer, if_exists, std::move(base_table_name), std::move(alter_table_options)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterSchemaStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - auto rename_alter = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformAlterSchemaStmt(transformer, if_exists, qualified_name, std::move(rename_alter)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterTableOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAddConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto top_level_constraint = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformAddConstraint(transformer, std::move(top_level_constraint)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(2).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto identifier = list_pr.GetChild(3).Cast().identifier; - optional drop_behavior {}; - auto &drop_behavior_opt = list_pr.GetChild(4).Cast(); - if (drop_behavior_opt.HasResult()) { - auto drop_behavior_value = transformer.Transform(drop_behavior_opt.GetResult()); - drop_behavior = drop_behavior_value; - } - auto result = TransformDropConstraint(transformer, if_exists, identifier, drop_behavior); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAddColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto add_column_entry = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformAddColumn(transformer, has_result, if_not_exists, std::move(add_column_entry)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAddColumnEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto dotted_identifier = transformer.Transform>(list_pr.GetChild(0)); - optional type {}; - auto &type_opt = list_pr.GetChild(1).Cast(); - if (type_opt.HasResult()) { - auto type_value = transformer.Transform(type_opt.GetResult()); - type = type_value; - } - optional generated_column {}; - auto &generated_column_opt = list_pr.GetChild(2).Cast(); - if (generated_column_opt.HasResult()) { - auto generated_column_value = - transformer.Transform(generated_column_opt.GetResult()); - generated_column = std::move(generated_column_value); - } - optional> column_constraint {}; - auto &column_constraint_opt = list_pr.GetChild(3).Cast(); - if (column_constraint_opt.HasResult()) { - vector column_constraint_value; - auto &column_constraint_value_repeat_1 = column_constraint_opt.GetResult().Cast(); - for (auto &column_constraint_value_item_1 : column_constraint_value_repeat_1.GetChildren()) { - auto column_constraint_value_value_1 = - transformer.Transform(column_constraint_value_item_1.get()); - column_constraint_value.push_back(std::move(column_constraint_value_value_1)); - } - column_constraint = std::move(column_constraint_value); - } - auto result = TransformAddColumnEntry(transformer, dotted_identifier, type, std::move(generated_column), - std::move(column_constraint)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(2).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto nested_column_name = transformer.Transform>(list_pr.GetChild(3)); - optional drop_behavior {}; - auto &drop_behavior_opt = list_pr.GetChild(4).Cast(); - if (drop_behavior_opt.HasResult()) { - auto drop_behavior_value = transformer.Transform(drop_behavior_opt.GetResult()); - drop_behavior = drop_behavior_value; - } - auto result = TransformDropColumn(transformer, has_result, if_exists, std::move(nested_column_name), drop_behavior); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto nested_column_name = transformer.Transform>(list_pr.GetChild(2)); - auto alter_column_entry = transformer.Transform>(list_pr.GetChild(3)); - auto result = - TransformAlterColumn(transformer, has_result, std::move(nested_column_name), std::move(alter_column_entry)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRenameColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto nested_column_name = transformer.Transform>(list_pr.GetChild(2)); - auto identifier = list_pr.GetChild(4).Cast().identifier; - auto result = TransformRenameColumn(transformer, has_result, std::move(nested_column_name), identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNestedColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> identifier_dot {}; - auto &identifier_dot_opt = list_pr.GetChild(0).Cast(); - if (identifier_dot_opt.HasResult()) { - vector identifier_dot_value; - auto &identifier_dot_value_repeat_1 = identifier_dot_opt.GetResult().Cast(); - for (auto &identifier_dot_value_item_1 : identifier_dot_value_repeat_1.GetChildren()) { - auto identifier_dot_value_value_1 = transformer.Transform(identifier_dot_value_item_1.get()); - identifier_dot_value.push_back(identifier_dot_value_value_1); - } - identifier_dot = identifier_dot_value; - } - auto column_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformNestedColumnName(transformer, identifier_dot, column_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIdentifierDotInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformIdentifierDot(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRenameAlterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(2).Cast().identifier; - auto result = TransformRenameAlter(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetPartitionedByInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(3))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformSetPartitionedBy(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformResetPartitionedByInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformResetPartitionedBy(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetSortedByInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto order_by_expressions = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(3))); - auto result = TransformSetSortedBy(transformer, std::move(order_by_expressions)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformResetSortedByInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformResetSortedBy(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rel_option_list = - transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformSetOptions(transformer, std::move(rel_option_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformResetOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rel_option_list = - transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformResetOptions(transformer, std::move(rel_option_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterColumnEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAddOrDropDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAddDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformAddDefault(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDropDefault(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformChangeNullabilityInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto drop_or_set = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformChangeNullability(transformer, drop_or_set); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropOrSetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDropNullabilityInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDropNullability(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetNullabilityInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSetNullability(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAlterTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - optional type {}; - auto &type_opt = list_pr.GetChild(2).Cast(); - if (type_opt.HasResult()) { - auto type_value = transformer.Transform(type_opt.GetResult()); - type = type_value; - } - optional> using_expression {}; - auto &using_expression_opt = list_pr.GetChild(3).Cast(); - if (using_expression_opt.HasResult()) { - auto using_expression_value = - transformer.Transform>(using_expression_opt.GetResult()); - using_expression = std::move(using_expression_value); - } - auto result = TransformAlterType(transformer, has_result, type, std::move(using_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUsingExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformUsingExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterViewStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto base_table_name = transformer.Transform>(list_pr.GetChild(2)); - auto rename_alter = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformAlterViewStmt(transformer, if_exists, std::move(base_table_name), std::move(rename_alter)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterSequenceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto qualified_sequence_name = transformer.Transform(list_pr.GetChild(2)); - auto alter_sequence_options = transformer.Transform>(list_pr.GetChild(3)); - auto result = - TransformAlterSequenceStmt(transformer, if_exists, qualified_sequence_name, std::move(alter_sequence_options)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformQualifiedSequenceNameInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional catalog_qualification {}; - auto &catalog_qualification_opt = list_pr.GetChild(0).Cast(); - if (catalog_qualification_opt.HasResult()) { - auto catalog_qualification_value = transformer.Transform(catalog_qualification_opt.GetResult()); - catalog_qualification = catalog_qualification_value; - } - optional schema_qualification {}; - auto &schema_qualification_opt = list_pr.GetChild(1).Cast(); - if (schema_qualification_opt.HasResult()) { - auto schema_qualification_value = transformer.Transform(schema_qualification_opt.GetResult()); - schema_qualification = schema_qualification_value; - } - auto sequence_name = list_pr.GetChild(2).Cast().identifier; - auto result = - TransformQualifiedSequenceName(transformer, catalog_qualification, schema_qualification, sequence_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformAlterSequenceOptionsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformRenameAlterSequenceOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rename_alter = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformRenameAlterSequenceOptions(transformer, std::move(rename_alter)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetSequenceOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector>> sequence_option; - auto &sequence_option_repeat = list_pr.GetChild(0).Cast(); - for (auto &sequence_option_item : sequence_option_repeat.GetChildren()) { - auto sequence_option_value = - transformer.Transform>>(sequence_option_item.get()); - sequence_option.push_back(std::move(sequence_option_value)); - } - auto result = TransformSetSequenceOption(transformer, std::move(sequence_option)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAlterDatabaseStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto identifier = list_pr.GetChild(2).Cast().identifier; - auto identifier_1 = list_pr.GetChild(6).Cast().identifier; - auto result = TransformAlterDatabaseStmt(transformer, if_exists, identifier, identifier_1); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAnalyzeStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto analyze_keyword = transformer.Transform(list_pr.GetChild(0)); - optional analyze_verbose {}; - auto &analyze_verbose_opt = list_pr.GetChild(1).Cast(); - if (analyze_verbose_opt.HasResult()) { - auto analyze_verbose_value = transformer.Transform(analyze_verbose_opt.GetResult()); - analyze_verbose = analyze_verbose_value; - } - optional analyze_target {}; - auto &analyze_target_opt = list_pr.GetChild(2).Cast(); - if (analyze_target_opt.HasResult()) { - auto analyze_target_value = transformer.Transform(analyze_target_opt.GetResult()); - analyze_target = std::move(analyze_target_value); - } - auto result = TransformAnalyzeStatement(transformer, analyze_keyword, analyze_verbose, std::move(analyze_target)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAnalyzeTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - optional> name_list {}; - auto &name_list_opt = list_pr.GetChild(1).Cast(); - if (name_list_opt.HasResult()) { - auto name_list_value = transformer.Transform>(name_list_opt.GetResult()); - name_list = name_list_value; - } - auto result = TransformAnalyzeTarget(transformer, std::move(base_table_name), name_list); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAnalyzeVerboseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAnalyzeVerbose(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAttachStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional or_replace {}; - auto &or_replace_opt = list_pr.GetChild(1).Cast(); - if (or_replace_opt.HasResult()) { - auto or_replace_value = transformer.Transform(or_replace_opt.GetResult()); - or_replace = or_replace_value; - } - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(3).Cast(); - has_result = has_result_opt.HasResult(); - auto database_path = transformer.Transform>(list_pr.GetChild(4)); - optional attach_alias {}; - auto &attach_alias_opt = list_pr.GetChild(5).Cast(); - if (attach_alias_opt.HasResult()) { - auto attach_alias_value = transformer.Transform(attach_alias_opt.GetResult()); - attach_alias = attach_alias_value; - } - optional> attach_options {}; - auto &attach_options_opt = list_pr.GetChild(6).Cast(); - if (attach_options_opt.HasResult()) { - auto attach_options_value = transformer.Transform>(attach_options_opt.GetResult()); - attach_options = attach_options_value; - } - auto result = TransformAttachStatement(transformer, or_replace, if_not_exists, has_result, std::move(database_path), - attach_alias, attach_options); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDatabasePathInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformDatabasePath(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAttachAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformAttachAlias(transformer, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAttachOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto generic_copy_option_list = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformAttachOptions(transformer, generic_copy_option_list); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformCallStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto qualified_table_function = transformer.Transform(list_pr.GetChild(1)); - auto table_function_arguments = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformCallStatement(transformer, qualified_table_function, std::move(table_function_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCheckpointStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional checkpoint_force {}; - auto &checkpoint_force_opt = list_pr.GetChild(0).Cast(); - if (checkpoint_force_opt.HasResult()) { - auto checkpoint_force_value = transformer.Transform(checkpoint_force_opt.GetResult()); - checkpoint_force = checkpoint_force_value; - } - optional catalog_name {}; - auto &catalog_name_opt = list_pr.GetChild(2).Cast(); - if (catalog_name_opt.HasResult()) { - auto catalog_name_value = catalog_name_opt.GetResult().Cast().identifier; - catalog_name = catalog_name_value; - } - auto result = TransformCheckpointStatement(transformer, checkpoint_force, catalog_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCheckpointForceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCheckpointForce(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto comment_on_type = transformer.Transform(list_pr.GetChild(2)); - auto dotted_identifier = transformer.Transform>(list_pr.GetChild(3)); - auto comment_value = transformer.Transform(list_pr.GetChild(5)); - auto result = TransformCommentStatement(transformer, comment_on_type, dotted_identifier, comment_value); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCommentOnTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentTableInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentTable(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentSequenceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentSequence(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentFunction(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentMacroTableInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentMacroTable(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentMacroInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentMacro(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentViewInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentView(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentDatabaseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentDatabase(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentIndex(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentSchema(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCommentColumn(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommentValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformStringLiteralValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformStringLiteralValue(transformer, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAnalyzeKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAnalyzeKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformExpressionStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression_alias; - auto expression_alias_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &expression_alias_item : expression_alias_items) { - auto expression_alias_value = transformer.Transform>(expression_alias_item.get()); - expression_alias.push_back(std::move(expression_alias_value)); - } - auto result = TransformExpressionStatement(transformer, std::move(expression_alias)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExpressionAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformConstraintNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformConstraintName(transformer, col_id_or_string); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCollationNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformCollationName(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type_variations = transformer.Transform>(list_pr.GetChild(0)); - optional> array_bounds {}; - auto &array_bounds_opt = list_pr.GetChild(1).Cast(); - if (array_bounds_opt.HasResult()) { - vector array_bounds_value; - auto &array_bounds_value_repeat_1 = array_bounds_opt.GetResult().Cast(); - for (auto &array_bounds_value_item_1 : array_bounds_value_repeat_1.GetChildren()) { - auto array_bounds_value_value_1 = transformer.Transform(array_bounds_value_item_1.get()); - array_bounds_value.push_back(array_bounds_value_value_1); - } - array_bounds = array_bounds_value; - } - auto result = TransformType(transformer, std::move(type_variations), array_bounds); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTypeVariationsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSimpleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCharacterSimpleTypeInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> type_modifiers {}; - auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); - if (type_modifiers_opt.HasResult()) { - auto type_modifiers_value = - transformer.Transform>>(type_modifiers_opt.GetResult()); - type_modifiers = std::move(type_modifiers_value); - } - auto result = TransformCharacterSimpleType(transformer, std::move(type_modifiers)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformQualifiedSimpleTypeInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto qualified_type_name = transformer.Transform(list_pr.GetChild(0)); - optional>> type_modifiers {}; - auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); - if (type_modifiers_opt.HasResult()) { - auto type_modifiers_value = - transformer.Transform>>(type_modifiers_opt.GetResult()); - type_modifiers = std::move(type_modifiers_value); - } - auto result = TransformQualifiedSimpleType(transformer, qualified_type_name, std::move(type_modifiers)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntervalTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntervalIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIntervalWithSpecifierInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIntervalWithRangeSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto interval_to_interval_as_type = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformIntervalWithRangeSpecifier(transformer, interval_to_interval_as_type); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIntervalWithSimpleSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto interval = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformIntervalWithSimpleSpecifier(transformer, interval); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIntervalWithoutSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIntervalWithoutSpecifier(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformYearKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformYearKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMonthKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMonthKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDayKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDayKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformHourKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformHourKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMinuteKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMinuteKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSecondKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSecondKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMillisecondKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMillisecondKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMicrosecondKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMicrosecondKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWeekKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWeekKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformQuarterKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformQuarterKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDecadeKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDecadeKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCenturyKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCenturyKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMillenniumKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMillenniumKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIntervalToIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformYearToMonthInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto year_keyword = transformer.Transform(list_pr.GetChild(0)); - auto month_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformYearToMonth(transformer, year_keyword, month_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDayToHourInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto day_keyword = transformer.Transform(list_pr.GetChild(0)); - auto hour_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformDayToHour(transformer, day_keyword, hour_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDayToMinuteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto day_keyword = transformer.Transform(list_pr.GetChild(0)); - auto minute_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformDayToMinute(transformer, day_keyword, minute_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDayToSecondInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto day_keyword = transformer.Transform(list_pr.GetChild(0)); - auto second_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformDayToSecond(transformer, day_keyword, second_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformHourToMinuteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto hour_keyword = transformer.Transform(list_pr.GetChild(0)); - auto minute_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformHourToMinute(transformer, hour_keyword, minute_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformHourToSecondInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto hour_keyword = transformer.Transform(list_pr.GetChild(0)); - auto second_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformHourToSecond(transformer, hour_keyword, second_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMinuteToSecondInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto minute_keyword = transformer.Transform(list_pr.GetChild(0)); - auto second_keyword = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformMinuteToSecond(transformer, minute_keyword, second_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBitTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - optional>> expression {}; - auto &expression_opt = list_pr.GetChild(2).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = - ExtractParseResultsFromList(ExtractResultFromParens(expression_opt.GetResult())); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformBitType(transformer, has_result, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformGeometryTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = - transformer.Transform>(ExtractResultFromParens(expression_opt.GetResult())); - expression = std::move(expression_value); - } - auto result = TransformGeometryType(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformVariantTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformVariantType(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNumericTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSimpleNumericTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - string child; - if (choice_result.type == ParseResultType::IDENTIFIER) { - child = choice_result.Cast().identifier.GetIdentifierName(); - } else if (choice_result.type == ParseResultType::KEYWORD) { - child = choice_result.Cast().keyword; - } else if (choice_result.type == ParseResultType::STRING) { - child = choice_result.Cast().result; - } else if (choice_result.type == ParseResultType::OPERATOR) { - child = choice_result.Cast().operator_token; - } else { - child = transformer.Transform(choice_result); - } - auto result = TransformSimpleNumericType(transformer, child); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDecimalNumericTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIntType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIntegerTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIntegerType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSmallintTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSmallintType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBigintTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformBigintType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRealTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRealType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBooleanTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformBooleanType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDoubleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDoubleType(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFloatTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> number_literal {}; - auto &number_literal_opt = list_pr.GetChild(1).Cast(); - if (number_literal_opt.HasResult()) { - auto number_literal_value = transformer.Transform>( - ExtractResultFromParens(number_literal_opt.GetResult())); - number_literal = std::move(number_literal_value); - } - auto result = TransformFloatType(transformer, std::move(number_literal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDecimalTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> type_modifiers {}; - auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); - if (type_modifiers_opt.HasResult()) { - auto type_modifiers_value = - transformer.Transform>>(type_modifiers_opt.GetResult()); - type_modifiers = std::move(type_modifiers_value); - } - auto result = TransformDecimalType(transformer, std::move(type_modifiers)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDecTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> type_modifiers {}; - auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); - if (type_modifiers_opt.HasResult()) { - auto type_modifiers_value = - transformer.Transform>>(type_modifiers_opt.GetResult()); - type_modifiers = std::move(type_modifiers_value); - } - auto result = TransformDecType(transformer, std::move(type_modifiers)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNumericModTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> type_modifiers {}; - auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); - if (type_modifiers_opt.HasResult()) { - auto type_modifiers_value = - transformer.Transform>>(type_modifiers_opt.GetResult()); - type_modifiers = std::move(type_modifiers_value); - } - auto result = TransformNumericModType(transformer, std::move(type_modifiers)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformQualifiedTypeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformTypeNameAsQualifiedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformTypeNameAsQualifiedName(transformer, type_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogReservedSchemaTypeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - vector reserved_schema_qualification; - auto &reserved_schema_qualification_repeat = list_pr.GetChild(1).Cast(); - for (auto &reserved_schema_qualification_item : reserved_schema_qualification_repeat.GetChildren()) { - auto reserved_schema_qualification_value = - transformer.Transform(reserved_schema_qualification_item.get()); - reserved_schema_qualification.push_back(reserved_schema_qualification_value); - } - auto reserved_type_name = list_pr.GetChild(2).Cast().identifier; - auto result = TransformCatalogReservedSchemaTypeName(transformer, catalog_qualification, - reserved_schema_qualification, reserved_type_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaReservedTypeNameInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_type_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSchemaReservedTypeName(transformer, schema_qualification, reserved_type_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTypeModifiersInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> expression {}; - auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformTypeModifiers(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRowTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> col_id_type_list {}; - auto &col_id_type_list_opt = list_pr.GetChild(1).Cast(); - if (col_id_type_list_opt.HasResult()) { - auto col_id_type_list_value = - transformer.Transform>(col_id_type_list_opt.GetResult()); - col_id_type_list = col_id_type_list_value; - } - auto result = TransformRowType(transformer, col_id_type_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetofTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformSetofType(transformer, type); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUnionTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_type_list = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformUnionType(transformer, col_id_type_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColIdTypeListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> col_id_type; - auto col_id_type_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &col_id_type_item : col_id_type_items) { - auto col_id_type_value = transformer.Transform>(col_id_type_item.get()); - col_id_type.push_back(col_id_type_value); - } - auto result = TransformColIdTypeList(transformer, col_id_type); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformMapTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> type {}; - auto &type_opt = list_pr.GetChild(1).Cast(); - if (type_opt.HasResult()) { - vector type_value; - auto type_value_items_1 = ExtractParseResultsFromList(ExtractResultFromParens(type_opt.GetResult())); - for (auto &type_value_item_1 : type_value_items_1) { - auto type_value_value_1 = transformer.Transform(type_value_item_1.get()); - type_value.push_back(type_value_value_1); - } - type = type_value; - } - auto result = TransformMapType(transformer, type); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTupleTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector type; - auto type_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); - for (auto &type_item : type_items) { - auto type_value = transformer.Transform(type_item.get()); - type.push_back(type_value); - } - auto result = TransformTupleType(transformer, type); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColIdTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - auto type = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformColIdType(transformer, col_id, type); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformArrayBoundsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformArrayKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformArrayKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformArrayKeywordWithBoundsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto square_brackets_array = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformArrayKeywordWithBounds(transformer, square_brackets_array); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSquareBracketsArrayInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - auto result = TransformSquareBracketsArray(transformer, std::move(expression)); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTimeTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto time_or_timestamp = transformer.Transform(list_pr.GetChild(0)); - optional>> type_modifiers {}; - auto &type_modifiers_opt = list_pr.GetChild(1).Cast(); - if (type_modifiers_opt.HasResult()) { - auto type_modifiers_value = - transformer.Transform>>(type_modifiers_opt.GetResult()); - type_modifiers = std::move(type_modifiers_value); - } - optional time_zone {}; - auto &time_zone_opt = list_pr.GetChild(2).Cast(); - if (time_zone_opt.HasResult()) { - auto time_zone_value = transformer.Transform(time_zone_opt.GetResult()); - time_zone = time_zone_value; - } - auto result = TransformTimeType(transformer, time_or_timestamp, std::move(type_modifiers), time_zone); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTimeOrTimestampInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTimeTypeIdInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTimeTypeId(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTimestampTypeIdInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTimestampTypeId(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTimeZoneInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto with_or_without = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformTimeZone(transformer, with_or_without); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithOrWithoutInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithRule(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithoutRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithoutRule(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformConnectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> session_target {}; - auto &session_target_opt = list_pr.GetChild(1).Cast(); - if (session_target_opt.HasResult()) { - auto session_target_value = transformer.Transform>(session_target_opt.GetResult()); - session_target = std::move(session_target_value); - } - auto result = TransformConnectStatement(transformer, std::move(session_target)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDisconnectStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformDisconnectStatement(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSessionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLocalSessionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformLocalSessionTarget(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformStringSessionTargetInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - optional> generic_copy_option_list {}; - auto &generic_copy_option_list_opt = list_pr.GetChild(1).Cast(); - if (generic_copy_option_list_opt.HasResult()) { - auto generic_copy_option_list_value = - transformer.Transform>(generic_copy_option_list_opt.GetResult()); - generic_copy_option_list = generic_copy_option_list_value; - } - auto result = TransformStringSessionTarget(transformer, string_literal, generic_copy_option_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogSessionTargetInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformCatalogSessionTarget(transformer, catalog_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCopyStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto copy_variations = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformCopyStatement(transformer, std::move(copy_variations)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCopyVariationsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCopyTableInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - optional> insert_column_list {}; - auto &insert_column_list_opt = list_pr.GetChild(1).Cast(); - if (insert_column_list_opt.HasResult()) { - auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); - insert_column_list = insert_column_list_value; - } - auto from_or_to = transformer.Transform(list_pr.GetChild(2)); - auto copy_file_name = transformer.Transform>(list_pr.GetChild(3)); - optional> copy_options {}; - auto ©_options_opt = list_pr.GetChild(4).Cast(); - if (copy_options_opt.HasResult()) { - auto copy_options_value = transformer.Transform>(copy_options_opt.GetResult()); - copy_options = copy_options_value; - } - auto result = TransformCopyTable(transformer, std::move(base_table_name), insert_column_list, from_or_to, - std::move(copy_file_name), copy_options); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFromOrToInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopyFromInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCopyFrom(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopyToInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCopyTo(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopySelectInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto copy_file_name = transformer.Transform>(list_pr.GetChild(2)); - optional> copy_options {}; - auto ©_options_opt = list_pr.GetChild(3).Cast(); - if (copy_options_opt.HasResult()) { - auto copy_options_value = transformer.Transform>(copy_options_opt.GetResult()); - copy_options = copy_options_value; - } - auto result = - TransformCopySelect(transformer, std::move(select_statement_internal), std::move(copy_file_name), copy_options); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCopyFileNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCopyFileNameExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCopyFileNameStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformCopyFileNameStringLiteral(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCopyFileNameIdentifierInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformCopyFileNameIdentifier(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCopyFileNameIdentifierColIdInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier_col_id = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformCopyFileNameIdentifierColId(transformer, identifier_col_id); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIdentifierColIdInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto col_id = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformIdentifierColId(transformer, identifier, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopyOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto copy_option_list = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformCopyOptions(transformer, has_result, copy_option_list); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopyOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSpecializedOptionListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto specialized_option = transformer.Transform(list_pr.GetChild(0)); - optional> specialized_option_tail {}; - auto &specialized_option_tail_opt = list_pr.GetChild(1).Cast(); - if (specialized_option_tail_opt.HasResult()) { - vector specialized_option_tail_value; - auto &specialized_option_tail_value_repeat_1 = - specialized_option_tail_opt.GetResult().Cast(); - for (auto &specialized_option_tail_value_item_1 : specialized_option_tail_value_repeat_1.GetChildren()) { - auto specialized_option_tail_value_value_1 = - transformer.Transform(specialized_option_tail_value_item_1.get()); - specialized_option_tail_value.push_back(specialized_option_tail_value_value_1); - } - specialized_option_tail = specialized_option_tail_value; - } - auto result = TransformSpecializedOptionList(transformer, specialized_option, specialized_option_tail); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSpecializedOptionTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto specialized_option = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformSpecializedOptionTail(transformer, has_result, specialized_option); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSpecializedOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSingleOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBinaryOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformBinaryOption(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFreezeOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformFreezeOption(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOidsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOidsOption(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCsvOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCsvOption(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformHeaderOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformHeaderOption(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNullAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformNullAsOption(transformer, has_result, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDelimiterAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformDelimiterAsOption(transformer, has_result, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformQuoteAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformQuoteAsOption(transformer, has_result, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformEscapeAsOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformEscapeAsOption(transformer, has_result, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformEncodingOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformEncodingOption(transformer, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformForceQuoteOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional force_quote {}; - auto &force_quote_opt = list_pr.GetChild(0).Cast(); - if (force_quote_opt.HasResult()) { - auto force_quote_value = transformer.Transform(force_quote_opt.GetResult()); - force_quote = force_quote_value; - } - auto star_symbol_column_list = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformForceQuoteOption(transformer, force_quote, star_symbol_column_list); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformStarSymbolColumnListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - vector result {}; - if (!(choice_result.name == "StarSymbol")) { - result = transformer.Transform>(choice_result); - } - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformForceQuoteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformForceQuote(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPartitionByOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto partition_by_column_list = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformPartitionByOption(transformer, partition_by_column_list); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformPartitionByColumnListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformStarPartitionByColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformStarPartitionByColumnList(transformer); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformParenthesizedPartitionByColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_list = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformParenthesizedPartitionByColumnList(transformer, column_list); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSinglePartitionByColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformSinglePartitionByColumnList(transformer, col_id); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformForceNullOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional force_not_null {}; - auto &force_not_null_opt = list_pr.GetChild(1).Cast(); - if (force_not_null_opt.HasResult()) { - auto force_not_null_value = transformer.Transform(force_not_null_opt.GetResult()); - force_not_null = force_not_null_value; - } - auto column_list = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformForceNullOption(transformer, force_not_null, column_list); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformForceNotNullInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformForceNotNull(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCopyGenericOptionListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector copy_generic_option; - auto copy_generic_option_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto ©_generic_option_item : copy_generic_option_items) { - auto copy_generic_option_value = transformer.Transform(copy_generic_option_item.get()); - copy_generic_option.push_back(copy_generic_option_value); - } - auto result = TransformCopyGenericOptionList(transformer, copy_generic_option); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopyGenericOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOrderByCopyOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional generic_copy_option_value {}; - auto &generic_copy_option_value_opt = list_pr.GetChild(2).Cast(); - if (generic_copy_option_value_opt.HasResult()) { - auto generic_copy_option_value_value = - transformer.Transform(generic_copy_option_value_opt.GetResult()); - generic_copy_option_value = std::move(generic_copy_option_value_value); - } - auto result = TransformOrderByCopyOption(transformer, std::move(generic_copy_option_value)); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformPartitionedByCopyOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional generic_copy_option_value {}; - auto &generic_copy_option_value_opt = list_pr.GetChild(2).Cast(); - if (generic_copy_option_value_opt.HasResult()) { - auto generic_copy_option_value_value = - transformer.Transform(generic_copy_option_value_opt.GetResult()); - generic_copy_option_value = std::move(generic_copy_option_value_value); - } - auto result = TransformPartitionedByCopyOption(transformer, std::move(generic_copy_option_value)); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformGenericCopyOptionListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector generic_copy_option; - auto generic_copy_option_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &generic_copy_option_item : generic_copy_option_items) { - auto generic_copy_option_value = transformer.Transform(generic_copy_option_item.get()); - generic_copy_option.push_back(generic_copy_option_value); - } - auto result = TransformGenericCopyOptionList(transformer, generic_copy_option); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformGenericCopyOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto copy_option_name = list_pr.GetChild(0).Cast().identifier; - optional generic_copy_option_value {}; - auto &generic_copy_option_value_opt = list_pr.GetChild(1).Cast(); - if (generic_copy_option_value_opt.HasResult()) { - auto generic_copy_option_value_value = - transformer.Transform(generic_copy_option_value_opt.GetResult()); - generic_copy_option_value = std::move(generic_copy_option_value_value); - } - auto result = TransformGenericCopyOption(transformer, copy_option_name, std::move(generic_copy_option_value)); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformGenericCopyOptionValueInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformGenericCopyOptionOrderListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto generic_copy_option_parenthesized_expression_list = - transformer.Transform>(list_pr.GetChild(0)); - auto result = - TransformGenericCopyOptionOrderList(transformer, std::move(generic_copy_option_parenthesized_expression_list)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformGenericCopyOptionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformGenericCopyOptionExpression(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformGenericCopyOptionParenthesizedExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto order_by_expression_list = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = - TransformGenericCopyOptionParenthesizedExpressionList(transformer, std::move(order_by_expression_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCopyFromDatabaseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCopyFromDatabaseWithFlagInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(2)); - auto col_id_1 = transformer.Transform(list_pr.GetChild(4)); - auto copy_database_flag = transformer.Transform(list_pr.GetChild(5)); - auto result = TransformCopyFromDatabaseWithFlag(transformer, col_id, col_id_1, copy_database_flag); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCopyFromDatabaseWithoutFlagInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(2)); - auto col_id_1 = transformer.Transform(list_pr.GetChild(4)); - auto result = TransformCopyFromDatabaseWithoutFlag(transformer, col_id, col_id_1); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCopyDatabaseFlagInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_or_data = transformer.Transform(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformCopyDatabaseFlag(transformer, schema_or_data); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSchemaOrDataInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopySchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCopySchema(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCopyDataInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCopyData(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateIndexStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional unique_index {}; - auto &unique_index_opt = list_pr.GetChild(0).Cast(); - if (unique_index_opt.HasResult()) { - auto unique_index_value = transformer.Transform(unique_index_opt.GetResult()); - unique_index = unique_index_value; - } - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(2).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - optional index_name {}; - auto &index_name_opt = list_pr.GetChild(3).Cast(); - if (index_name_opt.HasResult()) { - auto index_name_value = index_name_opt.GetResult().Cast().identifier; - index_name = index_name_value; - } - auto base_table_name = transformer.Transform>(list_pr.GetChild(5)); - optional> insert_column_list {}; - auto &insert_column_list_opt = list_pr.GetChild(6).Cast(); - if (insert_column_list_opt.HasResult()) { - auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); - insert_column_list = insert_column_list_value; - } - optional index_type {}; - auto &index_type_opt = list_pr.GetChild(7).Cast(); - if (index_type_opt.HasResult()) { - auto index_type_value = transformer.Transform(index_type_opt.GetResult()); - index_type = index_type_value; - } - optional>> index_element {}; - auto &index_element_opt = list_pr.GetChild(8).Cast(); - if (index_element_opt.HasResult()) { - vector> index_element_value; - auto index_element_value_items_1 = - ExtractParseResultsFromList(ExtractResultFromParens(index_element_opt.GetResult())); - for (auto &index_element_value_item_1 : index_element_value_items_1) { - auto index_element_value_value_1 = - transformer.Transform>(index_element_value_item_1.get()); - index_element_value.push_back(std::move(index_element_value_value_1)); - } - index_element = std::move(index_element_value); - } - optional>> with_list {}; - auto &with_list_opt = list_pr.GetChild(9).Cast(); - if (with_list_opt.HasResult()) { - auto with_list_value = - transformer.Transform>>(with_list_opt.GetResult()); - with_list = std::move(with_list_value); - } - optional> where_clause {}; - auto &where_clause_opt = list_pr.GetChild(10).Cast(); - if (where_clause_opt.HasResult()) { - auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); - where_clause = std::move(where_clause_value); - } - auto result = TransformCreateIndexStmt(transformer, unique_index, if_not_exists, index_name, - std::move(base_table_name), insert_column_list, index_type, - std::move(index_element), std::move(with_list), std::move(where_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWithListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rel_option_or_oids = - transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformWithList(transformer, std::move(rel_option_or_oids)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRelOptionOrOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRelOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector>> rel_option; - auto rel_option_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &rel_option_item : rel_option_items) { - auto rel_option_value = - transformer.Transform>>(rel_option_item.get()); - rel_option.push_back(std::move(rel_option_value)); - } - auto result = TransformRelOptionList(transformer, std::move(rel_option)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto with_or_without_oids = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformOids(transformer, with_or_without_oids); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWithOrWithoutOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithOids(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithoutOidsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithoutOids(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIndexElementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - optional desc_or_asc {}; - auto &desc_or_asc_opt = list_pr.GetChild(1).Cast(); - if (desc_or_asc_opt.HasResult()) { - auto desc_or_asc_value = transformer.Transform(desc_or_asc_opt.GetResult()); - desc_or_asc = desc_or_asc_value; - } - optional nulls_first_or_last {}; - auto &nulls_first_or_last_opt = list_pr.GetChild(2).Cast(); - if (nulls_first_or_last_opt.HasResult()) { - auto nulls_first_or_last_value = transformer.Transform(nulls_first_or_last_opt.GetResult()); - nulls_first_or_last = nulls_first_or_last_value; - } - auto result = TransformIndexElement(transformer, std::move(expression), desc_or_asc, nulls_first_or_last); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUniqueIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformUniqueIndex(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIndexTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformIndexType(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRelOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rel_option_name = transformer.Transform(list_pr.GetChild(0)); - optional> rel_option_argument_opt {}; - auto &rel_option_argument_opt_opt = list_pr.GetChild(1).Cast(); - if (rel_option_argument_opt_opt.HasResult()) { - auto rel_option_argument_opt_value = - transformer.Transform>(rel_option_argument_opt_opt.GetResult()); - rel_option_argument_opt = std::move(rel_option_argument_opt_value); - } - auto result = TransformRelOption(transformer, rel_option_name, std::move(rel_option_argument_opt)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRelOptionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - string child; - if (choice_result.type == ParseResultType::IDENTIFIER) { - child = choice_result.Cast().identifier.GetIdentifierName(); - } else if (choice_result.type == ParseResultType::KEYWORD) { - child = choice_result.Cast().keyword; - } else if (choice_result.type == ParseResultType::STRING) { - child = choice_result.Cast().result; - } else if (choice_result.type == ParseResultType::OPERATOR) { - child = choice_result.Cast().operator_token; - } else { - child = transformer.Transform(choice_result); - } - auto result = TransformRelOptionName(transformer, child); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformDottedIdentifierStringInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto dotted_identifier = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformDottedIdentifierString(transformer, dotted_identifier); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformRelOptionArgumentOptInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto def_arg = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformRelOptionArgumentOpt(transformer, std::move(def_arg)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDefArgInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDefArgNullInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto null_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformDefArgNull(transformer, null_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDefArgKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto reserved_keyword = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformDefArgKeyword(transformer, reserved_keyword); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDefArgStringLiteralInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformDefArgStringLiteral(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNoneLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNoneLiteral(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateMacroStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto macro_or_function = transformer.Transform(list_pr.GetChild(0)); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - vector> macro_definition; - auto macro_definition_items = ExtractParseResultsFromList(list_pr.GetChild(3)); - for (auto ¯o_definition_item : macro_definition_items) { - auto macro_definition_value = transformer.Transform>(macro_definition_item.get()); - macro_definition.push_back(std::move(macro_definition_value)); - } - auto result = TransformCreateMacroStmt(transformer, macro_or_function, if_not_exists, qualified_name, - std::move(macro_definition)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMacroOrFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMacroKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMacroKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFunctionKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformFunctionKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMacroDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> macro_parameters {}; - auto ¯o_parameters_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); - if (macro_parameters_opt.HasResult()) { - auto macro_parameters_value = transformer.Transform>(macro_parameters_opt.GetResult()); - macro_parameters = std::move(macro_parameters_value); - } - auto macro_definition_body = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformMacroDefinition(transformer, std::move(macro_parameters), std::move(macro_definition_body)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMacroDefinitionBodyInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMacroParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector macro_parameter; - auto macro_parameter_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto ¯o_parameter_item : macro_parameter_items) { - auto macro_parameter_value = transformer.Transform(macro_parameter_item.get()); - macro_parameter.push_back(std::move(macro_parameter_value)); - } - auto result = TransformMacroParameters(transformer, std::move(macro_parameter)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMacroParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSimpleParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type_func_name = transformer.Transform(list_pr.GetChild(0)); - optional type {}; - auto &type_opt = list_pr.GetChild(1).Cast(); - if (type_opt.HasResult()) { - auto type_value = transformer.Transform(type_opt.GetResult()); - type = type_value; - } - auto result = TransformSimpleParameter(transformer, type_func_name, type); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformScalarMacroDefinitionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformScalarMacroDefinition(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTableMacroDefinitionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformTableMacroDefinition(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateSchemaStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformCreateSchemaStmt(transformer, if_not_exists, qualified_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateSecretStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - optional secret_name {}; - auto &secret_name_opt = list_pr.GetChild(2).Cast(); - if (secret_name_opt.HasResult()) { - auto secret_name_value = transformer.Transform(secret_name_opt.GetResult()); - secret_name = secret_name_value; - } - optional secret_storage_specifier {}; - auto &secret_storage_specifier_opt = list_pr.GetChild(3).Cast(); - if (secret_storage_specifier_opt.HasResult()) { - auto secret_storage_specifier_value = - transformer.Transform(secret_storage_specifier_opt.GetResult()); - secret_storage_specifier = secret_storage_specifier_value; - } - auto generic_copy_option_list = transformer.Transform>(list_pr.GetChild(4)); - auto result = TransformCreateSecretStmt(transformer, if_not_exists, secret_name, secret_storage_specifier, - generic_copy_option_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSecretStorageSpecifierInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSecretStorageSpecifier(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSecretNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformSecretName(transformer, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateSequenceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - optional>>> sequence_option {}; - auto &sequence_option_opt = list_pr.GetChild(3).Cast(); - if (sequence_option_opt.HasResult()) { - vector>> sequence_option_value; - auto &sequence_option_value_repeat_1 = sequence_option_opt.GetResult().Cast(); - for (auto &sequence_option_value_item_1 : sequence_option_value_repeat_1.GetChildren()) { - auto sequence_option_value_value_1 = - transformer.Transform>>(sequence_option_value_item_1.get()); - sequence_option_value.push_back(std::move(sequence_option_value_value_1)); - } - sequence_option = std::move(sequence_option_value); - } - auto result = TransformCreateSequenceStmt(transformer, if_not_exists, qualified_name, std::move(sequence_option)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSequenceOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqSetCycleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqCycleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSeqCycle(transformer); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqNoCycleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSeqNoCycle(transformer); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqSetIncrementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformSeqSetIncrement(transformer, has_result, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqSetMinMaxInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto seq_min_or_max = transformer.Transform(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformSeqSetMinMax(transformer, seq_min_or_max, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqNoMinMaxInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto seq_min_or_max = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformSeqNoMinMax(transformer, seq_min_or_max); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqStartWithInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformSeqStartWith(transformer, has_result, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqOwnedByInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformSeqOwnedBy(transformer, qualified_name); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSeqMinOrMaxInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMinValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMinValue(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformMaxValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformMaxValue(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional or_replace {}; - auto &or_replace_opt = list_pr.GetChild(1).Cast(); - if (or_replace_opt.HasResult()) { - auto or_replace_value = transformer.Transform(or_replace_opt.GetResult()); - or_replace = or_replace_value; - } - optional temporary {}; - auto &temporary_opt = list_pr.GetChild(2).Cast(); - if (temporary_opt.HasResult()) { - auto temporary_value = transformer.Transform(temporary_opt.GetResult()); - temporary = temporary_value; - } - auto create_statement_variation = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformCreateStatement(transformer, or_replace, temporary, std::move(create_statement_variation)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateStatementVariationInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOrReplaceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOrReplace(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTemporaryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPersistentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformPersistent(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTempPersistentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTempPersistent(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformTemporaryPersistentInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformTemporaryPersistent(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateTableStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - auto create_table_definition = transformer.Transform(list_pr.GetChild(3)); - optional commit_action {}; - auto &commit_action_opt = list_pr.GetChild(4).Cast(); - if (commit_action_opt.HasResult()) { - auto commit_action_value = transformer.Transform(commit_action_opt.GetResult()); - commit_action = commit_action_value; - } - auto result = TransformCreateTableStmt(transformer, if_not_exists, qualified_name, - std::move(create_table_definition), commit_action); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateTableDefinitionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateTableAsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional identifier_list {}; - auto &identifier_list_opt = list_pr.GetChild(0).Cast(); - if (identifier_list_opt.HasResult()) { - auto identifier_list_value = transformer.Transform(identifier_list_opt.GetResult()); - identifier_list = std::move(identifier_list_value); - } - optional partition_sorted_options {}; - auto &partition_sorted_options_opt = list_pr.GetChild(1).Cast(); - if (partition_sorted_options_opt.HasResult()) { - auto partition_sorted_options_value = - transformer.Transform(partition_sorted_options_opt.GetResult()); - partition_sorted_options = std::move(partition_sorted_options_value); - } - optional>> with_list {}; - auto &with_list_opt = list_pr.GetChild(2).Cast(); - if (with_list_opt.HasResult()) { - auto with_list_value = - transformer.Transform>>(with_list_opt.GetResult()); - with_list = std::move(with_list_value); - } - auto statement = transformer.Transform>(list_pr.GetChild(4)); - optional with_data {}; - auto &with_data_opt = list_pr.GetChild(5).Cast(); - if (with_data_opt.HasResult()) { - auto with_data_value = transformer.Transform(with_data_opt.GetResult()); - with_data = with_data_value; - } - auto result = TransformCreateTableAs(transformer, std::move(identifier_list), std::move(partition_sorted_options), - std::move(with_list), std::move(statement), with_data); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPartitionSortedOptionsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPartitionOptSortedOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto partition_options = transformer.Transform>>(list_pr.GetChild(0)); - optional>> sorted_options {}; - auto &sorted_options_opt = list_pr.GetChild(1).Cast(); - if (sorted_options_opt.HasResult()) { - auto sorted_options_value = - transformer.Transform>>(sorted_options_opt.GetResult()); - sorted_options = std::move(sorted_options_value); - } - auto result = - TransformPartitionOptSortedOptions(transformer, std::move(partition_options), std::move(sorted_options)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSortedOptPartitionOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sorted_options = transformer.Transform>>(list_pr.GetChild(0)); - optional>> partition_options {}; - auto &partition_options_opt = list_pr.GetChild(1).Cast(); - if (partition_options_opt.HasResult()) { - auto partition_options_value = - transformer.Transform>>(partition_options_opt.GetResult()); - partition_options = std::move(partition_options_value); - } - auto result = - TransformSortedOptPartitionOptions(transformer, std::move(sorted_options), std::move(partition_options)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPartitionOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(2))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformPartitionOptions(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSortedOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(2))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformSortedOptions(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWithDataInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithDataOnlyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithDataOnly(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithNoDataInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithNoData(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIdentifierListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector identifier; - auto identifier_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &identifier_item : identifier_items) { - auto identifier_value = identifier_item.get().Cast().identifier; - identifier.push_back(identifier_value); - } - auto result = TransformIdentifierList(transformer, identifier); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional create_table_column_list {}; - auto &create_table_column_list_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); - if (create_table_column_list_opt.HasResult()) { - auto create_table_column_list_value = - transformer.Transform(create_table_column_list_opt.GetResult()); - create_table_column_list = std::move(create_table_column_list_value); - } - optional partition_sorted_options {}; - auto &partition_sorted_options_opt = list_pr.GetChild(1).Cast(); - if (partition_sorted_options_opt.HasResult()) { - auto partition_sorted_options_value = - transformer.Transform(partition_sorted_options_opt.GetResult()); - partition_sorted_options = std::move(partition_sorted_options_value); - } - optional>> with_list {}; - auto &with_list_opt = list_pr.GetChild(2).Cast(); - if (with_list_opt.HasResult()) { - auto with_list_value = - transformer.Transform>>(with_list_opt.GetResult()); - with_list = std::move(with_list_value); - } - auto result = TransformCreateColumnList(transformer, std::move(create_table_column_list), - std::move(partition_sorted_options), std::move(with_list)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIfNotExistsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIfNotExists(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformQualifiedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaReservedIdentifierOrStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_identifier_or_string_literal = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformSchemaReservedIdentifierOrStringLiteral(transformer, schema_qualification, - reserved_identifier_or_string_literal); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogReservedSchemaIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - vector reserved_schema_qualification; - auto &reserved_schema_qualification_repeat = list_pr.GetChild(1).Cast(); - for (auto &reserved_schema_qualification_item : reserved_schema_qualification_repeat.GetChildren()) { - auto reserved_schema_qualification_value = - transformer.Transform(reserved_schema_qualification_item.get()); - reserved_schema_qualification.push_back(reserved_schema_qualification_value); - } - auto reserved_identifier_or_string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformCatalogReservedSchemaIdentifier( - transformer, catalog_qualification, reserved_schema_qualification, reserved_identifier_or_string_literal); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformIdentifierOrStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - string child; - if (choice_result.type == ParseResultType::IDENTIFIER) { - child = choice_result.Cast().identifier.GetIdentifierName(); - } else if (choice_result.type == ParseResultType::KEYWORD) { - child = choice_result.Cast().keyword; - } else if (choice_result.type == ParseResultType::STRING) { - child = choice_result.Cast().result; - } else if (choice_result.type == ParseResultType::OPERATOR) { - child = choice_result.Cast().operator_token; - } else { - child = transformer.Transform(choice_result); - } - auto result = TransformIdentifierOrStringLiteral(transformer, child); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformReservedIdentifierOrStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - Identifier result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier; - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = Identifier(choice_pr.GetResult().Cast().keyword); - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = Identifier(choice_pr.GetResult().Cast().result); - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogQualificationInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformCatalogQualification(transformer, catalog_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaQualificationInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformSchemaQualification(transformer, schema_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformReservedSchemaQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto reserved_schema_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformReservedSchemaQualification(transformer, reserved_schema_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTableQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformTableQualification(transformer, table_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformReservedTableQualificationInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto reserved_table_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformReservedTableQualification(transformer, reserved_table_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCreateTableColumnListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector create_table_column_element; - auto create_table_column_element_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &create_table_column_element_item : create_table_column_element_items) { - auto create_table_column_element_value = - transformer.Transform(create_table_column_element_item.get()); - create_table_column_element.push_back(std::move(create_table_column_element_value)); - } - auto result = TransformCreateTableColumnList(transformer, std::move(create_table_column_element)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateTableColumnElementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateTableColumnDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_definition = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformCreateTableColumnDefinition(transformer, std::move(column_definition)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateTableConstraintInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto top_level_constraint = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformCreateTableConstraint(transformer, std::move(top_level_constraint)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnDefinitionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto dotted_identifier = transformer.Transform>(list_pr.GetChild(0)); - optional type {}; - auto &type_opt = list_pr.GetChild(1).Cast(); - if (type_opt.HasResult()) { - auto type_value = transformer.Transform(type_opt.GetResult()); - type = type_value; - } - optional generated_column {}; - auto &generated_column_opt = list_pr.GetChild(2).Cast(); - if (generated_column_opt.HasResult()) { - auto generated_column_value = - transformer.Transform(generated_column_opt.GetResult()); - generated_column = std::move(generated_column_value); - } - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(3).Cast(); - has_result = has_result_opt.HasResult(); - optional> column_constraint {}; - auto &column_constraint_opt = list_pr.GetChild(4).Cast(); - if (column_constraint_opt.HasResult()) { - vector column_constraint_value; - auto &column_constraint_value_repeat_1 = column_constraint_opt.GetResult().Cast(); - for (auto &column_constraint_value_item_1 : column_constraint_value_repeat_1.GetChildren()) { - auto column_constraint_value_value_1 = - transformer.Transform(column_constraint_value_item_1.get()); - column_constraint_value.push_back(std::move(column_constraint_value_value_1)); - } - column_constraint = std::move(column_constraint_value); - } - auto result = TransformColumnDefinition(transformer, dotted_identifier, type, std::move(generated_column), - has_result, std::move(column_constraint)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNotNullConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto child = transformer.Transform(choice_pr.GetResult()); - auto result = TransformNotNullConstraint(transformer, child); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNullConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNullConstraint(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformNotNullColumnConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotNullColumnConstraint(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUniqueConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformUniqueConstraint(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPrimaryKeyConstraintInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformPrimaryKeyConstraint(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDefaultValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_default_expr = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformDefaultValue(transformer, std::move(column_default_expr)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCheckConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformCheckConstraint(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformForeignKeyConstraintInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(1)); - optional> column_list {}; - auto &column_list_opt = list_pr.GetChild(2).Cast(); - if (column_list_opt.HasResult()) { - auto column_list_value = - transformer.Transform>(ExtractResultFromParens(column_list_opt.GetResult())); - column_list = column_list_value; - } - auto key_actions = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformForeignKeyConstraint(transformer, std::move(base_table_name), column_list, key_actions); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnCollationInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto dotted_identifier = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformColumnCollation(transformer, dotted_identifier); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnCompressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformColumnCompression(transformer, col_id_or_string); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformKeyActionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional update_action {}; - auto &update_action_opt = list_pr.GetChild(0).Cast(); - if (update_action_opt.HasResult()) { - auto update_action_value = transformer.Transform(update_action_opt.GetResult()); - update_action = update_action_value; - } - optional delete_action {}; - auto &delete_action_opt = list_pr.GetChild(1).Cast(); - if (delete_action_opt.HasResult()) { - auto delete_action_value = transformer.Transform(delete_action_opt.GetResult()); - delete_action = delete_action_value; - } - auto result = TransformKeyActions(transformer, update_action, delete_action); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUpdateActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto key_action = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformUpdateAction(transformer, key_action); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDeleteActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto key_action = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformDeleteAction(transformer, key_action); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNoKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNoKeyAction(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRestrictKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRestrictKeyAction(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCascadeKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCascadeKeyAction(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetNullKeyActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSetNullKeyAction(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSetDefaultKeyActionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformSetDefaultKeyAction(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTopLevelConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto top_level_constraint_list = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformTopLevelConstraint(transformer, has_result, std::move(top_level_constraint_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTopLevelConstraintListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTopCheckConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto check_constraint = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformTopCheckConstraint(transformer, std::move(check_constraint)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTopPrimaryKeyConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_id_list = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformTopPrimaryKeyConstraint(transformer, column_id_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTopUniqueConstraintInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_id_list = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformTopUniqueConstraint(transformer, column_id_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTopForeignKeyConstraintInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_id_list = transformer.Transform>(list_pr.GetChild(2)); - auto foreign_key_constraint = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformTopForeignKeyConstraint(transformer, column_id_list, std::move(foreign_key_constraint)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnIdListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id; - auto col_id_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &col_id_item : col_id_items) { - auto col_id_value = transformer.Transform(col_id_item.get()); - col_id.push_back(col_id_value); - } - auto result = TransformColumnIdList(transformer, col_id); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformDottedIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - optional> dot_col_label {}; - auto &dot_col_label_opt = list_pr.GetChild(1).Cast(); - if (dot_col_label_opt.HasResult()) { - vector dot_col_label_value; - auto &dot_col_label_value_repeat_1 = dot_col_label_opt.GetResult().Cast(); - for (auto &dot_col_label_value_item_1 : dot_col_label_value_repeat_1.GetChildren()) { - auto dot_col_label_value_value_1 = transformer.Transform(dot_col_label_value_item_1.get()); - dot_col_label_value.push_back(dot_col_label_value_value_1); - } - dot_col_label = dot_col_label_value; - } - auto result = TransformDottedIdentifier(transformer, identifier, dot_col_label); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformDotColLabelInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_label = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformDotColLabel(transformer, col_label); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColIdInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - Identifier result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier; - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = Identifier(choice_pr.GetResult().Cast().keyword); - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = Identifier(choice_pr.GetResult().Cast().result); - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColIdOrStringInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTypeFuncNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - Identifier result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier; - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = Identifier(choice_pr.GetResult().Cast().keyword); - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = Identifier(choice_pr.GetResult().Cast().result); - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTypeFuncKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColLabelInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColLabelOrStringInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColLabelIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_label = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformColLabelIdentifier(transformer, col_label); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformStringLiteralIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformStringLiteralIdentifier(transformer, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGeneratedColumnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto expression = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(2))); - optional generated_column_type {}; - auto &generated_column_type_opt = list_pr.GetChild(3).Cast(); - if (generated_column_type_opt.HasResult()) { - auto generated_column_type_value = transformer.Transform(generated_column_type_opt.GetResult()); - generated_column_type = generated_column_type_value; - } - auto result = TransformGeneratedColumn(transformer, has_result, std::move(expression), generated_column_type); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformGeneratedColumnTypeInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCommitActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto preserve_or_delete = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformCommitAction(transformer, preserve_or_delete); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPreserveOrDeleteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPreserveRowsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformPreserveRows(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDeleteRowsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDeleteRows(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformVirtualGeneratedColumnInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformVirtualGeneratedColumn(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformStoredGeneratedColumnInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformStoredGeneratedColumn(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateTriggerStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto trigger_name = transformer.Transform(list_pr.GetChild(2)); - auto trigger_timing = transformer.Transform(list_pr.GetChild(3)); - auto trigger_event = transformer.Transform(list_pr.GetChild(4)); - auto base_table_name = transformer.Transform>(list_pr.GetChild(6)); - optional referencing_clause {}; - auto &referencing_clause_opt = list_pr.GetChild(7).Cast(); - if (referencing_clause_opt.HasResult()) { - auto referencing_clause_value = - transformer.Transform(referencing_clause_opt.GetResult()); - referencing_clause = referencing_clause_value; - } - optional for_each_clause {}; - auto &for_each_clause_opt = list_pr.GetChild(8).Cast(); - if (for_each_clause_opt.HasResult()) { - auto for_each_clause_value = transformer.Transform(for_each_clause_opt.GetResult()); - for_each_clause = for_each_clause_value; - } - auto trigger_body = transformer.Transform>(list_pr.GetChild(9)); - auto result = TransformCreateTriggerStmt(transformer, if_not_exists, trigger_name, trigger_timing, trigger_event, - std::move(base_table_name), referencing_clause, for_each_clause, - std::move(trigger_body)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTriggerBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTriggerNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformTriggerName(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformReferencingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto referencing_item = transformer.Transform(list_pr.GetChild(1)); - optional referencing_item_1 {}; - auto &referencing_item_1_opt = list_pr.GetChild(2).Cast(); - if (referencing_item_1_opt.HasResult()) { - auto referencing_item_1_value = - transformer.Transform(referencing_item_1_opt.GetResult()); - referencing_item_1 = referencing_item_1_value; - } - auto result = TransformReferencingClause(transformer, referencing_item, referencing_item_1); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformReferencingItemInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformReferencingNewTableAsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformReferencingNewTableAs(transformer, col_id); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformReferencingOldTableAsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformReferencingOldTableAs(transformer, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerTimingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerBeforeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTriggerBefore(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerAfterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTriggerAfter(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerInsteadOfInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTriggerInsteadOf(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerEventInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerEventInsertInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTriggerEventInsert(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerEventDeleteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTriggerEventDelete(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerEventUpdateInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTriggerEventUpdate(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformTriggerEventUpdateOfInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto trigger_column_list = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformTriggerEventUpdateOf(transformer, trigger_column_list); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTriggerColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id; - auto col_id_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &col_id_item : col_id_items) { - auto col_id_value = transformer.Transform(col_id_item.get()); - col_id.push_back(col_id_value); - } - auto result = TransformTriggerColumnList(transformer, col_id); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformForEachClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformForEachRowInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformForEachRow(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformForEachStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformForEachStatement(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateTypeStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(1).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(2)); - auto create_type = transformer.Transform>(list_pr.GetChild(4)); - auto result = TransformCreateTypeStmt(transformer, if_not_exists, qualified_name, std::move(create_type)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateTypeFromTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformCreateTypeFromType(transformer, type); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformEnumSelectTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformEnumSelectType(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformEnumStringLiteralListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> string_literal {}; - auto &string_literal_opt = ExtractResultFromParens(list_pr.GetChild(1)).Cast(); - if (string_literal_opt.HasResult()) { - vector string_literal_value; - auto string_literal_value_items_1 = ExtractParseResultsFromList(string_literal_opt.GetResult()); - for (auto &string_literal_value_item_1 : string_literal_value_items_1) { - auto string_literal_value_value_1 = transformer.Transform(string_literal_value_item_1.get()); - string_literal_value.push_back(string_literal_value_value_1); - } - string_literal = string_literal_value; - } - auto result = TransformEnumStringLiteralList(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateViewStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional create_secure {}; - auto &create_secure_opt = list_pr.GetChild(0).Cast(); - if (create_secure_opt.HasResult()) { - auto create_secure_value = transformer.Transform(create_secure_opt.GetResult()); - create_secure = create_secure_value; - } - optional create_recursive {}; - auto &create_recursive_opt = list_pr.GetChild(1).Cast(); - if (create_recursive_opt.HasResult()) { - auto create_recursive_value = transformer.Transform(create_recursive_opt.GetResult()); - create_recursive = create_recursive_value; - } - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(3).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto qualified_name = transformer.Transform(list_pr.GetChild(4)); - optional> insert_column_list {}; - auto &insert_column_list_opt = list_pr.GetChild(5).Cast(); - if (insert_column_list_opt.HasResult()) { - auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); - insert_column_list = insert_column_list_value; - } - optional>> with_list {}; - auto &with_list_opt = list_pr.GetChild(6).Cast(); - if (with_list_opt.HasResult()) { - auto with_list_value = - transformer.Transform>>(with_list_opt.GetResult()); - with_list = std::move(with_list_value); - } - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(8)); - auto result = - TransformCreateViewStmt(transformer, create_secure, create_recursive, if_not_exists, qualified_name, - insert_column_list, std::move(with_list), std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCreateRecursiveInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCreateRecursive(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCreateSecureInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCreateSecure(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformDeallocateStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional deallocate_prepare {}; - auto &deallocate_prepare_opt = list_pr.GetChild(1).Cast(); - if (deallocate_prepare_opt.HasResult()) { - auto deallocate_prepare_value = transformer.Transform(deallocate_prepare_opt.GetResult()); - deallocate_prepare = deallocate_prepare_value; - } - auto identifier = list_pr.GetChild(2).Cast().identifier; - auto result = TransformDeallocateStatement(transformer, deallocate_prepare, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDeallocatePrepareInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDeallocatePrepare(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDeleteStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional with_clause {}; - auto &with_clause_opt = list_pr.GetChild(0).Cast(); - if (with_clause_opt.HasResult()) { - auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); - with_clause = std::move(with_clause_value); - } - auto target_opt_alias = transformer.Transform>(list_pr.GetChild(3)); - optional>> delete_using_clause {}; - auto &delete_using_clause_opt = list_pr.GetChild(4).Cast(); - if (delete_using_clause_opt.HasResult()) { - auto delete_using_clause_value = - transformer.Transform>>(delete_using_clause_opt.GetResult()); - delete_using_clause = std::move(delete_using_clause_value); - } - optional> where_clause {}; - auto &where_clause_opt = list_pr.GetChild(5).Cast(); - if (where_clause_opt.HasResult()) { - auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); - where_clause = std::move(where_clause_value); - } - optional>> returning_clause {}; - auto &returning_clause_opt = list_pr.GetChild(6).Cast(); - if (returning_clause_opt.HasResult()) { - auto returning_clause_value = - transformer.Transform>>(returning_clause_opt.GetResult()); - returning_clause = std::move(returning_clause_value); - } - auto result = - TransformDeleteStatement(transformer, std::move(with_clause), std::move(target_opt_alias), - std::move(delete_using_clause), std::move(where_clause), std::move(returning_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTruncateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformTruncateStatement(transformer, has_result, std::move(base_table_name)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTargetOptAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - optional col_id {}; - auto &col_id_opt = list_pr.GetChild(2).Cast(); - if (col_id_opt.HasResult()) { - auto col_id_value = transformer.Transform(col_id_opt.GetResult()); - col_id = col_id_value; - } - auto result = TransformTargetOptAlias(transformer, std::move(base_table_name), has_result, col_id); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDeleteUsingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> table_ref; - auto table_ref_items = ExtractParseResultsFromList(list_pr.GetChild(1)); - for (auto &table_ref_item : table_ref_items) { - auto table_ref_value = transformer.Transform>(table_ref_item.get()); - table_ref.push_back(std::move(table_ref_value)); - } - auto result = TransformDeleteUsingClause(transformer, std::move(table_ref)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDescribeStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto child = transformer.Transform>(choice_pr.GetResult()); - auto result = TransformDescribeStatement(transformer, std::move(child)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformShowDeprecatedSelectInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto show_rule = transformer.Transform(list_pr.GetChild(0)); - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformShowDeprecatedSelect(transformer, show_rule, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDescribeSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto describe_or_summarize = transformer.Transform(list_pr.GetChild(0)); - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformDescribeSelect(transformer, describe_or_summarize, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformShowAllTablesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto show_or_describe = transformer.Transform(list_pr.GetChild(0)); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(2).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformShowAllTables(transformer, show_or_describe, has_result); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformShowTablesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto show_or_describe = transformer.Transform(list_pr.GetChild(0)); - auto qualified_name = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformShowTables(transformer, show_or_describe, qualified_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformShowByNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto show_rule = transformer.Transform(list_pr.GetChild(0)); - optional show_target {}; - auto &show_target_opt = list_pr.GetChild(1).Cast(); - if (show_target_opt.HasResult()) { - auto show_target_value = transformer.Transform(show_target_opt.GetResult()); - show_target = std::move(show_target_value); - } - auto result = TransformShowByName(transformer, show_rule, std::move(show_target)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDescribeByNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto describe_or_summarize = transformer.Transform(list_pr.GetChild(0)); - optional describe_target {}; - auto &describe_target_opt = list_pr.GetChild(1).Cast(); - if (describe_target_opt.HasResult()) { - auto describe_target_value = transformer.Transform(describe_target_opt.GetResult()); - describe_target = std::move(describe_target_value); - } - auto result = TransformDescribeByName(transformer, describe_or_summarize, std::move(describe_target)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDescribeOrSummarizeInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformShowTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - DescribeTarget result {}; - if (!(choice_result.name == "ShowSpecialForm")) { - result = transformer.Transform(choice_result); - } - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformShowDeprecatedQualifiedTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto qualified_table_name = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformShowDeprecatedQualifiedTableName(transformer, std::move(qualified_table_name)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformShowSettingNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto setting_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformShowSettingName(transformer, setting_name); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDescribeTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDescribeBaseTableNameInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformDescribeBaseTableName(transformer, std::move(base_table_name)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDescribeStringLiteralInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformDescribeStringLiteral(transformer, string_literal); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSummarizeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto summarize_rule = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformSummarize(transformer, summarize_rule); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSummarizeRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSummarizeRule(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformShowOrDescribeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformShowRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformShowRule(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDescribeRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDescribeLongRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDescribeLongRule(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDescRuleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDescRule(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDetachStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(2).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto catalog_name = list_pr.GetChild(3).Cast().identifier; - auto result = TransformDetachStatement(transformer, has_result, if_exists, catalog_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto drop_entries = transformer.Transform>(list_pr.GetChild(1)); - optional drop_behavior {}; - auto &drop_behavior_opt = list_pr.GetChild(2).Cast(); - if (drop_behavior_opt.HasResult()) { - auto drop_behavior_value = transformer.Transform(drop_behavior_opt.GetResult()); - drop_behavior = drop_behavior_value; - } - auto result = TransformDropStatement(transformer, std::move(drop_entries), drop_behavior); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropEntriesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropTriggerInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto trigger_name = transformer.Transform(list_pr.GetChild(2)); - auto base_table_name = transformer.Transform>(list_pr.GetChild(4)); - auto result = TransformDropTrigger(transformer, if_exists, trigger_name, std::move(base_table_name)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropTableInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_or_view = transformer.Transform(list_pr.GetChild(0)); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector> base_table_name; - auto base_table_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &base_table_name_item : base_table_name_items) { - auto base_table_name_value = transformer.Transform>(base_table_name_item.get()); - base_table_name.push_back(std::move(base_table_name_value)); - } - auto result = TransformDropTable(transformer, table_or_view, if_exists, std::move(base_table_name)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropTableFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto comment_macro_table = transformer.Transform(list_pr.GetChild(0)); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector table_function_name; - auto table_function_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &table_function_name_item : table_function_name_items) { - auto table_function_name_value = table_function_name_item.get().Cast().identifier; - table_function_name.push_back(table_function_name_value); - } - auto result = TransformDropTableFunction(transformer, comment_macro_table, if_exists, table_function_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto function_type_macro = transformer.Transform(list_pr.GetChild(0)); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector function_identifier; - auto function_identifier_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &function_identifier_item : function_identifier_items) { - auto function_identifier_value = transformer.Transform(function_identifier_item.get()); - function_identifier.push_back(function_identifier_value); - } - auto result = TransformDropFunction(transformer, function_type_macro, if_exists, function_identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector qualified_name; - auto qualified_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &qualified_name_item : qualified_name_items) { - auto qualified_name_value = transformer.Transform(qualified_name_item.get()); - qualified_name.push_back(qualified_name_value); - } - auto result = TransformDropSchema(transformer, if_exists, qualified_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector qualified_index_name; - auto qualified_index_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &qualified_index_name_item : qualified_index_name_items) { - auto qualified_index_name_value = transformer.Transform(qualified_index_name_item.get()); - qualified_index_name.push_back(qualified_index_name_value); - } - auto result = TransformDropIndex(transformer, if_exists, qualified_index_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformQualifiedIndexNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformQualifiedIndexNameStringInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto index_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformQualifiedIndexNameString(transformer, index_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaReservedIndexInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_index_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSchemaReservedIndex(transformer, schema_qualification, reserved_index_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogReservedSchemaIndexInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_schema_qualification = transformer.Transform(list_pr.GetChild(1)); - auto reserved_index_name = list_pr.GetChild(2).Cast().identifier; - auto result = TransformCatalogReservedSchemaIndex(transformer, catalog_qualification, reserved_schema_qualification, - reserved_index_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDropSequenceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector qualified_sequence_name; - auto qualified_sequence_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &qualified_sequence_name_item : qualified_sequence_name_items) { - auto qualified_sequence_name_value = transformer.Transform(qualified_sequence_name_item.get()); - qualified_sequence_name.push_back(qualified_sequence_name_value); - } - auto result = TransformDropSequence(transformer, if_exists, qualified_sequence_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropCollationInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector collation_name; - auto collation_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &collation_name_item : collation_name_items) { - auto collation_name_value = transformer.Transform(collation_name_item.get()); - collation_name.push_back(collation_name_value); - } - auto result = TransformDropCollation(transformer, if_exists, collation_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(1).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - vector qualified_type_name; - auto qualified_type_name_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &qualified_type_name_item : qualified_type_name_items) { - auto qualified_type_name_value = transformer.Transform(qualified_type_name_item.get()); - qualified_type_name.push_back(qualified_type_name_value); - } - auto result = TransformDropType(transformer, if_exists, qualified_type_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDropSecretInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional temporary {}; - auto &temporary_opt = list_pr.GetChild(0).Cast(); - if (temporary_opt.HasResult()) { - auto temporary_value = transformer.Transform(temporary_opt.GetResult()); - temporary = temporary_value; - } - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(2).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto secret_name = transformer.Transform(list_pr.GetChild(3)); - optional drop_secret_storage {}; - auto &drop_secret_storage_opt = list_pr.GetChild(4).Cast(); - if (drop_secret_storage_opt.HasResult()) { - auto drop_secret_storage_value = transformer.Transform(drop_secret_storage_opt.GetResult()); - drop_secret_storage = drop_secret_storage_value; - } - auto result = TransformDropSecret(transformer, temporary, if_exists, secret_name, drop_secret_storage); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTableOrViewInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformMaterializedViewEntryInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformMaterializedViewEntry(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFunctionTypeMacroInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformFunctionTypeMacroKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformFunctionTypeMacroKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformFunctionTypeFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformFunctionTypeFunction(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDropBehaviorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCascadeDropBehaviorInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformCascadeDropBehavior(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformRestrictDropBehaviorInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformRestrictDropBehavior(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIfExistsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIfExists(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDropSecretStorageInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformDropSecretStorage(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExecuteStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - optional> table_function_arguments {}; - auto &table_function_arguments_opt = list_pr.GetChild(2).Cast(); - if (table_function_arguments_opt.HasResult()) { - auto table_function_arguments_value = - transformer.Transform>(table_function_arguments_opt.GetResult()); - table_function_arguments = std::move(table_function_arguments_value); - } - auto result = TransformExecuteStatement(transformer, identifier, std::move(table_function_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExplainStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional analyze_keyword {}; - auto &analyze_keyword_opt = list_pr.GetChild(1).Cast(); - if (analyze_keyword_opt.HasResult()) { - auto analyze_keyword_value = transformer.Transform(analyze_keyword_opt.GetResult()); - analyze_keyword = analyze_keyword_value; - } - optional> explain_option_list {}; - auto &explain_option_list_opt = list_pr.GetChild(2).Cast(); - if (explain_option_list_opt.HasResult()) { - auto explain_option_list_value = - transformer.Transform>(explain_option_list_opt.GetResult()); - explain_option_list = explain_option_list_value; - } - auto explainable_statements = transformer.Transform>(list_pr.GetChild(3)); - auto result = - TransformExplainStatement(transformer, analyze_keyword, explain_option_list, std::move(explainable_statements)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExplainOptionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector explain_option; - auto explain_option_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &explain_option_item : explain_option_items) { - auto explain_option_value = transformer.Transform(explain_option_item.get()); - explain_option.push_back(explain_option_value); - } - auto result = TransformExplainOptionList(transformer, explain_option); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformExplainOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto explain_option_name = transformer.Transform(list_pr.GetChild(0)); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - auto result = TransformExplainOption(transformer, explain_option_name, std::move(expression)); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExplainOptionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = TransformExplainOptionName(transformer, choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformExplainSelectStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformExplainSelectStatement(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExplainableStatementsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExportStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional export_source {}; - auto &export_source_opt = list_pr.GetChild(2).Cast(); - if (export_source_opt.HasResult()) { - auto export_source_value = transformer.Transform(export_source_opt.GetResult()); - export_source = export_source_value; - } - auto string_literal = transformer.Transform(list_pr.GetChild(3)); - optional> generic_copy_option_list {}; - auto &generic_copy_option_list_opt = list_pr.GetChild(4).Cast(); - if (generic_copy_option_list_opt.HasResult()) { - auto generic_copy_option_list_value = - transformer.Transform>(generic_copy_option_list_opt.GetResult()); - generic_copy_option_list = generic_copy_option_list_value; - } - auto result = TransformExportStatement(transformer, export_source, string_literal, generic_copy_option_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExportSourceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformExportSource(transformer, catalog_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformImportStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformImportStatement(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnReferenceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto child = transformer.Transform>(choice_pr.GetResult()); - auto result = TransformColumnReference(transformer, std::move(child)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNestedSchemaTableColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_schema_qualification = transformer.Transform(list_pr.GetChild(1)); - auto reserved_schema_qualification_1 = transformer.Transform(list_pr.GetChild(2)); - vector reserved_schema_qualification_2; - auto &reserved_schema_qualification_2_repeat = list_pr.GetChild(3).Cast(); - for (auto &reserved_schema_qualification_2_item : reserved_schema_qualification_2_repeat.GetChildren()) { - auto reserved_schema_qualification_2_value = - transformer.Transform(reserved_schema_qualification_2_item.get()); - reserved_schema_qualification_2.push_back(reserved_schema_qualification_2_value); - } - auto reserved_column_name = list_pr.GetChild(4).Cast().identifier; - auto result = TransformNestedSchemaTableColumnName(transformer, catalog_qualification, - reserved_schema_qualification, reserved_schema_qualification_1, - reserved_schema_qualification_2, reserved_column_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogReservedSchemaTableColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_schema_qualification = transformer.Transform(list_pr.GetChild(1)); - auto reserved_table_qualification = transformer.Transform(list_pr.GetChild(2)); - auto reserved_column_name = list_pr.GetChild(3).Cast().identifier; - auto result = - TransformCatalogReservedSchemaTableColumnName(transformer, catalog_qualification, reserved_schema_qualification, - reserved_table_qualification, reserved_column_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaReservedTableColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_table_qualification = transformer.Transform(list_pr.GetChild(1)); - auto reserved_column_name = list_pr.GetChild(2).Cast().identifier; - auto result = TransformSchemaReservedTableColumnName(transformer, schema_qualification, - reserved_table_qualification, reserved_column_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTableReservedColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_column_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformTableReservedColumnName(transformer, table_qualification, reserved_column_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFunctionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto function_identifier = transformer.Transform(list_pr.GetChild(0)); - auto function_expression_arguments = transformer.Transform(list_pr.GetChild(1)); - optional> within_group_clause {}; - auto &within_group_clause_opt = list_pr.GetChild(2).Cast(); - if (within_group_clause_opt.HasResult()) { - auto within_group_clause_value = - transformer.Transform>(within_group_clause_opt.GetResult()); - within_group_clause = std::move(within_group_clause_value); - } - optional> filter_clause {}; - auto &filter_clause_opt = list_pr.GetChild(3).Cast(); - if (filter_clause_opt.HasResult()) { - auto filter_clause_value = transformer.Transform>(filter_clause_opt.GetResult()); - filter_clause = std::move(filter_clause_value); - } - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(4).Cast(); - has_result = has_result_opt.HasResult(); - optional> over_clause {}; - auto &over_clause_opt = list_pr.GetChild(5).Cast(); - if (over_clause_opt.HasResult()) { - auto over_clause_value = transformer.Transform>(over_clause_opt.GetResult()); - over_clause = std::move(over_clause_value); - } - auto result = TransformFunctionExpression(transformer, function_identifier, - std::move(function_expression_arguments), std::move(within_group_clause), - std::move(filter_clause), has_result, std::move(over_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformFunctionExpressionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto function_expression_argument_list = - transformer.Transform(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformFunctionExpressionArguments(transformer, std::move(function_expression_argument_list)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformFunctionExpressionArgumentListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional distinct_or_all {}; - auto &distinct_or_all_opt = list_pr.GetChild(0).Cast(); - if (distinct_or_all_opt.HasResult()) { - auto distinct_or_all_value = transformer.Transform(distinct_or_all_opt.GetResult()); - distinct_or_all = distinct_or_all_value; - } - optional> function_argument_list {}; - auto &function_argument_list_opt = list_pr.GetChild(1).Cast(); - if (function_argument_list_opt.HasResult()) { - auto function_argument_list_value = - transformer.Transform>(function_argument_list_opt.GetResult()); - function_argument_list = std::move(function_argument_list_value); - } - optional> order_by_clause {}; - auto &order_by_clause_opt = list_pr.GetChild(2).Cast(); - if (order_by_clause_opt.HasResult()) { - auto order_by_clause_value = transformer.Transform>(order_by_clause_opt.GetResult()); - order_by_clause = std::move(order_by_clause_value); - } - optional ignore_or_respect_nulls {}; - auto &ignore_or_respect_nulls_opt = list_pr.GetChild(3).Cast(); - if (ignore_or_respect_nulls_opt.HasResult()) { - auto ignore_or_respect_nulls_value = transformer.Transform(ignore_or_respect_nulls_opt.GetResult()); - ignore_or_respect_nulls = ignore_or_respect_nulls_value; - } - auto result = - TransformFunctionExpressionArgumentList(transformer, distinct_or_all, std::move(function_argument_list), - std::move(order_by_clause), ignore_or_respect_nulls); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformFunctionArgumentListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector function_argument; - auto function_argument_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &function_argument_item : function_argument_items) { - auto function_argument_value = transformer.Transform(function_argument_item.get()); - function_argument.push_back(std::move(function_argument_value)); - } - auto result = TransformFunctionArgumentList(transformer, std::move(function_argument)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFunctionIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformFunctionNameAsQualifiedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto function_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformFunctionNameAsQualifiedName(transformer, function_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogReservedSchemaFunctionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - optional> reserved_schema_qualification {}; - auto &reserved_schema_qualification_opt = list_pr.GetChild(1).Cast(); - if (reserved_schema_qualification_opt.HasResult()) { - vector reserved_schema_qualification_value; - auto &reserved_schema_qualification_value_repeat_1 = - reserved_schema_qualification_opt.GetResult().Cast(); - for (auto &reserved_schema_qualification_value_item_1 : - reserved_schema_qualification_value_repeat_1.GetChildren()) { - auto reserved_schema_qualification_value_value_1 = - transformer.Transform(reserved_schema_qualification_value_item_1.get()); - reserved_schema_qualification_value.push_back(reserved_schema_qualification_value_value_1); - } - reserved_schema_qualification = reserved_schema_qualification_value; - } - auto reserved_function_name = list_pr.GetChild(2).Cast().identifier; - auto result = TransformCatalogReservedSchemaFunctionName(transformer, catalog_qualification, - reserved_schema_qualification, reserved_function_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaReservedFunctionNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_function_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSchemaReservedFunctionName(transformer, schema_qualification, reserved_function_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDistinctOrAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDistinctKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDistinctKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAllKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAllKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWithinGroupClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto order_by_clause = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(2))); - auto result = TransformWithinGroupClause(transformer, std::move(order_by_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFilterClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto filter_clause_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformFilterClause(transformer, std::move(filter_clause_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformFilterClauseExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto filter_clause_contents = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformFilterClauseExpression(transformer, std::move(filter_clause_contents)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformFilterClauseContentsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformFilterClauseContents(transformer, has_result, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIgnoreOrRespectNullsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIgnoreNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIgnoreNulls(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRespectNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRespectNulls(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformParenthesisExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> expression {}; - auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformParenthesisExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLiteralExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = TransformLiteralExpression(transformer, choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformConstantLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto child = transformer.Transform(choice_pr.GetResult()); - auto result = TransformConstantLiteral(transformer, child); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNullLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNullLiteral(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTrueLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTrueLiteral(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFalseLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformFalseLiteral(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCastExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto cast_or_try_cast = transformer.Transform(list_pr.GetChild(0)); - auto cast_arguments = transformer.Transform(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformCastExpression(transformer, cast_or_try_cast, std::move(cast_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCastArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto type = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformCastArguments(transformer, std::move(expression), type); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCastOrTryCastInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCastKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCastKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTryCastKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTryCastKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColIdDotInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformColIdDot(transformer, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformStarExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> star_qualifier_list {}; - auto &star_qualifier_list_opt = list_pr.GetChild(0).Cast(); - if (star_qualifier_list_opt.HasResult()) { - auto star_qualifier_list_value = transformer.Transform>(star_qualifier_list_opt.GetResult()); - star_qualifier_list = star_qualifier_list_value; - } - optional exclude_list {}; - auto &exclude_list_opt = list_pr.GetChild(2).Cast(); - if (exclude_list_opt.HasResult()) { - auto exclude_list_value = transformer.Transform(exclude_list_opt.GetResult()); - exclude_list = exclude_list_value; - } - optional>> replace_list {}; - auto &replace_list_opt = list_pr.GetChild(3).Cast(); - if (replace_list_opt.HasResult()) { - auto replace_list_value = - transformer.Transform>>(replace_list_opt.GetResult()); - replace_list = std::move(replace_list_value); - } - optional> rename_list {}; - auto &rename_list_opt = list_pr.GetChild(4).Cast(); - if (rename_list_opt.HasResult()) { - auto rename_list_value = transformer.Transform>(rename_list_opt.GetResult()); - rename_list = rename_list_value; - } - auto result = - TransformStarExpression(transformer, star_qualifier_list, exclude_list, std::move(replace_list), rename_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformStarQualifierListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id_dot; - auto &col_id_dot_repeat = list_pr.GetChild(0).Cast(); - for (auto &col_id_dot_item : col_id_dot_repeat.GetChildren()) { - auto col_id_dot_value = transformer.Transform(col_id_dot_item.get()); - col_id_dot.push_back(col_id_dot_value); - } - auto result = TransformStarQualifierList(transformer, col_id_dot); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto exclude_names = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformExcludeList(transformer, exclude_names); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeNamesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector exclude_name; - auto exclude_name_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &exclude_name_item : exclude_name_items) { - auto exclude_name_value = transformer.Transform(exclude_name_item.get()); - exclude_name.push_back(exclude_name_value); - } - auto result = TransformExcludeNameList(transformer, exclude_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeNameSingleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto exclude_name = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformExcludeNameSingle(transformer, exclude_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeDottedNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto dotted_identifier = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformExcludeDottedName(transformer, dotted_identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeColumnNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformExcludeColumnName(transformer, col_id_or_string); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformReplaceListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto replace_entries = - transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformReplaceList(transformer, std::move(replace_entries)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformReplaceEntriesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformReplaceEntrySingleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto replace_entry = transformer.Transform>>(list_pr.GetChild(0)); - auto result = TransformReplaceEntrySingle(transformer, std::move(replace_entry)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformReplaceEntryListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector>> replace_entry; - auto replace_entry_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &replace_entry_item : replace_entry_items) { - auto replace_entry_value = - transformer.Transform>>(replace_entry_item.get()); - replace_entry.push_back(std::move(replace_entry_value)); - } - auto result = TransformReplaceEntryList(transformer, std::move(replace_entry)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformReplaceEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto column_reference = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformReplaceEntry(transformer, std::move(expression), std::move(column_reference)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRenameListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rename_entries = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformRenameList(transformer, rename_entries); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformRenameEntriesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformRenameEntryListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> rename_entry; - auto rename_entry_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &rename_entry_item : rename_entry_items) { - auto rename_entry_value = transformer.Transform>(rename_entry_item.get()); - rename_entry.push_back(rename_entry_value); - } - auto result = TransformRenameEntryList(transformer, rename_entry); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformSingleRenameEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto rename_entry = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformSingleRenameEntry(transformer, rename_entry); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformRenameEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto exclude_name = transformer.Transform(list_pr.GetChild(0)); - auto identifier = list_pr.GetChild(2).Cast().identifier; - auto result = TransformRenameEntry(transformer, exclude_name, identifier); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformSubqueryExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional subquery_not {}; - auto &subquery_not_opt = list_pr.GetChild(0).Cast(); - if (subquery_not_opt.HasResult()) { - auto subquery_not_value = transformer.Transform(subquery_not_opt.GetResult()); - subquery_not = subquery_not_value; - } - optional subquery_exists {}; - auto &subquery_exists_opt = list_pr.GetChild(1).Cast(); - if (subquery_exists_opt.HasResult()) { - auto subquery_exists_value = transformer.Transform(subquery_exists_opt.GetResult()); - subquery_exists = subquery_exists_value; - } - auto subquery_reference = transformer.Transform>(list_pr.GetChild(2)); - auto result = - TransformSubqueryExpression(transformer, subquery_not, subquery_exists, std::move(subquery_reference)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSubqueryNotInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSubqueryNot(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSubqueryExistsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSubqueryExists(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCaseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - vector case_when_then; - auto &case_when_then_repeat = list_pr.GetChild(2).Cast(); - for (auto &case_when_then_item : case_when_then_repeat.GetChildren()) { - auto case_when_then_value = transformer.Transform(case_when_then_item.get()); - case_when_then.push_back(std::move(case_when_then_value)); - } - optional> case_else {}; - auto &case_else_opt = list_pr.GetChild(3).Cast(); - if (case_else_opt.HasResult()) { - auto case_else_value = transformer.Transform>(case_else_opt.GetResult()); - case_else = std::move(case_else_value); - } - auto result = - TransformCaseExpression(transformer, std::move(expression), std::move(case_when_then), std::move(case_else)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCaseWhenThenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto expression_1 = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformCaseWhenThen(transformer, std::move(expression), std::move(expression_1)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCaseElseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformCaseElse(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTypeLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type = transformer.Transform(list_pr.GetChild(0)); - auto string_literal = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformTypeLiteral(transformer, type, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntervalLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto interval_parameter = transformer.Transform>(list_pr.GetChild(1)); - optional interval {}; - auto &interval_opt = list_pr.GetChild(2).Cast(); - if (interval_opt.HasResult()) { - auto interval_value = transformer.Transform(interval_opt.GetResult()); - interval = interval_value; - } - auto result = TransformIntervalLiteral(transformer, std::move(interval_parameter), interval); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntervalParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIntervalStringParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformIntervalStringParameter(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFrameClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto framing = transformer.Transform(list_pr.GetChild(0)); - auto frame_extent = transformer.Transform>(list_pr.GetChild(1)); - optional window_exclude_clause {}; - auto &window_exclude_clause_opt = list_pr.GetChild(2).Cast(); - if (window_exclude_clause_opt.HasResult()) { - auto window_exclude_clause_value = - transformer.Transform(window_exclude_clause_opt.GetResult()); - window_exclude_clause = window_exclude_clause_value; - } - auto result = TransformFrameClause(transformer, framing, std::move(frame_extent), window_exclude_clause); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRowsFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRowsFraming(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRangeFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRangeFraming(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGroupsFramingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformGroupsFraming(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFrameExtentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSingleFrameExtentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto frame_bound = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformSingleFrameExtent(transformer, std::move(frame_bound)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBetweenFrameExtentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto frame_bound = transformer.Transform(list_pr.GetChild(1)); - auto frame_bound_1 = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformBetweenFrameExtent(transformer, std::move(frame_bound), std::move(frame_bound_1)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFrameBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFrameUnboundedInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto preceding_or_following = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformFrameUnbounded(transformer, preceding_or_following); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFrameExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto preceding_or_following = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformFrameExpression(transformer, std::move(expression), preceding_or_following); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFrameCurrentRowInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformFrameCurrentRow(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPrecedingOrFollowingInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPrecedingFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformPrecedingFrame(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFollowingFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformFollowingFrame(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformWindowExcludeClauseInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto window_exclude_element = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformWindowExcludeClause(transformer, window_exclude_element); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformWindowExcludeElementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeCurrentRowInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformExcludeCurrentRow(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeGroupInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformExcludeGroup(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeTiesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformExcludeTies(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeNoOthersInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformExcludeNoOthers(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWindowFrameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIdentifierWindowFrameInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformIdentifierWindowFrame(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformParensIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = ExtractResultFromParens(list_pr.GetChild(0)).Cast().identifier; - auto result = TransformParensIdentifier(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformWindowFrameDefinitionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformWindowFrameNameContentsParensInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto window_frame_name_contents = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformWindowFrameNameContentsParens(transformer, std::move(window_frame_name_contents)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformWindowFrameNameContentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional base_window_name {}; - auto &base_window_name_opt = list_pr.GetChild(0).Cast(); - if (base_window_name_opt.HasResult()) { - auto base_window_name_value = transformer.Transform(base_window_name_opt.GetResult()); - base_window_name = base_window_name_value; - } - auto window_frame_contents = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformWindowFrameNameContents(transformer, base_window_name, std::move(window_frame_contents)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformWindowFrameContentsParensInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto window_frame_contents = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformWindowFrameContentsParens(transformer, std::move(window_frame_contents)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformWindowFrameContentsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> window_partition {}; - auto &window_partition_opt = list_pr.GetChild(0).Cast(); - if (window_partition_opt.HasResult()) { - auto window_partition_value = - transformer.Transform>>(window_partition_opt.GetResult()); - window_partition = std::move(window_partition_value); - } - optional> order_by_clause {}; - auto &order_by_clause_opt = list_pr.GetChild(1).Cast(); - if (order_by_clause_opt.HasResult()) { - auto order_by_clause_value = transformer.Transform>(order_by_clause_opt.GetResult()); - order_by_clause = std::move(order_by_clause_value); - } - optional frame_clause {}; - auto &frame_clause_opt = list_pr.GetChild(2).Cast(); - if (frame_clause_opt.HasResult()) { - auto frame_clause_value = transformer.Transform(frame_clause_opt.GetResult()); - frame_clause = std::move(frame_clause_value); - } - auto result = TransformWindowFrameContents(transformer, std::move(window_partition), std::move(order_by_clause), - std::move(frame_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBaseWindowNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformBaseWindowName(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformWindowPartitionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformWindowPartition(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformListExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformArrayBoundedListExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto bounded_list_expression = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformArrayBoundedListExpression(transformer, has_result, std::move(bounded_list_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformArrayParensSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformArrayParensSelect(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformBoundedListExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformBoundedListExpression(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformStructExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> struct_field {}; - auto &struct_field_opt = list_pr.GetChild(1).Cast(); - if (struct_field_opt.HasResult()) { - vector struct_field_value; - auto struct_field_value_items_1 = ExtractParseResultsFromList(struct_field_opt.GetResult()); - for (auto &struct_field_value_item_1 : struct_field_value_items_1) { - auto struct_field_value_value_1 = transformer.Transform(struct_field_value_item_1.get()); - struct_field_value.push_back(std::move(struct_field_value_value_1)); - } - struct_field = std::move(struct_field_value); - } - auto result = TransformStructExpression(transformer, std::move(struct_field)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformStructFieldInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformStructField(transformer, col_id_or_string, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMapExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto map_struct_expression = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformMapExpression(transformer, std::move(map_struct_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMapStructExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>>> map_struct_field {}; - auto &map_struct_field_opt = list_pr.GetChild(1).Cast(); - if (map_struct_field_opt.HasResult()) { - vector>> map_struct_field_value; - auto map_struct_field_value_items_1 = ExtractParseResultsFromList(map_struct_field_opt.GetResult()); - for (auto &map_struct_field_value_item_1 : map_struct_field_value_items_1) { - auto map_struct_field_value_value_1 = - transformer.Transform>>(map_struct_field_value_item_1.get()); - map_struct_field_value.push_back(std::move(map_struct_field_value_value_1)); - } - map_struct_field = std::move(map_struct_field_value); - } - auto result = TransformMapStructExpression(transformer, std::move(map_struct_field)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMapStructFieldInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto expression_1 = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformMapStructField(transformer, std::move(expression), std::move(expression_1)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformGroupingExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto grouping_or_grouping_id = transformer.Transform(list_pr.GetChild(0)); - optional>> expression {}; - auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(1)).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformGroupingExpression(transformer, grouping_or_grouping_id, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformGroupingOrGroupingIdInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGroupingKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformGroupingKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGroupingIdKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformGroupingIdKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformQuestionMarkNumberedParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto number_literal = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformQuestionMarkNumberedParameter(transformer, std::move(number_literal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAnonymousParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAnonymousParameter(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNumberedParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto number_literal = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformNumberedParameter(transformer, std::move(number_literal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColLabelParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_label = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformColLabelParameter(transformer, col_label); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPositionalExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto number_literal = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformPositionalExpression(transformer, std::move(number_literal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDefaultExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDefaultExpression(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformListComprehensionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - vector col_id_or_string; - auto col_id_or_string_items = ExtractParseResultsFromList(list_pr.GetChild(3)); - for (auto &col_id_or_string_item : col_id_or_string_items) { - auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); - col_id_or_string.push_back(col_id_or_string_value); - } - auto expression_1 = transformer.Transform>(list_pr.GetChild(5)); - optional> list_comprehension_filter {}; - auto &list_comprehension_filter_opt = list_pr.GetChild(6).Cast(); - if (list_comprehension_filter_opt.HasResult()) { - auto list_comprehension_filter_value = - transformer.Transform>(list_comprehension_filter_opt.GetResult()); - list_comprehension_filter = std::move(list_comprehension_filter_value); - } - auto result = TransformListComprehensionExpression(transformer, std::move(expression), col_id_or_string, - std::move(expression_1), std::move(list_comprehension_filter)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformListComprehensionFilterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformListComprehensionFilter(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformParensExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformParensExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSingleExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto lambda_arrow_expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformExpression(transformer, std::move(lambda_arrow_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnDefaultExprInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_def_or_expr = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformColumnDefaultExpr(transformer, std::move(col_def_or_expr)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLambdaArrowExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto logical_or_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> single_arrow_pair {}; - auto &single_arrow_pair_opt = list_pr.GetChild(1).Cast(); - if (single_arrow_pair_opt.HasResult()) { - vector> single_arrow_pair_value; - auto &single_arrow_pair_value_repeat_1 = single_arrow_pair_opt.GetResult().Cast(); - for (auto &single_arrow_pair_value_item_1 : single_arrow_pair_value_repeat_1.GetChildren()) { - auto single_arrow_pair_value_value_1 = - transformer.Transform>(single_arrow_pair_value_item_1.get()); - single_arrow_pair_value.push_back(std::move(single_arrow_pair_value_value_1)); - } - single_arrow_pair = std::move(single_arrow_pair_value); - } - auto result = - TransformLambdaArrowExpression(transformer, std::move(logical_or_expression), std::move(single_arrow_pair)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSingleArrowPairInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto logical_or_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformSingleArrowPair(transformer, std::move(logical_or_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLogicalOrExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto logical_and_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> logical_or_expression_tail {}; - auto &logical_or_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (logical_or_expression_tail_opt.HasResult()) { - vector> logical_or_expression_tail_value; - auto &logical_or_expression_tail_value_repeat_1 = - logical_or_expression_tail_opt.GetResult().Cast(); - for (auto &logical_or_expression_tail_value_item_1 : logical_or_expression_tail_value_repeat_1.GetChildren()) { - auto logical_or_expression_tail_value_value_1 = - transformer.Transform>(logical_or_expression_tail_value_item_1.get()); - logical_or_expression_tail_value.push_back(std::move(logical_or_expression_tail_value_value_1)); - } - logical_or_expression_tail = std::move(logical_or_expression_tail_value); - } - auto result = TransformLogicalOrExpression(transformer, std::move(logical_and_expression), - std::move(logical_or_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLogicalOrExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto logical_and_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformLogicalOrExpressionTail(transformer, std::move(logical_and_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColDefOrExprInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_def_and_expr = transformer.Transform>(list_pr.GetChild(0)); - optional>> col_def_or_expression_tail {}; - auto &col_def_or_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (col_def_or_expression_tail_opt.HasResult()) { - vector> col_def_or_expression_tail_value; - auto &col_def_or_expression_tail_value_repeat_1 = - col_def_or_expression_tail_opt.GetResult().Cast(); - for (auto &col_def_or_expression_tail_value_item_1 : col_def_or_expression_tail_value_repeat_1.GetChildren()) { - auto col_def_or_expression_tail_value_value_1 = - transformer.Transform>(col_def_or_expression_tail_value_item_1.get()); - col_def_or_expression_tail_value.push_back(std::move(col_def_or_expression_tail_value_value_1)); - } - col_def_or_expression_tail = std::move(col_def_or_expression_tail_value); - } - auto result = - TransformColDefOrExpr(transformer, std::move(col_def_and_expr), std::move(col_def_or_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformColDefOrExpressionTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_def_and_expr = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformColDefOrExpressionTail(transformer, std::move(col_def_and_expr)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLogicalAndExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto logical_not_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> logical_and_expression_tail {}; - auto &logical_and_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (logical_and_expression_tail_opt.HasResult()) { - vector> logical_and_expression_tail_value; - auto &logical_and_expression_tail_value_repeat_1 = - logical_and_expression_tail_opt.GetResult().Cast(); - for (auto &logical_and_expression_tail_value_item_1 : - logical_and_expression_tail_value_repeat_1.GetChildren()) { - auto logical_and_expression_tail_value_value_1 = - transformer.Transform>(logical_and_expression_tail_value_item_1.get()); - logical_and_expression_tail_value.push_back(std::move(logical_and_expression_tail_value_value_1)); - } - logical_and_expression_tail = std::move(logical_and_expression_tail_value); - } - auto result = TransformLogicalAndExpression(transformer, std::move(logical_not_expression), - std::move(logical_and_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLogicalAndExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto logical_not_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformLogicalAndExpressionTail(transformer, std::move(logical_not_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColDefAndExprInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto is_distinct_from_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> col_def_and_expression_tail {}; - auto &col_def_and_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (col_def_and_expression_tail_opt.HasResult()) { - vector> col_def_and_expression_tail_value; - auto &col_def_and_expression_tail_value_repeat_1 = - col_def_and_expression_tail_opt.GetResult().Cast(); - for (auto &col_def_and_expression_tail_value_item_1 : - col_def_and_expression_tail_value_repeat_1.GetChildren()) { - auto col_def_and_expression_tail_value_value_1 = - transformer.Transform>(col_def_and_expression_tail_value_item_1.get()); - col_def_and_expression_tail_value.push_back(std::move(col_def_and_expression_tail_value_value_1)); - } - col_def_and_expression_tail = std::move(col_def_and_expression_tail_value); - } - auto result = TransformColDefAndExpr(transformer, std::move(is_distinct_from_expression), - std::move(col_def_and_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformColDefAndExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto is_distinct_from_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformColDefAndExpressionTail(transformer, std::move(is_distinct_from_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLogicalNotExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> not_expression {}; - auto ¬_expression_opt = list_pr.GetChild(0).Cast(); - if (not_expression_opt.HasResult()) { - auto not_expression_value = transformer.Transform>(not_expression_opt.GetResult()); - not_expression = std::move(not_expression_value); - } - auto is_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformLogicalNotExpression(transformer, std::move(not_expression), std::move(is_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNotExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector not_keyword; - auto ¬_keyword_repeat = list_pr.GetChild(0).Cast(); - for (auto ¬_keyword_item : not_keyword_repeat.GetChildren()) { - auto not_keyword_value = transformer.Transform(not_keyword_item.get()); - not_keyword.push_back(not_keyword_value); - } - auto result = TransformNotExpression(transformer, not_keyword); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNotKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIsExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto is_distinct_from_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> is_test {}; - auto &is_test_opt = list_pr.GetChild(1).Cast(); - if (is_test_opt.HasResult()) { - vector> is_test_value; - auto &is_test_value_repeat_1 = is_test_opt.GetResult().Cast(); - for (auto &is_test_value_item_1 : is_test_value_repeat_1.GetChildren()) { - auto is_test_value_value_1 = - transformer.Transform>(is_test_value_item_1.get()); - is_test_value.push_back(std::move(is_test_value_value_1)); - } - is_test = std::move(is_test_value); - } - auto result = TransformIsExpression(transformer, std::move(is_distinct_from_expression), std::move(is_test)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsTestInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto is_literal_value = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformIsLiteral(transformer, has_result, is_literal_value); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsLiteralValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUnknownLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformUnknownLiteral(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNotNullInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNotNullKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotNullKeyword(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNotNullOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotNullOperator(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsNullInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto is_null_operator = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformIsNull(transformer, std::move(is_null_operator)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsNullOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIsNullOperator(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformIsDistinctFromExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto comparison_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> is_distinct_from_tail {}; - auto &is_distinct_from_tail_opt = list_pr.GetChild(1).Cast(); - if (is_distinct_from_tail_opt.HasResult()) { - vector is_distinct_from_tail_value; - auto &is_distinct_from_tail_value_repeat_1 = is_distinct_from_tail_opt.GetResult().Cast(); - for (auto &is_distinct_from_tail_value_item_1 : is_distinct_from_tail_value_repeat_1.GetChildren()) { - auto is_distinct_from_tail_value_value_1 = - transformer.Transform(is_distinct_from_tail_value_item_1.get()); - is_distinct_from_tail_value.push_back(std::move(is_distinct_from_tail_value_value_1)); - } - is_distinct_from_tail = std::move(is_distinct_from_tail_value); - } - auto result = TransformIsDistinctFromExpression(transformer, std::move(comparison_expression), - std::move(is_distinct_from_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsDistinctFromTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto is_distinct_from_op = transformer.Transform(list_pr.GetChild(0)); - auto comparison_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformIsDistinctFromTail(transformer, is_distinct_from_op, std::move(comparison_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIsDistinctFromOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformIsDistinctFromOp(transformer, has_result); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformComparisonExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto between_in_like_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> comparison_expression_tail {}; - auto &comparison_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (comparison_expression_tail_opt.HasResult()) { - vector comparison_expression_tail_value; - auto &comparison_expression_tail_value_repeat_1 = - comparison_expression_tail_opt.GetResult().Cast(); - for (auto &comparison_expression_tail_value_item_1 : comparison_expression_tail_value_repeat_1.GetChildren()) { - auto comparison_expression_tail_value_value_1 = - transformer.Transform(comparison_expression_tail_value_item_1.get()); - comparison_expression_tail_value.push_back(std::move(comparison_expression_tail_value_value_1)); - } - comparison_expression_tail = std::move(comparison_expression_tail_value); - } - auto result = TransformComparisonExpression(transformer, std::move(between_in_like_expression), - std::move(comparison_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformComparisonExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto comparison_operator = transformer.Transform(list_pr.GetChild(0)); - optional> not_expression {}; - auto ¬_expression_opt = list_pr.GetChild(1).Cast(); - if (not_expression_opt.HasResult()) { - auto not_expression_value = transformer.Transform>(not_expression_opt.GetResult()); - not_expression = std::move(not_expression_value); - } - auto between_in_like_expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformComparisonExpressionTail(transformer, comparison_operator, std::move(not_expression), - std::move(between_in_like_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformComparisonOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOperatorEqualInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOperatorEqual(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOperatorNotEqualInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOperatorNotEqual(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOperatorLessThanInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOperatorLessThan(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformOperatorGreaterThanInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformOperatorGreaterThan(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformOperatorLessThanEqualsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformOperatorLessThanEquals(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformOperatorGreaterThanEqualsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOperatorGreaterThanEquals(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformBetweenInLikeExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto other_operator_expression = transformer.Transform>(list_pr.GetChild(0)); - optional between_in_like_op {}; - auto &between_in_like_op_opt = list_pr.GetChild(1).Cast(); - if (between_in_like_op_opt.HasResult()) { - auto between_in_like_op_value = - transformer.Transform(between_in_like_op_opt.GetResult()); - between_in_like_op = std::move(between_in_like_op_value); - } - auto result = TransformBetweenInLikeExpression(transformer, std::move(other_operator_expression), - std::move(between_in_like_op)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBetweenInLikeOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto between_in_like_op_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformBetweenInLikeOp(transformer, has_result, std::move(between_in_like_op_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformBetweenInLikeOpExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLikeClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto like_variations = transformer.Transform(list_pr.GetChild(0)); - auto other_operator_expression = transformer.Transform>(list_pr.GetChild(1)); - optional> escape_clause {}; - auto &escape_clause_opt = list_pr.GetChild(2).Cast(); - if (escape_clause_opt.HasResult()) { - auto escape_clause_value = transformer.Transform>(escape_clause_opt.GetResult()); - escape_clause = std::move(escape_clause_value); - } - auto result = TransformLikeClause(transformer, like_variations, std::move(other_operator_expression), - std::move(escape_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformEscapeClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto comparison_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformEscapeClause(transformer, std::move(comparison_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLikeVariationsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformLikeTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformLikeToken(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformILikeTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformILikeToken(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGlobTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformGlobToken(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSimilarToTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSimilarToToken(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRegexMatchTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRegexMatchToken(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformRegexInsensitiveMatchTokenInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRegexInsensitiveMatchToken(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNotILikeOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotILikeOp(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNotLikeOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotLikeOp(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformNotRegexInsensitiveMatchOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotRegexInsensitiveMatchOp(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNotSimilarToOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNotSimilarToOp(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto in_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformInClause(transformer, std::move(in_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformInContainsExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto other_operator_expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformInContainsExpression(transformer, std::move(other_operator_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformInExpressionList(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformInSelectStatement(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBetweenClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto other_operator_expression = transformer.Transform>(list_pr.GetChild(1)); - auto other_operator_expression_1 = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformBetweenClause(transformer, std::move(other_operator_expression), - std::move(other_operator_expression_1)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOtherOperatorExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto bitwise_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> other_operator_tail {}; - auto &other_operator_tail_opt = list_pr.GetChild(1).Cast(); - if (other_operator_tail_opt.HasResult()) { - vector other_operator_tail_value; - auto &other_operator_tail_value_repeat_1 = other_operator_tail_opt.GetResult().Cast(); - for (auto &other_operator_tail_value_item_1 : other_operator_tail_value_repeat_1.GetChildren()) { - auto other_operator_tail_value_value_1 = - transformer.Transform(other_operator_tail_value_item_1.get()); - other_operator_tail_value.push_back(std::move(other_operator_tail_value_value_1)); - } - other_operator_tail = std::move(other_operator_tail_value); - } - auto result = - TransformOtherOperatorExpression(transformer, std::move(bitwise_expression), std::move(other_operator_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOtherOperatorTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto other_operator = transformer.Transform(list_pr.GetChild(0)); - auto bitwise_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformOtherOperatorTail(transformer, std::move(other_operator), std::move(bitwise_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOtherOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformAnyAllParsedOperatorInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto any_all_operator = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformAnyAllParsedOperator(transformer, any_all_operator); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNamedOtherOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - string child; - if (choice_result.type == ParseResultType::IDENTIFIER) { - child = choice_result.Cast().identifier.GetIdentifierName(); - } else if (choice_result.type == ParseResultType::KEYWORD) { - child = choice_result.Cast().keyword; - } else if (choice_result.type == ParseResultType::STRING) { - child = choice_result.Cast().result; - } else if (choice_result.type == ParseResultType::OPERATOR) { - child = choice_result.Cast().operator_token; - } else { - child = transformer.Transform(choice_result); - } - auto result = TransformNamedOtherOperator(transformer, child); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAnyAllOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto any_op = transformer.Transform(list_pr.GetChild(0)); - auto any_or_all = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformAnyAllOperator(transformer, any_op, any_or_all); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformAnyOrAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSubqueryAnyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSubqueryAny(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSubqueryAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSubqueryAll(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInetOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformJsonOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - string result = "->>"; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformListOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformStringOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformQualifiedOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto qualified_operator_contents = transformer.Transform(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformQualifiedOperator(transformer, qualified_operator_contents); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformQualifiedOperatorContentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> col_id_dot {}; - auto &col_id_dot_opt = list_pr.GetChild(0).Cast(); - if (col_id_dot_opt.HasResult()) { - vector col_id_dot_value; - auto &col_id_dot_value_repeat_1 = col_id_dot_opt.GetResult().Cast(); - for (auto &col_id_dot_value_item_1 : col_id_dot_value_repeat_1.GetChildren()) { - auto col_id_dot_value_value_1 = transformer.Transform(col_id_dot_value_item_1.get()); - col_id_dot_value.push_back(col_id_dot_value_value_1); - } - col_id_dot = col_id_dot_value; - } - auto any_op = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformQualifiedOperatorContents(transformer, col_id_dot, any_op); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAnyOpInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBitwiseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto additive_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> bitwise_expression_tail {}; - auto &bitwise_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (bitwise_expression_tail_opt.HasResult()) { - vector bitwise_expression_tail_value; - auto &bitwise_expression_tail_value_repeat_1 = - bitwise_expression_tail_opt.GetResult().Cast(); - for (auto &bitwise_expression_tail_value_item_1 : bitwise_expression_tail_value_repeat_1.GetChildren()) { - auto bitwise_expression_tail_value_value_1 = - transformer.Transform(bitwise_expression_tail_value_item_1.get()); - bitwise_expression_tail_value.push_back(std::move(bitwise_expression_tail_value_value_1)); - } - bitwise_expression_tail = std::move(bitwise_expression_tail_value); - } - auto result = - TransformBitwiseExpression(transformer, std::move(additive_expression), std::move(bitwise_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformBitwiseExpressionTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto bit_operator = transformer.Transform(list_pr.GetChild(0)); - auto additive_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformBitwiseExpressionTail(transformer, bit_operator, std::move(additive_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBitOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAdditiveExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto multiplicative_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> additive_expression_tail {}; - auto &additive_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (additive_expression_tail_opt.HasResult()) { - vector additive_expression_tail_value; - auto &additive_expression_tail_value_repeat_1 = - additive_expression_tail_opt.GetResult().Cast(); - for (auto &additive_expression_tail_value_item_1 : additive_expression_tail_value_repeat_1.GetChildren()) { - auto additive_expression_tail_value_value_1 = - transformer.Transform(additive_expression_tail_value_item_1.get()); - additive_expression_tail_value.push_back(std::move(additive_expression_tail_value_value_1)); - } - additive_expression_tail = std::move(additive_expression_tail_value); - } - auto result = TransformAdditiveExpression(transformer, std::move(multiplicative_expression), - std::move(additive_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformAdditiveExpressionTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto term = transformer.Transform(list_pr.GetChild(0)); - auto multiplicative_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = - TransformAdditiveExpressionTail(transformer, term, std::move(multiplicative_expression), parse_result.offset); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTermInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformMultiplicativeExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto exponentiation_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> multiplicative_expression_tail {}; - auto &multiplicative_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (multiplicative_expression_tail_opt.HasResult()) { - vector multiplicative_expression_tail_value; - auto &multiplicative_expression_tail_value_repeat_1 = - multiplicative_expression_tail_opt.GetResult().Cast(); - for (auto &multiplicative_expression_tail_value_item_1 : - multiplicative_expression_tail_value_repeat_1.GetChildren()) { - auto multiplicative_expression_tail_value_value_1 = - transformer.Transform(multiplicative_expression_tail_value_item_1.get()); - multiplicative_expression_tail_value.push_back(std::move(multiplicative_expression_tail_value_value_1)); - } - multiplicative_expression_tail = std::move(multiplicative_expression_tail_value); - } - auto result = TransformMultiplicativeExpression(transformer, std::move(exponentiation_expression), - std::move(multiplicative_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMultiplicativeExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto factor = transformer.Transform(list_pr.GetChild(0)); - auto exponentiation_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformMultiplicativeExpressionTail(transformer, factor, std::move(exponentiation_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFactorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformExponentiationExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto collate_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> exponentiation_expression_tail {}; - auto &exponentiation_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (exponentiation_expression_tail_opt.HasResult()) { - vector exponentiation_expression_tail_value; - auto &exponentiation_expression_tail_value_repeat_1 = - exponentiation_expression_tail_opt.GetResult().Cast(); - for (auto &exponentiation_expression_tail_value_item_1 : - exponentiation_expression_tail_value_repeat_1.GetChildren()) { - auto exponentiation_expression_tail_value_value_1 = - transformer.Transform(exponentiation_expression_tail_value_item_1.get()); - exponentiation_expression_tail_value.push_back(std::move(exponentiation_expression_tail_value_value_1)); - } - exponentiation_expression_tail = std::move(exponentiation_expression_tail_value); - } - auto result = TransformExponentiationExpression(transformer, std::move(collate_expression), - std::move(exponentiation_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExponentiationExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto exponent_operator = transformer.Transform(list_pr.GetChild(0)); - auto collate_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformExponentiationExpressionTail(transformer, exponent_operator, std::move(collate_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExponentOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCollateExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto at_time_zone_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> collate_expression_tail {}; - auto &collate_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (collate_expression_tail_opt.HasResult()) { - vector> collate_expression_tail_value; - auto &collate_expression_tail_value_repeat_1 = - collate_expression_tail_opt.GetResult().Cast(); - for (auto &collate_expression_tail_value_item_1 : collate_expression_tail_value_repeat_1.GetChildren()) { - auto collate_expression_tail_value_value_1 = - transformer.Transform>(collate_expression_tail_value_item_1.get()); - collate_expression_tail_value.push_back(std::move(collate_expression_tail_value_value_1)); - } - collate_expression_tail = std::move(collate_expression_tail_value); - } - auto result = - TransformCollateExpression(transformer, std::move(at_time_zone_expression), std::move(collate_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCollateExpressionTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto at_time_zone_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformCollateExpressionTail(transformer, std::move(at_time_zone_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformAtTimeZoneExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto prefix_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> at_time_zone_expression_tail {}; - auto &at_time_zone_expression_tail_opt = list_pr.GetChild(1).Cast(); - if (at_time_zone_expression_tail_opt.HasResult()) { - vector> at_time_zone_expression_tail_value; - auto &at_time_zone_expression_tail_value_repeat_1 = - at_time_zone_expression_tail_opt.GetResult().Cast(); - for (auto &at_time_zone_expression_tail_value_item_1 : - at_time_zone_expression_tail_value_repeat_1.GetChildren()) { - auto at_time_zone_expression_tail_value_value_1 = - transformer.Transform>(at_time_zone_expression_tail_value_item_1.get()); - at_time_zone_expression_tail_value.push_back(std::move(at_time_zone_expression_tail_value_value_1)); - } - at_time_zone_expression_tail = std::move(at_time_zone_expression_tail_value); - } - auto result = TransformAtTimeZoneExpression(transformer, std::move(prefix_expression), - std::move(at_time_zone_expression_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformAtTimeZoneExpressionTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto prefix_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformAtTimeZoneExpressionTail(transformer, std::move(prefix_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPrefixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformMinusPrefixOperatorInternal(PEGTransformer &transformer, ParseResult &parse_result) { - string result = "-"; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPlusPrefixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - string result = "+"; - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformTildePrefixOperatorInternal(PEGTransformer &transformer, ParseResult &parse_result) { - string result = "~"; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBaseExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto single_expression = transformer.Transform>(list_pr.GetChild(0)); - optional>> indirection_list {}; - auto &indirection_list_opt = list_pr.GetChild(1).Cast(); - if (indirection_list_opt.HasResult()) { - auto indirection_list_value = - transformer.Transform>>(indirection_list_opt.GetResult()); - indirection_list = std::move(indirection_list_value); - } - auto result = TransformBaseExpression(transformer, std::move(single_expression), std::move(indirection_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIndirectionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> indirection; - auto &indirection_repeat = list_pr.GetChild(0).Cast(); - for (auto &indirection_item : indirection_repeat.GetChildren()) { - auto indirection_value = transformer.Transform>(indirection_item.get()); - indirection.push_back(std::move(indirection_value)); - } - auto result = TransformIndirectionList(transformer, std::move(indirection)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIndirectionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCastOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformCastOperator(transformer, type); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDotOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDotMethodOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto method_expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformDotMethodOperator(transformer, std::move(method_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDotColumnOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_label = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformDotColumnOperator(transformer, col_label); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMethodExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_label = transformer.Transform(list_pr.GetChild(0)); - auto method_expression_arguments = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformMethodExpression(transformer, col_label, std::move(method_expression_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMethodExpressionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto method_expression_argument_list = - transformer.Transform(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformMethodExpressionArguments(transformer, std::move(method_expression_argument_list)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMethodExpressionArgumentListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional distinct_or_all {}; - auto &distinct_or_all_opt = list_pr.GetChild(0).Cast(); - if (distinct_or_all_opt.HasResult()) { - auto distinct_or_all_value = transformer.Transform(distinct_or_all_opt.GetResult()); - distinct_or_all = distinct_or_all_value; - } - optional> method_function_arguments {}; - auto &method_function_arguments_opt = list_pr.GetChild(1).Cast(); - if (method_function_arguments_opt.HasResult()) { - auto method_function_arguments_value = - transformer.Transform>(method_function_arguments_opt.GetResult()); - method_function_arguments = std::move(method_function_arguments_value); - } - optional> order_by_clause {}; - auto &order_by_clause_opt = list_pr.GetChild(2).Cast(); - if (order_by_clause_opt.HasResult()) { - auto order_by_clause_value = transformer.Transform>(order_by_clause_opt.GetResult()); - order_by_clause = std::move(order_by_clause_value); - } - optional ignore_or_respect_nulls {}; - auto &ignore_or_respect_nulls_opt = list_pr.GetChild(3).Cast(); - if (ignore_or_respect_nulls_opt.HasResult()) { - auto ignore_or_respect_nulls_value = transformer.Transform(ignore_or_respect_nulls_opt.GetResult()); - ignore_or_respect_nulls = ignore_or_respect_nulls_value; - } - auto result = - TransformMethodExpressionArgumentList(transformer, distinct_or_all, std::move(method_function_arguments), - std::move(order_by_clause), ignore_or_respect_nulls); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMethodFunctionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector function_argument; - auto function_argument_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &function_argument_item : function_argument_items) { - auto function_argument_value = transformer.Transform(function_argument_item.get()); - function_argument.push_back(std::move(function_argument_value)); - } - auto result = TransformMethodFunctionArguments(transformer, std::move(function_argument)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSliceExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto slice_bound = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformSliceExpression(transformer, std::move(slice_bound)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSliceBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(0).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - optional> end_slice_bound {}; - auto &end_slice_bound_opt = list_pr.GetChild(1).Cast(); - if (end_slice_bound_opt.HasResult()) { - auto end_slice_bound_value = - transformer.Transform>(end_slice_bound_opt.GetResult()); - end_slice_bound = std::move(end_slice_bound_value); - } - optional> step_slice_bound {}; - auto &step_slice_bound_opt = list_pr.GetChild(2).Cast(); - if (step_slice_bound_opt.HasResult()) { - auto step_slice_bound_value = - transformer.Transform>(step_slice_bound_opt.GetResult()); - step_slice_bound = std::move(step_slice_bound_value); - } - auto result = TransformSliceBound(transformer, std::move(expression), std::move(end_slice_bound), - std::move(step_slice_bound)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformEndSliceBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> end_slice_value {}; - auto &end_slice_value_opt = list_pr.GetChild(1).Cast(); - if (end_slice_value_opt.HasResult()) { - auto end_slice_value_value = - transformer.Transform>(end_slice_value_opt.GetResult()); - end_slice_value = std::move(end_slice_value_value); - } - auto result = TransformEndSliceBound(transformer, std::move(end_slice_value)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformEndSliceValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformEndSliceMinusInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformEndSliceMinus(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformStepSliceBoundInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - auto result = TransformStepSliceBound(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPostfixOperatorInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformPostfixOperator(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSpecialFunctionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCoalesceExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformCoalesceExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUnpackExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformUnpackExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTryExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformTryExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnsExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto expression = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(2))); - auto result = TransformColumnsExpression(transformer, has_result, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExtractExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto extract_arguments = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformExtractExpression(transformer, std::move(extract_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExtractArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto extract_argument = transformer.Transform>(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformExtractArguments(transformer, std::move(extract_argument), std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLambdaExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id_or_string; - auto col_id_or_string_items = ExtractParseResultsFromList(list_pr.GetChild(1)); - for (auto &col_id_or_string_item : col_id_or_string_items) { - auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); - col_id_or_string.push_back(col_id_or_string_value); - } - auto expression = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformLambdaExpression(transformer, col_id_or_string, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNullIfExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto null_if_arguments = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformNullIfExpression(transformer, std::move(null_if_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNullIfArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto expression_1 = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformNullIfArguments(transformer, std::move(expression), std::move(expression_1)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPositionExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto position_arguments = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformPositionExpression(transformer, std::move(position_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPositionArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto other_operator_expression = transformer.Transform>(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformPositionArguments(transformer, std::move(other_operator_expression), std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRowExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> expression {}; - auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(1)).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformRowExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSubstringExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto substring_arguments = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformSubstringExpression(transformer, std::move(substring_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSubstringArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSubstringExpressionListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformSubstringExpressionList(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSubstringParametersInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto substring_from_for = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformSubstringParameters(transformer, std::move(expression), std::move(substring_from_for)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSubstringFromForInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSubstringFromOptionalForInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto from_expression = transformer.Transform>(list_pr.GetChild(0)); - optional> for_expression {}; - auto &for_expression_opt = list_pr.GetChild(1).Cast(); - if (for_expression_opt.HasResult()) { - auto for_expression_value = transformer.Transform>(for_expression_opt.GetResult()); - for_expression = std::move(for_expression_value); - } - auto result = TransformSubstringFromOptionalFor(transformer, std::move(from_expression), std::move(for_expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSubstringForInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto for_expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformSubstringFor(transformer, std::move(for_expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTrimExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto trim_arguments = transformer.Transform(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformTrimExpression(transformer, std::move(trim_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTrimArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional trim_direction {}; - auto &trim_direction_opt = list_pr.GetChild(0).Cast(); - if (trim_direction_opt.HasResult()) { - auto trim_direction_value = transformer.Transform(trim_direction_opt.GetResult()); - trim_direction = trim_direction_value; - } - optional> trim_source {}; - auto &trim_source_opt = list_pr.GetChild(1).Cast(); - if (trim_source_opt.HasResult()) { - auto trim_source_value = transformer.Transform>(trim_source_opt.GetResult()); - trim_source = std::move(trim_source_value); - } - vector> expression; - auto expression_items = ExtractParseResultsFromList(list_pr.GetChild(2)); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformTrimArguments(transformer, trim_direction, std::move(trim_source), std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTrimDirectionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTrimBothInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTrimBoth(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTrimLeadingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTrimLeading(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTrimTrailingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTrimTrailing(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTrimSourceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(0).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - auto result = TransformTrimSource(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOverlayExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto overlay_arguments = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformOverlayExpression(transformer, std::move(overlay_arguments)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOverlayArgumentsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOverlayParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto expression_1 = transformer.Transform>(list_pr.GetChild(2)); - auto from_expression = transformer.Transform>(list_pr.GetChild(3)); - optional> for_expression {}; - auto &for_expression_opt = list_pr.GetChild(4).Cast(); - if (for_expression_opt.HasResult()) { - auto for_expression_value = transformer.Transform>(for_expression_opt.GetResult()); - for_expression = std::move(for_expression_value); - } - auto result = TransformOverlayParameters(transformer, std::move(expression), std::move(expression_1), - std::move(from_expression), std::move(for_expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFromExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformFromExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformForExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformForExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOverlayExpressionListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformOverlayExpressionList(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExtractArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExtractDatePartArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto extract_date_part = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformExtractDatePartArgument(transformer, extract_date_part); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExtractIdentifierArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformExtractIdentifierArgument(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExtractStringArgumentInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformExtractStringArgument(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExtractDatePartInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformExternalResourceStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateExternalResourceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(3)); - optional attach_alias {}; - auto &attach_alias_opt = list_pr.GetChild(4).Cast(); - if (attach_alias_opt.HasResult()) { - auto attach_alias_value = transformer.Transform(attach_alias_opt.GetResult()); - attach_alias = attach_alias_value; - } - optional> external_resource_creation_options {}; - auto &external_resource_creation_options_opt = list_pr.GetChild(5).Cast(); - if (external_resource_creation_options_opt.HasResult()) { - auto external_resource_creation_options_value = - transformer.Transform>(external_resource_creation_options_opt.GetResult()); - external_resource_creation_options = external_resource_creation_options_value; - } - auto result = TransformCreateExternalResourceStmt(transformer, string_literal, attach_alias, - external_resource_creation_options); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformRegisterExternalResourceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(3)); - optional attach_alias {}; - auto &attach_alias_opt = list_pr.GetChild(4).Cast(); - if (attach_alias_opt.HasResult()) { - auto attach_alias_value = transformer.Transform(attach_alias_opt.GetResult()); - attach_alias = attach_alias_value; - } - auto expression = transformer.Transform>(list_pr.GetChild(6)); - auto result = - TransformRegisterExternalResourceStmt(transformer, string_literal, attach_alias, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDestroyExternalResourceStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(3)); - auto result = TransformDestroyExternalResourceStmt(transformer, col_id); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformShowExternalResourcesStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional show_all_modifier {}; - auto &show_all_modifier_opt = list_pr.GetChild(1).Cast(); - if (show_all_modifier_opt.HasResult()) { - auto show_all_modifier_value = transformer.Transform(show_all_modifier_opt.GetResult()); - show_all_modifier = show_all_modifier_value; - } - auto result = TransformShowExternalResourcesStmt(transformer, show_all_modifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformShowAllModifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformShowAllModifier(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformExternalResourceCreationOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto generic_copy_option_list = transformer.Transform>(list_pr.GetChild(0)); - auto result = generic_copy_option_list; - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional with_clause {}; - auto &with_clause_opt = list_pr.GetChild(0).Cast(); - if (with_clause_opt.HasResult()) { - auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); - with_clause = std::move(with_clause_value); - } - optional or_action {}; - auto &or_action_opt = list_pr.GetChild(2).Cast(); - if (or_action_opt.HasResult()) { - auto or_action_value = transformer.Transform(or_action_opt.GetResult()); - or_action = or_action_value; - } - auto insert_target = transformer.Transform>(list_pr.GetChild(4)); - optional by_name_or_position {}; - auto &by_name_or_position_opt = list_pr.GetChild(5).Cast(); - if (by_name_or_position_opt.HasResult()) { - auto by_name_or_position_value = transformer.Transform(by_name_or_position_opt.GetResult()); - by_name_or_position = by_name_or_position_value; - } - optional> insert_column_list {}; - auto &insert_column_list_opt = list_pr.GetChild(6).Cast(); - if (insert_column_list_opt.HasResult()) { - auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); - insert_column_list = insert_column_list_value; - } - auto insert_values = transformer.Transform(list_pr.GetChild(7)); - optional> on_conflict_clause {}; - auto &on_conflict_clause_opt = list_pr.GetChild(8).Cast(); - if (on_conflict_clause_opt.HasResult()) { - auto on_conflict_clause_value = - transformer.Transform>(on_conflict_clause_opt.GetResult()); - on_conflict_clause = std::move(on_conflict_clause_value); - } - optional>> returning_clause {}; - auto &returning_clause_opt = list_pr.GetChild(9).Cast(); - if (returning_clause_opt.HasResult()) { - auto returning_clause_value = - transformer.Transform>>(returning_clause_opt.GetResult()); - returning_clause = std::move(returning_clause_value); - } - auto result = TransformInsertStatement(transformer, std::move(with_clause), or_action, std::move(insert_target), - by_name_or_position, insert_column_list, std::move(insert_values), - std::move(on_conflict_clause), std::move(returning_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOrActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertOrReplaceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformInsertOrReplace(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertOrIgnoreInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformInsertOrIgnore(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformByNameOrPositionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertByNameOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto insert_by_name = transformer.Transform(list_pr.GetChild(1)); - auto result = insert_by_name; - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformInsertByPositionOrderInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto insert_by_position = transformer.Transform(list_pr.GetChild(1)); - auto result = insert_by_position; - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertByNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformInsertByName(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertByPositionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformInsertByPosition(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - optional insert_alias {}; - auto &insert_alias_opt = list_pr.GetChild(1).Cast(); - if (insert_alias_opt.HasResult()) { - auto insert_alias_value = transformer.Transform(insert_alias_opt.GetResult()); - insert_alias = insert_alias_value; - } - auto result = TransformInsertTarget(transformer, std::move(base_table_name), insert_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInsertAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformInsertAlias(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id; - auto col_id_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &col_id_item : col_id_items) { - auto col_id_value = transformer.Transform(col_id_item.get()); - col_id.push_back(col_id_value); - } - auto result = TransformColumnList(transformer, col_id); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_list = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformInsertColumnList(transformer, column_list); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformInsertValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSelectInsertValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformSelectInsertValues(transformer, std::move(select_statement_internal)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDefaultValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDefaultValues(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOnConflictClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional on_conflict_target {}; - auto &on_conflict_target_opt = list_pr.GetChild(2).Cast(); - if (on_conflict_target_opt.HasResult()) { - auto on_conflict_target_value = - transformer.Transform(on_conflict_target_opt.GetResult()); - on_conflict_target = std::move(on_conflict_target_value); - } - auto on_conflict_action = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformOnConflictClause(transformer, std::move(on_conflict_target), std::move(on_conflict_action)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOnConflictTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOnConflictExpressionTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_id_list = transformer.Transform>(list_pr.GetChild(0)); - optional> where_clause {}; - auto &where_clause_opt = list_pr.GetChild(1).Cast(); - if (where_clause_opt.HasResult()) { - auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); - where_clause = std::move(where_clause_value); - } - auto result = TransformOnConflictExpressionTarget(transformer, column_id_list, std::move(where_clause)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOnConflictIndexTargetInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto constraint_name = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformOnConflictIndexTarget(transformer, constraint_name); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOnConflictActionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOnConflictUpdateInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto update_set_clause = transformer.Transform>(list_pr.GetChild(3)); - optional> where_clause {}; - auto &where_clause_opt = list_pr.GetChild(4).Cast(); - if (where_clause_opt.HasResult()) { - auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); - where_clause = std::move(where_clause_value); - } - auto result = TransformOnConflictUpdate(transformer, std::move(update_set_clause), std::move(where_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOnConflictNothingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOnConflictNothing(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformReturningClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformReturningClause(transformer, std::move(target_list)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLoadStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(1)); - optional from_source {}; - auto &from_source_opt = list_pr.GetChild(2).Cast(); - if (from_source_opt.HasResult()) { - auto from_source_value = transformer.Transform(from_source_opt.GetResult()); - from_source = from_source_value; - } - optional extension_alias {}; - auto &extension_alias_opt = list_pr.GetChild(3).Cast(); - if (extension_alias_opt.HasResult()) { - auto extension_alias_value = transformer.Transform(extension_alias_opt.GetResult()); - extension_alias = extension_alias_value; - } - auto result = TransformLoadStatement(transformer, col_id_or_string, from_source, extension_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformExtensionAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformExtensionAlias(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInstallStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - optional install_and_load {}; - auto &install_and_load_opt = list_pr.GetChild(2).Cast(); - if (install_and_load_opt.HasResult()) { - auto install_and_load_value = transformer.Transform(install_and_load_opt.GetResult()); - install_and_load = install_and_load_value; - } - auto identifier_or_string_literal = transformer.Transform(list_pr.GetChild(3)); - optional from_source {}; - auto &from_source_opt = list_pr.GetChild(4).Cast(); - if (from_source_opt.HasResult()) { - auto from_source_value = transformer.Transform(from_source_opt.GetResult()); - from_source = from_source_value; - } - optional version_number {}; - auto &version_number_opt = list_pr.GetChild(5).Cast(); - if (version_number_opt.HasResult()) { - auto version_number_value = transformer.Transform(version_number_opt.GetResult()); - version_number = version_number_value; - } - auto result = TransformInstallStatement(transformer, has_result, install_and_load, identifier_or_string_literal, - from_source, version_number); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInstallAndLoadInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformInstallAndLoad(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformUpdateExtensionsStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> identifier {}; - auto &identifier_opt = list_pr.GetChild(2).Cast(); - if (identifier_opt.HasResult()) { - vector identifier_value; - auto identifier_value_items_1 = - ExtractParseResultsFromList(ExtractResultFromParens(identifier_opt.GetResult())); - for (auto &identifier_value_item_1 : identifier_value_items_1) { - auto identifier_value_value_1 = identifier_value_item_1.get().Cast().identifier; - identifier_value.push_back(identifier_value_value_1); - } - identifier = identifier_value; - } - auto result = TransformUpdateExtensionsStatement(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFromSourceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformFromSourceIdentifierInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformFromSourceIdentifier(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFromSourceStringInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformFromSourceString(transformer, string_literal); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformVersionNumberInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier_or_string_literal = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformVersionNumber(transformer, identifier_or_string_literal); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformExtensionRepositoryStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCreateExtensionRepositoryStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional or_replace {}; - auto &or_replace_opt = list_pr.GetChild(1).Cast(); - if (or_replace_opt.HasResult()) { - auto or_replace_value = transformer.Transform(or_replace_opt.GetResult()); - or_replace = or_replace_value; - } - optional if_not_exists {}; - auto &if_not_exists_opt = list_pr.GetChild(4).Cast(); - if (if_not_exists_opt.HasResult()) { - auto if_not_exists_value = transformer.Transform(if_not_exists_opt.GetResult()); - if_not_exists = if_not_exists_value; - } - auto col_id_or_string = transformer.Transform(list_pr.GetChild(5)); - auto repository_prefix = transformer.Transform(list_pr.GetChild(6)); - optional> repository_public_key {}; - auto &repository_public_key_opt = list_pr.GetChild(7).Cast(); - if (repository_public_key_opt.HasResult()) { - auto repository_public_key_value = transformer.Transform>(repository_public_key_opt.GetResult()); - repository_public_key = repository_public_key_value; - } - auto result = TransformCreateExtensionRepositoryStmt(transformer, or_replace, if_not_exists, col_id_or_string, - repository_prefix, repository_public_key); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformRepositoryPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformRepositoryPrefix(transformer, has_result, string_literal); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformRepositoryPublicKeyInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - vector string_literal; - auto string_literal_items = ExtractParseResultsFromList(list_pr.GetChild(3)); - for (auto &string_literal_item : string_literal_items) { - auto string_literal_value = transformer.Transform(string_literal_item.get()); - string_literal.push_back(string_literal_value); - } - auto result = TransformRepositoryPublicKey(transformer, has_result, string_literal); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformDropExtensionRepositoryStmtInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional if_exists {}; - auto &if_exists_opt = list_pr.GetChild(3).Cast(); - if (if_exists_opt.HasResult()) { - auto if_exists_value = transformer.Transform(if_exists_opt.GetResult()); - if_exists = if_exists_value; - } - auto col_id_or_string = transformer.Transform(list_pr.GetChild(4)); - auto result = TransformDropExtensionRepositoryStmt(transformer, if_exists, col_id_or_string); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMergeIntoStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional with_clause {}; - auto &with_clause_opt = list_pr.GetChild(0).Cast(); - if (with_clause_opt.HasResult()) { - auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); - with_clause = std::move(with_clause_value); - } - auto target_opt_alias = transformer.Transform>(list_pr.GetChild(3)); - auto merge_into_using_clause = transformer.Transform>(list_pr.GetChild(4)); - auto join_qualifier = transformer.Transform(list_pr.GetChild(5)); - vector>> merge_match; - auto &merge_match_repeat = list_pr.GetChild(6).Cast(); - for (auto &merge_match_item : merge_match_repeat.GetChildren()) { - auto merge_match_value = - transformer.Transform>>(merge_match_item.get()); - merge_match.push_back(std::move(merge_match_value)); - } - optional>> returning_clause {}; - auto &returning_clause_opt = list_pr.GetChild(7).Cast(); - if (returning_clause_opt.HasResult()) { - auto returning_clause_value = - transformer.Transform>>(returning_clause_opt.GetResult()); - returning_clause = std::move(returning_clause_value); - } - auto result = TransformMergeIntoStatement(transformer, std::move(with_clause), std::move(target_opt_alias), - std::move(merge_into_using_clause), std::move(join_qualifier), - std::move(merge_match), std::move(returning_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMergeIntoUsingClauseInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_ref = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformMergeIntoUsingClause(transformer, std::move(table_ref)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMergeMatchInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>>(choice_pr.GetResult()); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMatchedClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> and_expression {}; - auto &and_expression_opt = list_pr.GetChild(2).Cast(); - if (and_expression_opt.HasResult()) { - auto and_expression_value = transformer.Transform>(and_expression_opt.GetResult()); - and_expression = std::move(and_expression_value); - } - auto matched_clause_action = transformer.Transform>(list_pr.GetChild(4)); - auto result = TransformMatchedClause(transformer, std::move(and_expression), std::move(matched_clause_action)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformMatchedClauseActionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> update_match_info {}; - auto &update_match_info_opt = list_pr.GetChild(1).Cast(); - if (update_match_info_opt.HasResult()) { - auto update_match_info_value = - transformer.Transform>(update_match_info_opt.GetResult()); - update_match_info = std::move(update_match_info_value); - } - auto result = TransformUpdateMatchClause(transformer, std::move(update_match_info)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateMatchInfoInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformUpdateMatchSetActionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto update_match_set_clause = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformUpdateMatchSetAction(transformer, std::move(update_match_set_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformUpdateByNameOrPositionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto by_name_or_position = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformUpdateByNameOrPosition(transformer, by_name_or_position); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDeleteMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDeleteMatchClause(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInsertMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> insert_match_info {}; - auto &insert_match_info_opt = list_pr.GetChild(1).Cast(); - if (insert_match_info_opt.HasResult()) { - auto insert_match_info_value = - transformer.Transform>(insert_match_info_opt.GetResult()); - insert_match_info = std::move(insert_match_info_value); - } - auto result = TransformInsertMatchClause(transformer, std::move(insert_match_info)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInsertMatchInfoInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformInsertDefaultValuesInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformInsertDefaultValues(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformInsertByNameOrPositionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional by_name_or_position {}; - auto &by_name_or_position_opt = list_pr.GetChild(0).Cast(); - if (by_name_or_position_opt.HasResult()) { - auto by_name_or_position_value = transformer.Transform(by_name_or_position_opt.GetResult()); - by_name_or_position = by_name_or_position_value; - } - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformInsertByNameOrPosition(transformer, by_name_or_position, has_result); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInsertValuesListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> insert_column_list {}; - auto &insert_column_list_opt = list_pr.GetChild(0).Cast(); - if (insert_column_list_opt.HasResult()) { - auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); - insert_column_list = insert_column_list_value; - } - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(2))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformInsertValuesList(transformer, insert_column_list, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformDoNothingMatchClauseInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformDoNothingMatchClause(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformErrorMatchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> expression {}; - auto &expression_opt = list_pr.GetChild(1).Cast(); - if (expression_opt.HasResult()) { - auto expression_value = transformer.Transform>(expression_opt.GetResult()); - expression = std::move(expression_value); - } - auto result = TransformErrorMatchClause(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformUpdateMatchSetClauseInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto update_match_set_info = transformer.Transform>(list_pr.GetChild(1)); - auto result = std::move(update_match_set_info); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateMatchSetInfoInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto &choice_result = choice_pr.GetResult(); - unique_ptr result {}; - if (!(choice_result.name == "StarSymbol")) { - result = transformer.Transform>(choice_result); - } - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAndExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformAndExpression(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNotMatchedClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional by_source_or_target {}; - auto &by_source_or_target_opt = list_pr.GetChild(3).Cast(); - if (by_source_or_target_opt.HasResult()) { - auto by_source_or_target_value = - transformer.Transform(by_source_or_target_opt.GetResult()); - by_source_or_target = by_source_or_target_value; - } - optional> and_expression {}; - auto &and_expression_opt = list_pr.GetChild(4).Cast(); - if (and_expression_opt.HasResult()) { - auto and_expression_value = transformer.Transform>(and_expression_opt.GetResult()); - and_expression = std::move(and_expression_value); - } - auto matched_clause_action = transformer.Transform>(list_pr.GetChild(6)); - auto result = TransformNotMatchedClause(transformer, by_source_or_target, std::move(and_expression), - std::move(matched_clause_action)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBySourceOrTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBySourceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformBySource(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformByTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformByTarget(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformPivotOnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto pivot_column_list = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformPivotOn(transformer, std::move(pivot_column_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotUsingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformPivotUsing(transformer, std::move(target_list)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotColumnListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector pivot_column_entry; - auto pivot_column_entry_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &pivot_column_entry_item : pivot_column_entry_items) { - auto pivot_column_entry_value = transformer.Transform(pivot_column_entry_item.get()); - pivot_column_entry.push_back(std::move(pivot_column_entry_value)); - } - auto result = TransformPivotColumnList(transformer, std::move(pivot_column_entry)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotColumnEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPivotColumnExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformPivotColumnExpression(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPivotColumnSubqueryInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_expression = transformer.Transform>(list_pr.GetChild(0)); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(2))); - auto result = - TransformPivotColumnSubquery(transformer, std::move(base_expression), std::move(select_statement_internal)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntoNameValuesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(2)); - auto optional_parens_name_list = transformer.Transform>(list_pr.GetChild(4)); - auto result = TransformIntoNameValues(transformer, col_id_or_string, optional_parens_name_list); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOptionalParensNameListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformParenthesizedNameListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id_or_string; - auto col_id_or_string_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &col_id_or_string_item : col_id_or_string_items) { - auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); - col_id_or_string.push_back(col_id_or_string_value); - } - auto result = TransformParenthesizedNameList(transformer, col_id_or_string); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformBareNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id_or_string; - auto col_id_or_string_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &col_id_or_string_item : col_id_or_string_items) { - auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); - col_id_or_string.push_back(col_id_or_string_value); - } - auto result = TransformBareNameList(transformer, col_id_or_string); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformIncludeOrExcludeNullsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformIncludeNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformIncludeNulls(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformExcludeNullsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformExcludeNulls(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUnpivotHeaderInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(result); -} - -unique_ptr -PEGTransformerFactory::TransformUnpivotHeaderSingleInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformUnpivotHeaderSingle(transformer, col_id_or_string); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformUnpivotHeaderListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id_or_string; - auto col_id_or_string_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &col_id_or_string_item : col_id_or_string_items) { - auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); - col_id_or_string.push_back(col_id_or_string_value); - } - auto result = TransformUnpivotHeaderList(transformer, col_id_or_string); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformPragmaStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto pragma_assign_or_function = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformPragmaStatement(transformer, std::move(pragma_assign_or_function)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPragmaAssignOrFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPragmaAssignInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto setting_name = list_pr.GetChild(0).Cast().identifier; - auto variable_list = transformer.Transform>>(list_pr.GetChild(2)); - auto result = TransformPragmaAssign(transformer, setting_name, std::move(variable_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPragmaFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto pragma_name = list_pr.GetChild(0).Cast().identifier; - optional>> pragma_parameters {}; - auto &pragma_parameters_opt = list_pr.GetChild(1).Cast(); - if (pragma_parameters_opt.HasResult()) { - auto pragma_parameters_value = - transformer.Transform>>(pragma_parameters_opt.GetResult()); - pragma_parameters = std::move(pragma_parameters_value); - } - auto result = TransformPragmaFunction(transformer, pragma_name, std::move(pragma_parameters)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPragmaParametersInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformPragmaParameters(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPrepareStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - optional> type_list {}; - auto &type_list_opt = list_pr.GetChild(2).Cast(); - if (type_list_opt.HasResult()) { - auto type_list_value = transformer.Transform>(type_list_opt.GetResult()); - type_list = type_list_value; - } - auto statement = transformer.Transform>(list_pr.GetChild(4)); - auto result = TransformPrepareStatement(transformer, identifier, type_list, std::move(statement)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTypeListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector type; - auto type_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &type_item : type_items) { - auto type_value = transformer.Transform(type_item.get()); - type.push_back(type_value); - } - auto result = TransformTypeList(transformer, type); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformSelectStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformSelectStatement(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSelectSetOpChainInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto intersect_chain = transformer.Transform>(list_pr.GetChild(0)); - optional, unique_ptr>>> select_set_op_chain_tail {}; - auto &select_set_op_chain_tail_opt = list_pr.GetChild(1).Cast(); - if (select_set_op_chain_tail_opt.HasResult()) { - vector, unique_ptr>> select_set_op_chain_tail_value; - auto &select_set_op_chain_tail_value_repeat_1 = - select_set_op_chain_tail_opt.GetResult().Cast(); - for (auto &select_set_op_chain_tail_value_item_1 : select_set_op_chain_tail_value_repeat_1.GetChildren()) { - auto select_set_op_chain_tail_value_value_1 = - transformer.Transform, unique_ptr>>( - select_set_op_chain_tail_value_item_1.get()); - select_set_op_chain_tail_value.push_back(std::move(select_set_op_chain_tail_value_value_1)); - } - select_set_op_chain_tail = std::move(select_set_op_chain_tail_value); - } - auto result = - TransformSelectSetOpChain(transformer, std::move(intersect_chain), std::move(select_set_op_chain_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSelectSetOpChainTailInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto setop_clause = transformer.Transform>(list_pr.GetChild(0)); - auto intersect_chain = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformSelectSetOpChainTail(transformer, std::move(setop_clause), std::move(intersect_chain)); - return make_uniq, unique_ptr>>>( - std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntersectChainInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_atom = transformer.Transform>(list_pr.GetChild(0)); - optional, unique_ptr>>> intersect_chain_tail {}; - auto &intersect_chain_tail_opt = list_pr.GetChild(1).Cast(); - if (intersect_chain_tail_opt.HasResult()) { - vector, unique_ptr>> intersect_chain_tail_value; - auto &intersect_chain_tail_value_repeat_1 = intersect_chain_tail_opt.GetResult().Cast(); - for (auto &intersect_chain_tail_value_item_1 : intersect_chain_tail_value_repeat_1.GetChildren()) { - auto intersect_chain_tail_value_value_1 = - transformer.Transform, unique_ptr>>( - intersect_chain_tail_value_item_1.get()); - intersect_chain_tail_value.push_back(std::move(intersect_chain_tail_value_value_1)); - } - intersect_chain_tail = std::move(intersect_chain_tail_value); - } - auto result = TransformIntersectChain(transformer, std::move(select_atom), std::move(intersect_chain_tail)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformIntersectChainTailInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto set_intersect_clause = transformer.Transform>(list_pr.GetChild(0)); - auto select_atom = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformIntersectChainTail(transformer, std::move(set_intersect_clause), std::move(select_atom)); - return make_uniq, unique_ptr>>>( - std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetIntersectClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional distinct_or_all {}; - auto &distinct_or_all_opt = list_pr.GetChild(1).Cast(); - if (distinct_or_all_opt.HasResult()) { - auto distinct_or_all_value = transformer.Transform(distinct_or_all_opt.GetResult()); - distinct_or_all = distinct_or_all_value; - } - auto result = TransformSetIntersectClause(transformer, distinct_or_all); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSelectAtomInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSelectParensInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformSelectParens(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetopClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto setop_type = transformer.Transform(list_pr.GetChild(0)); - optional distinct_or_all {}; - auto &distinct_or_all_opt = list_pr.GetChild(1).Cast(); - if (distinct_or_all_opt.HasResult()) { - auto distinct_or_all_value = transformer.Transform(distinct_or_all_opt.GetResult()); - distinct_or_all = distinct_or_all_value; - } - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(2).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformSetopClause(transformer, setop_type, distinct_or_all, has_result); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetopTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetopUnionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSetopUnion(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetopExceptInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSetopExcept(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSelectStatementTypeInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformResultModifiersInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> order_by_clause {}; - auto &order_by_clause_opt = list_pr.GetChild(0).Cast(); - if (order_by_clause_opt.HasResult()) { - auto order_by_clause_value = transformer.Transform>(order_by_clause_opt.GetResult()); - order_by_clause = std::move(order_by_clause_value); - } - optional> limit_offset {}; - auto &limit_offset_opt = list_pr.GetChild(1).Cast(); - if (limit_offset_opt.HasResult()) { - auto limit_offset_value = transformer.Transform>(limit_offset_opt.GetResult()); - limit_offset = std::move(limit_offset_value); - } - auto result = TransformResultModifiers(transformer, std::move(order_by_clause), std::move(limit_offset)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLimitOffsetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLimitOffsetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto limit_clause = transformer.Transform(list_pr.GetChild(0)); - optional offset_clause {}; - auto &offset_clause_opt = list_pr.GetChild(1).Cast(); - if (offset_clause_opt.HasResult()) { - auto offset_clause_value = transformer.Transform(offset_clause_opt.GetResult()); - offset_clause = std::move(offset_clause_value); - } - auto result = TransformLimitOffsetClause(transformer, std::move(limit_clause), std::move(offset_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOffsetLimitClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto offset_clause = transformer.Transform(list_pr.GetChild(0)); - optional limit_clause {}; - auto &limit_clause_opt = list_pr.GetChild(1).Cast(); - if (limit_clause_opt.HasResult()) { - auto limit_clause_value = transformer.Transform(limit_clause_opt.GetResult()); - limit_clause = std::move(limit_clause_value); - } - auto result = TransformOffsetLimitClause(transformer, std::move(offset_clause), std::move(limit_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOffsetFetchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto offset_clause = transformer.Transform(list_pr.GetChild(0)); - auto fetch_clause = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformOffsetFetchClause(transformer, std::move(offset_clause), std::move(fetch_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFetchOnlyClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto fetch_clause = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformFetchOnlyClause(transformer, std::move(fetch_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTableStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformTableStatement(transformer, std::move(base_table_name)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOptionalParensSimpleSelectInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSimpleSelectParensInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto simple_select = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformSimpleSelectParens(transformer, std::move(simple_select)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSelectFromInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSelectFromClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_clause = transformer.Transform>(list_pr.GetChild(0)); - optional> from_clause {}; - auto &from_clause_opt = list_pr.GetChild(1).Cast(); - if (from_clause_opt.HasResult()) { - auto from_clause_value = transformer.Transform>(from_clause_opt.GetResult()); - from_clause = std::move(from_clause_value); - } - auto result = TransformSelectFromClause(transformer, std::move(select_clause), std::move(from_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFromSelectClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto from_clause = transformer.Transform>(list_pr.GetChild(0)); - optional> select_clause {}; - auto &select_clause_opt = list_pr.GetChild(1).Cast(); - if (select_clause_opt.HasResult()) { - auto select_clause_value = transformer.Transform>(select_clause_opt.GetResult()); - select_clause = std::move(select_clause_value); - } - auto result = TransformFromSelectClause(transformer, std::move(from_clause), std::move(select_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWithStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); - optional> insert_column_list {}; - auto &insert_column_list_opt = list_pr.GetChild(1).Cast(); - if (insert_column_list_opt.HasResult()) { - auto insert_column_list_value = transformer.Transform>(insert_column_list_opt.GetResult()); - insert_column_list = insert_column_list_value; - } - optional>> using_key {}; - auto &using_key_opt = list_pr.GetChild(2).Cast(); - if (using_key_opt.HasResult()) { - auto using_key_value = transformer.Transform>>(using_key_opt.GetResult()); - using_key = std::move(using_key_value); - } - optional materialized {}; - auto &materialized_opt = list_pr.GetChild(4).Cast(); - if (materialized_opt.HasResult()) { - auto materialized_value = transformer.Transform(materialized_opt.GetResult()); - materialized = materialized_value; - } - auto cte_body = transformer.Transform>(list_pr.GetChild(5)); - auto result = TransformWithStatement(transformer, col_id_or_string, insert_column_list, std::move(using_key), - materialized, std::move(cte_body)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCTEBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCTESelectBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformCTESelectBody(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCTEDMLBodyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto statement = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformCTEDMLBody(transformer, std::move(statement)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUsingKeyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(2))); - auto result = TransformUsingKey(transformer, std::move(target_list)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformMaterializedInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformMaterialized(transformer, has_result); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSelectClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional distinct_clause {}; - auto &distinct_clause_opt = list_pr.GetChild(1).Cast(); - if (distinct_clause_opt.HasResult()) { - auto distinct_clause_value = transformer.Transform(distinct_clause_opt.GetResult()); - distinct_clause = std::move(distinct_clause_value); - } - optional>> target_list {}; - auto &target_list_opt = list_pr.GetChild(2).Cast(); - if (target_list_opt.HasResult()) { - auto target_list_value = - transformer.Transform>>(target_list_opt.GetResult()); - target_list = std::move(target_list_value); - } - auto result = TransformSelectClause(transformer, std::move(distinct_clause), std::move(target_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTargetListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> aliased_expression; - auto aliased_expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &aliased_expression_item : aliased_expression_items) { - auto aliased_expression_value = - transformer.Transform>(aliased_expression_item.get()); - aliased_expression.push_back(std::move(aliased_expression_value)); - } - auto result = TransformTargetList(transformer, std::move(aliased_expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColumnAliasesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id_or_string; - auto col_id_or_string_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &col_id_or_string_item : col_id_or_string_items) { - auto col_id_or_string_value = transformer.Transform(col_id_or_string_item.get()); - col_id_or_string.push_back(col_id_or_string_value); - } - auto result = TransformColumnAliases(transformer, col_id_or_string); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformDistinctClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDistinctAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDistinctAll(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDistinctOnInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional>> distinct_on_targets {}; - auto &distinct_on_targets_opt = list_pr.GetChild(1).Cast(); - if (distinct_on_targets_opt.HasResult()) { - auto distinct_on_targets_value = - transformer.Transform>>(distinct_on_targets_opt.GetResult()); - distinct_on_targets = std::move(distinct_on_targets_value); - } - auto result = TransformDistinctOn(transformer, std::move(distinct_on_targets)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDistinctOnTargetsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformDistinctOnTargets(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformInnerTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTableSubqueryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional table_alias_colon {}; - auto &table_alias_colon_opt = list_pr.GetChild(0).Cast(); - if (table_alias_colon_opt.HasResult()) { - auto table_alias_colon_value = transformer.Transform(table_alias_colon_opt.GetResult()); - table_alias_colon = table_alias_colon_value; - } - optional lateral {}; - auto &lateral_opt = list_pr.GetChild(1).Cast(); - if (lateral_opt.HasResult()) { - auto lateral_value = transformer.Transform(lateral_opt.GetResult()); - lateral = lateral_value; - } - auto subquery_reference = transformer.Transform>(list_pr.GetChild(2)); - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(3).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - auto result = - TransformTableSubquery(transformer, table_alias_colon, lateral, std::move(subquery_reference), table_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBaseTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional table_alias_colon {}; - auto &table_alias_colon_opt = list_pr.GetChild(0).Cast(); - if (table_alias_colon_opt.HasResult()) { - auto table_alias_colon_value = transformer.Transform(table_alias_colon_opt.GetResult()); - table_alias_colon = table_alias_colon_value; - } - auto base_table_name = transformer.Transform>(list_pr.GetChild(1)); - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(2).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - optional> at_clause {}; - auto &at_clause_opt = list_pr.GetChild(3).Cast(); - if (at_clause_opt.HasResult()) { - auto at_clause_value = transformer.Transform>(at_clause_opt.GetResult()); - at_clause = std::move(at_clause_value); - } - optional> sample_clause {}; - auto &sample_clause_opt = list_pr.GetChild(4).Cast(); - if (sample_clause_opt.HasResult()) { - auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); - sample_clause = std::move(sample_clause_value); - } - auto result = TransformBaseTableRef(transformer, table_alias_colon, std::move(base_table_name), table_alias, - std::move(at_clause), std::move(sample_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTableAliasColonInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id_or_string = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformTableAliasColon(transformer, col_id_or_string); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformValuesRefInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional table_alias_colon {}; - auto &table_alias_colon_opt = list_pr.GetChild(0).Cast(); - if (table_alias_colon_opt.HasResult()) { - auto table_alias_colon_value = transformer.Transform(table_alias_colon_opt.GetResult()); - table_alias_colon = table_alias_colon_value; - } - auto values_clause = transformer.Transform>(list_pr.GetChild(1)); - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(2).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - auto result = TransformValuesRef(transformer, table_alias_colon, std::move(values_clause), table_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformParensTableRefInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional table_alias_colon {}; - auto &table_alias_colon_opt = list_pr.GetChild(0).Cast(); - if (table_alias_colon_opt.HasResult()) { - auto table_alias_colon_value = transformer.Transform(table_alias_colon_opt.GetResult()); - table_alias_colon = table_alias_colon_value; - } - auto table_ref = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(2).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - optional> sample_clause {}; - auto &sample_clause_opt = list_pr.GetChild(3).Cast(); - if (sample_clause_opt.HasResult()) { - auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); - sample_clause = std::move(sample_clause_value); - } - auto result = TransformParensTableRef(transformer, table_alias_colon, std::move(table_ref), table_alias, - std::move(sample_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformJoinOrPivotInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTablePivotClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_pivot_clause_body = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(2).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - auto result = TransformTablePivotClause(transformer, std::move(table_pivot_clause_body), table_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTablePivotClauseBodyInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = transformer.Transform>>(list_pr.GetChild(0)); - vector pivot_value_list; - auto &pivot_value_list_repeat = list_pr.GetChild(2).Cast(); - for (auto &pivot_value_list_item : pivot_value_list_repeat.GetChildren()) { - auto pivot_value_list_value = transformer.Transform(pivot_value_list_item.get()); - pivot_value_list.push_back(std::move(pivot_value_list_value)); - } - optional> pivot_group_by_list {}; - auto &pivot_group_by_list_opt = list_pr.GetChild(3).Cast(); - if (pivot_group_by_list_opt.HasResult()) { - auto pivot_group_by_list_value = transformer.Transform>(pivot_group_by_list_opt.GetResult()); - pivot_group_by_list = pivot_group_by_list_value; - } - auto result = TransformTablePivotClauseBody(transformer, std::move(target_list), std::move(pivot_value_list), - pivot_group_by_list); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotGroupByListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto optional_parens_name_list = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformPivotGroupByList(transformer, optional_parens_name_list); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformTableUnpivotClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional include_or_exclude_nulls {}; - auto &include_or_exclude_nulls_opt = list_pr.GetChild(1).Cast(); - if (include_or_exclude_nulls_opt.HasResult()) { - auto include_or_exclude_nulls_value = transformer.Transform(include_or_exclude_nulls_opt.GetResult()); - include_or_exclude_nulls = include_or_exclude_nulls_value; - } - auto table_unpivot_clause_body = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(2))); - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(3).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - auto result = TransformTableUnpivotClause(transformer, include_or_exclude_nulls, - std::move(table_unpivot_clause_body), table_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTableUnpivotClauseBodyInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto unpivot_header = transformer.Transform>(list_pr.GetChild(0)); - vector unpivot_value_list; - auto &unpivot_value_list_repeat = list_pr.GetChild(2).Cast(); - for (auto &unpivot_value_list_item : unpivot_value_list_repeat.GetChildren()) { - auto unpivot_value_list_value = transformer.Transform(unpivot_value_list_item.get()); - unpivot_value_list.push_back(std::move(unpivot_value_list_value)); - } - auto result = TransformTableUnpivotClauseBody(transformer, unpivot_header, std::move(unpivot_value_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotHeaderInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformPivotHeader(transformer, std::move(base_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotValueListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto pivot_header = transformer.Transform>(list_pr.GetChild(0)); - auto pivot_value_target = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformPivotValueList(transformer, std::move(pivot_header), std::move(pivot_value_target)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotValueTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotEnumTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformPivotEnumTarget(transformer, identifier); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotListTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto pivot_target_list = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformPivotListTarget(transformer, std::move(pivot_target_list)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUnpivotValueListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto unpivot_header = transformer.Transform>(list_pr.GetChild(0)); - auto unpivot_target_list = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformUnpivotValueList(transformer, unpivot_header, std::move(unpivot_target_list)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformPivotTargetListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformPivotTargetList(transformer, std::move(target_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUnpivotTargetListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto target_list = - transformer.Transform>>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformUnpivotTargetList(transformer, std::move(target_list)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLateralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformLateral(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformBaseTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformUnqualifiedBaseTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformUnqualifiedBaseTableName(transformer, table_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformQualifiedTableNameInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaReservedTableInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_qualification = transformer.Transform(list_pr.GetChild(0)); - auto reserved_table_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSchemaReservedTable(transformer, schema_qualification, reserved_table_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogReservedSchemaTableInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_qualification = transformer.Transform(list_pr.GetChild(0)); - vector reserved_schema_qualification; - auto &reserved_schema_qualification_repeat = list_pr.GetChild(1).Cast(); - for (auto &reserved_schema_qualification_item : reserved_schema_qualification_repeat.GetChildren()) { - auto reserved_schema_qualification_value = - transformer.Transform(reserved_schema_qualification_item.get()); - reserved_schema_qualification.push_back(reserved_schema_qualification_value); - } - auto reserved_table_name = list_pr.GetChild(2).Cast().identifier; - auto result = TransformCatalogReservedSchemaTable(transformer, catalog_qualification, reserved_schema_qualification, - reserved_table_name); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTableFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTableFunctionLateralOptInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional lateral {}; - auto &lateral_opt = list_pr.GetChild(0).Cast(); - if (lateral_opt.HasResult()) { - auto lateral_value = transformer.Transform(lateral_opt.GetResult()); - lateral = lateral_value; - } - auto qualified_table_function = transformer.Transform(list_pr.GetChild(1)); - auto table_function_arguments = transformer.Transform>(list_pr.GetChild(2)); - optional with_ordinality {}; - auto &with_ordinality_opt = list_pr.GetChild(3).Cast(); - if (with_ordinality_opt.HasResult()) { - auto with_ordinality_value = transformer.Transform(with_ordinality_opt.GetResult()); - with_ordinality = with_ordinality_value; - } - optional table_alias {}; - auto &table_alias_opt = list_pr.GetChild(4).Cast(); - if (table_alias_opt.HasResult()) { - auto table_alias_value = transformer.Transform(table_alias_opt.GetResult()); - table_alias = table_alias_value; - } - auto result = TransformTableFunctionLateralOpt(transformer, lateral, qualified_table_function, - std::move(table_function_arguments), with_ordinality, table_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTableFunctionAliasColonInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_alias_colon = transformer.Transform(list_pr.GetChild(0)); - auto qualified_table_function = transformer.Transform(list_pr.GetChild(1)); - auto table_function_arguments = transformer.Transform>(list_pr.GetChild(2)); - optional with_ordinality {}; - auto &with_ordinality_opt = list_pr.GetChild(3).Cast(); - if (with_ordinality_opt.HasResult()) { - auto with_ordinality_value = transformer.Transform(with_ordinality_opt.GetResult()); - with_ordinality = with_ordinality_value; - } - optional> sample_clause {}; - auto &sample_clause_opt = list_pr.GetChild(4).Cast(); - if (sample_clause_opt.HasResult()) { - auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); - sample_clause = std::move(sample_clause_value); - } - auto result = TransformTableFunctionAliasColon(transformer, table_alias_colon, qualified_table_function, - std::move(table_function_arguments), with_ordinality, - std::move(sample_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWithOrdinalityInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformWithOrdinality(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformQualifiedTableFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional catalog_qualification {}; - auto &catalog_qualification_opt = list_pr.GetChild(0).Cast(); - if (catalog_qualification_opt.HasResult()) { - auto catalog_qualification_value = transformer.Transform(catalog_qualification_opt.GetResult()); - catalog_qualification = catalog_qualification_value; - } - optional> schema_qualification {}; - auto &schema_qualification_opt = list_pr.GetChild(1).Cast(); - if (schema_qualification_opt.HasResult()) { - vector schema_qualification_value; - auto &schema_qualification_value_repeat_1 = schema_qualification_opt.GetResult().Cast(); - for (auto &schema_qualification_value_item_1 : schema_qualification_value_repeat_1.GetChildren()) { - auto schema_qualification_value_value_1 = - transformer.Transform(schema_qualification_value_item_1.get()); - schema_qualification_value.push_back(schema_qualification_value_value_1); - } - schema_qualification = schema_qualification_value; - } - auto table_function_name = list_pr.GetChild(2).Cast().identifier; - auto result = - TransformQualifiedTableFunction(transformer, catalog_qualification, schema_qualification, table_function_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformTableFunctionArgumentsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional> function_argument {}; - auto &function_argument_opt = ExtractResultFromParens(list_pr.GetChild(0)).Cast(); - if (function_argument_opt.HasResult()) { - vector function_argument_value; - auto function_argument_value_items_1 = ExtractParseResultsFromList(function_argument_opt.GetResult()); - for (auto &function_argument_value_item_1 : function_argument_value_items_1) { - auto function_argument_value_value_1 = - transformer.Transform(function_argument_value_item_1.get()); - function_argument_value.push_back(std::move(function_argument_value_value_1)); - } - function_argument = std::move(function_argument_value); - } - auto result = TransformTableFunctionArguments(transformer, std::move(function_argument)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFunctionArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNamedFunctionArgumentInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto named_parameter = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformNamedFunctionArgument(transformer, std::move(named_parameter)); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformPositionalFunctionArgumentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformPositionalFunctionArgument(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNamedParameterInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto type_func_name = transformer.Transform(list_pr.GetChild(0)); - optional type {}; - auto &type_opt = list_pr.GetChild(1).Cast(); - if (type_opt.HasResult()) { - auto type_value = transformer.Transform(type_opt.GetResult()); - type = type_value; - } - auto expression = transformer.Transform>(list_pr.GetChild(3)); - auto result = TransformNamedParameter(transformer, type_func_name, type, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformTableAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTableAliasAsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier_or_string_literal = transformer.Transform(list_pr.GetChild(1)); - optional> column_aliases {}; - auto &column_aliases_opt = list_pr.GetChild(2).Cast(); - if (column_aliases_opt.HasResult()) { - auto column_aliases_value = transformer.Transform>(column_aliases_opt.GetResult()); - column_aliases = column_aliases_value; - } - auto result = TransformTableAliasAs(transformer, identifier_or_string_literal, column_aliases); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformTableAliasWithoutAsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - optional> column_aliases {}; - auto &column_aliases_opt = list_pr.GetChild(1).Cast(); - if (column_aliases_opt.HasResult()) { - auto column_aliases_value = transformer.Transform>(column_aliases_opt.GetResult()); - column_aliases = column_aliases_value; - } - auto result = TransformTableAliasWithoutAs(transformer, identifier, column_aliases); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAtClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto at_specifier = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformAtClause(transformer, std::move(at_specifier)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAtSpecifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto at_unit = transformer.Transform(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformAtSpecifier(transformer, at_unit, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAtUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformVersionAtUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformVersionAtUnit(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformTimestampAtUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformTimestampAtUnit(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformJoinClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNearestJoinClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNearestJoinAliasedInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional join_type {}; - auto &join_type_opt = list_pr.GetChild(0).Cast(); - if (join_type_opt.HasResult()) { - auto join_type_value = transformer.Transform(join_type_opt.GetResult()); - join_type = join_type_value; - } - auto table_ref = transformer.Transform>(list_pr.GetChild(2)); - optional approx_or_exact {}; - auto &approx_or_exact_opt = list_pr.GetChild(3).Cast(); - if (approx_or_exact_opt.HasResult()) { - auto approx_or_exact_value = transformer.Transform(approx_or_exact_opt.GetResult()); - approx_or_exact = approx_or_exact_value; - } - optional> number_literal {}; - auto &number_literal_opt = list_pr.GetChild(5).Cast(); - if (number_literal_opt.HasResult()) { - auto number_literal_value = transformer.Transform>(number_literal_opt.GetResult()); - number_literal = std::move(number_literal_value); - } - auto distance_or_similarity = transformer.Transform(list_pr.GetChild(7)); - auto expression = transformer.Transform>(list_pr.GetChild(8)); - auto result = TransformNearestJoinAliased(transformer, join_type, std::move(table_ref), approx_or_exact, - std::move(number_literal), distance_or_similarity, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNearestJoinBareInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional join_type {}; - auto &join_type_opt = list_pr.GetChild(0).Cast(); - if (join_type_opt.HasResult()) { - auto join_type_value = transformer.Transform(join_type_opt.GetResult()); - join_type = join_type_value; - } - auto nearest_bare_table_ref = transformer.Transform>(list_pr.GetChild(2)); - optional approx_or_exact {}; - auto &approx_or_exact_opt = list_pr.GetChild(3).Cast(); - if (approx_or_exact_opt.HasResult()) { - auto approx_or_exact_value = transformer.Transform(approx_or_exact_opt.GetResult()); - approx_or_exact = approx_or_exact_value; - } - optional> number_literal {}; - auto &number_literal_opt = list_pr.GetChild(5).Cast(); - if (number_literal_opt.HasResult()) { - auto number_literal_value = transformer.Transform>(number_literal_opt.GetResult()); - number_literal = std::move(number_literal_value); - } - auto distance_or_similarity = transformer.Transform(list_pr.GetChild(7)); - auto expression = transformer.Transform>(list_pr.GetChild(8)); - auto result = TransformNearestJoinBare(transformer, join_type, std::move(nearest_bare_table_ref), approx_or_exact, - std::move(number_literal), distance_or_similarity, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNearestBareTableRefInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformNearestValuesRefInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto values_clause = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformNearestValuesRef(transformer, std::move(values_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNearestTableFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional lateral {}; - auto &lateral_opt = list_pr.GetChild(0).Cast(); - if (lateral_opt.HasResult()) { - auto lateral_value = transformer.Transform(lateral_opt.GetResult()); - lateral = lateral_value; - } - auto qualified_table_function = transformer.Transform(list_pr.GetChild(1)); - auto table_function_arguments = transformer.Transform>(list_pr.GetChild(2)); - optional with_ordinality {}; - auto &with_ordinality_opt = list_pr.GetChild(3).Cast(); - if (with_ordinality_opt.HasResult()) { - auto with_ordinality_value = transformer.Transform(with_ordinality_opt.GetResult()); - with_ordinality = with_ordinality_value; - } - auto result = TransformNearestTableFunction(transformer, lateral, qualified_table_function, - std::move(table_function_arguments), with_ordinality); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNearestTableSubqueryInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional lateral {}; - auto &lateral_opt = list_pr.GetChild(0).Cast(); - if (lateral_opt.HasResult()) { - auto lateral_value = transformer.Transform(lateral_opt.GetResult()); - lateral = lateral_value; - } - auto subquery_reference = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformNearestTableSubquery(transformer, lateral, std::move(subquery_reference)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNearestBaseTableRefInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - optional> at_clause {}; - auto &at_clause_opt = list_pr.GetChild(1).Cast(); - if (at_clause_opt.HasResult()) { - auto at_clause_value = transformer.Transform>(at_clause_opt.GetResult()); - at_clause = std::move(at_clause_value); - } - optional> sample_clause {}; - auto &sample_clause_opt = list_pr.GetChild(2).Cast(); - if (sample_clause_opt.HasResult()) { - auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); - sample_clause = std::move(sample_clause_value); - } - auto result = TransformNearestBaseTableRef(transformer, std::move(base_table_name), std::move(at_clause), - std::move(sample_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformNearestParensTableRefInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto table_ref = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - optional> sample_clause {}; - auto &sample_clause_opt = list_pr.GetChild(1).Cast(); - if (sample_clause_opt.HasResult()) { - auto sample_clause_value = transformer.Transform>(sample_clause_opt.GetResult()); - sample_clause = std::move(sample_clause_value); - } - auto result = TransformNearestParensTableRef(transformer, std::move(table_ref), std::move(sample_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformApproxOrExactInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNearestApproxInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNearestApprox(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNearestExactInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNearestExact(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformDistanceOrSimilarityInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNearestDistanceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNearestDistance(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNearestSimilarityInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNearestSimilarity(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRegularJoinClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional asof {}; - auto &asof_opt = list_pr.GetChild(0).Cast(); - if (asof_opt.HasResult()) { - auto asof_value = transformer.Transform(asof_opt.GetResult()); - asof = asof_value; - } - optional join_type {}; - auto &join_type_opt = list_pr.GetChild(1).Cast(); - if (join_type_opt.HasResult()) { - auto join_type_value = transformer.Transform(join_type_opt.GetResult()); - join_type = join_type_value; - } - auto table_ref = transformer.Transform>(list_pr.GetChild(3)); - auto join_qualifier = transformer.Transform(list_pr.GetChild(4)); - auto result = - TransformRegularJoinClause(transformer, asof, join_type, std::move(table_ref), std::move(join_qualifier)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformJoinByClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_label = - transformer.Transform(ExtractResultFromParens(list_pr.GetChild(2)).Cast().GetChild(1)); - auto table_ref = transformer.Transform>(list_pr.GetChild(3)); - auto join_qualifier = transformer.Transform(list_pr.GetChild(4)); - auto result = TransformJoinByClause(transformer, col_label, std::move(table_ref), std::move(join_qualifier)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAsofInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAsof(transformer); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformJoinWithoutOnClauseInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto join_prefix = transformer.Transform(list_pr.GetChild(0)); - auto inner_table_ref = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformJoinWithoutOnClause(transformer, join_prefix, std::move(inner_table_ref)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformJoinQualifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOnClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformOnClause(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUsingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector column_name; - auto column_name_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); - for (auto &column_name_item : column_name_items) { - auto column_name_value = column_name_item.get().Cast().identifier; - column_name.push_back(column_name_value); - } - auto result = TransformUsingClause(transformer, column_name); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformJoinTypeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCrossJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCrossJoinPrefix(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNaturalJoinPrefixInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional join_type {}; - auto &join_type_opt = list_pr.GetChild(1).Cast(); - if (join_type_opt.HasResult()) { - auto join_type_value = transformer.Transform(join_type_opt.GetResult()); - join_type = join_type_value; - } - auto result = TransformNaturalJoinPrefix(transformer, join_type); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformPositionalJoinPrefixInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto result = TransformPositionalJoinPrefix(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFullJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformFullJoin(transformer, has_result); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformLeftJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformLeftJoin(transformer, has_result); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRightJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformRightJoin(transformer, has_result); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSemiJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSemiJoin(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAntiJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAntiJoin(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformInnerJoinInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformInnerJoin(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformFromClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> table_ref; - auto table_ref_items = ExtractParseResultsFromList(list_pr.GetChild(1)); - for (auto &table_ref_item : table_ref_items) { - auto table_ref_value = transformer.Transform>(table_ref_item.get()); - table_ref.push_back(std::move(table_ref_value)); - } - auto result = TransformFromClause(transformer, std::move(table_ref)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWhereClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformWhereClause(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformGroupByClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto group_by_expressions = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformGroupByClause(transformer, std::move(group_by_expressions)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformHavingClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformHavingClause(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformQualifyClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformQualifyClause(transformer, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSampleClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sample_entry = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformSampleClause(transformer, std::move(sample_entry)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformWindowClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> window_definition; - auto window_definition_items = ExtractParseResultsFromList(list_pr.GetChild(1)); - for (auto &window_definition_item : window_definition_items) { - auto window_definition_value = - transformer.Transform>(window_definition_item.get()); - window_definition.push_back(std::move(window_definition_value)); - } - auto result = TransformWindowClause(transformer, std::move(window_definition)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSampleEntryInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSampleEntryCountInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sample_count = transformer.Transform>(list_pr.GetChild(0)); - optional> sample_properties {}; - auto &sample_properties_opt = list_pr.GetChild(1).Cast(); - if (sample_properties_opt.HasResult()) { - auto sample_properties_value = transformer.Transform>( - ExtractResultFromParens(sample_properties_opt.GetResult())); - sample_properties = sample_properties_value; - } - auto result = TransformSampleEntryCount(transformer, std::move(sample_count), sample_properties); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSampleEntryFunctionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional sample_function {}; - auto &sample_function_opt = list_pr.GetChild(0).Cast(); - if (sample_function_opt.HasResult()) { - auto sample_function_value = transformer.Transform(sample_function_opt.GetResult()); - sample_function = sample_function_value; - } - auto sample_count = transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - optional repeatable_sample {}; - auto &repeatable_sample_opt = list_pr.GetChild(2).Cast(); - if (repeatable_sample_opt.HasResult()) { - auto repeatable_sample_value = transformer.Transform(repeatable_sample_opt.GetResult()); - repeatable_sample = repeatable_sample_value; - } - auto result = - TransformSampleEntryFunction(transformer, sample_function, std::move(sample_count), repeatable_sample); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSampleFunctionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformSampleFunction(transformer, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSamplePropertiesInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - optional sample_seed {}; - auto &sample_seed_opt = list_pr.GetChild(1).Cast(); - if (sample_seed_opt.HasResult()) { - auto sample_seed_value = - transformer.Transform(sample_seed_opt.GetResult().Cast().GetChild(1)); - sample_seed = sample_seed_value; - } - auto result = TransformSampleProperties(transformer, col_id, sample_seed); - return make_uniq>>(result); -} - -unique_ptr PEGTransformerFactory::TransformRepeatableSampleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sample_seed = transformer.Transform(ExtractResultFromParens(list_pr.GetChild(1))); - auto result = TransformRepeatableSample(transformer, sample_seed); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSampleSeedInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto number_literal = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformSampleSeed(transformer, std::move(number_literal)); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSampleCountInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto sample_value = transformer.Transform>(list_pr.GetChild(0)); - optional sample_unit {}; - auto &sample_unit_opt = list_pr.GetChild(1).Cast(); - if (sample_unit_opt.HasResult()) { - auto sample_unit_value = transformer.Transform(sample_unit_opt.GetResult()); - sample_unit = sample_unit_value; - } - auto result = TransformSampleCount(transformer, std::move(sample_value), sample_unit); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSampleValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSampleUnitInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSamplePercentageInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSamplePercentage(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSampleRowsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSampleRows(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGroupByExpressionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformGroupByAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformGroupByAll(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformGroupByListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector group_by_expression; - auto group_by_expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &group_by_expression_item : group_by_expression_items) { - auto group_by_expression_value = transformer.Transform(group_by_expression_item.get()); - group_by_expression.push_back(std::move(group_by_expression_value)); - } - auto result = TransformGroupByList(transformer, std::move(group_by_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformGroupByExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformGroupByBaseExpressionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformGroupByBaseExpression(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformEmptyGroupingItemInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformEmptyGroupingItem(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCubeOrRollupClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto cube_or_rollup = transformer.Transform(list_pr.GetChild(0)); - optional>> expression {}; - auto &expression_opt = ExtractResultFromParens(list_pr.GetChild(1)).Cast(); - if (expression_opt.HasResult()) { - vector> expression_value; - auto expression_value_items_1 = ExtractParseResultsFromList(expression_opt.GetResult()); - for (auto &expression_value_item_1 : expression_value_items_1) { - auto expression_value_value_1 = - transformer.Transform>(expression_value_item_1.get()); - expression_value.push_back(std::move(expression_value_value_1)); - } - expression = std::move(expression_value); - } - auto result = TransformCubeOrRollupClause(transformer, cube_or_rollup, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCubeOrRollupInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformCubeKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformCubeKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformRollupKeywordInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformRollupKeyword(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGroupingSetsClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector group_by_expression; - auto group_by_expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(2))); - for (auto &group_by_expression_item : group_by_expression_items) { - auto group_by_expression_value = transformer.Transform(group_by_expression_item.get()); - group_by_expression.push_back(std::move(group_by_expression_value)); - } - auto result = TransformGroupingSetsClause(transformer, std::move(group_by_expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSubqueryReferenceInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto select_statement_internal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(0))); - auto result = TransformSubqueryReference(transformer, std::move(select_statement_internal)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOrderByExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - optional desc_or_asc {}; - auto &desc_or_asc_opt = list_pr.GetChild(1).Cast(); - if (desc_or_asc_opt.HasResult()) { - auto desc_or_asc_value = transformer.Transform(desc_or_asc_opt.GetResult()); - desc_or_asc = desc_or_asc_value; - } - optional nulls_first_or_last {}; - auto &nulls_first_or_last_opt = list_pr.GetChild(2).Cast(); - if (nulls_first_or_last_opt.HasResult()) { - auto nulls_first_or_last_value = transformer.Transform(nulls_first_or_last_opt.GetResult()); - nulls_first_or_last = nulls_first_or_last_value; - } - auto result = TransformOrderByExpression(transformer, std::move(expression), desc_or_asc, nulls_first_or_last); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformDescOrAscInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDescendingOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformDescendingOrder(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformAscendingOrderInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformAscendingOrder(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNullsFirstOrLastInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNullsFirstInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNullsFirst(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNullsLastInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformNullsLast(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOrderByClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto order_by_expressions = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformOrderByClause(transformer, std::move(order_by_expressions)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOrderByExpressionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformOrderByExpressionListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector order_by_expression; - auto order_by_expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &order_by_expression_item : order_by_expression_items) { - auto order_by_expression_value = transformer.Transform(order_by_expression_item.get()); - order_by_expression.push_back(std::move(order_by_expression_value)); - } - auto result = TransformOrderByExpressionList(transformer, std::move(order_by_expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOrderByAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional desc_or_asc {}; - auto &desc_or_asc_opt = list_pr.GetChild(1).Cast(); - if (desc_or_asc_opt.HasResult()) { - auto desc_or_asc_value = transformer.Transform(desc_or_asc_opt.GetResult()); - desc_or_asc = desc_or_asc_value; - } - optional nulls_first_or_last {}; - auto &nulls_first_or_last_opt = list_pr.GetChild(2).Cast(); - if (nulls_first_or_last_opt.HasResult()) { - auto nulls_first_or_last_value = transformer.Transform(nulls_first_or_last_opt.GetResult()); - nulls_first_or_last = nulls_first_or_last_value; - } - auto result = TransformOrderByAll(transformer, desc_or_asc, nulls_first_or_last); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLimitClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto limit_value = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformLimitClause(transformer, std::move(limit_value)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOffsetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto offset_value = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformOffsetClause(transformer, std::move(offset_value)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformOffsetValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformOffsetValue(transformer, std::move(expression), has_result); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLimitValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLimitAllInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformLimitAll(transformer); - return make_uniq>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformLimitLiteralPercentInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto number_literal = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformLimitLiteralPercent(transformer, std::move(number_literal)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformLimitExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformLimitExpression(transformer, std::move(expression), has_result); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFetchClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto fetch_value = transformer.Transform(list_pr.GetChild(2)); - auto result = std::move(fetch_value); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformFetchValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformFetchValue(transformer, std::move(expression)); - return make_uniq>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformAliasedExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformColIdExpressionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto col_id = transformer.Transform(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformColIdExpression(transformer, col_id, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExpressionAsCollabelInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - auto col_label_or_string = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformExpressionAsCollabel(transformer, std::move(expression), col_label_or_string); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformExpressionOptIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto expression = transformer.Transform>(list_pr.GetChild(0)); - optional identifier {}; - auto &identifier_opt = list_pr.GetChild(1).Cast(); - if (identifier_opt.HasResult()) { - auto identifier_value = identifier_opt.GetResult().Cast().identifier; - identifier = identifier_value; - } - auto result = TransformExpressionOptIdentifier(transformer, std::move(expression), identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformValuesClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector>> values_expressions; - auto values_expressions_items = ExtractParseResultsFromList(list_pr.GetChild(1)); - for (auto &values_expressions_item : values_expressions_items) { - auto values_expressions_value = - transformer.Transform>>(values_expressions_item.get()); - values_expressions.push_back(std::move(values_expressions_value)); - } - auto result = TransformValuesClause(transformer, std::move(values_expressions)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformValuesExpressionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformValuesExpressions(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto set_assignment_or_time_zone = transformer.Transform>(list_pr.GetChild(1)); - auto result = TransformSetStatement(transformer, std::move(set_assignment_or_time_zone)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSetAssignmentOrTimeZoneInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformResetStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto set_variable_or_setting = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformResetStatement(transformer, set_variable_or_setting); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetSchemaInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformSetSchema(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformStandardAssignmentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto set_variable_or_setting = transformer.Transform(list_pr.GetChild(0)); - auto set_assignment = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformStandardAssignment(transformer, set_variable_or_setting, std::move(set_assignment)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformSetVariableOrSettingInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetTimeZoneInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto zone_value = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformSetTimeZone(transformer, std::move(zone_value)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformZoneValueInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformZoneLocalInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformZoneLocal(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformZoneDefaultInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformZoneDefault(transformer); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformZoneStringLiteralInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformZoneStringLiteral(transformer, string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformZoneIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(0).Cast().identifier; - auto result = TransformZoneIdentifier(transformer, identifier); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformZoneIntervalWithIntervalInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto string_literal = transformer.Transform(list_pr.GetChild(1)); - optional interval {}; - auto &interval_opt = list_pr.GetChild(2).Cast(); - if (interval_opt.HasResult()) { - auto interval_value = transformer.Transform(interval_opt.GetResult()); - interval = interval_value; - } - auto result = TransformZoneIntervalWithInterval(transformer, string_literal, interval); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformZoneIntervalWithPrecisionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto number_literal = - transformer.Transform>(ExtractResultFromParens(list_pr.GetChild(1))); - auto string_literal = transformer.Transform(list_pr.GetChild(2)); - auto result = TransformZoneIntervalWithPrecision(transformer, std::move(number_literal), string_literal); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformSetSettingInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional setting_scope {}; - auto &setting_scope_opt = list_pr.GetChild(0).Cast(); - if (setting_scope_opt.HasResult()) { - auto setting_scope_value = transformer.Transform(setting_scope_opt.GetResult()); - setting_scope = setting_scope_value; - } - auto setting_name = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSetSetting(transformer, setting_scope, setting_name); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetVariableInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto variable_scope = transformer.Transform(list_pr.GetChild(0)); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformSetVariable(transformer, variable_scope, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformVariableScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformVariableScope(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSettingScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformLocalScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformLocalScope(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSessionScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformSessionScope(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformGlobalScopeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformGlobalScope(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformSetAssignmentInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto variable_list = transformer.Transform>>(list_pr.GetChild(1)); - auto result = TransformSetAssignment(transformer, std::move(variable_list)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformVariableListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector> expression; - auto expression_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &expression_item : expression_items) { - auto expression_value = transformer.Transform>(expression_item.get()); - expression.push_back(std::move(expression_value)); - } - auto result = TransformVariableList(transformer, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformTransactionStatementInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBeginTransactionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - optional read_or_write {}; - auto &read_or_write_opt = list_pr.GetChild(2).Cast(); - if (read_or_write_opt.HasResult()) { - auto read_or_write_value = transformer.Transform(read_or_write_opt.GetResult()); - read_or_write = read_or_write_value; - } - auto result = TransformBeginTransaction(transformer, has_result, read_or_write); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformRollbackTransactionInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformRollbackTransaction(transformer, has_result); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformCommitTransactionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(1).Cast(); - has_result = has_result_opt.HasResult(); - auto result = TransformCommitTransaction(transformer, has_result); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformReadOrWriteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto read_only_or_read_write = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformReadOrWrite(transformer, read_only_or_read_write); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformReadOnlyOrReadWriteInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformReadOnlyInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformReadOnly(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformReadWriteInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformReadWrite(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUpdateStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional with_clause {}; - auto &with_clause_opt = list_pr.GetChild(0).Cast(); - if (with_clause_opt.HasResult()) { - auto with_clause_value = transformer.Transform(with_clause_opt.GetResult()); - with_clause = std::move(with_clause_value); - } - auto update_target = transformer.Transform>(list_pr.GetChild(2)); - auto update_set_clause = transformer.Transform>(list_pr.GetChild(3)); - optional> from_clause {}; - auto &from_clause_opt = list_pr.GetChild(4).Cast(); - if (from_clause_opt.HasResult()) { - auto from_clause_value = transformer.Transform>(from_clause_opt.GetResult()); - from_clause = std::move(from_clause_value); - } - optional> where_clause {}; - auto &where_clause_opt = list_pr.GetChild(5).Cast(); - if (where_clause_opt.HasResult()) { - auto where_clause_value = transformer.Transform>(where_clause_opt.GetResult()); - where_clause = std::move(where_clause_value); - } - optional>> returning_clause {}; - auto &returning_clause_opt = list_pr.GetChild(6).Cast(); - if (returning_clause_opt.HasResult()) { - auto returning_clause_value = - transformer.Transform>>(returning_clause_opt.GetResult()); - returning_clause = std::move(returning_clause_value); - } - auto result = TransformUpdateStatement(transformer, std::move(with_clause), std::move(update_target), - std::move(update_set_clause), std::move(from_clause), - std::move(where_clause), std::move(returning_clause)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBaseTableSetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - auto result = TransformBaseTableSet(transformer, std::move(base_table_name)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformBaseTableAliasSetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto base_table_name = transformer.Transform>(list_pr.GetChild(0)); - optional update_alias {}; - auto &update_alias_opt = list_pr.GetChild(1).Cast(); - if (update_alias_opt.HasResult()) { - auto update_alias_value = transformer.Transform(update_alias_opt.GetResult()); - update_alias = update_alias_value; - } - auto result = TransformBaseTableAliasSet(transformer, std::move(base_table_name), update_alias); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateAliasInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool has_result {}; - auto &has_result_opt = list_pr.GetChild(0).Cast(); - has_result = has_result_opt.HasResult(); - auto col_id = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformUpdateAlias(transformer, has_result, col_id); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUpdateSetClauseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform>(choice_pr.GetResult()); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateSetTupleInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector column_name; - auto column_name_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &column_name_item : column_name_items) { - auto column_name_value = column_name_item.get().Cast().identifier; - column_name.push_back(column_name_value); - } - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformUpdateSetTuple(transformer, column_name, std::move(expression)); - return make_uniq>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformUpdateSetElementListInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector>> update_set_element; - auto update_set_element_items = ExtractParseResultsFromList(list_pr.GetChild(0)); - for (auto &update_set_element_item : update_set_element_items) { - auto update_set_element_value = - transformer.Transform>>(update_set_element_item.get()); - update_set_element.push_back(std::move(update_set_element_value)); - } - auto result = TransformUpdateSetElementList(transformer, std::move(update_set_element)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUpdateSetElementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto update_set_column_target = transformer.Transform(list_pr.GetChild(0)); - auto expression = transformer.Transform>(list_pr.GetChild(2)); - auto result = TransformUpdateSetElement(transformer, update_set_column_target, std::move(expression)); - return make_uniq>>>(std::move(result)); -} - -unique_ptr -PEGTransformerFactory::TransformUpdateSetColumnTargetInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto column_name = list_pr.GetChild(0).Cast().identifier; - optional> dot_identifier {}; - auto &dot_identifier_opt = list_pr.GetChild(1).Cast(); - if (dot_identifier_opt.HasResult()) { - vector dot_identifier_value; - auto &dot_identifier_value_repeat_1 = dot_identifier_opt.GetResult().Cast(); - for (auto &dot_identifier_value_item_1 : dot_identifier_value_repeat_1.GetChildren()) { - auto dot_identifier_value_value_1 = transformer.Transform(dot_identifier_value_item_1.get()); - dot_identifier_value.push_back(dot_identifier_value_value_1); - } - dot_identifier = dot_identifier_value; - } - auto result = TransformUpdateSetColumnTarget(transformer, column_name, dot_identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformUseStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto use_target = transformer.Transform(list_pr.GetChild(1)); - auto result = TransformUseStatement(transformer, use_target); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformUseTargetInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformSchemaNameAsUseTargetInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto schema_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformSchemaNameAsUseTarget(transformer, schema_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformCatalogNameAsUseTargetInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_name = list_pr.GetChild(0).Cast().identifier; - auto result = TransformCatalogNameAsUseTarget(transformer, catalog_name); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformUseTargetCatalogSchemaInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto catalog_name = list_pr.GetChild(0).Cast().identifier; - auto reserved_schema_name = list_pr.GetChild(2).Cast().identifier; - optional> dot_identifier {}; - auto &dot_identifier_opt = list_pr.GetChild(3).Cast(); - if (dot_identifier_opt.HasResult()) { - vector dot_identifier_value; - auto &dot_identifier_value_repeat_1 = dot_identifier_opt.GetResult().Cast(); - for (auto &dot_identifier_value_item_1 : dot_identifier_value_repeat_1.GetChildren()) { - auto dot_identifier_value_value_1 = transformer.Transform(dot_identifier_value_item_1.get()); - dot_identifier_value.push_back(dot_identifier_value_value_1); - } - dot_identifier = dot_identifier_value; - } - auto result = TransformUseTargetCatalogSchema(transformer, catalog_name, reserved_schema_name, dot_identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformDotIdentifierInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; - auto result = TransformDotIdentifier(transformer, identifier); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformVacuumStatementInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional vacuum_options {}; - auto &vacuum_options_opt = list_pr.GetChild(1).Cast(); - if (vacuum_options_opt.HasResult()) { - auto vacuum_options_value = transformer.Transform(vacuum_options_opt.GetResult()); - vacuum_options = vacuum_options_value; - } - optional analyze_target {}; - auto &analyze_target_opt = list_pr.GetChild(2).Cast(); - if (analyze_target_opt.HasResult()) { - auto analyze_target_value = transformer.Transform(analyze_target_opt.GetResult()); - analyze_target = std::move(analyze_target_value); - } - auto result = TransformVacuumStatement(transformer, vacuum_options, std::move(analyze_target)); - return make_uniq>>(std::move(result)); -} - -unique_ptr PEGTransformerFactory::TransformVacuumOptionsInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = transformer.Transform(choice_pr.GetResult()); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformVacuumParensOptionsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector vacuum_option; - auto vacuum_option_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &vacuum_option_item : vacuum_option_items) { - auto vacuum_option_value = transformer.Transform(vacuum_option_item.get()); - vacuum_option.push_back(vacuum_option_value); - } - auto result = TransformVacuumParensOptions(transformer, vacuum_option); - return make_uniq>(result); -} - -unique_ptr -PEGTransformerFactory::TransformVacuumLegacyOptionsInternal(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - optional opt_full {}; - auto &opt_full_opt = list_pr.GetChild(0).Cast(); - if (opt_full_opt.HasResult()) { - auto opt_full_value = transformer.Transform(opt_full_opt.GetResult()); - opt_full = opt_full_value; - } - optional opt_freeze {}; - auto &opt_freeze_opt = list_pr.GetChild(1).Cast(); - if (opt_freeze_opt.HasResult()) { - auto opt_freeze_value = transformer.Transform(opt_freeze_opt.GetResult()); - opt_freeze = opt_freeze_value; - } - optional opt_verbose {}; - auto &opt_verbose_opt = list_pr.GetChild(2).Cast(); - if (opt_verbose_opt.HasResult()) { - auto opt_verbose_value = transformer.Transform(opt_verbose_opt.GetResult()); - opt_verbose = opt_verbose_value; - } - optional opt_analyze {}; - auto &opt_analyze_opt = list_pr.GetChild(3).Cast(); - if (opt_analyze_opt.HasResult()) { - auto opt_analyze_value = transformer.Transform(opt_analyze_opt.GetResult()); - opt_analyze = opt_analyze_value; - } - auto result = TransformVacuumLegacyOptions(transformer, opt_full, opt_freeze, opt_verbose, opt_analyze); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformVacuumOptionInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - string result; - if (choice_pr.GetResult().type == ParseResultType::IDENTIFIER) { - result = choice_pr.GetResult().Cast().identifier.GetIdentifierName(); - } else if (choice_pr.GetResult().type == ParseResultType::KEYWORD) { - result = choice_pr.GetResult().Cast().keyword; - } else if (choice_pr.GetResult().type == ParseResultType::STRING) { - result = choice_pr.GetResult().Cast().result; - } else if (choice_pr.GetResult().type == ParseResultType::OPERATOR) { - result = choice_pr.GetResult().Cast().operator_token; - } else { - result = transformer.Transform(choice_pr.GetResult()); - } - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOptAnalyzeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto analyze_keyword = transformer.Transform(list_pr.GetChild(0)); - auto result = TransformOptAnalyze(transformer, analyze_keyword); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOptFullInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOptFull(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOptFreezeInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOptFreeze(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformOptVerboseInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto result = TransformOptVerbose(transformer); - return make_uniq>(result); -} - -unique_ptr PEGTransformerFactory::TransformNameListInternal(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - vector col_id; - auto col_id_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); - for (auto &col_id_item : col_id_items) { - auto col_id_value = transformer.Transform(col_id_item.get()); - col_id.push_back(col_id_value); - } - auto result = TransformNameList(transformer, col_id); - return make_uniq>>(result); -} - -void PEGTransformerFactory::RegisterGenerated() { - static const TransformFinalizeRule builtin_transform_rules[] = { - {"AlterStatement", &PEGTransformerFactory::TransformAlterStatementInternal}, - {"AlterOptions", &PEGTransformerFactory::TransformAlterOptionsInternal}, - {"AlterTableStmt", &PEGTransformerFactory::TransformAlterTableStmtInternal}, - {"AlterSchemaStmt", &PEGTransformerFactory::TransformAlterSchemaStmtInternal}, - {"AlterTableOptions", &PEGTransformerFactory::TransformAlterTableOptionsInternal}, - {"AddConstraint", &PEGTransformerFactory::TransformAddConstraintInternal}, - {"DropConstraint", &PEGTransformerFactory::TransformDropConstraintInternal}, - {"AddColumn", &PEGTransformerFactory::TransformAddColumnInternal}, - {"AddColumnEntry", &PEGTransformerFactory::TransformAddColumnEntryInternal}, - {"DropColumn", &PEGTransformerFactory::TransformDropColumnInternal}, - {"AlterColumn", &PEGTransformerFactory::TransformAlterColumnInternal}, - {"RenameColumn", &PEGTransformerFactory::TransformRenameColumnInternal}, - {"NestedColumnName", &PEGTransformerFactory::TransformNestedColumnNameInternal}, - {"IdentifierDot", &PEGTransformerFactory::TransformIdentifierDotInternal}, - {"RenameAlter", &PEGTransformerFactory::TransformRenameAlterInternal}, - {"SetPartitionedBy", &PEGTransformerFactory::TransformSetPartitionedByInternal}, - {"ResetPartitionedBy", &PEGTransformerFactory::TransformResetPartitionedByInternal}, - {"SetSortedBy", &PEGTransformerFactory::TransformSetSortedByInternal}, - {"ResetSortedBy", &PEGTransformerFactory::TransformResetSortedByInternal}, - {"SetOptions", &PEGTransformerFactory::TransformSetOptionsInternal}, - {"ResetOptions", &PEGTransformerFactory::TransformResetOptionsInternal}, - {"AlterColumnEntry", &PEGTransformerFactory::TransformAlterColumnEntryInternal}, - {"AddOrDropDefault", &PEGTransformerFactory::TransformAddOrDropDefaultInternal}, - {"AddDefault", &PEGTransformerFactory::TransformAddDefaultInternal}, - {"DropDefault", &PEGTransformerFactory::TransformDropDefaultInternal}, - {"ChangeNullability", &PEGTransformerFactory::TransformChangeNullabilityInternal}, - {"DropOrSet", &PEGTransformerFactory::TransformDropOrSetInternal}, - {"DropNullability", &PEGTransformerFactory::TransformDropNullabilityInternal}, - {"SetNullability", &PEGTransformerFactory::TransformSetNullabilityInternal}, - {"AlterType", &PEGTransformerFactory::TransformAlterTypeInternal}, - {"UsingExpression", &PEGTransformerFactory::TransformUsingExpressionInternal}, - {"AlterViewStmt", &PEGTransformerFactory::TransformAlterViewStmtInternal}, - {"AlterSequenceStmt", &PEGTransformerFactory::TransformAlterSequenceStmtInternal}, - {"QualifiedSequenceName", &PEGTransformerFactory::TransformQualifiedSequenceNameInternal}, - {"AlterSequenceOptions", &PEGTransformerFactory::TransformAlterSequenceOptionsInternal}, - {"RenameAlterSequenceOptions", &PEGTransformerFactory::TransformRenameAlterSequenceOptionsInternal}, - {"SetSequenceOption", &PEGTransformerFactory::TransformSetSequenceOptionInternal}, - {"AlterDatabaseStmt", &PEGTransformerFactory::TransformAlterDatabaseStmtInternal}, - {"AnalyzeStatement", &PEGTransformerFactory::TransformAnalyzeStatementInternal}, - {"AnalyzeTarget", &PEGTransformerFactory::TransformAnalyzeTargetInternal}, - {"AnalyzeVerbose", &PEGTransformerFactory::TransformAnalyzeVerboseInternal}, - {"AttachStatement", &PEGTransformerFactory::TransformAttachStatementInternal}, - {"DatabasePath", &PEGTransformerFactory::TransformDatabasePathInternal}, - {"AttachAlias", &PEGTransformerFactory::TransformAttachAliasInternal}, - {"AttachOptions", &PEGTransformerFactory::TransformAttachOptionsInternal}, - {"CallStatement", &PEGTransformerFactory::TransformCallStatementInternal}, - {"CheckpointStatement", &PEGTransformerFactory::TransformCheckpointStatementInternal}, - {"CheckpointForce", &PEGTransformerFactory::TransformCheckpointForceInternal}, - {"CommentStatement", &PEGTransformerFactory::TransformCommentStatementInternal}, - {"CommentOnType", &PEGTransformerFactory::TransformCommentOnTypeInternal}, - {"CommentTable", &PEGTransformerFactory::TransformCommentTableInternal}, - {"CommentSequence", &PEGTransformerFactory::TransformCommentSequenceInternal}, - {"CommentFunction", &PEGTransformerFactory::TransformCommentFunctionInternal}, - {"CommentMacroTable", &PEGTransformerFactory::TransformCommentMacroTableInternal}, - {"CommentMacro", &PEGTransformerFactory::TransformCommentMacroInternal}, - {"CommentView", &PEGTransformerFactory::TransformCommentViewInternal}, - {"CommentDatabase", &PEGTransformerFactory::TransformCommentDatabaseInternal}, - {"CommentIndex", &PEGTransformerFactory::TransformCommentIndexInternal}, - {"CommentSchema", &PEGTransformerFactory::TransformCommentSchemaInternal}, - {"CommentType", &PEGTransformerFactory::TransformCommentTypeInternal}, - {"CommentColumn", &PEGTransformerFactory::TransformCommentColumnInternal}, - {"CommentValue", &PEGTransformerFactory::TransformCommentValueInternal}, - {"StringLiteralValue", &PEGTransformerFactory::TransformStringLiteralValueInternal}, - {"AnalyzeKeyword", &PEGTransformerFactory::TransformAnalyzeKeywordInternal}, - {"ExpressionStatement", &PEGTransformerFactory::TransformExpressionStatementInternal}, - {"ExpressionAlias", &PEGTransformerFactory::TransformExpressionAliasInternal}, - {"ConstraintName", &PEGTransformerFactory::TransformConstraintNameInternal}, - {"CollationName", &PEGTransformerFactory::TransformCollationNameInternal}, - {"Type", &PEGTransformerFactory::TransformTypeInternal}, - {"TypeVariations", &PEGTransformerFactory::TransformTypeVariationsInternal}, - {"SimpleType", &PEGTransformerFactory::TransformSimpleTypeInternal}, - {"CharacterSimpleType", &PEGTransformerFactory::TransformCharacterSimpleTypeInternal}, - {"QualifiedSimpleType", &PEGTransformerFactory::TransformQualifiedSimpleTypeInternal}, - {"IntervalType", &PEGTransformerFactory::TransformIntervalTypeInternal}, - {"IntervalInterval", &PEGTransformerFactory::TransformIntervalIntervalInternal}, - {"IntervalWithSpecifier", &PEGTransformerFactory::TransformIntervalWithSpecifierInternal}, - {"IntervalWithRangeSpecifier", &PEGTransformerFactory::TransformIntervalWithRangeSpecifierInternal}, - {"IntervalWithSimpleSpecifier", &PEGTransformerFactory::TransformIntervalWithSimpleSpecifierInternal}, - {"IntervalWithoutSpecifier", &PEGTransformerFactory::TransformIntervalWithoutSpecifierInternal}, - {"YearKeyword", &PEGTransformerFactory::TransformYearKeywordInternal}, - {"MonthKeyword", &PEGTransformerFactory::TransformMonthKeywordInternal}, - {"DayKeyword", &PEGTransformerFactory::TransformDayKeywordInternal}, - {"HourKeyword", &PEGTransformerFactory::TransformHourKeywordInternal}, - {"MinuteKeyword", &PEGTransformerFactory::TransformMinuteKeywordInternal}, - {"SecondKeyword", &PEGTransformerFactory::TransformSecondKeywordInternal}, - {"MillisecondKeyword", &PEGTransformerFactory::TransformMillisecondKeywordInternal}, - {"MicrosecondKeyword", &PEGTransformerFactory::TransformMicrosecondKeywordInternal}, - {"WeekKeyword", &PEGTransformerFactory::TransformWeekKeywordInternal}, - {"QuarterKeyword", &PEGTransformerFactory::TransformQuarterKeywordInternal}, - {"DecadeKeyword", &PEGTransformerFactory::TransformDecadeKeywordInternal}, - {"CenturyKeyword", &PEGTransformerFactory::TransformCenturyKeywordInternal}, - {"MillenniumKeyword", &PEGTransformerFactory::TransformMillenniumKeywordInternal}, - {"Interval", &PEGTransformerFactory::TransformIntervalInternal}, - {"IntervalToInterval", &PEGTransformerFactory::TransformIntervalToIntervalInternal}, - {"YearToMonth", &PEGTransformerFactory::TransformYearToMonthInternal}, - {"DayToHour", &PEGTransformerFactory::TransformDayToHourInternal}, - {"DayToMinute", &PEGTransformerFactory::TransformDayToMinuteInternal}, - {"DayToSecond", &PEGTransformerFactory::TransformDayToSecondInternal}, - {"HourToMinute", &PEGTransformerFactory::TransformHourToMinuteInternal}, - {"HourToSecond", &PEGTransformerFactory::TransformHourToSecondInternal}, - {"MinuteToSecond", &PEGTransformerFactory::TransformMinuteToSecondInternal}, - {"BitType", &PEGTransformerFactory::TransformBitTypeInternal}, - {"GeometryType", &PEGTransformerFactory::TransformGeometryTypeInternal}, - {"VariantType", &PEGTransformerFactory::TransformVariantTypeInternal}, - {"NumericType", &PEGTransformerFactory::TransformNumericTypeInternal}, - {"SimpleNumericType", &PEGTransformerFactory::TransformSimpleNumericTypeInternal}, - {"DecimalNumericType", &PEGTransformerFactory::TransformDecimalNumericTypeInternal}, - {"IntType", &PEGTransformerFactory::TransformIntTypeInternal}, - {"IntegerType", &PEGTransformerFactory::TransformIntegerTypeInternal}, - {"SmallintType", &PEGTransformerFactory::TransformSmallintTypeInternal}, - {"BigintType", &PEGTransformerFactory::TransformBigintTypeInternal}, - {"RealType", &PEGTransformerFactory::TransformRealTypeInternal}, - {"BooleanType", &PEGTransformerFactory::TransformBooleanTypeInternal}, - {"DoubleType", &PEGTransformerFactory::TransformDoubleTypeInternal}, - {"FloatType", &PEGTransformerFactory::TransformFloatTypeInternal}, - {"DecimalType", &PEGTransformerFactory::TransformDecimalTypeInternal}, - {"DecType", &PEGTransformerFactory::TransformDecTypeInternal}, - {"NumericModType", &PEGTransformerFactory::TransformNumericModTypeInternal}, - {"QualifiedTypeName", &PEGTransformerFactory::TransformQualifiedTypeNameInternal}, - {"TypeNameAsQualifiedName", &PEGTransformerFactory::TransformTypeNameAsQualifiedNameInternal}, - {"CatalogReservedSchemaTypeName", &PEGTransformerFactory::TransformCatalogReservedSchemaTypeNameInternal}, - {"SchemaReservedTypeName", &PEGTransformerFactory::TransformSchemaReservedTypeNameInternal}, - {"TypeModifiers", &PEGTransformerFactory::TransformTypeModifiersInternal}, - {"RowType", &PEGTransformerFactory::TransformRowTypeInternal}, - {"SetofType", &PEGTransformerFactory::TransformSetofTypeInternal}, - {"UnionType", &PEGTransformerFactory::TransformUnionTypeInternal}, - {"ColIdTypeList", &PEGTransformerFactory::TransformColIdTypeListInternal}, - {"MapType", &PEGTransformerFactory::TransformMapTypeInternal}, - {"TupleType", &PEGTransformerFactory::TransformTupleTypeInternal}, - {"ColIdType", &PEGTransformerFactory::TransformColIdTypeInternal}, - {"ArrayBounds", &PEGTransformerFactory::TransformArrayBoundsInternal}, - {"ArrayKeyword", &PEGTransformerFactory::TransformArrayKeywordInternal}, - {"ArrayKeywordWithBounds", &PEGTransformerFactory::TransformArrayKeywordWithBoundsInternal}, - {"SquareBracketsArray", &PEGTransformerFactory::TransformSquareBracketsArrayInternal}, - {"TimeType", &PEGTransformerFactory::TransformTimeTypeInternal}, - {"TimeOrTimestamp", &PEGTransformerFactory::TransformTimeOrTimestampInternal}, - {"TimeTypeId", &PEGTransformerFactory::TransformTimeTypeIdInternal}, - {"TimestampTypeId", &PEGTransformerFactory::TransformTimestampTypeIdInternal}, - {"TimeZone", &PEGTransformerFactory::TransformTimeZoneInternal}, - {"WithOrWithout", &PEGTransformerFactory::TransformWithOrWithoutInternal}, - {"WithRule", &PEGTransformerFactory::TransformWithRuleInternal}, - {"WithoutRule", &PEGTransformerFactory::TransformWithoutRuleInternal}, - {"ConnectStatement", &PEGTransformerFactory::TransformConnectStatementInternal}, - {"DisconnectStatement", &PEGTransformerFactory::TransformDisconnectStatementInternal}, - {"SessionTarget", &PEGTransformerFactory::TransformSessionTargetInternal}, - {"LocalSessionTarget", &PEGTransformerFactory::TransformLocalSessionTargetInternal}, - {"StringSessionTarget", &PEGTransformerFactory::TransformStringSessionTargetInternal}, - {"CatalogSessionTarget", &PEGTransformerFactory::TransformCatalogSessionTargetInternal}, - {"CopyStatement", &PEGTransformerFactory::TransformCopyStatementInternal}, - {"CopyVariations", &PEGTransformerFactory::TransformCopyVariationsInternal}, - {"CopyTable", &PEGTransformerFactory::TransformCopyTableInternal}, - {"FromOrTo", &PEGTransformerFactory::TransformFromOrToInternal}, - {"CopyFrom", &PEGTransformerFactory::TransformCopyFromInternal}, - {"CopyTo", &PEGTransformerFactory::TransformCopyToInternal}, - {"CopySelect", &PEGTransformerFactory::TransformCopySelectInternal}, - {"CopyFileName", &PEGTransformerFactory::TransformCopyFileNameInternal}, - {"CopyFileNameExpression", &PEGTransformerFactory::TransformCopyFileNameExpressionInternal}, - {"CopyFileNameStringLiteral", &PEGTransformerFactory::TransformCopyFileNameStringLiteralInternal}, - {"CopyFileNameIdentifier", &PEGTransformerFactory::TransformCopyFileNameIdentifierInternal}, - {"CopyFileNameIdentifierColId", &PEGTransformerFactory::TransformCopyFileNameIdentifierColIdInternal}, - {"IdentifierColId", &PEGTransformerFactory::TransformIdentifierColIdInternal}, - {"CopyOptions", &PEGTransformerFactory::TransformCopyOptionsInternal}, - {"CopyOptionList", &PEGTransformerFactory::TransformCopyOptionListInternal}, - {"SpecializedOptionList", &PEGTransformerFactory::TransformSpecializedOptionListInternal}, - {"SpecializedOptionTail", &PEGTransformerFactory::TransformSpecializedOptionTailInternal}, - {"SpecializedOption", &PEGTransformerFactory::TransformSpecializedOptionInternal}, - {"SingleOption", &PEGTransformerFactory::TransformSingleOptionInternal}, - {"BinaryOption", &PEGTransformerFactory::TransformBinaryOptionInternal}, - {"FreezeOption", &PEGTransformerFactory::TransformFreezeOptionInternal}, - {"OidsOption", &PEGTransformerFactory::TransformOidsOptionInternal}, - {"CsvOption", &PEGTransformerFactory::TransformCsvOptionInternal}, - {"HeaderOption", &PEGTransformerFactory::TransformHeaderOptionInternal}, - {"NullAsOption", &PEGTransformerFactory::TransformNullAsOptionInternal}, - {"DelimiterAsOption", &PEGTransformerFactory::TransformDelimiterAsOptionInternal}, - {"QuoteAsOption", &PEGTransformerFactory::TransformQuoteAsOptionInternal}, - {"EscapeAsOption", &PEGTransformerFactory::TransformEscapeAsOptionInternal}, - {"EncodingOption", &PEGTransformerFactory::TransformEncodingOptionInternal}, - {"ForceQuoteOption", &PEGTransformerFactory::TransformForceQuoteOptionInternal}, - {"StarSymbolColumnList", &PEGTransformerFactory::TransformStarSymbolColumnListInternal}, - {"ForceQuote", &PEGTransformerFactory::TransformForceQuoteInternal}, - {"PartitionByOption", &PEGTransformerFactory::TransformPartitionByOptionInternal}, - {"PartitionByColumnList", &PEGTransformerFactory::TransformPartitionByColumnListInternal}, - {"StarPartitionByColumnList", &PEGTransformerFactory::TransformStarPartitionByColumnListInternal}, - {"ParenthesizedPartitionByColumnList", - &PEGTransformerFactory::TransformParenthesizedPartitionByColumnListInternal}, - {"SinglePartitionByColumnList", &PEGTransformerFactory::TransformSinglePartitionByColumnListInternal}, - {"ForceNullOption", &PEGTransformerFactory::TransformForceNullOptionInternal}, - {"ForceNotNull", &PEGTransformerFactory::TransformForceNotNullInternal}, - {"CopyGenericOptionList", &PEGTransformerFactory::TransformCopyGenericOptionListInternal}, - {"CopyGenericOption", &PEGTransformerFactory::TransformCopyGenericOptionInternal}, - {"OrderByCopyOption", &PEGTransformerFactory::TransformOrderByCopyOptionInternal}, - {"PartitionedByCopyOption", &PEGTransformerFactory::TransformPartitionedByCopyOptionInternal}, - {"GenericCopyOptionList", &PEGTransformerFactory::TransformGenericCopyOptionListInternal}, - {"GenericCopyOption", &PEGTransformerFactory::TransformGenericCopyOptionInternal}, - {"GenericCopyOptionValue", &PEGTransformerFactory::TransformGenericCopyOptionValueInternal}, - {"GenericCopyOptionOrderList", &PEGTransformerFactory::TransformGenericCopyOptionOrderListInternal}, - {"GenericCopyOptionExpression", &PEGTransformerFactory::TransformGenericCopyOptionExpressionInternal}, - {"GenericCopyOptionParenthesizedExpressionList", - &PEGTransformerFactory::TransformGenericCopyOptionParenthesizedExpressionListInternal}, - {"CopyFromDatabase", &PEGTransformerFactory::TransformCopyFromDatabaseInternal}, - {"CopyFromDatabaseWithFlag", &PEGTransformerFactory::TransformCopyFromDatabaseWithFlagInternal}, - {"CopyFromDatabaseWithoutFlag", &PEGTransformerFactory::TransformCopyFromDatabaseWithoutFlagInternal}, - {"CopyDatabaseFlag", &PEGTransformerFactory::TransformCopyDatabaseFlagInternal}, - {"SchemaOrData", &PEGTransformerFactory::TransformSchemaOrDataInternal}, - {"CopySchema", &PEGTransformerFactory::TransformCopySchemaInternal}, - {"CopyData", &PEGTransformerFactory::TransformCopyDataInternal}, - {"CreateIndexStmt", &PEGTransformerFactory::TransformCreateIndexStmtInternal}, - {"WithList", &PEGTransformerFactory::TransformWithListInternal}, - {"RelOptionOrOids", &PEGTransformerFactory::TransformRelOptionOrOidsInternal}, - {"RelOptionList", &PEGTransformerFactory::TransformRelOptionListInternal}, - {"Oids", &PEGTransformerFactory::TransformOidsInternal}, - {"WithOrWithoutOids", &PEGTransformerFactory::TransformWithOrWithoutOidsInternal}, - {"WithOids", &PEGTransformerFactory::TransformWithOidsInternal}, - {"WithoutOids", &PEGTransformerFactory::TransformWithoutOidsInternal}, - {"IndexElement", &PEGTransformerFactory::TransformIndexElementInternal}, - {"UniqueIndex", &PEGTransformerFactory::TransformUniqueIndexInternal}, - {"IndexType", &PEGTransformerFactory::TransformIndexTypeInternal}, - {"RelOption", &PEGTransformerFactory::TransformRelOptionInternal}, - {"RelOptionName", &PEGTransformerFactory::TransformRelOptionNameInternal}, - {"DottedIdentifierString", &PEGTransformerFactory::TransformDottedIdentifierStringInternal}, - {"RelOptionArgumentOpt", &PEGTransformerFactory::TransformRelOptionArgumentOptInternal}, - {"DefArg", &PEGTransformerFactory::TransformDefArgInternal}, - {"DefArgNull", &PEGTransformerFactory::TransformDefArgNullInternal}, - {"DefArgKeyword", &PEGTransformerFactory::TransformDefArgKeywordInternal}, - {"DefArgStringLiteral", &PEGTransformerFactory::TransformDefArgStringLiteralInternal}, - {"NoneLiteral", &PEGTransformerFactory::TransformNoneLiteralInternal}, - {"CreateMacroStmt", &PEGTransformerFactory::TransformCreateMacroStmtInternal}, - {"MacroOrFunction", &PEGTransformerFactory::TransformMacroOrFunctionInternal}, - {"MacroKeyword", &PEGTransformerFactory::TransformMacroKeywordInternal}, - {"FunctionKeyword", &PEGTransformerFactory::TransformFunctionKeywordInternal}, - {"MacroDefinition", &PEGTransformerFactory::TransformMacroDefinitionInternal}, - {"MacroDefinitionBody", &PEGTransformerFactory::TransformMacroDefinitionBodyInternal}, - {"MacroParameters", &PEGTransformerFactory::TransformMacroParametersInternal}, - {"MacroParameter", &PEGTransformerFactory::TransformMacroParameterInternal}, - {"SimpleParameter", &PEGTransformerFactory::TransformSimpleParameterInternal}, - {"ScalarMacroDefinition", &PEGTransformerFactory::TransformScalarMacroDefinitionInternal}, - {"TableMacroDefinition", &PEGTransformerFactory::TransformTableMacroDefinitionInternal}, - {"CreateSchemaStmt", &PEGTransformerFactory::TransformCreateSchemaStmtInternal}, - {"CreateSecretStmt", &PEGTransformerFactory::TransformCreateSecretStmtInternal}, - {"SecretStorageSpecifier", &PEGTransformerFactory::TransformSecretStorageSpecifierInternal}, - {"SecretName", &PEGTransformerFactory::TransformSecretNameInternal}, - {"CreateSequenceStmt", &PEGTransformerFactory::TransformCreateSequenceStmtInternal}, - {"SequenceOption", &PEGTransformerFactory::TransformSequenceOptionInternal}, - {"SeqSetCycle", &PEGTransformerFactory::TransformSeqSetCycleInternal}, - {"SeqCycle", &PEGTransformerFactory::TransformSeqCycleInternal}, - {"SeqNoCycle", &PEGTransformerFactory::TransformSeqNoCycleInternal}, - {"SeqSetIncrement", &PEGTransformerFactory::TransformSeqSetIncrementInternal}, - {"SeqSetMinMax", &PEGTransformerFactory::TransformSeqSetMinMaxInternal}, - {"SeqNoMinMax", &PEGTransformerFactory::TransformSeqNoMinMaxInternal}, - {"SeqStartWith", &PEGTransformerFactory::TransformSeqStartWithInternal}, - {"SeqOwnedBy", &PEGTransformerFactory::TransformSeqOwnedByInternal}, - {"SeqMinOrMax", &PEGTransformerFactory::TransformSeqMinOrMaxInternal}, - {"MinValue", &PEGTransformerFactory::TransformMinValueInternal}, - {"MaxValue", &PEGTransformerFactory::TransformMaxValueInternal}, - {"CreateStatement", &PEGTransformerFactory::TransformCreateStatementInternal}, - {"CreateStatementVariation", &PEGTransformerFactory::TransformCreateStatementVariationInternal}, - {"OrReplace", &PEGTransformerFactory::TransformOrReplaceInternal}, - {"Temporary", &PEGTransformerFactory::TransformTemporaryInternal}, - {"Persistent", &PEGTransformerFactory::TransformPersistentInternal}, - {"TempPersistent", &PEGTransformerFactory::TransformTempPersistentInternal}, - {"TemporaryPersistent", &PEGTransformerFactory::TransformTemporaryPersistentInternal}, - {"CreateTableStmt", &PEGTransformerFactory::TransformCreateTableStmtInternal}, - {"CreateTableDefinition", &PEGTransformerFactory::TransformCreateTableDefinitionInternal}, - {"CreateTableAs", &PEGTransformerFactory::TransformCreateTableAsInternal}, - {"PartitionSortedOptions", &PEGTransformerFactory::TransformPartitionSortedOptionsInternal}, - {"PartitionOptSortedOptions", &PEGTransformerFactory::TransformPartitionOptSortedOptionsInternal}, - {"SortedOptPartitionOptions", &PEGTransformerFactory::TransformSortedOptPartitionOptionsInternal}, - {"PartitionOptions", &PEGTransformerFactory::TransformPartitionOptionsInternal}, - {"SortedOptions", &PEGTransformerFactory::TransformSortedOptionsInternal}, - {"WithData", &PEGTransformerFactory::TransformWithDataInternal}, - {"WithDataOnly", &PEGTransformerFactory::TransformWithDataOnlyInternal}, - {"WithNoData", &PEGTransformerFactory::TransformWithNoDataInternal}, - {"IdentifierList", &PEGTransformerFactory::TransformIdentifierListInternal}, - {"CreateColumnList", &PEGTransformerFactory::TransformCreateColumnListInternal}, - {"IfNotExists", &PEGTransformerFactory::TransformIfNotExistsInternal}, - {"QualifiedName", &PEGTransformerFactory::TransformQualifiedNameInternal}, - {"SchemaReservedIdentifierOrStringLiteral", - &PEGTransformerFactory::TransformSchemaReservedIdentifierOrStringLiteralInternal}, - {"CatalogReservedSchemaIdentifier", &PEGTransformerFactory::TransformCatalogReservedSchemaIdentifierInternal}, - {"IdentifierOrStringLiteral", &PEGTransformerFactory::TransformIdentifierOrStringLiteralInternal}, - {"ReservedIdentifierOrStringLiteral", - &PEGTransformerFactory::TransformReservedIdentifierOrStringLiteralInternal}, - {"CatalogQualification", &PEGTransformerFactory::TransformCatalogQualificationInternal}, - {"SchemaQualification", &PEGTransformerFactory::TransformSchemaQualificationInternal}, - {"ReservedSchemaQualification", &PEGTransformerFactory::TransformReservedSchemaQualificationInternal}, - {"TableQualification", &PEGTransformerFactory::TransformTableQualificationInternal}, - {"ReservedTableQualification", &PEGTransformerFactory::TransformReservedTableQualificationInternal}, - {"CreateTableColumnList", &PEGTransformerFactory::TransformCreateTableColumnListInternal}, - {"CreateTableColumnElement", &PEGTransformerFactory::TransformCreateTableColumnElementInternal}, - {"CreateTableColumnDefinition", &PEGTransformerFactory::TransformCreateTableColumnDefinitionInternal}, - {"CreateTableConstraint", &PEGTransformerFactory::TransformCreateTableConstraintInternal}, - {"ColumnDefinition", &PEGTransformerFactory::TransformColumnDefinitionInternal}, - {"ColumnConstraint", &PEGTransformerFactory::TransformColumnConstraintInternal}, - {"NotNullConstraint", &PEGTransformerFactory::TransformNotNullConstraintInternal}, - {"NullConstraint", &PEGTransformerFactory::TransformNullConstraintInternal}, - {"NotNullColumnConstraint", &PEGTransformerFactory::TransformNotNullColumnConstraintInternal}, - {"UniqueConstraint", &PEGTransformerFactory::TransformUniqueConstraintInternal}, - {"PrimaryKeyConstraint", &PEGTransformerFactory::TransformPrimaryKeyConstraintInternal}, - {"DefaultValue", &PEGTransformerFactory::TransformDefaultValueInternal}, - {"CheckConstraint", &PEGTransformerFactory::TransformCheckConstraintInternal}, - {"ForeignKeyConstraint", &PEGTransformerFactory::TransformForeignKeyConstraintInternal}, - {"ColumnCollation", &PEGTransformerFactory::TransformColumnCollationInternal}, - {"ColumnCompression", &PEGTransformerFactory::TransformColumnCompressionInternal}, - {"KeyActions", &PEGTransformerFactory::TransformKeyActionsInternal}, - {"UpdateAction", &PEGTransformerFactory::TransformUpdateActionInternal}, - {"DeleteAction", &PEGTransformerFactory::TransformDeleteActionInternal}, - {"KeyAction", &PEGTransformerFactory::TransformKeyActionInternal}, - {"NoKeyAction", &PEGTransformerFactory::TransformNoKeyActionInternal}, - {"RestrictKeyAction", &PEGTransformerFactory::TransformRestrictKeyActionInternal}, - {"CascadeKeyAction", &PEGTransformerFactory::TransformCascadeKeyActionInternal}, - {"SetNullKeyAction", &PEGTransformerFactory::TransformSetNullKeyActionInternal}, - {"SetDefaultKeyAction", &PEGTransformerFactory::TransformSetDefaultKeyActionInternal}, - {"TopLevelConstraint", &PEGTransformerFactory::TransformTopLevelConstraintInternal}, - {"TopLevelConstraintList", &PEGTransformerFactory::TransformTopLevelConstraintListInternal}, - {"TopCheckConstraint", &PEGTransformerFactory::TransformTopCheckConstraintInternal}, - {"TopPrimaryKeyConstraint", &PEGTransformerFactory::TransformTopPrimaryKeyConstraintInternal}, - {"TopUniqueConstraint", &PEGTransformerFactory::TransformTopUniqueConstraintInternal}, - {"TopForeignKeyConstraint", &PEGTransformerFactory::TransformTopForeignKeyConstraintInternal}, - {"ColumnIdList", &PEGTransformerFactory::TransformColumnIdListInternal}, - {"DottedIdentifier", &PEGTransformerFactory::TransformDottedIdentifierInternal}, - {"DotColLabel", &PEGTransformerFactory::TransformDotColLabelInternal}, - {"ColId", &PEGTransformerFactory::TransformColIdInternal}, - {"ColIdOrString", &PEGTransformerFactory::TransformColIdOrStringInternal}, - {"TypeFuncName", &PEGTransformerFactory::TransformTypeFuncNameInternal}, - {"TypeFuncKeyword", &PEGTransformerFactory::TransformTypeFuncKeywordInternal}, - {"ColLabel", &PEGTransformerFactory::TransformColLabelInternal}, - {"ColLabelOrString", &PEGTransformerFactory::TransformColLabelOrStringInternal}, - {"ColLabelIdentifier", &PEGTransformerFactory::TransformColLabelIdentifierInternal}, - {"StringLiteralIdentifier", &PEGTransformerFactory::TransformStringLiteralIdentifierInternal}, - {"GeneratedColumn", &PEGTransformerFactory::TransformGeneratedColumnInternal}, - {"GeneratedColumnType", &PEGTransformerFactory::TransformGeneratedColumnTypeInternal}, - {"CommitAction", &PEGTransformerFactory::TransformCommitActionInternal}, - {"PreserveOrDelete", &PEGTransformerFactory::TransformPreserveOrDeleteInternal}, - {"PreserveRows", &PEGTransformerFactory::TransformPreserveRowsInternal}, - {"DeleteRows", &PEGTransformerFactory::TransformDeleteRowsInternal}, - {"VirtualGeneratedColumn", &PEGTransformerFactory::TransformVirtualGeneratedColumnInternal}, - {"StoredGeneratedColumn", &PEGTransformerFactory::TransformStoredGeneratedColumnInternal}, - {"CreateTriggerStmt", &PEGTransformerFactory::TransformCreateTriggerStmtInternal}, - {"TriggerBody", &PEGTransformerFactory::TransformTriggerBodyInternal}, - {"TriggerName", &PEGTransformerFactory::TransformTriggerNameInternal}, - {"ReferencingClause", &PEGTransformerFactory::TransformReferencingClauseInternal}, - {"ReferencingItem", &PEGTransformerFactory::TransformReferencingItemInternal}, - {"ReferencingNewTableAs", &PEGTransformerFactory::TransformReferencingNewTableAsInternal}, - {"ReferencingOldTableAs", &PEGTransformerFactory::TransformReferencingOldTableAsInternal}, - {"TriggerTiming", &PEGTransformerFactory::TransformTriggerTimingInternal}, - {"TriggerBefore", &PEGTransformerFactory::TransformTriggerBeforeInternal}, - {"TriggerAfter", &PEGTransformerFactory::TransformTriggerAfterInternal}, - {"TriggerInsteadOf", &PEGTransformerFactory::TransformTriggerInsteadOfInternal}, - {"TriggerEvent", &PEGTransformerFactory::TransformTriggerEventInternal}, - {"TriggerEventInsert", &PEGTransformerFactory::TransformTriggerEventInsertInternal}, - {"TriggerEventDelete", &PEGTransformerFactory::TransformTriggerEventDeleteInternal}, - {"TriggerEventUpdate", &PEGTransformerFactory::TransformTriggerEventUpdateInternal}, - {"TriggerEventUpdateOf", &PEGTransformerFactory::TransformTriggerEventUpdateOfInternal}, - {"TriggerColumnList", &PEGTransformerFactory::TransformTriggerColumnListInternal}, - {"ForEachClause", &PEGTransformerFactory::TransformForEachClauseInternal}, - {"ForEachRow", &PEGTransformerFactory::TransformForEachRowInternal}, - {"ForEachStatement", &PEGTransformerFactory::TransformForEachStatementInternal}, - {"CreateTypeStmt", &PEGTransformerFactory::TransformCreateTypeStmtInternal}, - {"CreateType", &PEGTransformerFactory::TransformCreateTypeInternal}, - {"CreateTypeFromType", &PEGTransformerFactory::TransformCreateTypeFromTypeInternal}, - {"EnumSelectType", &PEGTransformerFactory::TransformEnumSelectTypeInternal}, - {"EnumStringLiteralList", &PEGTransformerFactory::TransformEnumStringLiteralListInternal}, - {"CreateViewStmt", &PEGTransformerFactory::TransformCreateViewStmtInternal}, - {"CreateRecursive", &PEGTransformerFactory::TransformCreateRecursiveInternal}, - {"CreateSecure", &PEGTransformerFactory::TransformCreateSecureInternal}, - {"DeallocateStatement", &PEGTransformerFactory::TransformDeallocateStatementInternal}, - {"DeallocatePrepare", &PEGTransformerFactory::TransformDeallocatePrepareInternal}, - {"DeleteStatement", &PEGTransformerFactory::TransformDeleteStatementInternal}, - {"TruncateStatement", &PEGTransformerFactory::TransformTruncateStatementInternal}, - {"TargetOptAlias", &PEGTransformerFactory::TransformTargetOptAliasInternal}, - {"DeleteUsingClause", &PEGTransformerFactory::TransformDeleteUsingClauseInternal}, - {"DescribeStatement", &PEGTransformerFactory::TransformDescribeStatementInternal}, - {"ShowDeprecatedSelect", &PEGTransformerFactory::TransformShowDeprecatedSelectInternal}, - {"DescribeSelect", &PEGTransformerFactory::TransformDescribeSelectInternal}, - {"ShowAllTables", &PEGTransformerFactory::TransformShowAllTablesInternal}, - {"ShowTables", &PEGTransformerFactory::TransformShowTablesInternal}, - {"ShowByName", &PEGTransformerFactory::TransformShowByNameInternal}, - {"DescribeByName", &PEGTransformerFactory::TransformDescribeByNameInternal}, - {"DescribeOrSummarize", &PEGTransformerFactory::TransformDescribeOrSummarizeInternal}, - {"ShowTarget", &PEGTransformerFactory::TransformShowTargetInternal}, - {"ShowDeprecatedQualifiedTableName", &PEGTransformerFactory::TransformShowDeprecatedQualifiedTableNameInternal}, - {"ShowSettingName", &PEGTransformerFactory::TransformShowSettingNameInternal}, - {"DescribeTarget", &PEGTransformerFactory::TransformDescribeTargetInternal}, - {"DescribeBaseTableName", &PEGTransformerFactory::TransformDescribeBaseTableNameInternal}, - {"DescribeStringLiteral", &PEGTransformerFactory::TransformDescribeStringLiteralInternal}, - {"Summarize", &PEGTransformerFactory::TransformSummarizeInternal}, - {"SummarizeRule", &PEGTransformerFactory::TransformSummarizeRuleInternal}, - {"ShowOrDescribe", &PEGTransformerFactory::TransformShowOrDescribeInternal}, - {"ShowRule", &PEGTransformerFactory::TransformShowRuleInternal}, - {"DescribeRule", &PEGTransformerFactory::TransformDescribeRuleInternal}, - {"DescribeLongRule", &PEGTransformerFactory::TransformDescribeLongRuleInternal}, - {"DescRule", &PEGTransformerFactory::TransformDescRuleInternal}, - {"DetachStatement", &PEGTransformerFactory::TransformDetachStatementInternal}, - {"DropStatement", &PEGTransformerFactory::TransformDropStatementInternal}, - {"DropEntries", &PEGTransformerFactory::TransformDropEntriesInternal}, - {"DropTrigger", &PEGTransformerFactory::TransformDropTriggerInternal}, - {"DropTable", &PEGTransformerFactory::TransformDropTableInternal}, - {"DropTableFunction", &PEGTransformerFactory::TransformDropTableFunctionInternal}, - {"DropFunction", &PEGTransformerFactory::TransformDropFunctionInternal}, - {"DropSchema", &PEGTransformerFactory::TransformDropSchemaInternal}, - {"DropIndex", &PEGTransformerFactory::TransformDropIndexInternal}, - {"QualifiedIndexName", &PEGTransformerFactory::TransformQualifiedIndexNameInternal}, - {"QualifiedIndexNameString", &PEGTransformerFactory::TransformQualifiedIndexNameStringInternal}, - {"SchemaReservedIndex", &PEGTransformerFactory::TransformSchemaReservedIndexInternal}, - {"CatalogReservedSchemaIndex", &PEGTransformerFactory::TransformCatalogReservedSchemaIndexInternal}, - {"DropSequence", &PEGTransformerFactory::TransformDropSequenceInternal}, - {"DropCollation", &PEGTransformerFactory::TransformDropCollationInternal}, - {"DropType", &PEGTransformerFactory::TransformDropTypeInternal}, - {"DropSecret", &PEGTransformerFactory::TransformDropSecretInternal}, - {"TableOrView", &PEGTransformerFactory::TransformTableOrViewInternal}, - {"MaterializedViewEntry", &PEGTransformerFactory::TransformMaterializedViewEntryInternal}, - {"FunctionTypeMacro", &PEGTransformerFactory::TransformFunctionTypeMacroInternal}, - {"FunctionTypeMacroKeyword", &PEGTransformerFactory::TransformFunctionTypeMacroKeywordInternal}, - {"FunctionTypeFunction", &PEGTransformerFactory::TransformFunctionTypeFunctionInternal}, - {"DropBehavior", &PEGTransformerFactory::TransformDropBehaviorInternal}, - {"CascadeDropBehavior", &PEGTransformerFactory::TransformCascadeDropBehaviorInternal}, - {"RestrictDropBehavior", &PEGTransformerFactory::TransformRestrictDropBehaviorInternal}, - {"IfExists", &PEGTransformerFactory::TransformIfExistsInternal}, - {"DropSecretStorage", &PEGTransformerFactory::TransformDropSecretStorageInternal}, - {"ExecuteStatement", &PEGTransformerFactory::TransformExecuteStatementInternal}, - {"ExplainStatement", &PEGTransformerFactory::TransformExplainStatementInternal}, - {"ExplainOptionList", &PEGTransformerFactory::TransformExplainOptionListInternal}, - {"ExplainOption", &PEGTransformerFactory::TransformExplainOptionInternal}, - {"ExplainOptionName", &PEGTransformerFactory::TransformExplainOptionNameInternal}, - {"ExplainSelectStatement", &PEGTransformerFactory::TransformExplainSelectStatementInternal}, - {"ExplainableStatements", &PEGTransformerFactory::TransformExplainableStatementsInternal}, - {"ExportStatement", &PEGTransformerFactory::TransformExportStatementInternal}, - {"ExportSource", &PEGTransformerFactory::TransformExportSourceInternal}, - {"ImportStatement", &PEGTransformerFactory::TransformImportStatementInternal}, - {"ColumnReference", &PEGTransformerFactory::TransformColumnReferenceInternal}, - {"NestedSchemaTableColumnName", &PEGTransformerFactory::TransformNestedSchemaTableColumnNameInternal}, - {"CatalogReservedSchemaTableColumnName", - &PEGTransformerFactory::TransformCatalogReservedSchemaTableColumnNameInternal}, - {"SchemaReservedTableColumnName", &PEGTransformerFactory::TransformSchemaReservedTableColumnNameInternal}, - {"TableReservedColumnName", &PEGTransformerFactory::TransformTableReservedColumnNameInternal}, - {"FunctionExpression", &PEGTransformerFactory::TransformFunctionExpressionInternal}, - {"FunctionExpressionArguments", &PEGTransformerFactory::TransformFunctionExpressionArgumentsInternal}, - {"FunctionExpressionArgumentList", &PEGTransformerFactory::TransformFunctionExpressionArgumentListInternal}, - {"FunctionArgumentList", &PEGTransformerFactory::TransformFunctionArgumentListInternal}, - {"FunctionIdentifier", &PEGTransformerFactory::TransformFunctionIdentifierInternal}, - {"FunctionNameAsQualifiedName", &PEGTransformerFactory::TransformFunctionNameAsQualifiedNameInternal}, - {"CatalogReservedSchemaFunctionName", - &PEGTransformerFactory::TransformCatalogReservedSchemaFunctionNameInternal}, - {"SchemaReservedFunctionName", &PEGTransformerFactory::TransformSchemaReservedFunctionNameInternal}, - {"DistinctOrAll", &PEGTransformerFactory::TransformDistinctOrAllInternal}, - {"DistinctKeyword", &PEGTransformerFactory::TransformDistinctKeywordInternal}, - {"AllKeyword", &PEGTransformerFactory::TransformAllKeywordInternal}, - {"WithinGroupClause", &PEGTransformerFactory::TransformWithinGroupClauseInternal}, - {"FilterClause", &PEGTransformerFactory::TransformFilterClauseInternal}, - {"FilterClauseExpression", &PEGTransformerFactory::TransformFilterClauseExpressionInternal}, - {"FilterClauseContents", &PEGTransformerFactory::TransformFilterClauseContentsInternal}, - {"IgnoreOrRespectNulls", &PEGTransformerFactory::TransformIgnoreOrRespectNullsInternal}, - {"IgnoreNulls", &PEGTransformerFactory::TransformIgnoreNullsInternal}, - {"RespectNulls", &PEGTransformerFactory::TransformRespectNullsInternal}, - {"ParenthesisExpression", &PEGTransformerFactory::TransformParenthesisExpressionInternal}, - {"LiteralExpression", &PEGTransformerFactory::TransformLiteralExpressionInternal}, - {"ConstantLiteral", &PEGTransformerFactory::TransformConstantLiteralInternal}, - {"NullLiteral", &PEGTransformerFactory::TransformNullLiteralInternal}, - {"TrueLiteral", &PEGTransformerFactory::TransformTrueLiteralInternal}, - {"FalseLiteral", &PEGTransformerFactory::TransformFalseLiteralInternal}, - {"CastExpression", &PEGTransformerFactory::TransformCastExpressionInternal}, - {"CastArguments", &PEGTransformerFactory::TransformCastArgumentsInternal}, - {"CastOrTryCast", &PEGTransformerFactory::TransformCastOrTryCastInternal}, - {"CastKeyword", &PEGTransformerFactory::TransformCastKeywordInternal}, - {"TryCastKeyword", &PEGTransformerFactory::TransformTryCastKeywordInternal}, - {"ColIdDot", &PEGTransformerFactory::TransformColIdDotInternal}, - {"StarExpression", &PEGTransformerFactory::TransformStarExpressionInternal}, - {"StarQualifierList", &PEGTransformerFactory::TransformStarQualifierListInternal}, - {"ExcludeList", &PEGTransformerFactory::TransformExcludeListInternal}, - {"ExcludeNames", &PEGTransformerFactory::TransformExcludeNamesInternal}, - {"ExcludeNameList", &PEGTransformerFactory::TransformExcludeNameListInternal}, - {"ExcludeNameSingle", &PEGTransformerFactory::TransformExcludeNameSingleInternal}, - {"ExcludeName", &PEGTransformerFactory::TransformExcludeNameInternal}, - {"ExcludeDottedName", &PEGTransformerFactory::TransformExcludeDottedNameInternal}, - {"ExcludeColumnName", &PEGTransformerFactory::TransformExcludeColumnNameInternal}, - {"ReplaceList", &PEGTransformerFactory::TransformReplaceListInternal}, - {"ReplaceEntries", &PEGTransformerFactory::TransformReplaceEntriesInternal}, - {"ReplaceEntrySingle", &PEGTransformerFactory::TransformReplaceEntrySingleInternal}, - {"ReplaceEntryList", &PEGTransformerFactory::TransformReplaceEntryListInternal}, - {"ReplaceEntry", &PEGTransformerFactory::TransformReplaceEntryInternal}, - {"RenameList", &PEGTransformerFactory::TransformRenameListInternal}, - {"RenameEntries", &PEGTransformerFactory::TransformRenameEntriesInternal}, - {"RenameEntryList", &PEGTransformerFactory::TransformRenameEntryListInternal}, - {"SingleRenameEntry", &PEGTransformerFactory::TransformSingleRenameEntryInternal}, - {"RenameEntry", &PEGTransformerFactory::TransformRenameEntryInternal}, - {"SubqueryExpression", &PEGTransformerFactory::TransformSubqueryExpressionInternal}, - {"SubqueryNot", &PEGTransformerFactory::TransformSubqueryNotInternal}, - {"SubqueryExists", &PEGTransformerFactory::TransformSubqueryExistsInternal}, - {"CaseExpression", &PEGTransformerFactory::TransformCaseExpressionInternal}, - {"CaseWhenThen", &PEGTransformerFactory::TransformCaseWhenThenInternal}, - {"CaseElse", &PEGTransformerFactory::TransformCaseElseInternal}, - {"TypeLiteral", &PEGTransformerFactory::TransformTypeLiteralInternal}, - {"IntervalLiteral", &PEGTransformerFactory::TransformIntervalLiteralInternal}, - {"IntervalParameter", &PEGTransformerFactory::TransformIntervalParameterInternal}, - {"IntervalStringParameter", &PEGTransformerFactory::TransformIntervalStringParameterInternal}, - {"FrameClause", &PEGTransformerFactory::TransformFrameClauseInternal}, - {"Framing", &PEGTransformerFactory::TransformFramingInternal}, - {"RowsFraming", &PEGTransformerFactory::TransformRowsFramingInternal}, - {"RangeFraming", &PEGTransformerFactory::TransformRangeFramingInternal}, - {"GroupsFraming", &PEGTransformerFactory::TransformGroupsFramingInternal}, - {"FrameExtent", &PEGTransformerFactory::TransformFrameExtentInternal}, - {"SingleFrameExtent", &PEGTransformerFactory::TransformSingleFrameExtentInternal}, - {"BetweenFrameExtent", &PEGTransformerFactory::TransformBetweenFrameExtentInternal}, - {"FrameBound", &PEGTransformerFactory::TransformFrameBoundInternal}, - {"FrameUnbounded", &PEGTransformerFactory::TransformFrameUnboundedInternal}, - {"FrameExpression", &PEGTransformerFactory::TransformFrameExpressionInternal}, - {"FrameCurrentRow", &PEGTransformerFactory::TransformFrameCurrentRowInternal}, - {"PrecedingOrFollowing", &PEGTransformerFactory::TransformPrecedingOrFollowingInternal}, - {"PrecedingFrame", &PEGTransformerFactory::TransformPrecedingFrameInternal}, - {"FollowingFrame", &PEGTransformerFactory::TransformFollowingFrameInternal}, - {"WindowExcludeClause", &PEGTransformerFactory::TransformWindowExcludeClauseInternal}, - {"WindowExcludeElement", &PEGTransformerFactory::TransformWindowExcludeElementInternal}, - {"ExcludeCurrentRow", &PEGTransformerFactory::TransformExcludeCurrentRowInternal}, - {"ExcludeGroup", &PEGTransformerFactory::TransformExcludeGroupInternal}, - {"ExcludeTies", &PEGTransformerFactory::TransformExcludeTiesInternal}, - {"ExcludeNoOthers", &PEGTransformerFactory::TransformExcludeNoOthersInternal}, - {"WindowFrame", &PEGTransformerFactory::TransformWindowFrameInternal}, - {"IdentifierWindowFrame", &PEGTransformerFactory::TransformIdentifierWindowFrameInternal}, - {"ParensIdentifier", &PEGTransformerFactory::TransformParensIdentifierInternal}, - {"WindowFrameDefinition", &PEGTransformerFactory::TransformWindowFrameDefinitionInternal}, - {"WindowFrameNameContentsParens", &PEGTransformerFactory::TransformWindowFrameNameContentsParensInternal}, - {"WindowFrameNameContents", &PEGTransformerFactory::TransformWindowFrameNameContentsInternal}, - {"WindowFrameContentsParens", &PEGTransformerFactory::TransformWindowFrameContentsParensInternal}, - {"WindowFrameContents", &PEGTransformerFactory::TransformWindowFrameContentsInternal}, - {"BaseWindowName", &PEGTransformerFactory::TransformBaseWindowNameInternal}, - {"WindowPartition", &PEGTransformerFactory::TransformWindowPartitionInternal}, - {"ListExpression", &PEGTransformerFactory::TransformListExpressionInternal}, - {"ArrayBoundedListExpression", &PEGTransformerFactory::TransformArrayBoundedListExpressionInternal}, - {"ArrayParensSelect", &PEGTransformerFactory::TransformArrayParensSelectInternal}, - {"BoundedListExpression", &PEGTransformerFactory::TransformBoundedListExpressionInternal}, - {"StructExpression", &PEGTransformerFactory::TransformStructExpressionInternal}, - {"StructField", &PEGTransformerFactory::TransformStructFieldInternal}, - {"MapExpression", &PEGTransformerFactory::TransformMapExpressionInternal}, - {"MapStructExpression", &PEGTransformerFactory::TransformMapStructExpressionInternal}, - {"MapStructField", &PEGTransformerFactory::TransformMapStructFieldInternal}, - {"GroupingExpression", &PEGTransformerFactory::TransformGroupingExpressionInternal}, - {"GroupingOrGroupingId", &PEGTransformerFactory::TransformGroupingOrGroupingIdInternal}, - {"GroupingKeyword", &PEGTransformerFactory::TransformGroupingKeywordInternal}, - {"GroupingIdKeyword", &PEGTransformerFactory::TransformGroupingIdKeywordInternal}, - {"Parameter", &PEGTransformerFactory::TransformParameterInternal}, - {"QuestionMarkNumberedParameter", &PEGTransformerFactory::TransformQuestionMarkNumberedParameterInternal}, - {"AnonymousParameter", &PEGTransformerFactory::TransformAnonymousParameterInternal}, - {"NumberedParameter", &PEGTransformerFactory::TransformNumberedParameterInternal}, - {"ColLabelParameter", &PEGTransformerFactory::TransformColLabelParameterInternal}, - {"PositionalExpression", &PEGTransformerFactory::TransformPositionalExpressionInternal}, - {"DefaultExpression", &PEGTransformerFactory::TransformDefaultExpressionInternal}, - {"ListComprehensionExpression", &PEGTransformerFactory::TransformListComprehensionExpressionInternal}, - {"ListComprehensionFilter", &PEGTransformerFactory::TransformListComprehensionFilterInternal}, - {"ParensExpression", &PEGTransformerFactory::TransformParensExpressionInternal}, - {"SingleExpression", &PEGTransformerFactory::TransformSingleExpressionInternal}, - {"Expression", &PEGTransformerFactory::TransformExpressionInternal}, - {"ColumnDefaultExpr", &PEGTransformerFactory::TransformColumnDefaultExprInternal}, - {"LambdaArrowExpression", &PEGTransformerFactory::TransformLambdaArrowExpressionInternal}, - {"SingleArrowPair", &PEGTransformerFactory::TransformSingleArrowPairInternal}, - {"LogicalOrExpression", &PEGTransformerFactory::TransformLogicalOrExpressionInternal}, - {"LogicalOrExpressionTail", &PEGTransformerFactory::TransformLogicalOrExpressionTailInternal}, - {"ColDefOrExpr", &PEGTransformerFactory::TransformColDefOrExprInternal}, - {"ColDefOrExpressionTail", &PEGTransformerFactory::TransformColDefOrExpressionTailInternal}, - {"LogicalAndExpression", &PEGTransformerFactory::TransformLogicalAndExpressionInternal}, - {"LogicalAndExpressionTail", &PEGTransformerFactory::TransformLogicalAndExpressionTailInternal}, - {"ColDefAndExpr", &PEGTransformerFactory::TransformColDefAndExprInternal}, - {"ColDefAndExpressionTail", &PEGTransformerFactory::TransformColDefAndExpressionTailInternal}, - {"LogicalNotExpression", &PEGTransformerFactory::TransformLogicalNotExpressionInternal}, - {"NotExpression", &PEGTransformerFactory::TransformNotExpressionInternal}, - {"NotKeyword", &PEGTransformerFactory::TransformNotKeywordInternal}, - {"IsExpression", &PEGTransformerFactory::TransformIsExpressionInternal}, - {"IsTest", &PEGTransformerFactory::TransformIsTestInternal}, - {"IsLiteral", &PEGTransformerFactory::TransformIsLiteralInternal}, - {"IsLiteralValue", &PEGTransformerFactory::TransformIsLiteralValueInternal}, - {"UnknownLiteral", &PEGTransformerFactory::TransformUnknownLiteralInternal}, - {"NotNull", &PEGTransformerFactory::TransformNotNullInternal}, - {"NotNullKeyword", &PEGTransformerFactory::TransformNotNullKeywordInternal}, - {"NotNullOperator", &PEGTransformerFactory::TransformNotNullOperatorInternal}, - {"IsNull", &PEGTransformerFactory::TransformIsNullInternal}, - {"IsNullOperator", &PEGTransformerFactory::TransformIsNullOperatorInternal}, - {"IsDistinctFromExpression", &PEGTransformerFactory::TransformIsDistinctFromExpressionInternal}, - {"IsDistinctFromTail", &PEGTransformerFactory::TransformIsDistinctFromTailInternal}, - {"IsDistinctFromOp", &PEGTransformerFactory::TransformIsDistinctFromOpInternal}, - {"ComparisonExpression", &PEGTransformerFactory::TransformComparisonExpressionInternal}, - {"ComparisonExpressionTail", &PEGTransformerFactory::TransformComparisonExpressionTailInternal}, - {"ComparisonOperator", &PEGTransformerFactory::TransformComparisonOperatorInternal}, - {"OperatorEqual", &PEGTransformerFactory::TransformOperatorEqualInternal}, - {"OperatorNotEqual", &PEGTransformerFactory::TransformOperatorNotEqualInternal}, - {"OperatorLessThan", &PEGTransformerFactory::TransformOperatorLessThanInternal}, - {"OperatorGreaterThan", &PEGTransformerFactory::TransformOperatorGreaterThanInternal}, - {"OperatorLessThanEquals", &PEGTransformerFactory::TransformOperatorLessThanEqualsInternal}, - {"OperatorGreaterThanEquals", &PEGTransformerFactory::TransformOperatorGreaterThanEqualsInternal}, - {"BetweenInLikeExpression", &PEGTransformerFactory::TransformBetweenInLikeExpressionInternal}, - {"BetweenInLikeOp", &PEGTransformerFactory::TransformBetweenInLikeOpInternal}, - {"BetweenInLikeOpExpression", &PEGTransformerFactory::TransformBetweenInLikeOpExpressionInternal}, - {"LikeClause", &PEGTransformerFactory::TransformLikeClauseInternal}, - {"EscapeClause", &PEGTransformerFactory::TransformEscapeClauseInternal}, - {"LikeVariations", &PEGTransformerFactory::TransformLikeVariationsInternal}, - {"LikeToken", &PEGTransformerFactory::TransformLikeTokenInternal}, - {"ILikeToken", &PEGTransformerFactory::TransformILikeTokenInternal}, - {"GlobToken", &PEGTransformerFactory::TransformGlobTokenInternal}, - {"SimilarToToken", &PEGTransformerFactory::TransformSimilarToTokenInternal}, - {"RegexMatchToken", &PEGTransformerFactory::TransformRegexMatchTokenInternal}, - {"RegexInsensitiveMatchToken", &PEGTransformerFactory::TransformRegexInsensitiveMatchTokenInternal}, - {"NotILikeOp", &PEGTransformerFactory::TransformNotILikeOpInternal}, - {"NotLikeOp", &PEGTransformerFactory::TransformNotLikeOpInternal}, - {"NotRegexInsensitiveMatchOp", &PEGTransformerFactory::TransformNotRegexInsensitiveMatchOpInternal}, - {"NotSimilarToOp", &PEGTransformerFactory::TransformNotSimilarToOpInternal}, - {"InClause", &PEGTransformerFactory::TransformInClauseInternal}, - {"InExpression", &PEGTransformerFactory::TransformInExpressionInternal}, - {"InContainsExpression", &PEGTransformerFactory::TransformInContainsExpressionInternal}, - {"InExpressionList", &PEGTransformerFactory::TransformInExpressionListInternal}, - {"InSelectStatement", &PEGTransformerFactory::TransformInSelectStatementInternal}, - {"BetweenClause", &PEGTransformerFactory::TransformBetweenClauseInternal}, - {"OtherOperatorExpression", &PEGTransformerFactory::TransformOtherOperatorExpressionInternal}, - {"OtherOperatorTail", &PEGTransformerFactory::TransformOtherOperatorTailInternal}, - {"OtherOperator", &PEGTransformerFactory::TransformOtherOperatorInternal}, - {"AnyAllParsedOperator", &PEGTransformerFactory::TransformAnyAllParsedOperatorInternal}, - {"NamedOtherOperator", &PEGTransformerFactory::TransformNamedOtherOperatorInternal}, - {"AnyAllOperator", &PEGTransformerFactory::TransformAnyAllOperatorInternal}, - {"AnyOrAll", &PEGTransformerFactory::TransformAnyOrAllInternal}, - {"SubqueryAny", &PEGTransformerFactory::TransformSubqueryAnyInternal}, - {"SubqueryAll", &PEGTransformerFactory::TransformSubqueryAllInternal}, - {"InetOperator", &PEGTransformerFactory::TransformInetOperatorInternal}, - {"JsonOperator", &PEGTransformerFactory::TransformJsonOperatorInternal}, - {"ListOperator", &PEGTransformerFactory::TransformListOperatorInternal}, - {"StringOperator", &PEGTransformerFactory::TransformStringOperatorInternal}, - {"QualifiedOperator", &PEGTransformerFactory::TransformQualifiedOperatorInternal}, - {"QualifiedOperatorContents", &PEGTransformerFactory::TransformQualifiedOperatorContentsInternal}, - {"AnyOp", &PEGTransformerFactory::TransformAnyOpInternal}, - {"BitwiseExpression", &PEGTransformerFactory::TransformBitwiseExpressionInternal}, - {"BitwiseExpressionTail", &PEGTransformerFactory::TransformBitwiseExpressionTailInternal}, - {"BitOperator", &PEGTransformerFactory::TransformBitOperatorInternal}, - {"AdditiveExpression", &PEGTransformerFactory::TransformAdditiveExpressionInternal}, - {"AdditiveExpressionTail", &PEGTransformerFactory::TransformAdditiveExpressionTailInternal}, - {"Term", &PEGTransformerFactory::TransformTermInternal}, - {"MultiplicativeExpression", &PEGTransformerFactory::TransformMultiplicativeExpressionInternal}, - {"MultiplicativeExpressionTail", &PEGTransformerFactory::TransformMultiplicativeExpressionTailInternal}, - {"Factor", &PEGTransformerFactory::TransformFactorInternal}, - {"ExponentiationExpression", &PEGTransformerFactory::TransformExponentiationExpressionInternal}, - {"ExponentiationExpressionTail", &PEGTransformerFactory::TransformExponentiationExpressionTailInternal}, - {"ExponentOperator", &PEGTransformerFactory::TransformExponentOperatorInternal}, - {"CollateExpression", &PEGTransformerFactory::TransformCollateExpressionInternal}, - {"CollateExpressionTail", &PEGTransformerFactory::TransformCollateExpressionTailInternal}, - {"AtTimeZoneExpression", &PEGTransformerFactory::TransformAtTimeZoneExpressionInternal}, - {"AtTimeZoneExpressionTail", &PEGTransformerFactory::TransformAtTimeZoneExpressionTailInternal}, - {"PrefixOperator", &PEGTransformerFactory::TransformPrefixOperatorInternal}, - {"MinusPrefixOperator", &PEGTransformerFactory::TransformMinusPrefixOperatorInternal}, - {"PlusPrefixOperator", &PEGTransformerFactory::TransformPlusPrefixOperatorInternal}, - {"TildePrefixOperator", &PEGTransformerFactory::TransformTildePrefixOperatorInternal}, - {"BaseExpression", &PEGTransformerFactory::TransformBaseExpressionInternal}, - {"IndirectionList", &PEGTransformerFactory::TransformIndirectionListInternal}, - {"Indirection", &PEGTransformerFactory::TransformIndirectionInternal}, - {"CastOperator", &PEGTransformerFactory::TransformCastOperatorInternal}, - {"DotOperator", &PEGTransformerFactory::TransformDotOperatorInternal}, - {"DotMethodOperator", &PEGTransformerFactory::TransformDotMethodOperatorInternal}, - {"DotColumnOperator", &PEGTransformerFactory::TransformDotColumnOperatorInternal}, - {"MethodExpression", &PEGTransformerFactory::TransformMethodExpressionInternal}, - {"MethodExpressionArguments", &PEGTransformerFactory::TransformMethodExpressionArgumentsInternal}, - {"MethodExpressionArgumentList", &PEGTransformerFactory::TransformMethodExpressionArgumentListInternal}, - {"MethodFunctionArguments", &PEGTransformerFactory::TransformMethodFunctionArgumentsInternal}, - {"SliceExpression", &PEGTransformerFactory::TransformSliceExpressionInternal}, - {"SliceBound", &PEGTransformerFactory::TransformSliceBoundInternal}, - {"EndSliceBound", &PEGTransformerFactory::TransformEndSliceBoundInternal}, - {"EndSliceValue", &PEGTransformerFactory::TransformEndSliceValueInternal}, - {"EndSliceMinus", &PEGTransformerFactory::TransformEndSliceMinusInternal}, - {"StepSliceBound", &PEGTransformerFactory::TransformStepSliceBoundInternal}, - {"PostfixOperator", &PEGTransformerFactory::TransformPostfixOperatorInternal}, - {"SpecialFunctionExpression", &PEGTransformerFactory::TransformSpecialFunctionExpressionInternal}, - {"CoalesceExpression", &PEGTransformerFactory::TransformCoalesceExpressionInternal}, - {"UnpackExpression", &PEGTransformerFactory::TransformUnpackExpressionInternal}, - {"TryExpression", &PEGTransformerFactory::TransformTryExpressionInternal}, - {"ColumnsExpression", &PEGTransformerFactory::TransformColumnsExpressionInternal}, - {"ExtractExpression", &PEGTransformerFactory::TransformExtractExpressionInternal}, - {"ExtractArguments", &PEGTransformerFactory::TransformExtractArgumentsInternal}, - {"LambdaExpression", &PEGTransformerFactory::TransformLambdaExpressionInternal}, - {"NullIfExpression", &PEGTransformerFactory::TransformNullIfExpressionInternal}, - {"NullIfArguments", &PEGTransformerFactory::TransformNullIfArgumentsInternal}, - {"PositionExpression", &PEGTransformerFactory::TransformPositionExpressionInternal}, - {"PositionArguments", &PEGTransformerFactory::TransformPositionArgumentsInternal}, - {"RowExpression", &PEGTransformerFactory::TransformRowExpressionInternal}, - {"SubstringExpression", &PEGTransformerFactory::TransformSubstringExpressionInternal}, - {"SubstringArguments", &PEGTransformerFactory::TransformSubstringArgumentsInternal}, - {"SubstringExpressionList", &PEGTransformerFactory::TransformSubstringExpressionListInternal}, - {"SubstringParameters", &PEGTransformerFactory::TransformSubstringParametersInternal}, - {"SubstringFromFor", &PEGTransformerFactory::TransformSubstringFromForInternal}, - {"SubstringFromOptionalFor", &PEGTransformerFactory::TransformSubstringFromOptionalForInternal}, - {"SubstringFor", &PEGTransformerFactory::TransformSubstringForInternal}, - {"TrimExpression", &PEGTransformerFactory::TransformTrimExpressionInternal}, - {"TrimArguments", &PEGTransformerFactory::TransformTrimArgumentsInternal}, - {"TrimDirection", &PEGTransformerFactory::TransformTrimDirectionInternal}, - {"TrimBoth", &PEGTransformerFactory::TransformTrimBothInternal}, - {"TrimLeading", &PEGTransformerFactory::TransformTrimLeadingInternal}, - {"TrimTrailing", &PEGTransformerFactory::TransformTrimTrailingInternal}, - {"TrimSource", &PEGTransformerFactory::TransformTrimSourceInternal}, - {"OverlayExpression", &PEGTransformerFactory::TransformOverlayExpressionInternal}, - {"OverlayArguments", &PEGTransformerFactory::TransformOverlayArgumentsInternal}, - {"OverlayParameters", &PEGTransformerFactory::TransformOverlayParametersInternal}, - {"FromExpression", &PEGTransformerFactory::TransformFromExpressionInternal}, - {"ForExpression", &PEGTransformerFactory::TransformForExpressionInternal}, - {"OverlayExpressionList", &PEGTransformerFactory::TransformOverlayExpressionListInternal}, - {"ExtractArgument", &PEGTransformerFactory::TransformExtractArgumentInternal}, - {"ExtractDatePartArgument", &PEGTransformerFactory::TransformExtractDatePartArgumentInternal}, - {"ExtractIdentifierArgument", &PEGTransformerFactory::TransformExtractIdentifierArgumentInternal}, - {"ExtractStringArgument", &PEGTransformerFactory::TransformExtractStringArgumentInternal}, - {"ExtractDatePart", &PEGTransformerFactory::TransformExtractDatePartInternal}, - {"ExternalResourceStatement", &PEGTransformerFactory::TransformExternalResourceStatementInternal}, - {"CreateExternalResourceStmt", &PEGTransformerFactory::TransformCreateExternalResourceStmtInternal}, - {"RegisterExternalResourceStmt", &PEGTransformerFactory::TransformRegisterExternalResourceStmtInternal}, - {"DestroyExternalResourceStmt", &PEGTransformerFactory::TransformDestroyExternalResourceStmtInternal}, - {"ShowExternalResourcesStmt", &PEGTransformerFactory::TransformShowExternalResourcesStmtInternal}, - {"ShowAllModifier", &PEGTransformerFactory::TransformShowAllModifierInternal}, - {"ExternalResourceCreationOptions", &PEGTransformerFactory::TransformExternalResourceCreationOptionsInternal}, - {"InsertStatement", &PEGTransformerFactory::TransformInsertStatementInternal}, - {"OrAction", &PEGTransformerFactory::TransformOrActionInternal}, - {"InsertOrReplace", &PEGTransformerFactory::TransformInsertOrReplaceInternal}, - {"InsertOrIgnore", &PEGTransformerFactory::TransformInsertOrIgnoreInternal}, - {"ByNameOrPosition", &PEGTransformerFactory::TransformByNameOrPositionInternal}, - {"InsertByNameOrder", &PEGTransformerFactory::TransformInsertByNameOrderInternal}, - {"InsertByPositionOrder", &PEGTransformerFactory::TransformInsertByPositionOrderInternal}, - {"InsertByName", &PEGTransformerFactory::TransformInsertByNameInternal}, - {"InsertByPosition", &PEGTransformerFactory::TransformInsertByPositionInternal}, - {"InsertTarget", &PEGTransformerFactory::TransformInsertTargetInternal}, - {"InsertAlias", &PEGTransformerFactory::TransformInsertAliasInternal}, - {"ColumnList", &PEGTransformerFactory::TransformColumnListInternal}, - {"InsertColumnList", &PEGTransformerFactory::TransformInsertColumnListInternal}, - {"InsertValues", &PEGTransformerFactory::TransformInsertValuesInternal}, - {"SelectInsertValues", &PEGTransformerFactory::TransformSelectInsertValuesInternal}, - {"DefaultValues", &PEGTransformerFactory::TransformDefaultValuesInternal}, - {"OnConflictClause", &PEGTransformerFactory::TransformOnConflictClauseInternal}, - {"OnConflictTarget", &PEGTransformerFactory::TransformOnConflictTargetInternal}, - {"OnConflictExpressionTarget", &PEGTransformerFactory::TransformOnConflictExpressionTargetInternal}, - {"OnConflictIndexTarget", &PEGTransformerFactory::TransformOnConflictIndexTargetInternal}, - {"OnConflictAction", &PEGTransformerFactory::TransformOnConflictActionInternal}, - {"OnConflictUpdate", &PEGTransformerFactory::TransformOnConflictUpdateInternal}, - {"OnConflictNothing", &PEGTransformerFactory::TransformOnConflictNothingInternal}, - {"ReturningClause", &PEGTransformerFactory::TransformReturningClauseInternal}, - {"LoadStatement", &PEGTransformerFactory::TransformLoadStatementInternal}, - {"ExtensionAlias", &PEGTransformerFactory::TransformExtensionAliasInternal}, - {"InstallStatement", &PEGTransformerFactory::TransformInstallStatementInternal}, - {"InstallAndLoad", &PEGTransformerFactory::TransformInstallAndLoadInternal}, - {"UpdateExtensionsStatement", &PEGTransformerFactory::TransformUpdateExtensionsStatementInternal}, - {"FromSource", &PEGTransformerFactory::TransformFromSourceInternal}, - {"FromSourceIdentifier", &PEGTransformerFactory::TransformFromSourceIdentifierInternal}, - {"FromSourceString", &PEGTransformerFactory::TransformFromSourceStringInternal}, - {"VersionNumber", &PEGTransformerFactory::TransformVersionNumberInternal}, - {"ExtensionRepositoryStatement", &PEGTransformerFactory::TransformExtensionRepositoryStatementInternal}, - {"CreateExtensionRepositoryStmt", &PEGTransformerFactory::TransformCreateExtensionRepositoryStmtInternal}, - {"RepositoryPrefix", &PEGTransformerFactory::TransformRepositoryPrefixInternal}, - {"RepositoryPublicKey", &PEGTransformerFactory::TransformRepositoryPublicKeyInternal}, - {"DropExtensionRepositoryStmt", &PEGTransformerFactory::TransformDropExtensionRepositoryStmtInternal}, - {"MergeIntoStatement", &PEGTransformerFactory::TransformMergeIntoStatementInternal}, - {"MergeIntoUsingClause", &PEGTransformerFactory::TransformMergeIntoUsingClauseInternal}, - {"MergeMatch", &PEGTransformerFactory::TransformMergeMatchInternal}, - {"MatchedClause", &PEGTransformerFactory::TransformMatchedClauseInternal}, - {"MatchedClauseAction", &PEGTransformerFactory::TransformMatchedClauseActionInternal}, - {"UpdateMatchClause", &PEGTransformerFactory::TransformUpdateMatchClauseInternal}, - {"UpdateMatchInfo", &PEGTransformerFactory::TransformUpdateMatchInfoInternal}, - {"UpdateMatchSetAction", &PEGTransformerFactory::TransformUpdateMatchSetActionInternal}, - {"UpdateByNameOrPosition", &PEGTransformerFactory::TransformUpdateByNameOrPositionInternal}, - {"DeleteMatchClause", &PEGTransformerFactory::TransformDeleteMatchClauseInternal}, - {"InsertMatchClause", &PEGTransformerFactory::TransformInsertMatchClauseInternal}, - {"InsertMatchInfo", &PEGTransformerFactory::TransformInsertMatchInfoInternal}, - {"InsertDefaultValues", &PEGTransformerFactory::TransformInsertDefaultValuesInternal}, - {"InsertByNameOrPosition", &PEGTransformerFactory::TransformInsertByNameOrPositionInternal}, - {"InsertValuesList", &PEGTransformerFactory::TransformInsertValuesListInternal}, - {"DoNothingMatchClause", &PEGTransformerFactory::TransformDoNothingMatchClauseInternal}, - {"ErrorMatchClause", &PEGTransformerFactory::TransformErrorMatchClauseInternal}, - {"UpdateMatchSetClause", &PEGTransformerFactory::TransformUpdateMatchSetClauseInternal}, - {"UpdateMatchSetInfo", &PEGTransformerFactory::TransformUpdateMatchSetInfoInternal}, - {"AndExpression", &PEGTransformerFactory::TransformAndExpressionInternal}, - {"NotMatchedClause", &PEGTransformerFactory::TransformNotMatchedClauseInternal}, - {"BySourceOrTarget", &PEGTransformerFactory::TransformBySourceOrTargetInternal}, - {"BySource", &PEGTransformerFactory::TransformBySourceInternal}, - {"ByTarget", &PEGTransformerFactory::TransformByTargetInternal}, - {"PivotOn", &PEGTransformerFactory::TransformPivotOnInternal}, - {"PivotUsing", &PEGTransformerFactory::TransformPivotUsingInternal}, - {"PivotColumnList", &PEGTransformerFactory::TransformPivotColumnListInternal}, - {"PivotColumnEntry", &PEGTransformerFactory::TransformPivotColumnEntryInternal}, - {"PivotColumnExpression", &PEGTransformerFactory::TransformPivotColumnExpressionInternal}, - {"PivotColumnSubquery", &PEGTransformerFactory::TransformPivotColumnSubqueryInternal}, - {"IntoNameValues", &PEGTransformerFactory::TransformIntoNameValuesInternal}, - {"OptionalParensNameList", &PEGTransformerFactory::TransformOptionalParensNameListInternal}, - {"ParenthesizedNameList", &PEGTransformerFactory::TransformParenthesizedNameListInternal}, - {"BareNameList", &PEGTransformerFactory::TransformBareNameListInternal}, - {"IncludeOrExcludeNulls", &PEGTransformerFactory::TransformIncludeOrExcludeNullsInternal}, - {"IncludeNulls", &PEGTransformerFactory::TransformIncludeNullsInternal}, - {"ExcludeNulls", &PEGTransformerFactory::TransformExcludeNullsInternal}, - {"UnpivotHeader", &PEGTransformerFactory::TransformUnpivotHeaderInternal}, - {"UnpivotHeaderSingle", &PEGTransformerFactory::TransformUnpivotHeaderSingleInternal}, - {"UnpivotHeaderList", &PEGTransformerFactory::TransformUnpivotHeaderListInternal}, - {"PragmaStatement", &PEGTransformerFactory::TransformPragmaStatementInternal}, - {"PragmaAssignOrFunction", &PEGTransformerFactory::TransformPragmaAssignOrFunctionInternal}, - {"PragmaAssign", &PEGTransformerFactory::TransformPragmaAssignInternal}, - {"PragmaFunction", &PEGTransformerFactory::TransformPragmaFunctionInternal}, - {"PragmaParameters", &PEGTransformerFactory::TransformPragmaParametersInternal}, - {"PrepareStatement", &PEGTransformerFactory::TransformPrepareStatementInternal}, - {"TypeList", &PEGTransformerFactory::TransformTypeListInternal}, - {"SelectStatement", &PEGTransformerFactory::TransformSelectStatementInternal}, - {"SelectSetOpChain", &PEGTransformerFactory::TransformSelectSetOpChainInternal}, - {"SelectSetOpChainTail", &PEGTransformerFactory::TransformSelectSetOpChainTailInternal}, - {"IntersectChain", &PEGTransformerFactory::TransformIntersectChainInternal}, - {"IntersectChainTail", &PEGTransformerFactory::TransformIntersectChainTailInternal}, - {"SetIntersectClause", &PEGTransformerFactory::TransformSetIntersectClauseInternal}, - {"SelectAtom", &PEGTransformerFactory::TransformSelectAtomInternal}, - {"SelectParens", &PEGTransformerFactory::TransformSelectParensInternal}, - {"SetopClause", &PEGTransformerFactory::TransformSetopClauseInternal}, - {"SetopType", &PEGTransformerFactory::TransformSetopTypeInternal}, - {"SetopUnion", &PEGTransformerFactory::TransformSetopUnionInternal}, - {"SetopExcept", &PEGTransformerFactory::TransformSetopExceptInternal}, - {"SelectStatementType", &PEGTransformerFactory::TransformSelectStatementTypeInternal}, - {"ResultModifiers", &PEGTransformerFactory::TransformResultModifiersInternal}, - {"LimitOffset", &PEGTransformerFactory::TransformLimitOffsetInternal}, - {"LimitOffsetClause", &PEGTransformerFactory::TransformLimitOffsetClauseInternal}, - {"OffsetLimitClause", &PEGTransformerFactory::TransformOffsetLimitClauseInternal}, - {"OffsetFetchClause", &PEGTransformerFactory::TransformOffsetFetchClauseInternal}, - {"FetchOnlyClause", &PEGTransformerFactory::TransformFetchOnlyClauseInternal}, - {"TableStatement", &PEGTransformerFactory::TransformTableStatementInternal}, - {"OptionalParensSimpleSelect", &PEGTransformerFactory::TransformOptionalParensSimpleSelectInternal}, - {"SimpleSelectParens", &PEGTransformerFactory::TransformSimpleSelectParensInternal}, - {"SelectFrom", &PEGTransformerFactory::TransformSelectFromInternal}, - {"SelectFromClause", &PEGTransformerFactory::TransformSelectFromClauseInternal}, - {"FromSelectClause", &PEGTransformerFactory::TransformFromSelectClauseInternal}, - {"WithStatement", &PEGTransformerFactory::TransformWithStatementInternal}, - {"CTEBody", &PEGTransformerFactory::TransformCTEBodyInternal}, - {"CTESelectBody", &PEGTransformerFactory::TransformCTESelectBodyInternal}, - {"CTEDMLBody", &PEGTransformerFactory::TransformCTEDMLBodyInternal}, - {"UsingKey", &PEGTransformerFactory::TransformUsingKeyInternal}, - {"Materialized", &PEGTransformerFactory::TransformMaterializedInternal}, - {"SelectClause", &PEGTransformerFactory::TransformSelectClauseInternal}, - {"TargetList", &PEGTransformerFactory::TransformTargetListInternal}, - {"ColumnAliases", &PEGTransformerFactory::TransformColumnAliasesInternal}, - {"DistinctClause", &PEGTransformerFactory::TransformDistinctClauseInternal}, - {"DistinctAll", &PEGTransformerFactory::TransformDistinctAllInternal}, - {"DistinctOn", &PEGTransformerFactory::TransformDistinctOnInternal}, - {"DistinctOnTargets", &PEGTransformerFactory::TransformDistinctOnTargetsInternal}, - {"InnerTableRef", &PEGTransformerFactory::TransformInnerTableRefInternal}, - {"TableSubquery", &PEGTransformerFactory::TransformTableSubqueryInternal}, - {"BaseTableRef", &PEGTransformerFactory::TransformBaseTableRefInternal}, - {"TableAliasColon", &PEGTransformerFactory::TransformTableAliasColonInternal}, - {"ValuesRef", &PEGTransformerFactory::TransformValuesRefInternal}, - {"ParensTableRef", &PEGTransformerFactory::TransformParensTableRefInternal}, - {"JoinOrPivot", &PEGTransformerFactory::TransformJoinOrPivotInternal}, - {"TablePivotClause", &PEGTransformerFactory::TransformTablePivotClauseInternal}, - {"TablePivotClauseBody", &PEGTransformerFactory::TransformTablePivotClauseBodyInternal}, - {"PivotGroupByList", &PEGTransformerFactory::TransformPivotGroupByListInternal}, - {"TableUnpivotClause", &PEGTransformerFactory::TransformTableUnpivotClauseInternal}, - {"TableUnpivotClauseBody", &PEGTransformerFactory::TransformTableUnpivotClauseBodyInternal}, - {"PivotHeader", &PEGTransformerFactory::TransformPivotHeaderInternal}, - {"PivotValueList", &PEGTransformerFactory::TransformPivotValueListInternal}, - {"PivotValueTarget", &PEGTransformerFactory::TransformPivotValueTargetInternal}, - {"PivotEnumTarget", &PEGTransformerFactory::TransformPivotEnumTargetInternal}, - {"PivotListTarget", &PEGTransformerFactory::TransformPivotListTargetInternal}, - {"UnpivotValueList", &PEGTransformerFactory::TransformUnpivotValueListInternal}, - {"PivotTargetList", &PEGTransformerFactory::TransformPivotTargetListInternal}, - {"UnpivotTargetList", &PEGTransformerFactory::TransformUnpivotTargetListInternal}, - {"Lateral", &PEGTransformerFactory::TransformLateralInternal}, - {"BaseTableName", &PEGTransformerFactory::TransformBaseTableNameInternal}, - {"UnqualifiedBaseTableName", &PEGTransformerFactory::TransformUnqualifiedBaseTableNameInternal}, - {"QualifiedTableName", &PEGTransformerFactory::TransformQualifiedTableNameInternal}, - {"SchemaReservedTable", &PEGTransformerFactory::TransformSchemaReservedTableInternal}, - {"CatalogReservedSchemaTable", &PEGTransformerFactory::TransformCatalogReservedSchemaTableInternal}, - {"TableFunction", &PEGTransformerFactory::TransformTableFunctionInternal}, - {"TableFunctionLateralOpt", &PEGTransformerFactory::TransformTableFunctionLateralOptInternal}, - {"TableFunctionAliasColon", &PEGTransformerFactory::TransformTableFunctionAliasColonInternal}, - {"WithOrdinality", &PEGTransformerFactory::TransformWithOrdinalityInternal}, - {"QualifiedTableFunction", &PEGTransformerFactory::TransformQualifiedTableFunctionInternal}, - {"TableFunctionArguments", &PEGTransformerFactory::TransformTableFunctionArgumentsInternal}, - {"FunctionArgument", &PEGTransformerFactory::TransformFunctionArgumentInternal}, - {"NamedFunctionArgument", &PEGTransformerFactory::TransformNamedFunctionArgumentInternal}, - {"PositionalFunctionArgument", &PEGTransformerFactory::TransformPositionalFunctionArgumentInternal}, - {"NamedParameter", &PEGTransformerFactory::TransformNamedParameterInternal}, - {"TableAlias", &PEGTransformerFactory::TransformTableAliasInternal}, - {"TableAliasAs", &PEGTransformerFactory::TransformTableAliasAsInternal}, - {"TableAliasWithoutAs", &PEGTransformerFactory::TransformTableAliasWithoutAsInternal}, - {"AtClause", &PEGTransformerFactory::TransformAtClauseInternal}, - {"AtSpecifier", &PEGTransformerFactory::TransformAtSpecifierInternal}, - {"AtUnit", &PEGTransformerFactory::TransformAtUnitInternal}, - {"VersionAtUnit", &PEGTransformerFactory::TransformVersionAtUnitInternal}, - {"TimestampAtUnit", &PEGTransformerFactory::TransformTimestampAtUnitInternal}, - {"JoinClause", &PEGTransformerFactory::TransformJoinClauseInternal}, - {"NearestJoinClause", &PEGTransformerFactory::TransformNearestJoinClauseInternal}, - {"NearestJoinAliased", &PEGTransformerFactory::TransformNearestJoinAliasedInternal}, - {"NearestJoinBare", &PEGTransformerFactory::TransformNearestJoinBareInternal}, - {"NearestBareTableRef", &PEGTransformerFactory::TransformNearestBareTableRefInternal}, - {"NearestValuesRef", &PEGTransformerFactory::TransformNearestValuesRefInternal}, - {"NearestTableFunction", &PEGTransformerFactory::TransformNearestTableFunctionInternal}, - {"NearestTableSubquery", &PEGTransformerFactory::TransformNearestTableSubqueryInternal}, - {"NearestBaseTableRef", &PEGTransformerFactory::TransformNearestBaseTableRefInternal}, - {"NearestParensTableRef", &PEGTransformerFactory::TransformNearestParensTableRefInternal}, - {"ApproxOrExact", &PEGTransformerFactory::TransformApproxOrExactInternal}, - {"NearestApprox", &PEGTransformerFactory::TransformNearestApproxInternal}, - {"NearestExact", &PEGTransformerFactory::TransformNearestExactInternal}, - {"DistanceOrSimilarity", &PEGTransformerFactory::TransformDistanceOrSimilarityInternal}, - {"NearestDistance", &PEGTransformerFactory::TransformNearestDistanceInternal}, - {"NearestSimilarity", &PEGTransformerFactory::TransformNearestSimilarityInternal}, - {"RegularJoinClause", &PEGTransformerFactory::TransformRegularJoinClauseInternal}, - {"JoinByClause", &PEGTransformerFactory::TransformJoinByClauseInternal}, - {"Asof", &PEGTransformerFactory::TransformAsofInternal}, - {"JoinWithoutOnClause", &PEGTransformerFactory::TransformJoinWithoutOnClauseInternal}, - {"JoinQualifier", &PEGTransformerFactory::TransformJoinQualifierInternal}, - {"OnClause", &PEGTransformerFactory::TransformOnClauseInternal}, - {"UsingClause", &PEGTransformerFactory::TransformUsingClauseInternal}, - {"JoinType", &PEGTransformerFactory::TransformJoinTypeInternal}, - {"JoinPrefix", &PEGTransformerFactory::TransformJoinPrefixInternal}, - {"CrossJoinPrefix", &PEGTransformerFactory::TransformCrossJoinPrefixInternal}, - {"NaturalJoinPrefix", &PEGTransformerFactory::TransformNaturalJoinPrefixInternal}, - {"PositionalJoinPrefix", &PEGTransformerFactory::TransformPositionalJoinPrefixInternal}, - {"FullJoin", &PEGTransformerFactory::TransformFullJoinInternal}, - {"LeftJoin", &PEGTransformerFactory::TransformLeftJoinInternal}, - {"RightJoin", &PEGTransformerFactory::TransformRightJoinInternal}, - {"SemiJoin", &PEGTransformerFactory::TransformSemiJoinInternal}, - {"AntiJoin", &PEGTransformerFactory::TransformAntiJoinInternal}, - {"InnerJoin", &PEGTransformerFactory::TransformInnerJoinInternal}, - {"FromClause", &PEGTransformerFactory::TransformFromClauseInternal}, - {"WhereClause", &PEGTransformerFactory::TransformWhereClauseInternal}, - {"GroupByClause", &PEGTransformerFactory::TransformGroupByClauseInternal}, - {"HavingClause", &PEGTransformerFactory::TransformHavingClauseInternal}, - {"QualifyClause", &PEGTransformerFactory::TransformQualifyClauseInternal}, - {"SampleClause", &PEGTransformerFactory::TransformSampleClauseInternal}, - {"WindowClause", &PEGTransformerFactory::TransformWindowClauseInternal}, - {"SampleEntry", &PEGTransformerFactory::TransformSampleEntryInternal}, - {"SampleEntryCount", &PEGTransformerFactory::TransformSampleEntryCountInternal}, - {"SampleEntryFunction", &PEGTransformerFactory::TransformSampleEntryFunctionInternal}, - {"SampleFunction", &PEGTransformerFactory::TransformSampleFunctionInternal}, - {"SampleProperties", &PEGTransformerFactory::TransformSamplePropertiesInternal}, - {"RepeatableSample", &PEGTransformerFactory::TransformRepeatableSampleInternal}, - {"SampleSeed", &PEGTransformerFactory::TransformSampleSeedInternal}, - {"SampleCount", &PEGTransformerFactory::TransformSampleCountInternal}, - {"SampleValue", &PEGTransformerFactory::TransformSampleValueInternal}, - {"SampleUnit", &PEGTransformerFactory::TransformSampleUnitInternal}, - {"SamplePercentage", &PEGTransformerFactory::TransformSamplePercentageInternal}, - {"SampleRows", &PEGTransformerFactory::TransformSampleRowsInternal}, - {"GroupByExpressions", &PEGTransformerFactory::TransformGroupByExpressionsInternal}, - {"GroupByAll", &PEGTransformerFactory::TransformGroupByAllInternal}, - {"GroupByList", &PEGTransformerFactory::TransformGroupByListInternal}, - {"GroupByExpression", &PEGTransformerFactory::TransformGroupByExpressionInternal}, - {"GroupByBaseExpression", &PEGTransformerFactory::TransformGroupByBaseExpressionInternal}, - {"EmptyGroupingItem", &PEGTransformerFactory::TransformEmptyGroupingItemInternal}, - {"CubeOrRollupClause", &PEGTransformerFactory::TransformCubeOrRollupClauseInternal}, - {"CubeOrRollup", &PEGTransformerFactory::TransformCubeOrRollupInternal}, - {"CubeKeyword", &PEGTransformerFactory::TransformCubeKeywordInternal}, - {"RollupKeyword", &PEGTransformerFactory::TransformRollupKeywordInternal}, - {"GroupingSetsClause", &PEGTransformerFactory::TransformGroupingSetsClauseInternal}, - {"SubqueryReference", &PEGTransformerFactory::TransformSubqueryReferenceInternal}, - {"OrderByExpression", &PEGTransformerFactory::TransformOrderByExpressionInternal}, - {"DescOrAsc", &PEGTransformerFactory::TransformDescOrAscInternal}, - {"DescendingOrder", &PEGTransformerFactory::TransformDescendingOrderInternal}, - {"AscendingOrder", &PEGTransformerFactory::TransformAscendingOrderInternal}, - {"NullsFirstOrLast", &PEGTransformerFactory::TransformNullsFirstOrLastInternal}, - {"NullsFirst", &PEGTransformerFactory::TransformNullsFirstInternal}, - {"NullsLast", &PEGTransformerFactory::TransformNullsLastInternal}, - {"OrderByClause", &PEGTransformerFactory::TransformOrderByClauseInternal}, - {"OrderByExpressions", &PEGTransformerFactory::TransformOrderByExpressionsInternal}, - {"OrderByExpressionList", &PEGTransformerFactory::TransformOrderByExpressionListInternal}, - {"OrderByAll", &PEGTransformerFactory::TransformOrderByAllInternal}, - {"LimitClause", &PEGTransformerFactory::TransformLimitClauseInternal}, - {"OffsetClause", &PEGTransformerFactory::TransformOffsetClauseInternal}, - {"OffsetValue", &PEGTransformerFactory::TransformOffsetValueInternal}, - {"LimitValue", &PEGTransformerFactory::TransformLimitValueInternal}, - {"LimitAll", &PEGTransformerFactory::TransformLimitAllInternal}, - {"LimitLiteralPercent", &PEGTransformerFactory::TransformLimitLiteralPercentInternal}, - {"LimitExpression", &PEGTransformerFactory::TransformLimitExpressionInternal}, - {"FetchClause", &PEGTransformerFactory::TransformFetchClauseInternal}, - {"FetchValue", &PEGTransformerFactory::TransformFetchValueInternal}, - {"AliasedExpression", &PEGTransformerFactory::TransformAliasedExpressionInternal}, - {"ColIdExpression", &PEGTransformerFactory::TransformColIdExpressionInternal}, - {"ExpressionAsCollabel", &PEGTransformerFactory::TransformExpressionAsCollabelInternal}, - {"ExpressionOptIdentifier", &PEGTransformerFactory::TransformExpressionOptIdentifierInternal}, - {"ValuesClause", &PEGTransformerFactory::TransformValuesClauseInternal}, - {"ValuesExpressions", &PEGTransformerFactory::TransformValuesExpressionsInternal}, - {"SetStatement", &PEGTransformerFactory::TransformSetStatementInternal}, - {"SetAssignmentOrTimeZone", &PEGTransformerFactory::TransformSetAssignmentOrTimeZoneInternal}, - {"ResetStatement", &PEGTransformerFactory::TransformResetStatementInternal}, - {"SetSchema", &PEGTransformerFactory::TransformSetSchemaInternal}, - {"StandardAssignment", &PEGTransformerFactory::TransformStandardAssignmentInternal}, - {"SetVariableOrSetting", &PEGTransformerFactory::TransformSetVariableOrSettingInternal}, - {"SetTimeZone", &PEGTransformerFactory::TransformSetTimeZoneInternal}, - {"ZoneValue", &PEGTransformerFactory::TransformZoneValueInternal}, - {"ZoneLocal", &PEGTransformerFactory::TransformZoneLocalInternal}, - {"ZoneDefault", &PEGTransformerFactory::TransformZoneDefaultInternal}, - {"ZoneStringLiteral", &PEGTransformerFactory::TransformZoneStringLiteralInternal}, - {"ZoneIdentifier", &PEGTransformerFactory::TransformZoneIdentifierInternal}, - {"ZoneIntervalWithInterval", &PEGTransformerFactory::TransformZoneIntervalWithIntervalInternal}, - {"ZoneIntervalWithPrecision", &PEGTransformerFactory::TransformZoneIntervalWithPrecisionInternal}, - {"SetSetting", &PEGTransformerFactory::TransformSetSettingInternal}, - {"SetVariable", &PEGTransformerFactory::TransformSetVariableInternal}, - {"VariableScope", &PEGTransformerFactory::TransformVariableScopeInternal}, - {"SettingScope", &PEGTransformerFactory::TransformSettingScopeInternal}, - {"LocalScope", &PEGTransformerFactory::TransformLocalScopeInternal}, - {"SessionScope", &PEGTransformerFactory::TransformSessionScopeInternal}, - {"GlobalScope", &PEGTransformerFactory::TransformGlobalScopeInternal}, - {"SetAssignment", &PEGTransformerFactory::TransformSetAssignmentInternal}, - {"VariableList", &PEGTransformerFactory::TransformVariableListInternal}, - {"TransactionStatement", &PEGTransformerFactory::TransformTransactionStatementInternal}, - {"BeginTransaction", &PEGTransformerFactory::TransformBeginTransactionInternal}, - {"RollbackTransaction", &PEGTransformerFactory::TransformRollbackTransactionInternal}, - {"CommitTransaction", &PEGTransformerFactory::TransformCommitTransactionInternal}, - {"ReadOrWrite", &PEGTransformerFactory::TransformReadOrWriteInternal}, - {"ReadOnlyOrReadWrite", &PEGTransformerFactory::TransformReadOnlyOrReadWriteInternal}, - {"ReadOnly", &PEGTransformerFactory::TransformReadOnlyInternal}, - {"ReadWrite", &PEGTransformerFactory::TransformReadWriteInternal}, - {"UpdateStatement", &PEGTransformerFactory::TransformUpdateStatementInternal}, - {"UpdateTarget", &PEGTransformerFactory::TransformUpdateTargetInternal}, - {"BaseTableSet", &PEGTransformerFactory::TransformBaseTableSetInternal}, - {"BaseTableAliasSet", &PEGTransformerFactory::TransformBaseTableAliasSetInternal}, - {"UpdateAlias", &PEGTransformerFactory::TransformUpdateAliasInternal}, - {"UpdateSetClause", &PEGTransformerFactory::TransformUpdateSetClauseInternal}, - {"UpdateSetTuple", &PEGTransformerFactory::TransformUpdateSetTupleInternal}, - {"UpdateSetElementList", &PEGTransformerFactory::TransformUpdateSetElementListInternal}, - {"UpdateSetElement", &PEGTransformerFactory::TransformUpdateSetElementInternal}, - {"UpdateSetColumnTarget", &PEGTransformerFactory::TransformUpdateSetColumnTargetInternal}, - {"UseStatement", &PEGTransformerFactory::TransformUseStatementInternal}, - {"UseTarget", &PEGTransformerFactory::TransformUseTargetInternal}, - {"SchemaNameAsUseTarget", &PEGTransformerFactory::TransformSchemaNameAsUseTargetInternal}, - {"CatalogNameAsUseTarget", &PEGTransformerFactory::TransformCatalogNameAsUseTargetInternal}, - {"UseTargetCatalogSchema", &PEGTransformerFactory::TransformUseTargetCatalogSchemaInternal}, - {"DotIdentifier", &PEGTransformerFactory::TransformDotIdentifierInternal}, - {"VacuumStatement", &PEGTransformerFactory::TransformVacuumStatementInternal}, - {"VacuumOptions", &PEGTransformerFactory::TransformVacuumOptionsInternal}, - {"VacuumParensOptions", &PEGTransformerFactory::TransformVacuumParensOptionsInternal}, - {"VacuumLegacyOptions", &PEGTransformerFactory::TransformVacuumLegacyOptionsInternal}, - {"VacuumOption", &PEGTransformerFactory::TransformVacuumOptionInternal}, - {"OptAnalyze", &PEGTransformerFactory::TransformOptAnalyzeInternal}, - {"OptFull", &PEGTransformerFactory::TransformOptFullInternal}, - {"OptFreeze", &PEGTransformerFactory::TransformOptFreezeInternal}, - {"OptVerbose", &PEGTransformerFactory::TransformOptVerboseInternal}, - {"NameList", &PEGTransformerFactory::TransformNameListInternal}, - }; - for (const auto &rule : builtin_transform_rules) { - Register(rule.name, rule.finalize); - } -} - -} // namespace duckdb diff --git a/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp b/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp index 87789d7c8..bc326f193 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp @@ -8,6 +8,36 @@ namespace duckdb { static const TransformFrameOps STATEMENT_OPS = {"Statement", &PEGTransformerFactory::InitializeStatementTrampoline, &PEGTransformerFactory::FinalizeStatementTrampoline}; +static const TransformFrameOps PRAGMA_NAME_OPS = {"PragmaName", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps TYPE_NAME_OPS = {"TypeName", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps PLAIN_IDENTIFIER_OPS = {"PlainIdentifier", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps QUOTED_IDENTIFIER_OPS = {"QuotedIdentifier", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps RESERVED_KEYWORD_OPS = {"ReservedKeyword", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps UNRESERVED_KEYWORD_OPS = { + "UnreservedKeyword", &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps COLUMN_NAME_KEYWORD_OPS = { + "ColumnNameKeyword", &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps FUNC_NAME_KEYWORD_OPS = {"FuncNameKeyword", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps TYPE_NAME_KEYWORD_OPS = {"TypeNameKeyword", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; +static const TransformFrameOps SETTING_NAME_OPS = {"SettingName", + &PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline, + &PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline}; static const TransformFrameOps ALTER_STATEMENT_OPS = {"AlterStatement", &PEGTransformerFactory::InitializeAlterStatementTrampoline, &PEGTransformerFactory::FinalizeAlterStatementTrampoline}; @@ -149,6 +179,12 @@ static const TransformFrameOps CHECKPOINT_FORCE_OPS = {"CheckpointForce", static const TransformFrameOps COMMENT_STATEMENT_OPS = {"CommentStatement", &PEGTransformerFactory::InitializeCommentStatementTrampoline, &PEGTransformerFactory::FinalizeCommentStatementTrampoline}; +static const TransformFrameOps COMMENT_TARGET_OPS = {"CommentTarget", + &PEGTransformerFactory::InitializeCommentTargetTrampoline, + &PEGTransformerFactory::FinalizeCommentTargetTrampoline}; +static const TransformFrameOps COMMENT_STRING_LITERAL_IDENTIFIER_OPS = { + "CommentStringLiteralIdentifier", &PEGTransformerFactory::InitializeCommentStringLiteralIdentifierTrampoline, + &PEGTransformerFactory::FinalizeCommentStringLiteralIdentifierTrampoline}; static const TransformFrameOps COMMENT_ON_TYPE_OPS = {"CommentOnType", &PEGTransformerFactory::InitializeCommentOnTypeTrampoline, &PEGTransformerFactory::FinalizeCommentOnTypeTrampoline}; @@ -472,6 +508,9 @@ static const TransformFrameOps COPY_FILE_NAME_IDENTIFIER_COL_ID_OPS = { static const TransformFrameOps IDENTIFIER_COL_ID_OPS = {"IdentifierColId", &PEGTransformerFactory::InitializeIdentifierColIdTrampoline, &PEGTransformerFactory::FinalizeIdentifierColIdTrampoline}; +static const TransformFrameOps COPY_FILE_NAME_SUFFIX_OPS = { + "CopyFileNameSuffix", &PEGTransformerFactory::InitializeCopyFileNameSuffixTrampoline, + &PEGTransformerFactory::FinalizeCopyFileNameSuffixTrampoline}; static const TransformFrameOps COPY_OPTIONS_OPS = {"CopyOptions", &PEGTransformerFactory::InitializeCopyOptionsTrampoline, &PEGTransformerFactory::FinalizeCopyOptionsTrampoline}; @@ -1762,6 +1801,9 @@ static const TransformFrameOps NAMED_OTHER_OPERATOR_OPS = { static const TransformFrameOps OPERATOR_LITERAL_OPS = {"OperatorLiteral", &PEGTransformerFactory::InitializeOperatorLiteralTrampoline, &PEGTransformerFactory::FinalizeOperatorLiteralTrampoline}; +static const TransformFrameOps ANY_OPERATOR_LITERAL_OPS = { + "AnyOperatorLiteral", &PEGTransformerFactory::InitializeAnyOperatorLiteralTrampoline, + &PEGTransformerFactory::FinalizeAnyOperatorLiteralTrampoline}; static const TransformFrameOps ANY_ALL_OPERATOR_OPS = {"AnyAllOperator", &PEGTransformerFactory::InitializeAnyAllOperatorTrampoline, &PEGTransformerFactory::FinalizeAnyAllOperatorTrampoline}; @@ -1773,26 +1815,12 @@ static const TransformFrameOps SUBQUERY_ANY_OPS = {"SubqueryAny", static const TransformFrameOps SUBQUERY_ALL_OPS = {"SubqueryAll", &PEGTransformerFactory::InitializeSubqueryAllTrampoline, &PEGTransformerFactory::FinalizeSubqueryAllTrampoline}; -static const TransformFrameOps INET_OPERATOR_OPS = {"InetOperator", - &PEGTransformerFactory::InitializeInetOperatorTrampoline, - &PEGTransformerFactory::FinalizeInetOperatorTrampoline}; -static const TransformFrameOps JSON_OPERATOR_OPS = {"JsonOperator", - &PEGTransformerFactory::InitializeJsonOperatorTrampoline, - &PEGTransformerFactory::FinalizeJsonOperatorTrampoline}; -static const TransformFrameOps LIST_OPERATOR_OPS = {"ListOperator", - &PEGTransformerFactory::InitializeListOperatorTrampoline, - &PEGTransformerFactory::FinalizeListOperatorTrampoline}; -static const TransformFrameOps STRING_OPERATOR_OPS = {"StringOperator", - &PEGTransformerFactory::InitializeStringOperatorTrampoline, - &PEGTransformerFactory::FinalizeStringOperatorTrampoline}; static const TransformFrameOps QUALIFIED_OPERATOR_OPS = {"QualifiedOperator", &PEGTransformerFactory::InitializeQualifiedOperatorTrampoline, &PEGTransformerFactory::FinalizeQualifiedOperatorTrampoline}; static const TransformFrameOps QUALIFIED_OPERATOR_CONTENTS_OPS = { "QualifiedOperatorContents", &PEGTransformerFactory::InitializeQualifiedOperatorContentsTrampoline, &PEGTransformerFactory::FinalizeQualifiedOperatorContentsTrampoline}; -static const TransformFrameOps ANY_OP_OPS = {"AnyOp", &PEGTransformerFactory::InitializeAnyOpTrampoline, - &PEGTransformerFactory::FinalizeAnyOpTrampoline}; static const TransformFrameOps BITWISE_EXPRESSION_OPS = {"BitwiseExpression", &PEGTransformerFactory::InitializeBitwiseExpressionTrampoline, &PEGTransformerFactory::FinalizeBitwiseExpressionTrampoline}; @@ -2040,6 +2068,21 @@ static const TransformFrameOps SHOW_ALL_MODIFIER_OPS = {"ShowAllModifier", static const TransformFrameOps EXTERNAL_RESOURCE_CREATION_OPTIONS_OPS = { "ExternalResourceCreationOptions", &PEGTransformerFactory::InitializeExternalResourceCreationOptionsTrampoline, &PEGTransformerFactory::FinalizeExternalResourceCreationOptionsTrampoline}; +static const TransformFrameOps ATTACH_TO_EXTERNAL_RESOURCE_OPS = { + "AttachToExternalResource", &PEGTransformerFactory::InitializeAttachToExternalResourceTrampoline, + &PEGTransformerFactory::FinalizeAttachToExternalResourceTrampoline}; +static const TransformFrameOps CONNECT_TO_EXTERNAL_RESOURCE_OPS = { + "ConnectToExternalResource", &PEGTransformerFactory::InitializeConnectToExternalResourceTrampoline, + &PEGTransformerFactory::FinalizeConnectToExternalResourceTrampoline}; +static const TransformFrameOps EXTERNAL_RESOURCE_SOURCE_OPS = { + "ExternalResourceSource", &PEGTransformerFactory::InitializeExternalResourceSourceTrampoline, + &PEGTransformerFactory::FinalizeExternalResourceSourceTrampoline}; +static const TransformFrameOps EXTERNAL_RESOURCE_CREATE_CLAUSE_OPS = { + "ExternalResourceCreateClause", &PEGTransformerFactory::InitializeExternalResourceCreateClauseTrampoline, + &PEGTransformerFactory::FinalizeExternalResourceCreateClauseTrampoline}; +static const TransformFrameOps EXTERNAL_RESOURCE_REFERENCE_CLAUSE_OPS = { + "ExternalResourceReferenceClause", &PEGTransformerFactory::InitializeExternalResourceReferenceClauseTrampoline, + &PEGTransformerFactory::FinalizeExternalResourceReferenceClauseTrampoline}; static const TransformFrameOps INSERT_STATEMENT_OPS = {"InsertStatement", &PEGTransformerFactory::InitializeInsertStatementTrampoline, &PEGTransformerFactory::FinalizeInsertStatementTrampoline}; @@ -2600,6 +2643,9 @@ static const TransformFrameOps ON_CLAUSE_OPS = {"OnClause", &PEGTransformerFacto static const TransformFrameOps USING_CLAUSE_OPS = {"UsingClause", &PEGTransformerFactory::InitializeUsingClauseTrampoline, &PEGTransformerFactory::FinalizeUsingClauseTrampoline}; +static const TransformFrameOps USING_COLUMN_NAME_OPS = {"UsingColumnName", + &PEGTransformerFactory::InitializeUsingColumnNameTrampoline, + &PEGTransformerFactory::FinalizeUsingColumnNameTrampoline}; static const TransformFrameOps JOIN_TYPE_OPS = {"JoinType", &PEGTransformerFactory::InitializeJoinTypeTrampoline, &PEGTransformerFactory::FinalizeJoinTypeTrampoline}; static const TransformFrameOps JOIN_PREFIX_OPS = {"JoinPrefix", &PEGTransformerFactory::InitializeJoinPrefixTrampoline, @@ -2949,6 +2995,16 @@ static const TransformFrameOps NAME_LIST_OPS = {"NameList", &PEGTransformerFacto const case_insensitive_map_t &PEGTransformerFactory::GeneratedTransformFrameOps() { static const case_insensitive_map_t result = { {"Statement", &STATEMENT_OPS}, + {"PragmaName", &PRAGMA_NAME_OPS}, + {"TypeName", &TYPE_NAME_OPS}, + {"PlainIdentifier", &PLAIN_IDENTIFIER_OPS}, + {"QuotedIdentifier", "ED_IDENTIFIER_OPS}, + {"ReservedKeyword", &RESERVED_KEYWORD_OPS}, + {"UnreservedKeyword", &UNRESERVED_KEYWORD_OPS}, + {"ColumnNameKeyword", &COLUMN_NAME_KEYWORD_OPS}, + {"FuncNameKeyword", &FUNC_NAME_KEYWORD_OPS}, + {"TypeNameKeyword", &TYPE_NAME_KEYWORD_OPS}, + {"SettingName", &SETTING_NAME_OPS}, {"AlterStatement", &ALTER_STATEMENT_OPS}, {"AlterOptions", &ALTER_OPTIONS_OPS}, {"AlterTableStmt", &ALTER_TABLE_STMT_OPS}, @@ -2998,6 +3054,8 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"CheckpointStatement", &CHECKPOINT_STATEMENT_OPS}, {"CheckpointForce", &CHECKPOINT_FORCE_OPS}, {"CommentStatement", &COMMENT_STATEMENT_OPS}, + {"CommentTarget", &COMMENT_TARGET_OPS}, + {"CommentStringLiteralIdentifier", &COMMENT_STRING_LITERAL_IDENTIFIER_OPS}, {"CommentOnType", &COMMENT_ON_TYPE_OPS}, {"CommentTable", &COMMENT_TABLE_OPS}, {"CommentSequence", &COMMENT_SEQUENCE_OPS}, @@ -3115,6 +3173,7 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"CopyFileNameIdentifier", ©_FILE_NAME_IDENTIFIER_OPS}, {"CopyFileNameIdentifierColId", ©_FILE_NAME_IDENTIFIER_COL_ID_OPS}, {"IdentifierColId", &IDENTIFIER_COL_ID_OPS}, + {"CopyFileNameSuffix", ©_FILE_NAME_SUFFIX_OPS}, {"CopyOptions", ©_OPTIONS_OPS}, {"CopyOptionList", ©_OPTION_LIST_OPS}, {"SpecializedOptionList", &SPECIALIZED_OPTION_LIST_OPS}, @@ -3565,17 +3624,13 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"AnyAllParsedOperator", &ANY_ALL_PARSED_OPERATOR_OPS}, {"NamedOtherOperator", &NAMED_OTHER_OPERATOR_OPS}, {"OperatorLiteral", &OPERATOR_LITERAL_OPS}, + {"AnyOperatorLiteral", &ANY_OPERATOR_LITERAL_OPS}, {"AnyAllOperator", &ANY_ALL_OPERATOR_OPS}, {"AnyOrAll", &ANY_OR_ALL_OPS}, {"SubqueryAny", &SUBQUERY_ANY_OPS}, {"SubqueryAll", &SUBQUERY_ALL_OPS}, - {"InetOperator", &INET_OPERATOR_OPS}, - {"JsonOperator", &JSON_OPERATOR_OPS}, - {"ListOperator", &LIST_OPERATOR_OPS}, - {"StringOperator", &STRING_OPERATOR_OPS}, {"QualifiedOperator", &QUALIFIED_OPERATOR_OPS}, {"QualifiedOperatorContents", &QUALIFIED_OPERATOR_CONTENTS_OPS}, - {"AnyOp", &ANY_OP_OPS}, {"BitwiseExpression", &BITWISE_EXPRESSION_OPS}, {"BitwiseExpressionTail", &BITWISE_EXPRESSION_TAIL_OPS}, {"BitOperator", &BIT_OPERATOR_OPS}, @@ -3660,6 +3715,11 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"ShowExternalResourcesStmt", &SHOW_EXTERNAL_RESOURCES_STMT_OPS}, {"ShowAllModifier", &SHOW_ALL_MODIFIER_OPS}, {"ExternalResourceCreationOptions", &EXTERNAL_RESOURCE_CREATION_OPTIONS_OPS}, + {"AttachToExternalResource", &ATTACH_TO_EXTERNAL_RESOURCE_OPS}, + {"ConnectToExternalResource", &CONNECT_TO_EXTERNAL_RESOURCE_OPS}, + {"ExternalResourceSource", &EXTERNAL_RESOURCE_SOURCE_OPS}, + {"ExternalResourceCreateClause", &EXTERNAL_RESOURCE_CREATE_CLAUSE_OPS}, + {"ExternalResourceReferenceClause", &EXTERNAL_RESOURCE_REFERENCE_CLAUSE_OPS}, {"InsertStatement", &INSERT_STATEMENT_OPS}, {"OrAction", &OR_ACTION_OPS}, {"InsertOrReplace", &INSERT_OR_REPLACE_OPS}, @@ -3856,6 +3916,7 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"JoinQualifier", &JOIN_QUALIFIER_OPS}, {"OnClause", &ON_CLAUSE_OPS}, {"UsingClause", &USING_CLAUSE_OPS}, + {"UsingColumnName", &USING_COLUMN_NAME_OPS}, {"JoinType", &JOIN_TYPE_OPS}, {"JoinPrefix", &JOIN_PREFIX_OPS}, {"CrossJoinPrefix", &CROSS_JOIN_PREFIX_OPS}, @@ -4009,6 +4070,18 @@ PEGTransformerFactory::FinalizeStatementTrampoline(PEGTransformer &transformer, return make_uniq>>(std::move(result)); } +void PEGTransformerFactory::InitializeIdentifierOrKeywordTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + process.ReserveChildSlots(0); +} + +unique_ptr +PEGTransformerFactory::FinalizeIdentifierOrKeywordTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = TransformIdentifierOrKeyword(transformer, process.parse_result); + return make_uniq>(result); +} + void PEGTransformerFactory::InitializeAlterStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -4145,11 +4218,12 @@ PEGTransformerFactory::FinalizeAddConstraintTrampoline(PEGTransformer &transform void PEGTransformerFactory::InitializeDropConstraintTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(2); + process.ReserveChildSlots(3); auto &drop_behavior_opt = list_pr.GetChild(4).Cast(); if (drop_behavior_opt.HasResult()) { - process.PushChild({transformer.GetRule("DropBehavior"), drop_behavior_opt.GetResult()}, 1); + process.PushChild({transformer.GetRule("DropBehavior"), drop_behavior_opt.GetResult()}, 2); } + process.PushChild({transformer.GetRule("ConstraintName"), list_pr.GetChild(3)}, 1); auto &if_exists_opt = list_pr.GetChild(2).Cast(); if (if_exists_opt.HasResult()) { process.PushChild({transformer.GetRule("IfExists"), if_exists_opt.GetResult()}, 0); @@ -4159,17 +4233,16 @@ void PEGTransformerFactory::InitializeDropConstraintTrampoline(PEGTransformer &t unique_ptr PEGTransformerFactory::FinalizeDropConstraintTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); optional if_exists {}; if (process.child_results[0]) { if_exists = process.TakeResult(0); } - auto identifier = list_pr.GetChild(3).Cast().identifier; + auto constraint_name = process.TakeResult(1); optional drop_behavior {}; - if (process.child_results[1]) { - drop_behavior = process.TakeResult(1); + if (process.child_results[2]) { + drop_behavior = process.TakeResult(2); } - auto result = TransformDropConstraint(transformer, if_exists, identifier, drop_behavior); + auto result = TransformDropConstraint(transformer, if_exists, constraint_name, drop_behavior); return make_uniq>>(std::move(result)); } @@ -4319,7 +4392,8 @@ PEGTransformerFactory::FinalizeAlterColumnTrampoline(PEGTransformer &transformer void PEGTransformerFactory::InitializeRenameColumnTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(1); + process.ReserveChildSlots(2); + process.PushChild({transformer.GetRule("ColIdOrString"), list_pr.GetChild(4)}, 1); process.PushChild({transformer.GetRule("NestedColumnName"), list_pr.GetChild(2)}, 0); } @@ -4330,8 +4404,8 @@ PEGTransformerFactory::FinalizeRenameColumnTrampoline(PEGTransformer &transforme auto &has_result_opt = list_pr.GetChild(1).Cast(); has_result = has_result_opt.HasResult(); auto nested_column_name = process.TakeResult>(0); - auto identifier = list_pr.GetChild(4).Cast().identifier; - auto result = TransformRenameColumn(transformer, has_result, std::move(nested_column_name), identifier); + auto col_id_or_string = process.TakeResult(1); + auto result = TransformRenameColumn(transformer, has_result, std::move(nested_column_name), col_id_or_string); return make_uniq>>(std::move(result)); } @@ -4394,14 +4468,15 @@ PEGTransformerFactory::FinalizeIdentifierDotTrampoline(PEGTransformer &transform void PEGTransformerFactory::InitializeRenameAlterTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("ColIdOrString"), list_pr.GetChild(2)}, 0); } unique_ptr PEGTransformerFactory::FinalizeRenameAlterTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto identifier = list_pr.GetChild(2).Cast().identifier; - auto result = TransformRenameAlter(transformer, identifier); + auto col_id_or_string = process.TakeResult(0); + auto result = TransformRenameAlter(transformer, col_id_or_string); return make_uniq>>(std::move(result)); } @@ -5084,7 +5159,7 @@ void PEGTransformerFactory::InitializeCommentStatementTrampoline(PEGTransformer auto &list_pr = process.parse_result.Cast(); process.ReserveChildSlots(3); process.PushChild({transformer.GetRule("CommentValue"), list_pr.GetChild(5)}, 2); - process.PushChild({transformer.GetRule("DottedIdentifier"), list_pr.GetChild(3)}, 1); + process.PushChild({transformer.GetRule("CommentTarget"), list_pr.GetChild(3)}, 1); process.PushChild({transformer.GetRule("CommentOnType"), list_pr.GetChild(2)}, 0); } @@ -5092,12 +5167,48 @@ unique_ptr PEGTransformerFactory::FinalizeCommentStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto comment_on_type = process.TakeResult(0); - auto dotted_identifier = process.TakeResult>(1); + auto comment_target = process.TakeResult>(1); auto comment_value = process.TakeResult(2); - auto result = TransformCommentStatement(transformer, comment_on_type, dotted_identifier, comment_value); + auto result = TransformCommentStatement(transformer, comment_on_type, comment_target, comment_value); return make_uniq>>(std::move(result)); } +void PEGTransformerFactory::InitializeCommentTargetTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto &choice_result = choice_pr.GetResult(); + process.ReserveChildSlots(1); + auto child_rule = choice_result.GetRule(); + auto has_transform_process = child_rule && child_rule->transform_process; + if (!has_transform_process) { + throw InternalException("No transform process registered for rule '%s'", choice_result.name); + } + process.PushChild({*child_rule, choice_result}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeCommentTargetTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = process.TakeResult>(0); + return make_uniq>>(result); +} + +void PEGTransformerFactory::InitializeCommentStringLiteralIdentifierTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("StringLiteralIdentifier"), list_pr.GetChild(0)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeCommentStringLiteralIdentifierTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto string_literal_identifier = process.TakeResult(0); + auto result = TransformCommentStringLiteralIdentifier(transformer, string_literal_identifier); + return make_uniq>>(result); +} + void PEGTransformerFactory::InitializeCommentOnTypeTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -7101,17 +7212,43 @@ PEGTransformerFactory::FinalizeCopyFileNameIdentifierColIdTrampoline(PEGTransfor void PEGTransformerFactory::InitializeIdentifierColIdTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(1); - process.PushChild({transformer.GetRule("ColId"), list_pr.GetChild(2)}, 0); + auto &repeat_pr = list_pr.GetChild(1).Cast(); + auto repeat_children = repeat_pr.GetChildren(); + auto dynamic_child_count = repeat_children.size(); + process.ReserveChildSlots(1 + dynamic_child_count - 1); + for (idx_t i = repeat_children.size(); i > 0; i--) { + auto child_idx = i - 1; + process.PushChild({transformer.GetRule("CopyFileNameSuffix"), repeat_children[child_idx].get()}, 0 + child_idx); + } } unique_ptr PEGTransformerFactory::FinalizeIdentifierColIdTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); + auto &dynamic_repeat_pr = list_pr.GetChild(1).Cast(); + auto dynamic_repeat_children = dynamic_repeat_pr.GetChildren(); + auto dynamic_child_count = dynamic_repeat_children.size(); auto identifier = list_pr.GetChild(0).Cast().identifier; - auto col_id = process.TakeResult(0); - auto result = TransformIdentifierColId(transformer, identifier, col_id); + vector copy_file_name_suffix; + for (idx_t i = 0; i < 0 + dynamic_child_count; i++) { + copy_file_name_suffix.push_back(process.TakeResult(i)); + } + auto result = TransformIdentifierColId(transformer, identifier, copy_file_name_suffix); + return make_uniq>(result); +} + +void PEGTransformerFactory::InitializeCopyFileNameSuffixTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("ColId"), list_pr.GetChild(1)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeCopyFileNameSuffixTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = process.TakeResult(0); return make_uniq>(result); } @@ -11233,7 +11370,8 @@ PEGTransformerFactory::FinalizeCreateSecureTrampoline(PEGTransformer &transforme void PEGTransformerFactory::InitializeDeallocateStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(1); + process.ReserveChildSlots(2); + process.PushChild({transformer.GetRule("ColIdOrString"), list_pr.GetChild(2)}, 1); auto &deallocate_prepare_opt = list_pr.GetChild(1).Cast(); if (deallocate_prepare_opt.HasResult()) { process.PushChild({transformer.GetRule("DeallocatePrepare"), deallocate_prepare_opt.GetResult()}, 0); @@ -11243,13 +11381,12 @@ void PEGTransformerFactory::InitializeDeallocateStatementTrampoline(PEGTransform unique_ptr PEGTransformerFactory::FinalizeDeallocateStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); optional deallocate_prepare {}; if (process.child_results[0]) { deallocate_prepare = process.TakeResult(0); } - auto identifier = list_pr.GetChild(2).Cast().identifier; - auto result = TransformDeallocateStatement(transformer, deallocate_prepare, identifier); + auto col_id_or_string = process.TakeResult(1); + auto result = TransformDeallocateStatement(transformer, deallocate_prepare, col_id_or_string); return make_uniq>>(std::move(result)); } @@ -12366,23 +12503,23 @@ PEGTransformerFactory::FinalizeDropSecretStorageTrampoline(PEGTransformer &trans void PEGTransformerFactory::InitializeExecuteStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(1); + process.ReserveChildSlots(2); auto &table_function_arguments_opt = list_pr.GetChild(2).Cast(); if (table_function_arguments_opt.HasResult()) { - process.PushChild({transformer.GetRule("TableFunctionArguments"), table_function_arguments_opt.GetResult()}, 0); + process.PushChild({transformer.GetRule("TableFunctionArguments"), table_function_arguments_opt.GetResult()}, 1); } + process.PushChild({transformer.GetRule("ColIdOrString"), list_pr.GetChild(1)}, 0); } unique_ptr PEGTransformerFactory::FinalizeExecuteStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; + auto col_id_or_string = process.TakeResult(0); optional> table_function_arguments {}; - if (process.child_results[0]) { - table_function_arguments = process.TakeResult>(0); + if (process.child_results[1]) { + table_function_arguments = process.TakeResult>(1); } - auto result = TransformExecuteStatement(transformer, identifier, std::move(table_function_arguments)); + auto result = TransformExecuteStatement(transformer, col_id_or_string, std::move(table_function_arguments)); return make_uniq>>(std::move(result)); } @@ -16274,20 +16411,32 @@ PEGTransformerFactory::FinalizeOperatorLiteralTrampoline(PEGTransformer &transfo return make_uniq>(result); } +void PEGTransformerFactory::InitializeAnyOperatorLiteralTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + process.ReserveChildSlots(0); +} + +unique_ptr +PEGTransformerFactory::FinalizeAnyOperatorLiteralTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = process.parse_result.Cast().operator_token; + return make_uniq>(result); +} + void PEGTransformerFactory::InitializeAnyAllOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(2); - process.PushChild({transformer.GetRule("AnyOrAll"), list_pr.GetChild(1)}, 1); - process.PushChild({transformer.GetRule("AnyOp"), list_pr.GetChild(0)}, 0); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("AnyOrAll"), list_pr.GetChild(1)}, 0); } unique_ptr PEGTransformerFactory::FinalizeAnyAllOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto any_op = process.TakeResult(0); - auto any_or_all = process.TakeResult(1); - auto result = TransformAnyAllOperator(transformer, any_op, any_or_all); + auto &list_pr = process.parse_result.Cast(); + auto any_operator_literal = list_pr.GetChild(0).Cast().operator_token; + auto any_or_all = process.TakeResult(0); + auto result = TransformAnyAllOperator(transformer, any_operator_literal, any_or_all); return make_uniq>>(result); } @@ -16333,57 +16482,6 @@ PEGTransformerFactory::FinalizeSubqueryAllTrampoline(PEGTransformer &transformer return make_uniq>(result); } -void PEGTransformerFactory::InitializeInetOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); -} - -unique_ptr -PEGTransformerFactory::FinalizeInetOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -void PEGTransformerFactory::InitializeJsonOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); -} - -unique_ptr -PEGTransformerFactory::FinalizeJsonOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - string result = "->>"; - return make_uniq>(result); -} - -void PEGTransformerFactory::InitializeListOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); -} - -unique_ptr -PEGTransformerFactory::FinalizeListOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - -void PEGTransformerFactory::InitializeStringOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); -} - -unique_ptr -PEGTransformerFactory::FinalizeStringOperatorTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; - return make_uniq>(result); -} - void PEGTransformerFactory::InitializeQualifiedOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -16409,15 +16507,13 @@ void PEGTransformerFactory::InitializeQualifiedOperatorContentsTrampoline(PEGTra auto &repeat_pr = repeat_opt.GetResult().Cast(); auto repeat_children = repeat_pr.GetChildren(); dynamic_child_count = repeat_children.size(); - process.ReserveChildSlots(2 + dynamic_child_count - 1); - process.PushChild({transformer.GetRule("AnyOp"), list_pr.GetChild(1)}, 1 + dynamic_child_count - 1); + process.ReserveChildSlots(1 + dynamic_child_count - 1); for (idx_t i = repeat_children.size(); i > 0; i--) { auto child_idx = i - 1; process.PushChild({transformer.GetRule("ColIdDot"), repeat_children[child_idx].get()}, 0 + child_idx); } } else { - process.ReserveChildSlots(2 - 1); - process.PushChild({transformer.GetRule("AnyOp"), list_pr.GetChild(1)}, 1 + dynamic_child_count - 1); + process.ReserveChildSlots(1 - 1); } } @@ -16440,20 +16536,8 @@ PEGTransformerFactory::FinalizeQualifiedOperatorContentsTrampoline(PEGTransforme } col_id_dot = std::move(col_id_dot_value); } - auto any_op = process.TakeResult(1 + dynamic_child_count - 1); - auto result = TransformQualifiedOperatorContents(transformer, col_id_dot, any_op); - return make_uniq>(result); -} - -void PEGTransformerFactory::InitializeAnyOpTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); -} - -unique_ptr PEGTransformerFactory::FinalizeAnyOpTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto &choice_pr = list_pr.Child(0); - auto result = choice_pr.GetResult().Cast().keyword; + auto any_operator_literal = list_pr.GetChild(1).Cast().operator_token; + auto result = TransformQualifiedOperatorContents(transformer, col_id_dot, any_operator_literal); return make_uniq>(result); } @@ -18123,13 +18207,13 @@ void PEGTransformerFactory::InitializeCreateExternalResourceStmtTrampoline(PEGTr GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); process.ReserveChildSlots(2); - auto &external_resource_creation_options_opt = list_pr.GetChild(5).Cast(); + auto &external_resource_creation_options_opt = list_pr.GetChild(4).Cast(); if (external_resource_creation_options_opt.HasResult()) { process.PushChild({transformer.GetRule("ExternalResourceCreationOptions"), external_resource_creation_options_opt.GetResult()}, 1); } - auto &attach_alias_opt = list_pr.GetChild(4).Cast(); + auto &attach_alias_opt = list_pr.GetChild(3).Cast(); if (attach_alias_opt.HasResult()) { process.PushChild({transformer.GetRule("AttachAlias"), attach_alias_opt.GetResult()}, 0); } @@ -18139,7 +18223,7 @@ unique_ptr PEGTransformerFactory::FinalizeCreateExternalResourceStmtTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - auto string_literal = TransformStringLiteral(transformer, list_pr.GetChild(3)); + auto string_literal = TransformStringLiteral(transformer, list_pr.GetChild(2)); optional attach_alias {}; if (process.child_results[0]) { attach_alias = process.TakeResult(0); @@ -18157,8 +18241,8 @@ void PEGTransformerFactory::InitializeRegisterExternalResourceStmtTrampoline(PEG GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); process.ReserveChildSlots(2); - process.PushChild({transformer.GetRule("Expression"), list_pr.GetChild(6)}, 1); - auto &attach_alias_opt = list_pr.GetChild(4).Cast(); + process.PushChild({transformer.GetRule("Expression"), list_pr.GetChild(5)}, 1); + auto &attach_alias_opt = list_pr.GetChild(3).Cast(); if (attach_alias_opt.HasResult()) { process.PushChild({transformer.GetRule("AttachAlias"), attach_alias_opt.GetResult()}, 0); } @@ -18168,7 +18252,7 @@ unique_ptr PEGTransformerFactory::FinalizeRegisterExternalResourceStmtTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - auto string_literal = TransformStringLiteral(transformer, list_pr.GetChild(3)); + auto string_literal = TransformStringLiteral(transformer, list_pr.GetChild(2)); optional attach_alias {}; if (process.child_results[0]) { attach_alias = process.TakeResult(0); @@ -18183,7 +18267,7 @@ void PEGTransformerFactory::InitializeDestroyExternalResourceStmtTrampoline(PEGT GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); process.ReserveChildSlots(1); - process.PushChild({transformer.GetRule("ColId"), list_pr.GetChild(3)}, 0); + process.PushChild({transformer.GetRule("ColId"), list_pr.GetChild(2)}, 0); } unique_ptr @@ -18241,6 +18325,117 @@ PEGTransformerFactory::FinalizeExternalResourceCreationOptionsTrampoline(PEGTran return make_uniq>>(result); } +void PEGTransformerFactory::InitializeAttachToExternalResourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(3); + auto &attach_options_opt = list_pr.GetChild(4).Cast(); + if (attach_options_opt.HasResult()) { + process.PushChild({transformer.GetRule("AttachOptions"), attach_options_opt.GetResult()}, 2); + } + process.PushChild({transformer.GetRule("AttachAlias"), list_pr.GetChild(3)}, 1); + process.PushChild({transformer.GetRule("ExternalResourceSource"), list_pr.GetChild(2)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeAttachToExternalResourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto external_resource_source = process.TakeResult>(0); + auto attach_alias = process.TakeResult(1); + optional> attach_options {}; + if (process.child_results[2]) { + attach_options = process.TakeResult>(2); + } + auto result = TransformAttachToExternalResource(transformer, std::move(external_resource_source), attach_alias, + attach_options); + return make_uniq>>(std::move(result)); +} + +void PEGTransformerFactory::InitializeConnectToExternalResourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(2); + auto &attach_options_opt = list_pr.GetChild(3).Cast(); + if (attach_options_opt.HasResult()) { + process.PushChild({transformer.GetRule("AttachOptions"), attach_options_opt.GetResult()}, 1); + } + process.PushChild({transformer.GetRule("ExternalResourceSource"), list_pr.GetChild(2)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeConnectToExternalResourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto external_resource_source = process.TakeResult>(0); + optional> attach_options {}; + if (process.child_results[1]) { + attach_options = process.TakeResult>(1); + } + auto result = TransformConnectToExternalResource(transformer, std::move(external_resource_source), attach_options); + return make_uniq>>(std::move(result)); +} + +void PEGTransformerFactory::InitializeExternalResourceSourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto &choice_result = choice_pr.GetResult(); + process.ReserveChildSlots(1); + auto child_rule = choice_result.GetRule(); + auto has_transform_process = child_rule && child_rule->transform_process; + if (!has_transform_process) { + throw InternalException("No transform process registered for rule '%s'", choice_result.name); + } + process.PushChild({*child_rule, choice_result}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeExternalResourceSourceTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = process.TakeResult>(0); + return make_uniq>>(std::move(result)); +} + +void PEGTransformerFactory::InitializeExternalResourceCreateClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + auto &external_resource_creation_options_opt = list_pr.GetChild(4).Cast(); + if (external_resource_creation_options_opt.HasResult()) { + process.PushChild({transformer.GetRule("ExternalResourceCreationOptions"), + external_resource_creation_options_opt.GetResult()}, + 0); + } +} + +unique_ptr +PEGTransformerFactory::FinalizeExternalResourceCreateClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + auto string_literal = TransformStringLiteral(transformer, list_pr.GetChild(3)); + optional> external_resource_creation_options {}; + if (process.child_results[0]) { + external_resource_creation_options = process.TakeResult>(0); + } + auto result = + TransformExternalResourceCreateClause(transformer, string_literal, external_resource_creation_options); + return make_uniq>>(std::move(result)); +} + +void PEGTransformerFactory::InitializeExternalResourceReferenceClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("ColId"), list_pr.GetChild(1)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeExternalResourceReferenceClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto col_id = process.TakeResult(0); + auto result = TransformExternalResourceReferenceClause(transformer, col_id); + return make_uniq>>(std::move(result)); +} + void PEGTransformerFactory::InitializeInsertStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -19912,25 +20107,25 @@ PEGTransformerFactory::FinalizePragmaParametersTrampoline(PEGTransformer &transf void PEGTransformerFactory::InitializePrepareStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - process.ReserveChildSlots(2); - process.PushChild({transformer.GetRule("Statement"), list_pr.GetChild(4)}, 1); + process.ReserveChildSlots(3); + process.PushChild({transformer.GetRule("Statement"), list_pr.GetChild(4)}, 2); auto &type_list_opt = list_pr.GetChild(2).Cast(); if (type_list_opt.HasResult()) { - process.PushChild({transformer.GetRule("TypeList"), type_list_opt.GetResult()}, 0); + process.PushChild({transformer.GetRule("TypeList"), type_list_opt.GetResult()}, 1); } + process.PushChild({transformer.GetRule("ColIdOrString"), list_pr.GetChild(1)}, 0); } unique_ptr PEGTransformerFactory::FinalizePrepareStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - auto &list_pr = process.parse_result.Cast(); - auto identifier = list_pr.GetChild(1).Cast().identifier; + auto col_id_or_string = process.TakeResult(0); optional> type_list {}; - if (process.child_results[0]) { - type_list = process.TakeResult>(0); + if (process.child_results[1]) { + type_list = process.TakeResult>(1); } - auto statement = process.TakeResult>(1); - auto result = TransformPrepareStatement(transformer, identifier, type_list, std::move(statement)); + auto statement = process.TakeResult>(2); + auto result = TransformPrepareStatement(transformer, col_id_or_string, type_list, std::move(statement)); return make_uniq>>(std::move(result)); } @@ -20505,9 +20700,9 @@ void PEGTransformerFactory::InitializeWithStatementTrampoline(PEGTransformer &tr if (using_key_opt.HasResult()) { process.PushChild({transformer.GetRule("UsingKey"), using_key_opt.GetResult()}, 2); } - auto &insert_column_list_opt = list_pr.GetChild(1).Cast(); - if (insert_column_list_opt.HasResult()) { - process.PushChild({transformer.GetRule("InsertColumnList"), insert_column_list_opt.GetResult()}, 1); + auto &column_aliases_opt = list_pr.GetChild(1).Cast(); + if (column_aliases_opt.HasResult()) { + process.PushChild({transformer.GetRule("ColumnAliases"), column_aliases_opt.GetResult()}, 1); } process.PushChild({transformer.GetRule("ColIdOrString"), list_pr.GetChild(0)}, 0); } @@ -20516,9 +20711,9 @@ unique_ptr PEGTransformerFactory::FinalizeWithStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto col_id_or_string = process.TakeResult(0); - optional> insert_column_list {}; + optional> column_aliases {}; if (process.child_results[1]) { - insert_column_list = process.TakeResult>(1); + column_aliases = process.TakeResult>(1); } optional>> using_key {}; if (process.child_results[2]) { @@ -20529,7 +20724,7 @@ PEGTransformerFactory::FinalizeWithStatementTrampoline(PEGTransformer &transform materialized = process.TakeResult(3); } auto cte_body = process.TakeResult>(4); - auto result = TransformWithStatement(transformer, col_id_or_string, insert_column_list, std::move(using_key), + auto result = TransformWithStatement(transformer, col_id_or_string, column_aliases, std::move(using_key), materialized, std::move(cte_body)); return make_uniq>>>(std::move(result)); } @@ -22290,21 +22485,69 @@ unique_ptr PEGTransformerFactory::FinalizeOnClauseTrampoli void PEGTransformerFactory::InitializeUsingClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { - process.ReserveChildSlots(0); + auto &list_pr = process.parse_result.Cast(); + auto list_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); + auto dynamic_child_count = list_items.size(); + process.ReserveChildSlots(1 + dynamic_child_count - 1); + for (idx_t i = list_items.size(); i > 0; i--) { + auto child_idx = i - 1; + process.PushChild({transformer.GetRule("UsingColumnName"), list_items[child_idx].get()}, 0 + child_idx); + } } unique_ptr PEGTransformerFactory::FinalizeUsingClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); - vector column_name; - auto column_name_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); - for (auto &column_name_item : column_name_items) { - column_name.push_back(column_name_item.get().Cast().identifier); + auto dynamic_list_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(1))); + auto dynamic_child_count = dynamic_list_items.size(); + vector using_column_name; + for (idx_t i = 0; i < 0 + dynamic_child_count; i++) { + using_column_name.push_back(process.TakeResult(i)); } - auto result = TransformUsingClause(transformer, column_name); + auto result = TransformUsingClause(transformer, using_column_name); return make_uniq>(std::move(result)); } +void PEGTransformerFactory::InitializeUsingColumnNameTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto &choice_result = choice_pr.GetResult(); + process.ReserveChildSlots(1); + auto child_rule = choice_result.GetRule(); + auto has_transform_process = child_rule && child_rule->transform_process; + if (choice_result.name.empty() || choice_result.type == ParseResultType::IDENTIFIER || + choice_result.type == ParseResultType::KEYWORD || choice_result.type == ParseResultType::STRING) { + return; + } + if (!has_transform_process) { + throw InternalException("No transform process registered for rule '%s'", choice_result.name); + } + process.PushChild({*child_rule, choice_result}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeUsingColumnNameTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + Identifier result; + if (process.child_results[0]) { + result = process.TakeResult(0); + } else { + auto &list_pr = process.parse_result.Cast(); + auto &choice_result = list_pr.Child(0).GetResult(); + if (choice_result.type == ParseResultType::IDENTIFIER) { + result = choice_result.Cast().identifier; + } else if (choice_result.type == ParseResultType::KEYWORD) { + result = Identifier(choice_result.Cast().keyword); + } else if (choice_result.type == ParseResultType::STRING) { + result = Identifier(choice_result.Cast().result); + } else { + result = Identifier(TransformIdentifierOrKeyword(transformer, choice_result)); + } + } + return make_uniq>(result); +} + void PEGTransformerFactory::InitializeJoinTypeTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -24636,7 +24879,7 @@ void PEGTransformerFactory::InitializeNameListTrampoline(PEGTransformer &transfo process.ReserveChildSlots(1 + dynamic_child_count - 1); for (idx_t i = list_items.size(); i > 0; i--) { auto child_idx = i - 1; - process.PushChild({transformer.GetRule("ColId"), list_items[child_idx].get()}, 0 + child_idx); + process.PushChild({transformer.GetRule("ColIdOrString"), list_items[child_idx].get()}, 0 + child_idx); } } @@ -24645,11 +24888,11 @@ unique_ptr PEGTransformerFactory::FinalizeNameListTrampoli auto &list_pr = process.parse_result.Cast(); auto dynamic_list_items = ExtractParseResultsFromList(ExtractResultFromParens(list_pr.GetChild(0))); auto dynamic_child_count = dynamic_list_items.size(); - vector col_id; + vector col_id_or_string; for (idx_t i = 0; i < 0 + dynamic_child_count; i++) { - col_id.push_back(process.TakeResult(i)); + col_id_or_string.push_back(process.TakeResult(i)); } - auto result = TransformNameList(transformer, col_id); + auto result = TransformNameList(transformer, col_id_or_string); return make_uniq>>(result); } diff --git a/src/duckdb/src/parser/peg/transformer/transform_generic_copy_option.cpp b/src/duckdb/src/parser/peg/transformer/transform_generic_copy_option.cpp index 3395bff41..1e1131735 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_generic_copy_option.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_generic_copy_option.cpp @@ -87,7 +87,27 @@ static GenericCopyOption BuildGenericCopyOption(const Identifier &generic_copy_o optional generic_copy_option_value) { GenericCopyOption copy_option; copy_option.name = Identifier(StringUtil::Lower(generic_copy_option_name.GetIdentifierName())); - if (!generic_copy_option_value || !generic_copy_option_value->has_value) { + const bool has_value = generic_copy_option_value && generic_copy_option_value->has_value; + if (!has_value && copy_option.name == "PARTITION_PATH") { + throw ParserException("PARTITION_PATH expects an expression"); + } + if (!has_value) { + return copy_option; + } + + if (copy_option.name == "PARTITION_PATH") { + // kept as-is, as it is bound against the partition columns + if (!generic_copy_option_value->is_order_list) { + copy_option.expression = std::move(generic_copy_option_value->expression); + return copy_option; + } + // an expression wrapped in () will trigger this case + auto &orders = generic_copy_option_value->order_list; + if (orders.size() != 1 || orders[0].type != OrderType::ORDER_DEFAULT || + orders[0].null_order != OrderByNullType::ORDER_DEFAULT) { + throw ParserException("PARTITION_PATH expects a single expression"); + } + copy_option.expression = std::move(orders[0].expression); return copy_option; } @@ -179,4 +199,28 @@ void PEGTransformerFactory::SplitGenericOptions(const vector } } +void PEGTransformerFactory::CollectGenericOptions(const vector &options_in, + case_insensitive_map_t> &options, + const char *statement_name) { + for (const auto &option : options_in) { + auto name = option.name.GetIdentifierName(); + if (option.expression) { + options[name] = option.expression->Copy(); + continue; + } + if (option.children.empty()) { + // Bare flag (e.g. `(SPOT)`) binds to boolean true, as in SplitGenericOptions. + options[name] = ConstantExpression::Boolean(true); + } else if (option.children.size() == 1) { + if (option.children[0].IsNull()) { + throw BinderException("NULL is not supported as a valid option for %s option %s", statement_name, + option.name); + } + options[name] = ConstantExpression::FromValue(option.children[0]); + } else { + throw ParserException("Option %s can only have one argument", option.name); + } + } +} + } // namespace duckdb diff --git a/src/duckdb/src/parser/peg/transformer/transform_pivot.cpp b/src/duckdb/src/parser/peg/transformer/transform_pivot.cpp index 13bf15bef..756208987 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_pivot.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_pivot.cpp @@ -73,85 +73,6 @@ PivotColumn PEGTransformerFactory::TransformPivotColumnExpression(PEGTransformer return result; } -unique_ptr PEGTransformerFactory::TransformPivotStatement(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - - auto current_param_count = transformer.ParamCount(); - auto source = TransformTableRef(transformer, list_pr.GetChild(1)); - auto next_param_count = transformer.ParamCount(); - bool has_parameters = next_param_count > current_param_count; - auto &pivot_columns = list_pr.Child(2); - auto select_node = make_uniq(); - auto &pivot_group = list_pr.Child(4); - if (!pivot_columns.HasResult()) { - select_node->from_table = TransformTableRef(transformer, list_pr.GetChild(1)); - if (pivot_group.HasResult()) { - auto pivot_group_list = transformer.Transform>(pivot_group.GetResult()); - GroupingSet set; - for (idx_t gr = 0; gr < pivot_group_list.size(); gr++) { - auto &group = pivot_group_list[gr]; - auto colref = make_uniq(Identifier(group)); - select_node->select_list.push_back(colref->Copy()); - select_node->groups.group_expressions.push_back(std::move(colref)); - set.insert(ProjectionIndex(gr)); - } - select_node->groups.grouping_sets.push_back(std::move(set)); - } - - vector> pivot_using; - transformer.TransformOptional>>(list_pr, 3, pivot_using); - for (auto &col : pivot_using) { - select_node->select_list.push_back(std::move(col)); - } - auto result = make_uniq(); - result->node = std::move(select_node); - return result; - } - auto columns = transformer.Transform>(pivot_columns.GetResult()); - for (idx_t c = 0; c < columns.size(); c++) { - auto &col = columns[c]; - if (!col.pivot_enum.empty() || !col.entries.empty()) { - continue; - } - if (col.pivot_expressions.size() != 1) { - throw InternalException("PIVOT statement with multiple names in pivot entry!?"); - } - auto enum_name = "__pivot_enum_" + UUID::ToString(UUID::GenerateRandomUUID()); - - auto new_select = make_uniq(); - transformer.ExtractCTEsRecursive(new_select->cte_map); - new_select->from_table = source->Copy(); - AddPivotEntry(transformer, enum_name, std::move(new_select), col.pivot_expressions[0]->Copy(), - std::move(col.subquery), has_parameters); - col.pivot_enum = Identifier(enum_name); - } - - // Generate the actual query, including the pivot - select_node->select_list.push_back(make_uniq()); - - auto pivot_ref = make_uniq(); - pivot_ref->source = std::move(source); - auto &pivot_aggregates = list_pr.Child(3); - if (pivot_aggregates.HasResult()) { - pivot_ref->aggregates = - transformer.Transform>>(pivot_aggregates.GetResult()); - } else { - // pivot but no aggregates specified - push a count star - vector> children; - auto function = make_uniq("count_star", std::move(children)); - pivot_ref->aggregates.push_back(std::move(function)); - } - if (pivot_group.HasResult()) { - pivot_ref->groups = transformer.Transform>(pivot_group.GetResult()); - } - pivot_ref->pivots = std::move(columns); - select_node->from_table = std::move(pivot_ref); - auto select_statement = make_uniq(); - select_statement->node = std::move(select_node); - return select_statement; -} - void PEGTransformerFactory::InitializePivotStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -293,79 +214,6 @@ bool PEGTransformerFactory::TransformExcludeNulls(PEGTransformer &transformer) { return false; } -unique_ptr PEGTransformerFactory::TransformUnpivotStatement(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto current_param_count = transformer.ParamCount(); - auto source = TransformTableRef(transformer, list_pr.GetChild(1)); - auto next_param_count = transformer.ParamCount(); - bool has_parameters = next_param_count > current_param_count; - auto target_list = transformer.Transform>>(list_pr.GetChild(3)); - auto &unpivot_names_opt = list_pr.Child(4); - vector columns; - UnpivotNameValues name_and_values; - if (!unpivot_names_opt.HasResult()) { - PivotColumn col; - col.unpivot_names.push_back("name"); - for (auto &expr : target_list) { - PivotColumnEntry entry; - entry.alias = expr->GetAlias(); - entry.expr = std::move(expr); - col.entries.push_back(std::move(entry)); - } - columns.push_back(std::move(col)); - } else { - name_and_values = transformer.Transform(unpivot_names_opt.GetResult()); - auto unpivot_list_size = name_and_values.column.unpivot_names.size(); - if (unpivot_list_size != 1) { - throw NotImplementedException("Only expected a single value after NAME, got %d instead.", - unpivot_list_size); - } - auto &col = name_and_values.column; - for (auto &expr : target_list) { - PivotColumnEntry entry; - entry.alias = expr->GetAlias(); - entry.expr = std::move(expr); - col.entries.push_back(std::move(entry)); - } - columns.push_back(std::move(col)); - } - - for (idx_t c = 0; c < columns.size(); c++) { - auto &col = columns[c]; - if (!col.pivot_enum.empty() || !col.entries.empty()) { - continue; - } - if (col.pivot_expressions.size() != 1) { - throw InternalException("PIVOT statement with multiple names in pivot entry!?"); - } - auto enum_name = "__pivot_enum_" + UUID::ToString(UUID::GenerateRandomUUID()); - - auto new_select = make_uniq(); - transformer.ExtractCTEsRecursive(new_select->cte_map); - new_select->from_table = source->Copy(); - AddPivotEntry(transformer, enum_name, std::move(new_select), col.pivot_expressions[0]->Copy(), - std::move(col.subquery), has_parameters); - col.pivot_enum = Identifier(enum_name); - } - - auto pivot_ref = make_uniq(); - pivot_ref->source = std::move(source); - if (!unpivot_names_opt.HasResult()) { - pivot_ref->unpivot_names.push_back("value"); - } else { - pivot_ref->unpivot_names = name_and_values.unpivot_names; - } - - auto result = make_uniq(); - pivot_ref->pivots = std::move(columns); - auto select_node = make_uniq(); - select_node->from_table = std::move(pivot_ref); - select_node->select_list.push_back(make_uniq()); - result->node = std::move(select_node); - return result; -} - void PEGTransformerFactory::InitializeUnpivotStatementTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); diff --git a/src/duckdb/src/parser/peg/transformer/transform_select.cpp b/src/duckdb/src/parser/peg/transformer/transform_select.cpp index 5b2d5a6b3..9e869dc71 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_select.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_select.cpp @@ -51,45 +51,6 @@ PEGTransformerFactory::TransformSelectStatement(PEGTransformer &transformer, return std::move(select_statement_internal); } -unique_ptr PEGTransformerFactory::TransformSelectStatementInternalRule(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - CommonTableExpressionMap cte_map; - transformer.TransformOptional(list_pr, 0, cte_map); - if (!cte_map.map.empty()) { - transformer.stored_cte_map.push_back(cte_map); - } - auto select_statement = transformer.Transform>(list_pr.Child(1)); - - vector> result_modifiers; - transformer.TransformOptional>>(list_pr, 2, result_modifiers); - if (!cte_map.map.empty()) { - // the CTEs are visible while transforming the select statement and its result modifiers - transformer.stored_cte_map.pop_back(); - select_statement->node->cte_map = std::move(cte_map); - } - for (auto &result_modifier : result_modifiers) { - select_statement->node->modifiers.push_back(std::move(result_modifier)); - } - if (select_statement->node->type != QueryNodeType::SELECT_NODE) { - return select_statement; - } - auto &select_node = select_statement->node->Cast(); - if (select_node.from_table->type != TableReferenceType::SHOW_REF) { - return select_statement; - } - auto &show_ref = select_node.from_table->Cast(); - if (!select_statement->node->cte_map.map.empty()) { - throw ParserException("%s with CTE not allowed - wrap the statement in a subquery instead", - EnumUtil::ToString(show_ref.show_type)); - } - if (!select_statement->node->modifiers.empty()) { - throw ParserException("%s with ORDER BY not allowed - wrap the statement in a subquery instead", - EnumUtil::ToString(show_ref.show_type)); - } - return select_statement; -} - static void PushSelectStatementInternalRemainder(GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); auto &result_modifiers_opt = list_pr.Child(2); @@ -264,34 +225,6 @@ bool PEGTransformerFactory::TransformWithOrdinality(PEGTransformer &transformer) return true; } -unique_ptr PEGTransformerFactory::TransformSimpleSelect(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto &opt_window_clause = list_pr.Child(4); - if (opt_window_clause.HasResult()) { - transformer.Transform>>(opt_window_clause.GetResult()); - } - auto select_node = transformer.Transform>(list_pr.Child(0)); - transformer.TransformOptional>(list_pr, 1, select_node->where_clause); - auto &group_opt = list_pr.Child(2); - if (group_opt.HasResult()) { - auto group_by_node = transformer.Transform(group_opt.GetResult()); - if (group_by_node.group_expressions.size() == 1 && ExpressionIsEmptyStar(*group_by_node.group_expressions[0])) { - select_node->aggregate_handling = AggregateHandling::FORCE_AGGREGATES; - group_by_node.group_expressions.clear(); - group_by_node.grouping_sets.clear(); - } - select_node->groups = std::move(group_by_node); - } - transformer.TransformOptional>(list_pr, 3, select_node->having); - transformer.TransformOptional>(list_pr, 5, select_node->qualify); - transformer.TransformOptional>(list_pr, 6, select_node->sample); - auto select_statement = make_uniq(); - select_statement->node = std::move(select_node); - transformer.window_clauses.clear(); - return select_statement; -} - static void RegisterWindowClause(PEGTransformer &transformer, const Identifier &window_name, WindowExpression &window_function) { auto it = transformer.window_clauses.find(window_name); @@ -442,32 +375,6 @@ QualifiedName PEGTransformerFactory::TransformSchemaReservedIdentifierOrStringLi return result; } -unique_ptr PEGTransformerFactory::TransformTableRef(PEGTransformer &transformer, ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - auto inner_table_ref = transformer.Transform>(list_pr.Child(0)); - auto &join_or_pivot_opt = list_pr.Child(1); - if (!join_or_pivot_opt.HasResult()) { - return inner_table_ref; - } - auto &repeat_join_or_pivot = join_or_pivot_opt.GetResult().Cast(); - for (auto join_or_pivot : repeat_join_or_pivot.GetChildren()) { - auto transform_join_or_pivot = transformer.Transform>(join_or_pivot); - if (transform_join_or_pivot->type == TableReferenceType::JOIN) { - auto &join_ref = transform_join_or_pivot->Cast(); - join_ref.left = std::move(inner_table_ref); - inner_table_ref = std::move(transform_join_or_pivot); - } else if (transform_join_or_pivot->type == TableReferenceType::PIVOT) { - auto &pivot_ref = transform_join_or_pivot->Cast(); - pivot_ref.source = std::move(inner_table_ref); - inner_table_ref = std::move(transform_join_or_pivot); - } else { - throw NotImplementedException("Unsupported TableRef type encountered: %s", - EnumUtil::ToString(transform_join_or_pivot->type)); - } - } - return inner_table_ref; -} - void PEGTransformerFactory::InitializeTableRefTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -1120,39 +1027,6 @@ PEGTransformerFactory::TransformGroupingSetsClause(PEGTransformer &transformer, return result; } -CommonTableExpressionMap PEGTransformerFactory::TransformWithClause(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - bool is_recursive = list_pr.Child(1).HasResult(); - auto with_statement_list = PEGTransformerFactory::ExtractParseResultsFromList(list_pr.Child(2)); - CommonTableExpressionMap result; - - for (idx_t entry_idx = 0; entry_idx < with_statement_list.size(); entry_idx++) { - auto with_entry = transformer.Transform>>( - with_statement_list[entry_idx]); - - if (is_recursive) { - auto &query_node = with_entry.second->query_node; - if (!query_node) { - throw ParserException("Recursive CTEs with DML statements are not supported"); - } - ValidateRecursiveCTEQueryNode(*query_node); - // Now safe to call on SELECT, VALUES, etc. - query_node = ToRecursiveCTE(std::move(query_node), with_entry.first, with_entry.second->aliases, - with_entry.second->key_targets); - } - auto &cte_name = with_entry.first; - - auto it = result.map.find(cte_name); - if (it != result.map.end()) { - // can't have two CTEs with same name - throw ParserException("Duplicate CTE name %s", cte_name); - } - result.map.insert(with_entry.first, std::move(with_entry.second)); - } - return result; -} - void PEGTransformerFactory::InitializeWithClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -1192,13 +1066,13 @@ PEGTransformerFactory::FinalizeWithClauseTrampoline(PEGTransformer &transformer, pair> PEGTransformerFactory::TransformWithStatement(PEGTransformer &transformer, const Identifier &col_id_or_string, - const optional> &insert_column_list, + const optional> &column_aliases, optional>> using_key, const optional &materialized, unique_ptr cte_body) { auto result = make_uniq(); auto cte_name = col_id_or_string; - if (insert_column_list) { - result->aliases = StringsToIdentifiers(*insert_column_list); + if (column_aliases) { + result->aliases = StringsToIdentifiers(*column_aliases); } if (using_key) { result->key_targets = std::move(*using_key); @@ -1256,17 +1130,6 @@ bool PEGTransformerFactory::TransformMaterialized(PEGTransformer &transformer, c return has_result; } -unique_ptr PEGTransformerFactory::TransformWindowDefinition(PEGTransformer &transformer, - ParseResult &parse_result) { - auto &list_pr = parse_result.Cast(); - transformer.in_window_definition = true; - auto window_function = transformer.Transform>(list_pr.Child(2)); - transformer.in_window_definition = false; - auto window_name = list_pr.Child(0).identifier; - RegisterWindowClause(transformer, window_name, *window_function); - return std::move(window_function); -} - void PEGTransformerFactory::InitializeWindowDefinitionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); diff --git a/src/duckdb/src/parser/tableref/table_function.cpp b/src/duckdb/src/parser/tableref/table_function.cpp index 735623a9a..53b798e6b 100644 --- a/src/duckdb/src/parser/tableref/table_function.cpp +++ b/src/duckdb/src/parser/tableref/table_function.cpp @@ -19,13 +19,21 @@ bool TableFunctionRef::Equals(const TableRef &other_p) const { return false; } auto &other = other_p.Cast(); - return function->Equals(*other.function); + return bind_info == other.bind_info && function->Equals(*other.function); +} + +const unique_ptr &TableFunctionRef::SerializableFunction() const { + if (bind_info) { + throw NotImplementedException("Cannot serialize a table function with process-local bind input"); + } + return function; } unique_ptr TableFunctionRef::Copy() { auto copy = make_uniq(); copy->function = function->Copy(); + copy->bind_info = bind_info; copy->column_name_alias = column_name_alias; copy->with_ordinality = with_ordinality; CopyProperties(*copy); diff --git a/src/duckdb/src/parser/token_iterator.cpp b/src/duckdb/src/parser/token_iterator.cpp index 0d9eab10e..7406e0029 100644 --- a/src/duckdb/src/parser/token_iterator.cpp +++ b/src/duckdb/src/parser/token_iterator.cpp @@ -10,9 +10,16 @@ TokenIterator::TokenIterator(unique_ptr> owned_tokens_p) if (!owned_tokens) { throw InternalException("Cannot construct an owning TokenIterator without tokens"); } + for (auto &token : tokens) { + token.ResetLiteralInfo(); + } } TokenIterator::TokenIterator(vector &tokens_p) : tokens(tokens_p) { + // A new root can receive tokens edited since an earlier match. + for (auto &token : tokens) { + token.ResetLiteralInfo(); + } } TokenIterator::TokenIterator(const TokenIterator &other) : tokens(other.tokens), position(other.position) { diff --git a/src/duckdb/src/planner/binder.cpp b/src/duckdb/src/planner/binder.cpp index 6d4553e6a..760557ccc 100644 --- a/src/duckdb/src/planner/binder.cpp +++ b/src/duckdb/src/planner/binder.cpp @@ -605,7 +605,7 @@ BoundStatement Binder::BindReturning(vector> return // returned, it should be guaranteed that the row has been inserted. // see https://github.com/duckdb/duckdb/issues/8310 auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::QUERY_RESULT; return result; } diff --git a/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp b/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp index ef6ca7e66..9dfe3d128 100644 --- a/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +++ b/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp @@ -114,6 +114,10 @@ static void NegatePercentileFractions(ClientContext &context, unique_ptrCast(), func, depth); + } if (inside_try) { throw BinderException("aggregates are not allowed inside the TRY expression"); } diff --git a/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp b/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp index 6d5f9a6af..0e18cec08 100644 --- a/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp +++ b/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp @@ -213,12 +213,11 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) if (uinteger_value) { // Array extraction: if the cast fails it's definitely out-of-bounds for a JSON array auto index = UIntegerValue::Get(*uinteger_value); - const_exp.GetValueMutable() = StringUtil::Format("$[%lld]", index); + const_exp.SetValue(StringUtil::Format("$[%lld]", index)); const_exp.SetReturnType(LogicalType::VARCHAR); } else if (const_exp.GetReturnType().id() == LogicalType::VARCHAR) { // Field extraction - const_exp.GetValueMutable() = - StringUtil::Format("$.\"%s\"", const_exp.GetValueMutable().ToString()); + const_exp.SetValue(StringUtil::Format("$.\"%s\"", const_exp.GetValue().ToString())); const_exp.SetReturnType(LogicalType::VARCHAR); } } @@ -227,9 +226,8 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) auto &i_exp = *children[1]; if (i_exp.GetExpressionClass() == ExpressionClass::BOUND_CONSTANT) { auto &const_exp = i_exp.Cast(); - if (!const_exp.GetValueMutable().IsNull() && const_exp.GetReturnType().IsIntegral()) { - const_exp.GetValueMutable() = - const_exp.GetValueMutable().DefaultCastAs(LogicalType::UINTEGER, true); + if (!const_exp.GetValue().IsNull() && const_exp.GetReturnType().IsIntegral()) { + const_exp.SetValue(const_exp.GetValue().DefaultCastAs(LogicalType::UINTEGER, true)); const_exp.SetReturnType(LogicalType::UINTEGER); } } @@ -266,8 +264,8 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) auto &i_exp = *children[1]; if (i_exp.GetExpressionClass() == ExpressionClass::BOUND_CONSTANT) { auto &const_exp = i_exp.Cast(); - if (!const_exp.GetValueMutable().IsNull()) { - const_exp.GetValueMutable() = StringUtil::Format("%s", const_exp.GetValueMutable().ToString()); + if (!const_exp.GetValue().IsNull()) { + const_exp.SetValue(StringUtil::Format("%s", const_exp.GetValue().ToString())); const_exp.SetReturnType(LogicalType::VARCHAR); } } @@ -276,9 +274,8 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) // Make sure we only extract fields, not array elements, by adding $. syntax if (name_exp.GetExpressionClass() == ExpressionClass::BOUND_CONSTANT) { auto &const_exp = name_exp.Cast(); - if (!const_exp.GetValueMutable().IsNull()) { - const_exp.GetValueMutable() = - StringUtil::Format("$.\"%s\"", const_exp.GetValueMutable().ToString()); + if (!const_exp.GetValue().IsNull()) { + const_exp.SetValue(StringUtil::Format("$.\"%s\"", const_exp.GetValue().ToString())); const_exp.SetReturnType(LogicalType::VARCHAR); } } diff --git a/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp b/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp index baa0825c3..f28df17bb 100644 --- a/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp +++ b/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp @@ -1,4 +1,5 @@ #include "duckdb/planner/binder.hpp" +#include "duckdb/planner/table_binding.hpp" #include "duckdb/parser/expression/star_expression.hpp" #include "duckdb/parser/expression/constant_expression.hpp" #include "duckdb/parser/expression/columnref_expression.hpp" @@ -9,6 +10,9 @@ #include "duckdb/function/scalar/regexp.hpp" #include "duckdb/parser/expression/function_expression.hpp" #include "duckdb/parser/expression/lambda_expression.hpp" +#include "duckdb/parser/expression/case_expression.hpp" +#include "duckdb/parser/expression/conjunction_expression.hpp" +#include "duckdb/parser/expression/window_expression.hpp" namespace duckdb { @@ -21,6 +25,20 @@ string GetColumnsStringValue(ParsedExpression &expr) { } } +static const vector &GetFunctionArguments(const ParsedExpression &expr) { + if (expr.GetExpressionClass() == ExpressionClass::WINDOW) { + return expr.Cast().GetArguments(); + } + return expr.Cast().GetArguments(); +} + +static vector &GetFunctionArgumentsMutable(ParsedExpression &expr) { + if (expr.GetExpressionClass() == ExpressionClass::WINDOW) { + return expr.Cast().GetArgumentsMutable(); + } + return expr.Cast().GetArgumentsMutable(); +} + StarExpressionType Binder::FindStarExpression(unique_ptr &expr, StarExpression **star, bool is_root, bool in_columns) { StarExpressionType has_star = StarExpressionType::NONE; @@ -89,7 +107,15 @@ StarExpressionType Binder::FindStarExpression(unique_ptr &expr *star = ¤t_star; has_star = StarExpressionType::STAR; } + // the star of COUNT(tbl.*) is rewritten when the aggregate is bound + optional_ptr count_star; + if (IsQualifiedCountStar(*expr)) { + count_star = &GetFunctionArguments(*expr)[0].GetExpression(); + } ParsedExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr &child_expr) { + if (child_expr.get() == count_star.get()) { + return; + } auto res = FindStarExpression(child_expr, star, false, in_columns); if (res != StarExpressionType::NONE) { has_star = res; @@ -254,6 +280,139 @@ optional_ptr Binder::GetResolvedColumnExpression(ParsedExpress return expr; } +static bool IsQualifiedStar(const ParsedExpression &expr) { + if (!StarExpression::IsStar(expr)) { + return false; + } + auto &star = expr.Cast(); + if (star.RelationName().empty()) { + return false; + } + if (!star.ExcludeList().empty()) { + return false; + } + if (!star.ReplaceList().empty()) { + return false; + } + if (!star.RenameList().empty()) { + return false; + } + return true; +} + +static bool IsCount(const Identifier &function_name, bool distinct) { + return function_name == "count" && !distinct; +} + +bool Binder::IsQualifiedCountStar(const ParsedExpression &expr) { + switch (expr.GetExpressionClass()) { + case ExpressionClass::FUNCTION: { + auto &function = expr.Cast(); + if (!IsCount(function.FunctionName(), function.Distinct())) { + return false; + } + break; + } + case ExpressionClass::WINDOW: { + auto &window = expr.Cast(); + if (!IsCount(window.FunctionName(), window.Distinct())) { + return false; + } + break; + } + default: + return false; + } + auto &arguments = GetFunctionArguments(expr); + return arguments.size() == 1 && IsQualifiedStar(arguments[0].GetExpression()); +} + +//! CASE WHEN col1 IS NOT NULL OR ... OR coln IS NOT NULL THEN 1 END +static unique_ptr AnyColumnNotNull(vector> columns) { + vector> checks; + for (auto &column : columns) { + checks.push_back(make_uniq(ExpressionType::OPERATOR_IS_NOT_NULL, std::move(column))); + } + auto case_expr = make_uniq(); + CaseCheck case_check; + case_check.when_expr = make_uniq(ExpressionType::CONJUNCTION_OR, std::move(checks)); + case_check.then_expr = ConstantExpression::FromValue(Value::BIGINT(1)); + case_expr->CaseChecksMutable().push_back(std::move(case_check)); + case_expr->ElseMutable() = ConstantExpression::FromValue(Value()); + return std::move(case_expr); +} + +static unique_ptr GetRowIdColumn(Binding &binding) { + if (binding.GetBindingType() != BindingType::TABLE) { + return nullptr; + } + auto &virtual_columns = binding.Cast().virtual_columns; + auto entry = virtual_columns.find(COLUMN_IDENTIFIER_ROW_ID); + if (entry == virtual_columns.end()) { + return nullptr; + } + column_t column_index; + if (!binding.TryGetBindingIndex(entry->second.name, column_index) || column_index != COLUMN_IDENTIFIER_ROW_ID) { + // the row id is shadowed by a regular column + return nullptr; + } + return make_uniq(entry->second.name, binding.GetBindingAlias()); +} + +//! Returns the argument that COUNT(tbl.*) counts, or nullptr if every row of tbl is counted +static unique_ptr GetCountStarArgument(StarExpression &star, BindContext &bind_context) { + if (bind_context.GetBindingsList().empty()) { + // nothing to resolve the relation against (e.g. when verifying a macro definition) + return nullptr; + } + ErrorData error; + auto binding = bind_context.GetBinding(star.RelationName(), error); + if (binding) { + if (!binding->IsNullExtended()) { + return nullptr; + } + auto row_id = GetRowIdColumn(*binding); + if (row_id) { + // the row id is only NULL for NULL-extended rows + return row_id; + } + // without a row id, a row in which all columns are NULL is indistinguishable from a NULL-extended row + vector> columns; + bind_context.GenerateAllColumnExpressions(star, columns); + return AnyColumnNotNull(std::move(columns)); + } + // struct.* + auto struct_binding = bind_context.GetMatchingBinding(star.RelationName(), star); + if (!struct_binding) { + error.Throw(); + } + if (!struct_binding->IsNullExtended()) { + return nullptr; + } + return make_uniq(star.RelationName(), struct_binding->GetBindingAlias()); +} + +//! COUNT(tbl.*) counts every row of tbl, except for the rows that an outer join NULL-extended +unique_ptr Binder::TryRewriteQualifiedCountStar(const ParsedExpression &expr) { + if (!IsQualifiedCountStar(expr)) { + return nullptr; + } + auto result = expr.Copy(); + if (result->GetAlias().empty()) { + // the rewrite is an implementation detail - keep the original expression as the name + result->SetAlias(Identifier(expr.ToString())); + } + auto &arguments = GetFunctionArgumentsMutable(*result); + auto &star = arguments[0].GetExpressionMutable()->Cast(); + auto count_argument = GetCountStarArgument(star, bind_context); + if (count_argument) { + arguments[0] = FunctionArgument(std::move(count_argument)); + } else { + arguments.clear(); + } + return result; +} + void Binder::ExpandStarExpression(unique_ptr expr, vector> &new_select_list) { TryTransformStarLike(expr); diff --git a/src/duckdb/src/planner/binder/expression/bind_window_expression.cpp b/src/duckdb/src/planner/binder/expression/bind_window_expression.cpp index 4cb18fcc5..4fd95ebea 100644 --- a/src/duckdb/src/planner/binder/expression/bind_window_expression.cpp +++ b/src/duckdb/src/planner/binder/expression/bind_window_expression.cpp @@ -8,6 +8,7 @@ #include "duckdb/parser/expression/constant_expression.hpp" #include "duckdb/parser/expression/function_expression.hpp" #include "duckdb/parser/expression/window_expression.hpp" +#include "duckdb/planner/binder.hpp" #include "duckdb/planner/expression/bound_aggregate_expression.hpp" #include "duckdb/planner/expression/bound_cast_expression.hpp" #include "duckdb/planner/expression/bound_columnref_expression.hpp" @@ -87,6 +88,10 @@ BindResult BaseSelectBinder::BindWindowExpression(WindowExpression &window, idx_ std::move(window.FilterMutable()), nullptr, window.Distinct()); return BindMacro(*macro, entry->Cast(), depth, macro_expr); } + auto count_star = binder.TryRewriteQualifiedCountStar(window); + if (count_star) { + return BindWindowExpression(count_star->Cast(), depth); + } auto name = window.GetAlias(); @@ -290,6 +295,15 @@ BindResult BaseSelectBinder::BindWindowExpression(WindowExpression &window, idx_ result->IgnoreNullsMutable() = window.IgnoreNulls(); result->DistinctMutable() = window.Distinct(); + const bool range_start = window.WindowStart() == WindowBoundary::EXPR_PRECEDING_RANGE || + window.WindowStart() == WindowBoundary::EXPR_FOLLOWING_RANGE; + const bool range_end = window.WindowEnd() == WindowBoundary::EXPR_PRECEDING_RANGE || + window.WindowEnd() == WindowBoundary::EXPR_FOLLOWING_RANGE; + if ((range_start || range_end) && bound_orders.size() == 1) { + result->RetainSQLRange(range_start ? bound_start.get() : nullptr, range_end ? bound_end.get() : nullptr, + bound_orders[0]->GetReturnType()); + } + // Convert RANGE boundary expressions to ORDER +/- expressions. // Note that PRECEDING and FOLLOWING refer to the sequential order in the frame, // not the natural ordering of the type. This means that the offset arithmetic must be reversed diff --git a/src/duckdb/src/planner/binder/query_node/bind_recursive_cte_node.cpp b/src/duckdb/src/planner/binder/query_node/bind_recursive_cte_node.cpp index 87a26ffaa..8bf83d31b 100644 --- a/src/duckdb/src/planner/binder/query_node/bind_recursive_cte_node.cpp +++ b/src/duckdb/src/planner/binder/query_node/bind_recursive_cte_node.cpp @@ -101,10 +101,11 @@ BoundStatement Binder::BindNode(RecursiveCTENode &statement) { QueryErrorContext error_context(expr->GetQueryLocation()); - EntryLookupInfo function_lookup(CatalogType::AGGREGATE_FUNCTION_ENTRY, - QualifiedName(func_expr.FunctionName()), error_context); - auto entry = GetCatalogEntry(func_expr.GetQualifiedName().Catalog(), Identifier::DefaultSchema(), - function_lookup, OnEntryNotFound::RETURN_NULL); + auto function_name = func_expr.GetQualifiedName(); + BindSchemaOrCatalog(function_name); + EntryLookupInfo function_lookup(CatalogType::AGGREGATE_FUNCTION_ENTRY, BindTableName(function_name), + error_context); + auto entry = GetCatalogEntry(function_lookup, OnEntryNotFound::RETURN_NULL); if (!entry || entry->type != CatalogType::AGGREGATE_FUNCTION_ENTRY) { throw BinderException( diff --git a/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp b/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp index 66281e15e..237cbc936 100644 --- a/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp +++ b/src/duckdb/src/planner/binder/query_node/bind_trigger_expansion.cpp @@ -460,7 +460,7 @@ BoundStatement Binder::ExpandTriggers(QueryNode &node, TableCatalogEntry &table, if (!has_returning) { auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::CHANGED_ROWS; return chain; } @@ -533,7 +533,7 @@ BoundStatement Binder::ExpandTriggers(QueryNode &node, TableCatalogEntry &table, result.plan = std::move(returning_projection); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::QUERY_RESULT; return result; } @@ -720,7 +720,7 @@ BoundStatement Binder::ExpandRowTriggers(QueryNode &node, vector`): the resource already exists — the physical operator + // looks it up in the manager at execution. Nothing to resolve here. + if (!external_resource.reference_name.empty()) { + return; + } + + // Create form (`NEW TEMPORARY EXTERNAL RESOURCE '' (opts)`): the type is a string literal set by the + // parser, so only the create params need resolving. + BindExternalResourceParams(external_resource.parsed_params, external_resource.params); + external_resource.parsed_params.clear(); +} + BoundStatement Binder::Bind(AttachStatement &stmt) { BoundStatement result; result.types = {LogicalType::BOOLEAN}; @@ -37,10 +51,15 @@ BoundStatement Binder::Bind(AttachStatement &stmt) { } stmt.info->parsed_options.clear(); + // Bind the external resource clause (ATTACH/CONNECT TO EXTERNAL RESOURCE ...): resolve the type + create params. + if (stmt.info->external_resource) { + BindExternalResource(*stmt.info->external_resource); + } + result.plan = make_uniq(std::move(stmt.info)); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::NOTHING; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_call.cpp b/src/duckdb/src/planner/binder/statement/bind_call.cpp index 32ee6fa34..9f602b671 100644 --- a/src/duckdb/src/planner/binder/statement/bind_call.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_call.cpp @@ -17,7 +17,7 @@ BoundStatement Binder::Bind(CallStatement &stmt) { // CALL is `SELECT * FROM func()` (which already propagates call_return_type) forced to materialize. auto result = Bind(select_statement); - GetStatementProperties().output_type = QueryResultOutputType::FORCE_MATERIALIZED; + GetStatementProperties().result_eagerness = ResultEagerness::FORCED; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_connect.cpp b/src/duckdb/src/planner/binder/statement/bind_connect.cpp index e8a237b5e..b6f196b40 100644 --- a/src/duckdb/src/planner/binder/statement/bind_connect.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_connect.cpp @@ -29,10 +29,15 @@ BoundStatement Binder::Bind(ConnectStatement &stmt) { stmt.info->parsed_options.clear(); } + // Bind the external resource clause (ATTACH/CONNECT TO EXTERNAL RESOURCE ...): resolve the type + create params. + if (stmt.info->external_resource) { + BindExternalResource(*stmt.info->external_resource); + } + result.plan = make_uniq(std::move(stmt.info)); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::NOTHING; return result; } @@ -45,7 +50,7 @@ BoundStatement Binder::Bind(DisconnectStatement &stmt) { result.plan = make_uniq(std::move(stmt.info)); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::NOTHING; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_copy.cpp b/src/duckdb/src/planner/binder/statement/bind_copy.cpp index fbc5cb59b..f3579c2f8 100644 --- a/src/duckdb/src/planner/binder/statement/bind_copy.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_copy.cpp @@ -11,6 +11,7 @@ #include "duckdb/main/client_context.hpp" #include "duckdb/main/database.hpp" #include "duckdb/parser/expression/columnref_expression.hpp" +#include "duckdb/parser/expression/function_expression.hpp" #include "duckdb/parser/expression/star_expression.hpp" #include "duckdb/parser/query_node/select_node.hpp" #include "duckdb/parser/statement/copy_statement.hpp" @@ -21,6 +22,7 @@ #include "duckdb/parser/tableref/basetableref.hpp" #include "duckdb/parser/tableref/column_data_ref.hpp" #include "duckdb/planner/binder.hpp" +#include "duckdb/planner/expression/bound_reference_expression.hpp" #include "duckdb/planner/operator/logical_column_data_get.hpp" #include "duckdb/planner/operator/logical_copy_to_file.hpp" #include "duckdb/planner/operator/logical_get.hpp" @@ -130,6 +132,7 @@ struct CopyToParsedOptions { optional hive_file_pattern; optional preserve_order; optional return_type; + unique_ptr partition_path; bool UserSetUseTmpFile() const { return use_tmp_file.has_value(); @@ -209,6 +212,8 @@ struct CopyToResolvedOptions { bool hive_file_pattern = true; PreserveOrderType preserve_order = PreserveOrderType::AUTOMATIC; CopyFunctionReturnType return_type = CopyFunctionReturnType::CHANGED_ROWS; + //! Unbound, as it is bound against the partition columns + unique_ptr partition_path; bool Rotate() const { return file_size_bytes.IsValid() || batches_per_file.IsValid(); @@ -265,6 +270,7 @@ static CopyToResolvedOptions ResolveCopyToOptions(ClientContext &context, const result.hive_file_pattern = options.HiveFilePattern(); result.preserve_order = options.PreserveOrder(); result.return_type = options.ReturnType(); + result.partition_path = std::move(options.partition_path); return result; } @@ -306,6 +312,14 @@ static void ValidateCopyToOptionCombinations(const CopyToParsedOptions &options, throw NotImplementedException("Can't combine WRITE_EMPTY_FILE false with ORDER BY"); } } + if (options.partition_path) { + if (!options.Partitioned()) { + throw BinderException("PARTITION_PATH requires PARTITION_BY"); + } + if (options.hive_file_pattern.has_value()) { + throw BinderException("Can't combine HIVE_FILE_PATTERN and PARTITION_PATH for COPY"); + } + } if (options.ReturnType() == CopyFunctionReturnType::WRITTEN_FILE_STATISTICS && !function.copy_to_get_written_statistics) { throw NotImplementedException("RETURN_STATS is not supported for the \"%s\" copy format", format); @@ -319,10 +333,70 @@ static void ValidateCopyToOutputColumns(const CopyToResolvedOptions &options, id } } +//! Binds the PARTITION_PATH expression, which may only reference partition columns. Partition column i (in PARTITION_BY +//! order) is bound as reference i. +class PartitionPathBinder : public ExpressionBinder { +public: + PartitionPathBinder(Binder &binder, ClientContext &context, const vector &names, + const vector &types, const vector &partition_columns) + : ExpressionBinder(binder, context), names(names), types(types), partition_columns(partition_columns) { + target_type = LogicalType::VARCHAR; + } + +protected: + BindResult BindExpression(unique_ptr &expr_ptr, idx_t depth, bool root_expression) override { + auto &expr = *expr_ptr; + switch (expr.GetExpressionClass()) { + case ExpressionClass::WINDOW: + return BindResult(BinderException::Unsupported(expr, "window functions are not allowed in PARTITION_PATH")); + case ExpressionClass::SUBQUERY: + return BindResult(BinderException::Unsupported(expr, "cannot use subquery in PARTITION_PATH")); + case ExpressionClass::COLUMN_REF: + return BindColumnReference(expr.Cast()); + default: + return ExpressionBinder::BindExpression(expr_ptr, depth, root_expression); + } + } + + BindResult BindLambdaFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry &function, + idx_t depth) override { + return BindResult(BinderException::Unsupported(expr, "lambda functions are not allowed in PARTITION_PATH")); + } + + string UnsupportedAggregateMessage() override { + return "aggregate functions are not allowed in PARTITION_PATH"; + } + +private: + BindResult BindColumnReference(ColumnRefExpression &col_ref) { + if (col_ref.ColumnNames().size() == 1) { + auto &column_name = col_ref.GetColumnName(); + for (idx_t i = 0; i < partition_columns.size(); i++) { + auto column_idx = partition_columns[i]; + if (names[column_idx] == column_name) { + return BindResult(make_uniq(types[column_idx], i)); + } + } + } + throw BinderException(col_ref, "Column \"%s\" referenced in PARTITION_PATH is not a PARTITION_BY column", + col_ref.ToString()); + } + +private: + const vector &names; + const vector &types; + const vector &partition_columns; +}; + BoundStatement Binder::BindCopyTo(CopyStatement &stmt, const CopyFunction &function, CopyToType copy_to_type) { if (function.plan) { // plan rewrite COPY TO - return function.plan(*this, stmt); + auto result = function.plan(*this, stmt); + // a rewrite that re-binds the COPY consumes PARTITION_PATH + if (stmt.info && stmt.info->parsed_options.find("partition_path") != stmt.info->parsed_options.end()) { + throw NotImplementedException("PARTITION_PATH is not supported for FORMAT \"%s\"", stmt.info->format); + } + return result; } auto ©_info = *stmt.info; @@ -337,6 +411,11 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt, const CopyFunction &funct } CopyToParsedOptions parsed_options; + auto partition_path_entry = stmt.info->parsed_options.find("partition_path"); + if (partition_path_entry != stmt.info->parsed_options.end()) { + parsed_options.partition_path = std::move(partition_path_entry->second); + stmt.info->parsed_options.erase(partition_path_entry); + } CopyFunctionBindInput bind_input(*stmt.info, function.function_info); bind_input.file_extension = function.extension; @@ -480,6 +559,16 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt, const CopyFunction &funct select_node.types, resolved_options.partition_cols, resolved_options.write_partition_columns); auto function_data = function.copy_to_bind(context, bind_input, names_to_write, types_to_write); + unique_ptr partition_path_expression; + if (resolved_options.partition_path) { + PartitionPathBinder partition_path_binder(*this, context, select_node.names, select_node.types, + resolved_options.partition_cols); + partition_path_expression = partition_path_binder.Bind(resolved_options.partition_path); + if (partition_path_expression->HasParameter()) { + throw ParameterNotResolvedException(); + } + } + // now create the copy information auto copy = make_uniq(function, std::move(function_data), std::move(stmt.info), GenerateTableIndex()); @@ -502,6 +591,7 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt, const CopyFunction &funct copy->preserve_order = resolved_options.preserve_order; copy->hive_file_pattern = resolved_options.hive_file_pattern; copy->order_columns = std::move(resolved_options.order_columns); + copy->partition_path_expression = std::move(partition_path_expression); copy->names = unique_column_names; copy->expected_types = select_node.types; @@ -687,7 +777,16 @@ void Binder::BindCopyOptions(CopyInfo &info) { info.file_path = inputs[0].ToString(); info.file_path_expression.reset(); } + unique_ptr partition_path; for (auto &[option_name, option_expr] : info.parsed_options) { + if (option_name == "partition_path") { + // bound later against the partition columns + if (!option_expr) { + throw BinderException("PARTITION_PATH expects an expression"); + } + partition_path = std::move(option_expr); + continue; + } auto inputs = BindCopyOption(context, option_binder, option_name, option_expr); if (option_name == "format") { // format specifier: interpret this option @@ -704,11 +803,17 @@ void Binder::BindCopyOptions(CopyInfo &info) { info.format = ExtractFormat(info.file_path); } info.parsed_options.clear(); + if (partition_path) { + info.parsed_options["partition_path"] = std::move(partition_path); + } } BoundStatement Binder::Bind(CopyStatement &stmt, CopyToType copy_to_type) { // bind the copy options BindCopyOptions(*stmt.info); + if (stmt.info->is_from && stmt.info->parsed_options.find("partition_path") != stmt.info->parsed_options.end()) { + throw InvalidInputException("Option partition_path is not supported for reading - only for writing"); + } if (!stmt.info->is_from && !stmt.info->select_statement) { // copy table into file without a query @@ -825,7 +930,7 @@ BoundStatement Binder::Bind(CopyStatement &stmt, CopyToType copy_to_type) { } auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::CHANGED_ROWS; if (stmt.info->is_from) { return BindCopyFrom(stmt, function); diff --git a/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp b/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp index 7e872df0a..beb487b31 100644 --- a/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp @@ -128,7 +128,7 @@ BoundStatement Binder::Bind(CopyDatabaseStatement &stmt) { result.plan = std::move(plan); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::NOTHING; DatabaseModificationType modification; diff --git a/src/duckdb/src/planner/binder/statement/bind_create.cpp b/src/duckdb/src/planner/binder/statement/bind_create.cpp index 079242fbf..ff37ab62c 100644 --- a/src/duckdb/src/planner/binder/statement/bind_create.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_create.cpp @@ -13,6 +13,7 @@ #include "duckdb/main/database.hpp" #include "duckdb/main/database_manager.hpp" #include "duckdb/main/secret/secret_manager.hpp" +#include "duckdb/optimizer/remote_pushdown_optimizer.hpp" #include "duckdb/parser/constraints/foreign_key_constraint.hpp" #include "duckdb/parser/constraints/list.hpp" #include "duckdb/parser/constraints/unique_constraint.hpp" @@ -87,7 +88,11 @@ void Binder::BindSchemaOrCatalog(CatalogEntryRetriever &retriever, Identifier &c auto &search_path = retriever.GetSearchPath(); auto catalog_names = search_path.GetCatalogsForSchema(schema); if (catalog_names.empty()) { - catalog_names.emplace_back(DatabaseManager::GetDefaultDatabase(context)); + // with no default database there is no schema for the name to be ambiguous with + auto default_database = DatabaseManager::TryGetDefaultDatabase(context); + if (!IsInvalidCatalog(default_database)) { + catalog_names.emplace_back(std::move(default_database)); + } } for (auto &catalog_name : catalog_names) { auto catalog_ptr = Catalog::GetCatalogEntry(retriever, catalog_name); @@ -365,6 +370,12 @@ void Binder::BindView(ClientContext &context, const SelectStatement &stmt, const } void Binder::BindCreateViewInfo(CreateViewInfo &base) { + // references to the view's own catalog are resolved through the view's search path anyway - drop the qualifier so + // the view keeps working when the database is attached under a different alias + auto &view_catalog = base.GetQualifiedName().Catalog(); + if (base.query && !view_catalog.empty()) { + RemotePushdownOptimizer::StripCatalogName(*base.query, view_catalog); + } if (base.binding_mode == CreateViewBindingMode::SKIP_BINDING) { return; } @@ -842,7 +853,6 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { auto catalog_type = stmt.info->type; auto return_type = StatementReturnType::NOTHING; - auto output_type = QueryResultOutputType::FORCE_MATERIALIZED; auto &properties = GetStatementProperties(); switch (catalog_type) { case CatalogType::SCHEMA_ENTRY: { @@ -1094,7 +1104,7 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { } properties.return_type = return_type; - properties.output_type = output_type; + properties.result_eagerness = ResultEagerness::FORCED; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_create_table.cpp b/src/duckdb/src/planner/binder/statement/bind_create_table.cpp index 5dfa3e9e0..02c26da6c 100644 --- a/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_create_table.cpp @@ -727,7 +727,7 @@ unique_ptr Binder::BindCreateTableInfo(unique_ptr &expr) { + TableFunctionBinder binder(*this, context, "External resource", "External resource parameter"); + auto bound = binder.Bind(expr); + return ExpressionExecutor::EvaluateScalar(context, *bound); +} + +void Binder::BindExternalResourceParams(case_insensitive_map_t> &parsed_params, + unordered_map ¶ms) { + for (auto &entry : parsed_params) { + params[entry.first] = BindExternalResourceValue(entry.second); + } +} + BoundStatement Binder::Bind(ExternalResourceStatement &stmt) { if (stmt.operation == ExternalResourceOperation::SHOW) { // SHOW [ALL] EXTERNAL RESOURCES desugars to `SELECT * FROM duckdb_external_resources(all := )`. @@ -31,7 +44,7 @@ BoundStatement Binder::Bind(ExternalResourceStatement &stmt) { select_statement.node = std::move(select_node); auto show_result = Bind(select_statement); - GetStatementProperties().output_type = QueryResultOutputType::FORCE_MATERIALIZED; + GetStatementProperties().result_eagerness = ResultEagerness::FORCED; return show_result; } @@ -39,12 +52,6 @@ BoundStatement Binder::Bind(ExternalResourceStatement &stmt) { result.types = {LogicalType::BOOLEAN}; result.names = {"Success"}; - TableFunctionBinder binder(*this, context, "External resource", "External resource parameter"); - auto eval = [&](unique_ptr &expr) { - auto bound = binder.Bind(expr); - return ExpressionExecutor::EvaluateScalar(context, *bound); - }; - BoundExternalResource data; data.operation = stmt.operation; data.name = stmt.name.GetIdentifierName(); @@ -57,11 +64,9 @@ BoundStatement Binder::Bind(ExternalResourceStatement &stmt) { if (stmt.operation != ExternalResourceOperation::DESTROY) { // CREATE / REGISTER: the resource type is a string literal; only the create params need resolving. data.type = stmt.type; - for (auto &entry : stmt.options) { - data.params[entry.first] = eval(entry.second); - } + BindExternalResourceParams(stmt.options, data.params); if (stmt.operation == ExternalResourceOperation::REGISTER) { - data.handle = eval(stmt.handle); + data.handle = BindExternalResourceValue(stmt.handle); if (data.handle.IsNull()) { throw BinderException("REGISTER EXTERNAL RESOURCE: the handle must not be NULL"); } @@ -71,7 +76,7 @@ BoundStatement Binder::Bind(ExternalResourceStatement &stmt) { result.plan = make_uniq(std::move(data)); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::NOTHING; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_insert.cpp b/src/duckdb/src/planner/binder/statement/bind_insert.cpp index 0f20c2eca..f5b54de11 100644 --- a/src/duckdb/src/planner/binder/statement/bind_insert.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_insert.cpp @@ -719,7 +719,7 @@ BoundStatement Binder::BindNode(InsertQueryNode &node) { result.plan = std::move(insert); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::CHANGED_ROWS; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_load.cpp b/src/duckdb/src/planner/binder/statement/bind_load.cpp index 8bcf5c90e..291295f14 100644 --- a/src/duckdb/src/planner/binder/statement/bind_load.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_load.cpp @@ -31,7 +31,7 @@ BoundStatement Binder::Bind(LoadStatement &stmt) { result.plan = make_uniq(std::move(stmt.info)); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = load_type == LoadType::CREATE_REPOSITORY ? StatementReturnType::QUERY_RESULT : StatementReturnType::NOTHING; return result; diff --git a/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp b/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp index ad7dbe43b..e1b5fe86f 100644 --- a/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp @@ -26,7 +26,7 @@ BoundStatement Binder::Bind(LogicalPlanStatement &stmt) { result.plan = std::move(stmt.plan); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::ALLOW_STREAMING; + properties.result_eagerness = ResultEagerness::AUTO; properties.return_type = StatementReturnType::QUERY_RESULT; // TODO could also be something else if (parent) { diff --git a/src/duckdb/src/planner/binder/statement/bind_merge_into.cpp b/src/duckdb/src/planner/binder/statement/bind_merge_into.cpp index b034a266c..46dcfb8f6 100644 --- a/src/duckdb/src/planner/binder/statement/bind_merge_into.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_merge_into.cpp @@ -463,7 +463,7 @@ BoundStatement Binder::BindNode(MergeQueryNode &node) { result.types = {LogicalType::BIGINT}; auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::CHANGED_ROWS; return result; } diff --git a/src/duckdb/src/planner/binder/statement/bind_prepare.cpp b/src/duckdb/src/planner/binder/statement/bind_prepare.cpp index 4c0579726..74f0953cc 100644 --- a/src/duckdb/src/planner/binder/statement/bind_prepare.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_prepare.cpp @@ -20,7 +20,7 @@ BoundStatement Binder::Bind(PrepareStatement &stmt) { // this is required because most clients ALWAYS invoke prepared statements auto &properties = GetStatementProperties(); properties.requires_valid_transaction = false; - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.bound_all_parameters = true; properties.parameter_count = 0; properties.return_type = StatementReturnType::NOTHING; diff --git a/src/duckdb/src/planner/binder/statement/bind_select.cpp b/src/duckdb/src/planner/binder/statement/bind_select.cpp index f878587f9..15221a46a 100644 --- a/src/duckdb/src/planner/binder/statement/bind_select.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_select.cpp @@ -7,7 +7,7 @@ namespace duckdb { BoundStatement Binder::Bind(SelectStatement &stmt) { auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::ALLOW_STREAMING; + properties.result_eagerness = ResultEagerness::AUTO; properties.return_type = StatementReturnType::QUERY_RESULT; auto result = Bind(*stmt.node); // A bare table-function passthrough honors the function's call_return_type (e.g. a CONNECT-routed diff --git a/src/duckdb/src/planner/binder/statement/bind_update.cpp b/src/duckdb/src/planner/binder/statement/bind_update.cpp index 9b146b998..85abb3144 100644 --- a/src/duckdb/src/planner/binder/statement/bind_update.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_update.cpp @@ -285,7 +285,7 @@ BoundStatement Binder::BindNode(UpdateQueryNode &node) { result.plan = std::move(update); auto &properties = GetStatementProperties(); - properties.output_type = QueryResultOutputType::FORCE_MATERIALIZED; + properties.result_eagerness = ResultEagerness::FORCED; properties.return_type = StatementReturnType::CHANGED_ROWS; return result; } diff --git a/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp b/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp index aad01499b..efec48b5c 100644 --- a/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +++ b/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp @@ -344,8 +344,10 @@ BoundStatement Binder::Bind(BaseTableRef &ref) { auto root_index = bound_child.plan->GetRootIndex(); if (view_catalog_entry.security_type == ViewSecurityType::SECURE_VIEW) { // wrap the plan of a secure view - this prevents the optimizer from pushing into the view - bound_child.plan = - make_uniq(view_catalog_entry.name.GetIdentifierName(), std::move(bound_child.plan)); + bound_child.plan = make_uniq( + view_catalog_entry.name.GetIdentifierName(), + view_catalog_entry.ParentSchema().GetQualifiedName(view_catalog_entry.name), bound_child.types, + entry_at_clause, std::move(bound_child.plan)); } bind_context.AddView(root_index, subquery.alias, subquery, bound_child, view_catalog_entry); return bound_child; diff --git a/src/duckdb/src/planner/binder/tableref/bind_expressionlistref.cpp b/src/duckdb/src/planner/binder/tableref/bind_expressionlistref.cpp index 40722ec1e..d91ae8a6f 100644 --- a/src/duckdb/src/planner/binder/tableref/bind_expressionlistref.cpp +++ b/src/duckdb/src/planner/binder/tableref/bind_expressionlistref.cpp @@ -2,12 +2,35 @@ #include "duckdb/parser/tableref/expressionlistref.hpp" #include "duckdb/planner/expression_binder/insert_binder.hpp" #include "duckdb/common/to_string.hpp" +#include "duckdb/logging/logger.hpp" #include "duckdb/planner/expression/bound_cast_expression.hpp" #include "duckdb/planner/operator/logical_expression_get.hpp" #include "duckdb/planner/operator/logical_dummy_scan.hpp" namespace duckdb { +static void WarnIfDecimalScaleIsReduced(ClientContext &context, const LogicalType &source_type, + const LogicalType &target_type, idx_t column_idx, + vector &warned_about_scale_reduction) { + if (warned_about_scale_reduction[column_idx]) { + return; + } + if (source_type.id() != LogicalTypeId::DECIMAL || target_type.id() != LogicalTypeId::DECIMAL) { + return; + } + auto source_scale = DecimalType::GetScale(source_type); + auto target_scale = DecimalType::GetScale(target_type); + if (source_scale <= target_scale) { + return; + } + DUCKDB_LOG_WARNING(context, + "Potential loss of decimal precision while resolving a VALUES column: type %s is being cast " + "to %s, reducing the scale from %d to %d. This may cause values to be rounded. Explicitly " + "cast all values to a compatible DECIMAL type to avoid this warning.", + source_type.ToString(), target_type.ToString(), source_scale, target_scale); + warned_about_scale_reduction[column_idx] = true; +} + BoundStatement Binder::Bind(ExpressionListRef &expr) { BoundStatement result; result.types = expr.expected_types; @@ -85,14 +108,17 @@ BoundStatement Binder::Bind(ExpressionListRef &expr) { type = LogicalType::NormalizeType(type); } // finally do another loop over the expressions and add casts where required + vector warned_about_scale_reduction(result.types.size(), false); for (idx_t list_idx = 0; list_idx < values.size(); list_idx++) { auto &list = values[list_idx]; for (idx_t val_idx = 0; val_idx < list.size(); val_idx++) { if (!should_infer[val_idx]) { continue; } - list[val_idx] = - BoundCastExpression::AddCastToType(context, std::move(list[val_idx]), result.types[val_idx]); + auto source_type = ExpressionBinder::GetExpressionReturnType(*list[val_idx]); + auto &target_type = result.types[val_idx]; + WarnIfDecimalScaleIsReduced(context, source_type, target_type, val_idx, warned_about_scale_reduction); + list[val_idx] = BoundCastExpression::AddCastToType(context, std::move(list[val_idx]), target_type); } } } diff --git a/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp b/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp index e4c96f7ec..4bd8d8543 100644 --- a/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +++ b/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp @@ -365,6 +365,18 @@ BoundStatement Binder::Bind(JoinRef &ref) { } } + // a positional join pads the shorter side with NULLs + const bool full_outer = result->type == JoinType::OUTER || ref.ref_type == JoinRefType::POSITIONAL; + if (result->type == JoinType::LEFT || full_outer) { + for (auto &binding : right_binder.bind_context.GetBindingsList()) { + binding->SetNullExtended(); + } + } + if (result->type == JoinType::RIGHT || full_outer) { + for (auto &binding : left_binder.bind_context.GetBindingsList()) { + binding->SetNullExtended(); + } + } auto right_bindings = right_binder.bind_context.GetBindingAliases(); auto left_bindings = left_binder.bind_context.GetBindingAliases(); bind_context.AddContext(std::move(left_binder.bind_context)); diff --git a/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp b/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp index 292ab624b..ac3719064 100644 --- a/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +++ b/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp @@ -314,8 +314,10 @@ BoundStatement Binder::BindTableFunctionInternal(TableFunction &table_function, auto get = make_uniq(bind_index, table_function, std::move(bind_data), return_types, return_names, virtual_columns); + get->bind_info = ref.bind_info; get->parameters = parameters; get->named_parameters = named_parameters; + get->source_ordinality = ref.with_ordinality; get->input_table_types = input_table_types; get->input_table_names = input_table_names; if (ref.with_ordinality == OrdinalityType::WITH_ORDINALITY && !correlated_columns.empty()) { diff --git a/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp b/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp index 4b471496c..baa5c7525 100644 --- a/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp +++ b/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp @@ -157,12 +157,16 @@ static bool CreateJoinCondition(Expression &expr, const unordered_setGetExpressionType()) && CreateJoinCondition(*expr, left_bindings, right_bindings, conditions)) { continue; diff --git a/src/duckdb/src/planner/bound_expression_sql_exporter.cpp b/src/duckdb/src/planner/bound_expression_sql_exporter.cpp index 8307a5c1e..eb504ed13 100644 --- a/src/duckdb/src/planner/bound_expression_sql_exporter.cpp +++ b/src/duckdb/src/planner/bound_expression_sql_exporter.cpp @@ -764,7 +764,8 @@ class BoundExpressionSQLExportState { issues.push_back(InternalInvariant(child_path, "Bound expression has a null child")); continue; } - if (expected_types[child_index] && source[child_index]->GetReturnType() != *expected_types[child_index]) { + if (expected_types[child_index].has_value() && + source[child_index]->GetReturnType() != expected_types[child_index].value()) { issues.push_back(InternalExpressionInvariant(child_path, *source[child_index], "Bound expression child has an unexpected type")); continue; diff --git a/src/duckdb/src/planner/expression.cpp b/src/duckdb/src/planner/expression.cpp index 5da7f0522..c33e9ecc4 100644 --- a/src/duckdb/src/planner/expression.cpp +++ b/src/duckdb/src/planner/expression.cpp @@ -13,6 +13,13 @@ Expression::Expression(ExpressionType type, ExpressionClass expression_class, Lo : BaseExpression(type, expression_class), return_type(std::move(return_type)) { } +unique_ptr Expression::PreserveReturnType(const LogicalType &type, unique_ptr replacement) { + D_ASSERT(replacement); + D_ASSERT(replacement->GetReturnType() == type); + replacement->SetReturnType(type); + return replacement; +} + Expression::~Expression() { } diff --git a/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp b/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp index a596224a3..f98bd5d44 100644 --- a/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp +++ b/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp @@ -154,13 +154,13 @@ unique_ptr BoundAggregateExpression::Deserialize(Deserializer &deser if (!return_type.IsAggregateState()) { throw SerializationException("Aggregate State export should return an aggregate state type"); } - ExportAggregateFunction::SetStateExport(*result, std::move(return_type)); + ExportAggregateFunction::SetStateExport(*result, return_type); } else if (result->return_type != return_type) { // return type mismatch - push a cast auto &context = deserializer.Get(); return BoundCastExpression::AddCastToType(context, std::move(result), return_type); } - return std::move(result); + return Expression::PreserveReturnType(return_type, std::move(result)); } } // namespace duckdb diff --git a/src/duckdb/src/planner/expression/bound_constant_expression.cpp b/src/duckdb/src/planner/expression/bound_constant_expression.cpp index 27b1eccc7..692e79df3 100644 --- a/src/duckdb/src/planner/expression/bound_constant_expression.cpp +++ b/src/duckdb/src/planner/expression/bound_constant_expression.cpp @@ -9,6 +9,21 @@ BoundConstantExpression::BoundConstantExpression(Value value_p) value(std::move(value_p)) { } +void BoundConstantExpression::SetValue(Value value_p) { + return_type = value_p.type(); + value = std::move(value_p); +} + +Value BoundConstantExpression::TakeValue() { + return std::move(value); +} + +void BoundConstantExpression::SetReturnType(LogicalType type) { + D_ASSERT(value.type() == type); + value = value.WithType(type); + return_type = std::move(type); +} + string BoundConstantExpression::ToString() const { return value.ToSQLString(); } diff --git a/src/duckdb/src/planner/expression/bound_function_expression.cpp b/src/duckdb/src/planner/expression/bound_function_expression.cpp index 478d436f6..07d90bcb7 100644 --- a/src/duckdb/src/planner/expression/bound_function_expression.cpp +++ b/src/duckdb/src/planner/expression/bound_function_expression.cpp @@ -11,6 +11,14 @@ namespace duckdb { +static optional_ptr GetLambdaExpression(const BoundFunctionExpression &expr) { + if (!expr.Function().HasBindLambdaCallback()) { + return nullptr; + } + D_ASSERT(expr.BindInfo()); + return expr.BindInfo()->Cast().GetLambdaExpression(); +} + BoundFunctionExpression::BoundFunctionExpression(BoundScalarFunction bound_function, vector> arguments, unique_ptr bind_info_p, bool is_operator) @@ -44,32 +52,30 @@ bool BoundFunctionExpression::RequiresOrderedExecution() const { } bool BoundFunctionExpression::IsVolatile() const { - return function.GetStability() == FunctionStability::VOLATILE ? true : Expression::IsVolatile(); + auto lambda_expr = GetLambdaExpression(*this); + return function.GetStability() == FunctionStability::VOLATILE || (lambda_expr && lambda_expr->IsVolatile()) || + Expression::IsVolatile(); } bool BoundFunctionExpression::IsConsistent() const { - return function.GetStability() != FunctionStability::CONSISTENT ? false : Expression::IsConsistent(); + auto lambda_expr = GetLambdaExpression(*this); + return function.GetStability() == FunctionStability::CONSISTENT && (!lambda_expr || lambda_expr->IsConsistent()) && + Expression::IsConsistent(); } bool BoundFunctionExpression::IsFoldable() const { // functions with side effects cannot be folded: they have to be executed once for every row - if (function.HasBindLambdaCallback()) { - // This is a lambda function - D_ASSERT(bind_info); - auto &lambda_bind_data = bind_info->Cast(); - auto lambda_expr = lambda_bind_data.GetLambdaExpression(); - if (lambda_expr && lambda_expr->IsVolatile()) { - return false; - } + auto lambda_expr = GetLambdaExpression(*this); + if (lambda_expr && lambda_expr->IsVolatile()) { + return false; } return function.GetStability() == FunctionStability::VOLATILE ? false : Expression::IsFoldable(); } bool BoundFunctionExpression::CanThrow() const { - if (function.GetErrorMode() == FunctionErrors::CAN_THROW_RUNTIME_ERROR) { - return true; - } - return Expression::CanThrow(); + auto lambda_expr = GetLambdaExpression(*this); + return function.GetErrorMode() == FunctionErrors::CAN_THROW_RUNTIME_ERROR || + (lambda_expr && lambda_expr->CanThrow()) || Expression::CanThrow(); } string BoundFunctionExpression::ToString() const { @@ -155,6 +161,9 @@ void BoundFunctionExpression::Serialize(Serializer &serializer) const { // serialize legacy expression for backwards compatibility FunctionToStringInput input(function, bind_info.get(), children); auto legacy_expr = function.GetLegacySerializeCallback()(input); + legacy_expr->SetReturnType(return_type); + legacy_expr->SetAlias(alias); + legacy_expr->SetQueryLocation(query_location); legacy_expr->Serialize(serializer); return; } @@ -212,7 +221,10 @@ unique_ptr BoundFunctionExpression::Deserialize(Deserializer &deseri // replace the function expression with the bound expression auto bound_expression = entry.first.GetBindExpressionCallback()(bind_input); if (bound_expression) { - return bound_expression; + if (bound_expression->GetReturnType() != return_type) { + return BoundCastExpression::AddCastToType(context, std::move(bound_expression), return_type); + } + return Expression::PreserveReturnType(return_type, std::move(bound_expression)); } // Otherwise, fall through and continue on normally } @@ -224,7 +236,7 @@ unique_ptr BoundFunctionExpression::Deserialize(Deserializer &deseri auto &context = deserializer.Get(); return BoundCastExpression::AddCastToType(context, std::move(result), return_type); } - return std::move(result); + return Expression::PreserveReturnType(return_type, std::move(result)); } } // namespace duckdb diff --git a/src/duckdb/src/planner/expression/bound_window_expression.cpp b/src/duckdb/src/planner/expression/bound_window_expression.cpp index 66252c8ea..32918f6ab 100644 --- a/src/duckdb/src/planner/expression/bound_window_expression.cpp +++ b/src/duckdb/src/planner/expression/bound_window_expression.cpp @@ -1,6 +1,8 @@ #include "duckdb/planner/expression/bound_window_expression.hpp" #include "duckdb/catalog/catalog_entry/window_function_catalog_entry.hpp" #include "duckdb/parser/expression/window_expression.hpp" +#include "duckdb/parser/expression/constant_expression.hpp" +#include "duckdb/planner/expression/bound_constant_expression.hpp" #include "duckdb/parser/expression_map.hpp" #include "duckdb/function/aggregate_function.hpp" @@ -151,6 +153,17 @@ bool BoundWindowExpression::KeysAreCompatible(const BoundWindowExpression &other return true; } +void BoundWindowExpression::RetainSQLRange(optional_ptr start, optional_ptr end, + const LogicalType &order_type) { + sql_range_start = start && start->GetExpressionClass() == ExpressionClass::BOUND_CONSTANT + ? ConstantExpression::FromValue(start->Cast().GetValue()) + : nullptr; + sql_range_end = end && end->GetExpressionClass() == ExpressionClass::BOUND_CONSTANT + ? ConstantExpression::FromValue(end->Cast().GetValue()) + : nullptr; + sql_range_order_type = order_type; +} + unique_ptr BoundWindowExpression::Copy() const { unique_ptr agg_copy; if (aggregate) { @@ -195,6 +208,9 @@ unique_ptr BoundWindowExpression::Copy() const { new_window->exclude_clause = exclude_clause; new_window->start_expr = start_expr ? start_expr->Copy() : nullptr; new_window->end_expr = end_expr ? end_expr->Copy() : nullptr; + new_window->sql_range_start = sql_range_start ? sql_range_start->Copy() : nullptr; + new_window->sql_range_end = sql_range_end ? sql_range_end->Copy() : nullptr; + new_window->sql_range_order_type = sql_range_order_type; new_window->ignore_nulls = ignore_nulls; new_window->distinct = distinct; @@ -273,6 +289,10 @@ void BoundWindowExpression::Serialize(Serializer &serializer) const { serializer.WriteProperty(212, "exclude_clause", exclude_clause); serializer.WriteProperty(213, "distinct", distinct); serializer.WriteProperty(214, "arg_orders", arg_orders); + serializer.WritePropertyWithDefault(215, "sql_range_start", sql_range_start, unique_ptr()); + serializer.WritePropertyWithDefault(216, "sql_range_end", sql_range_end, unique_ptr()); + serializer.WritePropertyWithDefault(217, "sql_range_order_type", sql_range_order_type, + LogicalType::INVALID); } unique_ptr BoundWindowExpression::Deserialize(Deserializer &deserializer) { @@ -318,6 +338,12 @@ unique_ptr BoundWindowExpression::Deserialize(Deserializer &deserial deserializer.ReadProperty(212, "exclude_clause", result->exclude_clause); deserializer.ReadProperty(213, "distinct", result->distinct); deserializer.ReadPropertyWithExplicitDefault(214, "arg_orders", result->arg_orders, vector()); + deserializer.ReadPropertyWithExplicitDefault(215, "sql_range_start", result->sql_range_start, + unique_ptr()); + deserializer.ReadPropertyWithExplicitDefault(216, "sql_range_end", result->sql_range_end, + unique_ptr()); + deserializer.ReadPropertyWithExplicitDefault(217, "sql_range_order_type", result->sql_range_order_type, + LogicalType::INVALID); // Builtin window functions didn't used to be serialized, so we need to look them up in the system catalog if (!result->aggregate && !result->window) { diff --git a/src/duckdb/src/planner/logical_operator_deep_copy.cpp b/src/duckdb/src/planner/logical_operator_deep_copy.cpp index 712c54356..1a8aa50b5 100644 --- a/src/duckdb/src/planner/logical_operator_deep_copy.cpp +++ b/src/duckdb/src/planner/logical_operator_deep_copy.cpp @@ -135,6 +135,15 @@ void LogicalOperatorDeepCopy::VisitOperator(LogicalOperator &op) { ReplaceTableIndex(op); break; } + case LogicalOperatorType::LOGICAL_EMPTY_RESULT: { + auto &empty_result = op.Cast(); + for (auto &binding : empty_result.bindings) { + if (table_idx_replacements.find(binding.table_index) == table_idx_replacements.end()) { + table_idx_replacements[binding.table_index] = binder.GenerateTableIndex(); + } + } + break; + } case LogicalOperatorType::LOGICAL_CTE_REF: { ReplaceTableIndex(op); break; @@ -234,6 +243,26 @@ void TableBindingReplacer::VisitOperator(LogicalOperator &op) { } break; } + case LogicalOperatorType::LOGICAL_SECURE_VIEW: { + auto &view = op.Cast(); + for (auto &binding : view.output_bindings) { + auto entry = table_idx_replacements.find(binding.table_index); + if (entry != table_idx_replacements.end()) { + binding.table_index = entry->second; + } + } + break; + } + case LogicalOperatorType::LOGICAL_EMPTY_RESULT: { + auto &empty_result = op.Cast(); + for (auto &binding : empty_result.bindings) { + auto entry = table_idx_replacements.find(binding.table_index); + if (entry != table_idx_replacements.end()) { + binding.table_index = entry->second; + } + } + break; + } default: break; } diff --git a/src/duckdb/src/planner/logical_plan_verification_result.cpp b/src/duckdb/src/planner/logical_plan_verification_result.cpp index 3a997b438..b6f473064 100644 --- a/src/duckdb/src/planner/logical_plan_verification_result.cpp +++ b/src/duckdb/src/planner/logical_plan_verification_result.cpp @@ -434,7 +434,8 @@ bool LogicalPlanVerificationIssue::IsValid() const { case LogicalPlanVerificationIssueCode::UNSUPPORTED_OPERATOR: return path.has_value() && construct.has_value() && construct->type == LogicalPlanVerificationConstructType::LOGICAL_OPERATOR && - *construct->logical_operator != LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR; + construct->logical_operator.has_value() && + construct->logical_operator.value() != LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR; case LogicalPlanVerificationIssueCode::UNSUPPORTED_EXPRESSION: return path.has_value() && construct.has_value() && construct->type == LogicalPlanVerificationConstructType::EXPRESSION; diff --git a/src/duckdb/src/planner/operator/logical_copy_to_file.cpp b/src/duckdb/src/planner/operator/logical_copy_to_file.cpp index 2b9047bd8..947262b3c 100644 --- a/src/duckdb/src/planner/operator/logical_copy_to_file.cpp +++ b/src/duckdb/src/planner/operator/logical_copy_to_file.cpp @@ -76,6 +76,8 @@ void LogicalCopyToFile::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault(223, "batches_per_file", batches_per_file, optional_idx()); serializer.WritePropertyWithDefault(224, "order_columns", order_columns); serializer.WritePropertyWithDefault(225, "table_index", table_index, TableIndex(0)); + serializer.WritePropertyWithDefault>(226, "partition_path_expression", + partition_path_expression); } unique_ptr LogicalCopyToFile::Deserialize(Deserializer &deserializer) { @@ -130,6 +132,9 @@ unique_ptr LogicalCopyToFile::Deserialize(Deserializer &deseria auto batches_per_file = deserializer.ReadPropertyWithExplicitDefault(223, "batches_per_file", optional_idx()); auto order_columns = deserializer.ReadPropertyWithExplicitDefault(224, "order_columns", vector()); auto table_index = deserializer.ReadPropertyWithExplicitDefault(225, "table_index", TableIndex(0)); + unique_ptr partition_path_expression; + deserializer.ReadPropertyWithDefault>(226, "partition_path_expression", + partition_path_expression); if (!has_serialize) { // If not serialized, re-bind with the copy info @@ -165,6 +170,7 @@ unique_ptr LogicalCopyToFile::Deserialize(Deserializer &deseria result->batch_size_bytes = batch_size_bytes; result->batches_per_file = batches_per_file; result->order_columns = std::move(order_columns); + result->partition_path_expression = std::move(partition_path_expression); return std::move(result); } diff --git a/src/duckdb/src/planner/operator/logical_get.cpp b/src/duckdb/src/planner/operator/logical_get.cpp index acf2978c7..9612ea649 100644 --- a/src/duckdb/src/planner/operator/logical_get.cpp +++ b/src/duckdb/src/planner/operator/logical_get.cpp @@ -9,7 +9,6 @@ #include "duckdb/storage/data_table.hpp" #include "duckdb/common/serializer/serializer.hpp" #include "duckdb/common/serializer/deserializer.hpp" -#include "duckdb/parser/tableref/table_function_ref.hpp" #include "duckdb/planner/filter/expression_filter.hpp" namespace duckdb { @@ -305,6 +304,9 @@ void LogicalGet::SetPartitionsToScan(vector partition_indices) { } void LogicalGet::Serialize(Serializer &serializer) const { + if (bind_info) { + throw NotImplementedException("Cannot serialize a table function with process-local bind input"); + } LogicalOperator::Serialize(serializer); serializer.WriteProperty(200, "table_index", table_index); serializer.WriteProperty(201, "returned_types", returned_types); @@ -313,9 +315,7 @@ void LogicalGet::Serialize(Serializer &serializer) const { serializer.WriteProperty(204, "projection_ids", projection_ids); serializer.WriteProperty(205, "table_filters", table_filters); FunctionSerializer::Serialize(serializer, function, bind_data.get()); - if (!function.serialize) { - D_ASSERT(!function.serialize); - // no serialize method: serialize input values and named_parameters for rebinding purposes + if (!function.serialize || serializer.ShouldSerialize(StorageVersion::V2_0_0)) { serializer.WriteProperty(206, "parameters", parameters); serializer.WriteProperty(207, "named_parameters", named_parameters); serializer.WriteProperty(208, "input_table_types", input_table_types); @@ -328,6 +328,8 @@ void LogicalGet::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault>(214, "row_group_order_options", row_group_order_options); serializer.WritePropertyWithDefault(215, "scan_partition_indices", scan_partition_indices, vector()); + serializer.WritePropertyWithDefault(216, "source_ordinality", source_ordinality, + OrdinalityType::WITHOUT_ORDINALITY); } unique_ptr LogicalGet::Deserialize(Deserializer &deserializer) { @@ -346,14 +348,13 @@ unique_ptr LogicalGet::Deserialize(Deserializer &deserializer) auto &function = result->function; auto has_serialize = entry.second; unique_ptr bind_data; - if (!has_serialize) { - deserializer.ReadProperty(206, "parameters", result->parameters); - deserializer.ReadProperty(207, "named_parameters", result->named_parameters); - deserializer.ReadProperty(208, "input_table_types", result->input_table_types); - deserializer.ReadProperty(209, "input_table_names", result->input_table_names); - } else { + if (has_serialize) { bind_data = FunctionSerializer::FunctionDeserialize(deserializer, function); } + deserializer.ReadPropertyWithDefault(206, "parameters", result->parameters); + deserializer.ReadPropertyWithDefault(207, "named_parameters", result->named_parameters); + deserializer.ReadPropertyWithDefault(208, "input_table_types", result->input_table_types); + deserializer.ReadPropertyWithDefault(209, "input_table_names", result->input_table_names); deserializer.ReadProperty(210, "projected_input", result->projected_input); deserializer.ReadPropertyWithDefault(211, "column_indexes", result->column_ids); result->extra_info = deserializer.ReadPropertyWithExplicitDefault(212, "extra_info", {}); @@ -362,6 +363,8 @@ unique_ptr LogicalGet::Deserialize(Deserializer &deserializer) deserializer.ReadPropertyWithDefault>(214, "row_group_order_options"); auto scan_partition_indices = deserializer.ReadPropertyWithExplicitDefault>(215, "scan_partition_indices", vector()); + result->source_ordinality = deserializer.ReadPropertyWithExplicitDefault( + 216, "source_ordinality", OrdinalityType::WITHOUT_ORDINALITY); if (!legacy_column_ids.empty()) { if (!result->column_ids.empty()) { throw SerializationException( diff --git a/src/duckdb/src/planner/operator/logical_secure_view.cpp b/src/duckdb/src/planner/operator/logical_secure_view.cpp index 8d20b0158..719025285 100644 --- a/src/duckdb/src/planner/operator/logical_secure_view.cpp +++ b/src/duckdb/src/planner/operator/logical_secure_view.cpp @@ -1,9 +1,48 @@ #include "duckdb/planner/operator/logical_secure_view.hpp" +#include "duckdb/planner/expression/bound_columnref_expression.hpp" +#include "duckdb/planner/tableref/bound_at_clause.hpp" #include "duckdb/common/string_util.hpp" +#include "duckdb/planner/operator/logical_get.hpp" namespace duckdb { +//! Statistics gathered inside a view describe the data it reads - they may only be exposed to the caller if +//! every row that is read is also emitted. Any operator that removes rows means the statistics below it also cover +//! rows that the view hides, so only row-preserving operators are accepted here. +static bool EmitsAllRows(const LogicalOperator &op) { + switch (op.type) { + case LogicalOperatorType::LOGICAL_SECURE_VIEW: + // a nested secure view applies this same rule to its own contents - nothing beyond what it exposes itself + // can reach this boundary, so there is no need to look inside it + return true; + case LogicalOperatorType::LOGICAL_PROJECTION: + case LogicalOperatorType::LOGICAL_ORDER_BY: + case LogicalOperatorType::LOGICAL_EXPRESSION_GET: + case LogicalOperatorType::LOGICAL_DUMMY_SCAN: + break; + case LogicalOperatorType::LOGICAL_GET: { + auto &get = op.Cast(); + if (get.table_filters.HasFilters() || get.extra_info.sample_options || get.dynamic_filters) { + return false; + } + if (!get.children.empty()) { + // an in-out function decides itself which of the rows it reads it emits + return false; + } + break; + } + default: + return false; + } + for (auto &child : op.children) { + if (!EmitsAllRows(*child)) { + return false; + } + } + return true; +} + LogicalSecureView::LogicalSecureView() : LogicalOperator(LogicalOperatorType::LOGICAL_SECURE_VIEW) { } @@ -12,6 +51,36 @@ LogicalSecureView::LogicalSecureView(string view_name_p, unique_ptr source_types_p, optional_ptr at_clause, + unique_ptr child) + : LogicalOperator(LogicalOperatorType::LOGICAL_SECURE_VIEW), view_name(std::move(view_name_p)), has_source(true), + source_name(std::move(source_name_p)), source_types(std::move(source_types_p)), + has_at_clause(at_clause != nullptr) { + if (at_clause) { + at_unit = at_clause->Unit(); + at_value = at_clause->GetValue(); + } + output_bindings = child->GetColumnBindings(); + D_ASSERT(output_bindings.size() == source_types.size()); + for (idx_t i = 0; i < source_types.size(); i++) { + output_expressions.push_back( + make_uniq(source_types[i], ColumnBinding(TableIndex(0), ProjectionIndex(i)))); + } + children.push_back(std::move(child)); +} + +void LogicalSecureView::AnalyzeStatistics(LogicalOperator &plan) { + if (plan.type == LogicalOperatorType::LOGICAL_SECURE_VIEW) { + // the statistics of a view may only be exposed if the view emits every row it reads - otherwise they would + // describe values from rows that the view does not return + plan.Cast().propagate_statistics = EmitsAllRows(*plan.children[0]); + } + for (auto &child : plan.children) { + AnalyzeStatistics(*child); + } +} + vector LogicalSecureView::GetColumnBindings() { return children[0]->GetColumnBindings(); } @@ -22,7 +91,11 @@ idx_t LogicalSecureView::EstimateCardinality(ClientContext &context) { // filters using the statistics of the view contents must not escape the boundary return estimated_cardinality; } - return children[0]->EstimateCardinality(context); + if (!propagate_statistics) { + // the estimate of the child changes as filters are pushed into the view - never remember it here + return children[0]->EstimateCardinality(context); + } + return LogicalOperator::EstimateCardinality(context); } InsertionOrderPreservingMap LogicalSecureView::ParamsToString() const { diff --git a/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp b/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp index 92a5dd220..1273f6075 100644 --- a/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp +++ b/src/duckdb/src/planner/subquery/delim_join_cte_rewriter.cpp @@ -2536,6 +2536,64 @@ static bool SingleJoinRHSIsDeduplicated(LogicalComparisonJoin &join) { return true; } +// Decorrelation partitions the RHS by its domain. Only retain this fact for repeatable, locally owned inputs. +static bool CanRestrictCorrelationDomain(LogicalOperator &op, unordered_set &local_ctes) { + switch (op.type) { + case LogicalOperatorType::LOGICAL_GET: + if (!op.Cast().GetTable()) { + return false; + } + break; + case LogicalOperatorType::LOGICAL_RECURSIVE_CTE: { + auto &cte = op.Cast(); + if (cte.ref_recurring || !cte.key_targets.empty()) { + return false; + } + local_ctes.insert(cte.table_index); + break; + } + case LogicalOperatorType::LOGICAL_MATERIALIZED_CTE: + local_ctes.insert(op.Cast().table_index); + break; + case LogicalOperatorType::LOGICAL_CTE_REF: + if (!local_ctes.count(op.Cast().cte_index)) { + return false; + } + break; + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: + case LogicalOperatorType::LOGICAL_PROJECTION: + case LogicalOperatorType::LOGICAL_FILTER: + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: + case LogicalOperatorType::LOGICAL_DISTINCT: + case LogicalOperatorType::LOGICAL_WINDOW: + case LogicalOperatorType::LOGICAL_LIMIT: + case LogicalOperatorType::LOGICAL_ORDER_BY: + case LogicalOperatorType::LOGICAL_UNION: + case LogicalOperatorType::LOGICAL_DUMMY_SCAN: + case LogicalOperatorType::LOGICAL_EXPRESSION_GET: + break; + default: + return false; + } + bool repeatable = true; + LogicalOperatorVisitor::EnumerateExpressions(op, [&](unique_ptr *expr) { + repeatable &= !(*expr)->IsVolatile() && !ExpressionBarrier::Contains(**expr); + ExpressionIterator::VisitExpression(**expr, [&](const BoundFunctionExpression &func) { + repeatable &= !func.Function().RequiresOrderedExecution(); + }); + }); + if (!repeatable) { + return false; + } + for (auto &child : op.children) { + if (!CanRestrictCorrelationDomain(*child, local_ctes)) { + return false; + } + } + return true; +} + DelimJoinCTERewriter::DelimJoinCTERewriter(Binder &binder) : binder(binder) { auto &config = DBConfig::GetConfig(binder.context); cte_deliminator_enabled = @@ -2577,6 +2635,12 @@ BindingReplacementGraph DelimJoinCTERewriter::MaterializeDelimJoinAsCTE(unique_p return {}; } generated_dedup_cte_indexes.push_back(dedup_cte_index); + unordered_set local_ctes {dedup_cte_index}; + const bool requires_left_row = join.join_type == JoinType::INNER || join.join_type == JoinType::LEFT || + join.join_type == JoinType::SEMI || join.join_type == JoinType::ANTI || + join.join_type == JoinType::MARK; + // Only RHS partitions are removed; ordinary filter pushdown handles the producer. + const bool can_restrict_input = requires_left_row && CanRestrictCorrelationDomain(*plan->children[1], local_ctes); plan->children[0]->ResolveOperatorTypes(); auto left_bindings = plan->children[0]->GetColumnBindings(); @@ -2699,6 +2763,9 @@ BindingReplacementGraph DelimJoinCTERewriter::MaterializeDelimJoinAsCTE(unique_p output_replacements.Merge(cte_output_replacements); auto cte = make_uniq(cte_name, cte_index, left_column_count, std::move(cte_source), std::move(cte_child), CTEMaterialize::CTE_MATERIALIZE_DEFAULT); + if (can_restrict_input) { + cte->filter_dependency = make_uniq(left_cte_ref_index, dedup_child_index); + } plan = std::move(cte); return output_replacements; } diff --git a/src/duckdb/src/planner/table_binding.cpp b/src/duckdb/src/planner/table_binding.cpp index c1cd9ce83..8202018d6 100644 --- a/src/duckdb/src/planner/table_binding.cpp +++ b/src/duckdb/src/planner/table_binding.cpp @@ -65,6 +65,14 @@ void Binding::SetColumnType(idx_t col_idx, LogicalType type_p) { types[col_idx] = std::move(type_p); } +void Binding::SetNullExtended() { + null_extended = true; +} + +bool Binding::IsNullExtended() const { + return null_extended; +} + const Identifier &Binding::GetAlias() const { return alias.GetAlias(); } diff --git a/src/duckdb/src/storage/buffer/block_handle.cpp b/src/duckdb/src/storage/buffer/block_handle.cpp index 1ae4950dc..f185a2338 100644 --- a/src/duckdb/src/storage/buffer/block_handle.cpp +++ b/src/duckdb/src/storage/buffer/block_handle.cpp @@ -106,22 +106,22 @@ void BlockMemory::ResizeBuffer(BlockLock &l, idx_t block_size, idx_t block_heade D_ASSERT(memory_usage == buffer->AllocSize()); } -bool BlockMemory::CanUnload() const { +CanUnloadResult BlockMemory::CanUnload() const { if (GetState() == BlockState::BLOCK_UNLOADED) { // The block has already been unloaded. - return false; + return CanUnloadResult::ALREADY_UNLOADED; } if (GetReaders() > 0) { // There are active readers. - return false; + return CanUnloadResult::PINNED; } if (BlockId() >= MAXIMUM_BLOCK && MustWriteToTemporaryFile() && !GetBufferManager().HasTemporaryDirectory()) { // The block memory cannot be destroyed upon eviction/unpinning. // In order to unload this block we need to write it to a temporary buffer. // However, no temporary directory is specified, hence, we cannot unload. - return false; + return CanUnloadResult::NO_TEMP_DIRECTORY; } - return true; + return CanUnloadResult::CAN_UNLOAD; } unique_ptr BlockMemory::UnloadAndTakeBlock(BlockLock &l, QueryContext context) { @@ -132,7 +132,7 @@ unique_ptr BlockMemory::UnloadAndTakeBlock(BlockLock &l, QueryContex return nullptr; } D_ASSERT(IsSwizzled()); - D_ASSERT(CanUnload()); + D_ASSERT(CanUnload() == CanUnloadResult::CAN_UNLOAD); if (BlockId() >= MAXIMUM_BLOCK && MustWriteToTemporaryFile()) { // This is a temporary block that cannot be destroyed upon evict/unpin. diff --git a/src/duckdb/src/storage/buffer/buffer_pool.cpp b/src/duckdb/src/storage/buffer/buffer_pool.cpp index 58169b146..3c36dcdad 100644 --- a/src/duckdb/src/storage/buffer/buffer_pool.cpp +++ b/src/duckdb/src/storage/buffer/buffer_pool.cpp @@ -357,7 +357,10 @@ BufferPool::EvictionResult BufferPool::EvictObjectCacheEntries(MemoryTag tag, id bool success = false; while (!object_cache->IsEmpty()) { - const idx_t freed_mem = object_cache->EvictToReduceMemory(extra_memory); + const idx_t used = memory_usage.GetUsedMemory(MemoryUsageCaches::NO_FLUSH); + const idx_t overshoot = used > memory_limit ? (used - memory_limit) : 0; + const idx_t target = MaxValue(extra_memory, overshoot); + const idx_t freed_mem = object_cache->EvictToReduceMemory(target); // Break if all entries cannot be evicted. if (freed_mem == 0) { break; @@ -500,7 +503,16 @@ void EvictionQueue::IterateUnloadableBlocks(FN fn) { // This node is the block's live queue entry, and we just dequeued it: the block no longer // has an entry in the queue. Live entries are never counted as dead, so no decrement. handle->SetHasLiveQueueEntry(lock, false); - if (!handle->CanUnload()) { + switch (handle->CanUnload()) { + case CanUnloadResult::CAN_UNLOAD: + break; + case CanUnloadResult::NO_TEMP_DIRECTORY: + // Unpinned temporary block that cannot be offloaded yet: re-enqueue until temp directory is set. + handle->SetHasLiveQueueEntry(lock, true); + q.enqueue(std::move(node)); + return; + case CanUnloadResult::PINNED: + case CanUnloadResult::ALREADY_UNLOADED: // The block cannot be unloaded right now (e.g. it is pinned). It gets a new queue // entry when it is unpinned again. continue; diff --git a/src/duckdb/src/storage/checkpoint_manager.cpp b/src/duckdb/src/storage/checkpoint_manager.cpp index a0a7a427f..3a4536e28 100644 --- a/src/duckdb/src/storage/checkpoint_manager.cpp +++ b/src/duckdb/src/storage/checkpoint_manager.cpp @@ -198,6 +198,25 @@ static catalog_entry_vector_t GetCatalogEntries(vector(); + catalog.ScanSchemas([&](SchemaCatalogEntry &schema) { + if (has_buffered_replays) { + return; + } + schema.Scan(CatalogType::TABLE_ENTRY, [&](CatalogEntry &entry) { + if (has_buffered_replays || entry.type != CatalogType::TABLE_ENTRY) { + return; + } + auto &table = entry.Cast(); + auto &indexes = table.GetStorage().GetDataTableInfo()->GetIndexes(); + has_buffered_replays = indexes.HasBufferedReplays(); + }); + }); + return has_buffered_replays; +} + void SingleFileCheckpointWriter::CreateCheckpoint() { auto &storage_manager = db.GetStorageManager().Cast(); if (storage_manager.InMemory()) { @@ -207,6 +226,10 @@ void SingleFileCheckpointWriter::CreateCheckpoint() { // don't checkpoint invalidated databases return; } + // A context-free checkpoint cannot persist buffered operations on an unbound index. Keep the WAL instead. + if (!context && HasBufferedIndexReplays(db)) { + return; + } // assert that the checkpoint manager hasn't been used before D_ASSERT(!metadata_writer); @@ -653,7 +676,7 @@ void CheckpointReader::ReadIndex(CatalogTransaction transaction, Deserializer &d // Create an unbound index and add it to the table. auto unbound_index = make_uniq(std::move(create_info), std::move(index_storage_info), TableIOManager::Get(data_table), data_table.db); - table_info->GetIndexes().AddIndex(std::move(unbound_index)); + table_info->GetIndexes().AddIndex(std::move(unbound_index), index.oid); } //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/storage/compression/bitpacking.cpp b/src/duckdb/src/storage/compression/bitpacking.cpp index 9710ca142..181126521 100644 --- a/src/duckdb/src/storage/compression/bitpacking.cpp +++ b/src/duckdb/src/storage/compression/bitpacking.cpp @@ -685,7 +685,7 @@ struct BitpackingScanState : public SegmentScanState { auto algorithm_group_index = offset / BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; D_ASSERT(algorithm_group_index < algorithm_group_count); auto algorithm_group_offset = algorithm_group_index * algorithm_group_size; - return payload->SubArray(algorithm_group_offset, algorithm_group_size); + return payload.value().SubArray(algorithm_group_offset, algorithm_group_size); } //! Unpacks the algorithm group at the current row offset. diff --git a/src/duckdb/src/storage/compression/dict_fsst/decompression.cpp b/src/duckdb/src/storage/compression/dict_fsst/decompression.cpp index 6ae6087ad..758c17019 100644 --- a/src/duckdb/src/storage/compression/dict_fsst/decompression.cpp +++ b/src/duckdb/src/storage/compression/dict_fsst/decompression.cpp @@ -206,7 +206,7 @@ void CompressedStringScanState::Select(Vector &result, idx_t start, const Select for (; decompress_position < string_number; decompress_position++) { decompress_offset += string_lengths[decompress_position]; } - result_data.WriteValue(FetchStringFromDict(result, decompress_offset, string_number)); + result_data.WriteStringRef(FetchStringFromDict(result, decompress_offset, string_number)); } } diff --git a/src/duckdb/src/storage/compression/rle.cpp b/src/duckdb/src/storage/compression/rle.cpp index b2f67a49c..e5e0df6e2 100644 --- a/src/duckdb/src/storage/compression/rle.cpp +++ b/src/duckdb/src/storage/compression/rle.cpp @@ -14,6 +14,22 @@ namespace duckdb { using rle_count_t = uint16_t; +template +bool RLEValueEqual(const T &lhs, const T &rhs) { + return lhs == rhs; +} + +template <> +bool RLEValueEqual(const float &lhs, const float &rhs) { + // IEEE == collapses +0 and -0; compare the bit pattern instead. + return Load(const_data_ptr_cast(&lhs)) == Load(const_data_ptr_cast(&rhs)); +} + +template <> +bool RLEValueEqual(const double &lhs, const double &rhs) { + return Load(const_data_ptr_cast(&lhs)) == Load(const_data_ptr_cast(&rhs)); +} + //===--------------------------------------------------------------------===// // Analyze //===--------------------------------------------------------------------===// @@ -53,7 +69,7 @@ struct RLEState { seen_count++; last_seen_count++; all_null = false; - } else if (last_value == data[idx]) { + } else if (RLEValueEqual(last_value, data[idx])) { // the last value is identical to this value: increment the last_seen_count last_seen_count++; } else { diff --git a/src/duckdb/src/storage/data_table.cpp b/src/duckdb/src/storage/data_table.cpp index 5d5e6b9f4..7015799ff 100644 --- a/src/duckdb/src/storage/data_table.cpp +++ b/src/duckdb/src/storage/data_table.cpp @@ -360,8 +360,12 @@ bool DataTable::HasUniqueIndexes() const { return info->indexes.HasUniqueIndexes(); } -void DataTable::AddIndex(unique_ptr index) { - info->indexes.AddIndex(std::move(index)); +void DataTable::AddIndex(unique_ptr index, idx_t index_oid) { + info->indexes.AddIndex(std::move(index), index_oid); +} + +void DataTable::AddConstraintIndex(unique_ptr index) { + info->indexes.AddIndex(std::move(index), /*index_oid=*/optional_idx()); } bool DataTable::HasForeignKeyIndex(const vector &keys, ForeignKeyType type) { @@ -1134,7 +1138,7 @@ void DataTable::ScanTableSegment(DuckTransaction &transaction, idx_t row_start, InitializeScanWithOffset(transaction, state, column_ids, row_start, row_start + count); auto row_start_aligned = - state.table_state.row_group->GetRowStart() + state.table_state.vector_index * STANDARD_VECTOR_SIZE; + state.table_state.GetRowGroup()->GetRowStart() + state.table_state.vector_index * STANDARD_VECTOR_SIZE; idx_t current_row = row_start_aligned; while (current_row < end) { @@ -1686,7 +1690,7 @@ void DataTable::AddIndex(const ColumnList &columns, const vector & auto &io_manager = TableIOManager::Get(*this); auto art = make_uniq(index_info.name, type, physical_ids, io_manager, std::move(expressions), db, nullptr, index_info); - info->indexes.AddIndex(std::move(art)); + info->indexes.AddIndex(std::move(art), /*index_oid=*/optional_idx()); } } // namespace duckdb diff --git a/src/duckdb/src/storage/external_file_cache/caching_file_system.cpp b/src/duckdb/src/storage/external_file_cache/caching_file_system.cpp index 7bda90c4c..7cc61df21 100644 --- a/src/duckdb/src/storage/external_file_cache/caching_file_system.cpp +++ b/src/duckdb/src/storage/external_file_cache/caching_file_system.cpp @@ -164,13 +164,13 @@ CachingFileSystem CachingFileSystem::Get(ClientContext &context) { return CachingFileSystem(FileSystem::GetFileSystem(context), *context.db); } -unique_ptr CachingFileSystem::OpenFile(const OpenFileInfo &path, FileOpenFlags flags, +unique_ptr CachingFileSystem::OpenFile(const OpenFileInfo &path, const FileOpenFlags &flags, optional_ptr opener) { return make_uniq(QueryContext(), *this, path, flags, opener); } unique_ptr CachingFileSystem::OpenFile(QueryContext context, const OpenFileInfo &path, - FileOpenFlags flags, optional_ptr opener) { + const FileOpenFlags &flags, optional_ptr opener) { return make_uniq(context, *this, path, flags, opener); } diff --git a/src/duckdb/src/storage/external_file_cache/caching_file_system_wrapper.cpp b/src/duckdb/src/storage/external_file_cache/caching_file_system_wrapper.cpp index 9442f056e..c54fb20a8 100644 --- a/src/duckdb/src/storage/external_file_cache/caching_file_system_wrapper.cpp +++ b/src/duckdb/src/storage/external_file_cache/caching_file_system_wrapper.cpp @@ -221,6 +221,11 @@ FileMetadata CachingFileSystemWrapper::Stats(FileHandle &handle) { return underlying_file_system.Stats(*file_handle); } +optional CachingFileSystemWrapper::GetStatsIfExists(const OpenFileInfo &file, + optional_ptr opener) { + return underlying_file_system.GetStatsIfExists(file, opener); +} + //===----------------------------------------------------------------------===// // Directory Operations //===----------------------------------------------------------------------===// diff --git a/src/duckdb/src/storage/index_entry.cpp b/src/duckdb/src/storage/index_entry.cpp index 6554801da..d63e0d88b 100644 --- a/src/duckdb/src/storage/index_entry.cpp +++ b/src/duckdb/src/storage/index_entry.cpp @@ -18,7 +18,8 @@ namespace duckdb { -IndexEntry::IndexEntry(unique_ptr index_p) : owned_index(std::move(index_p)) { +IndexEntry::IndexEntry(unique_ptr index_p, optional_idx catalog_index_oid_p) + : catalog_index_oid(catalog_index_oid_p), owned_index(std::move(index_p)) { if (owned_index->IsBound()) { bind_state = IndexBindState::BOUND; } else { @@ -114,8 +115,8 @@ void IndexEntry::InitializeLocalIndexes(TableIndexList &delete_indexes, TableInd } auto constraint_type = bound_index.GetConstraintType(); - delete_indexes.AddIndex(bound_index.CreateEmptyCopy(constraint_type)); - append_indexes.AddIndex(bound_index.CreateEmptyCopy(constraint_type)); + delete_indexes.AddIndex(bound_index.CreateEmptyCopy(constraint_type), catalog_index_oid); + append_indexes.AddIndex(bound_index.CreateEmptyCopy(constraint_type), catalog_index_oid); } void IndexEntry::AppendToDeleteIndexes(DataChunk &chunk, Vector &row_ids) { @@ -315,6 +316,14 @@ string IndexEntry::GetIndexType() const { return owned_index->GetIndexType(); } +bool IndexEntry::HasBufferedReplays() const { + auto entry_lock = lock.GetSharedLock(); + if (!owned_index || owned_index->IsBound()) { + return false; + } + return owned_index->Cast().HasBufferedReplays(); +} + void IndexEntry::Retire() { auto entry_lock = lock.GetExclusiveLock(); deltas.Reset(); diff --git a/src/duckdb/src/storage/local_storage.cpp b/src/duckdb/src/storage/local_storage.cpp index 5331d2ea6..f1eb984cc 100644 --- a/src/duckdb/src/storage/local_storage.cpp +++ b/src/duckdb/src/storage/local_storage.cpp @@ -44,6 +44,7 @@ LocalTableStorage::LocalTableStorage(ClientContext &context, DataTable &new_data parent_collection.CommitDropColumn(alter_column_index); row_groups = std::move(parent.row_groups); row_groups->collection = std::move(new_collection); + row_groups->ResetCollectionAccounting(); append_indexes.Move(parent.append_indexes); delete_indexes.Move(parent.delete_indexes); @@ -60,6 +61,7 @@ LocalTableStorage::LocalTableStorage(DataTable &new_data_table, LocalTableStorag parent_collection.CommitDropColumn(drop_column_index); row_groups = std::move(parent.row_groups); row_groups->collection = std::move(new_collection); + row_groups->ResetCollectionAccounting(); append_indexes.Move(parent.append_indexes); delete_indexes.Move(parent.delete_indexes); @@ -74,6 +76,7 @@ LocalTableStorage::LocalTableStorage(ClientContext &context, DataTable &new_dt, auto new_collection = parent_collection.AddColumn(context, new_column, default_executor); row_groups = std::move(parent.row_groups); row_groups->collection = std::move(new_collection); + row_groups->ResetCollectionAccounting(); append_indexes.Move(parent.append_indexes); delete_indexes.Move(parent.delete_indexes); } @@ -560,6 +563,7 @@ void LocalStorage::Update(DataTable &table, DuckTableEntry &table_entry, Vector void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage, optional_ptr commit_state) { if (storage.is_dropped) { + storage.Rollback(); return; } if (storage.GetCollection().GetTotalRows() <= storage.deleted_rows) { @@ -590,9 +594,8 @@ void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage, optional_ // check if we have written data // if we have, we cannot merge to disk after all // so we need to revert the data we have already written - // this only happens for transactions that deleted rows after bulk-appending: a pure bulk - // append always takes the merge path above, using its pre-flushed blocks as written - D_ASSERT(!storage.HasFlushedRowGroups() || storage.deleted_rows > 0); + // this happens when rows were deleted after a bulk append, or when the optimistic writer + // flushed a partial row group that does not qualify as a bulk append storage.Rollback(); // append to the indexes storage.AppendToIndexes(transaction, append_state); diff --git a/src/duckdb/src/storage/optimistic_data_writer.cpp b/src/duckdb/src/storage/optimistic_data_writer.cpp index e155b2e10..7c2569d53 100644 --- a/src/duckdb/src/storage/optimistic_data_writer.cpp +++ b/src/duckdb/src/storage/optimistic_data_writer.cpp @@ -121,6 +121,13 @@ void OptimisticWriteCollection::FinalizeFlush() { unflushed_data_size = 0; } +void OptimisticWriteCollection::ResetCollectionAccounting() { + prev_allocated_size = 0; + unflushed_data_size = 0; + unflushed_row_groups.clear(); + flushed_row_groups.clear(); +} + void OptimisticDataWriter::WriteUnflushedRowGroups(OptimisticWriteCollection &row_groups) { auto total_row_groups = row_groups.collection->GetRowGroupCount(); if (row_groups.flushed_row_groups.size() == total_row_groups && row_groups.partial_block_managers.empty()) { diff --git a/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp b/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp index f0f41016b..f7d44ca1d 100644 --- a/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +++ b/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp @@ -673,12 +673,14 @@ void LogicalLimit::Serialize(Serializer &serializer) const { LogicalOperator::Serialize(serializer); serializer.WriteProperty(200, "limit_val", limit_val); serializer.WriteProperty(201, "offset_val", offset_val); + serializer.WritePropertyWithDefault(202, "unpruned_offset", unpruned_offset, optional_idx()); } unique_ptr LogicalLimit::Deserialize(Deserializer &deserializer) { auto limit_val = deserializer.ReadProperty(200, "limit_val"); auto offset_val = deserializer.ReadProperty(201, "offset_val"); auto result = duckdb::unique_ptr(new LogicalLimit(std::move(limit_val), std::move(offset_val))); + deserializer.ReadPropertyWithExplicitDefault(202, "unpruned_offset", result->unpruned_offset, optional_idx()); return std::move(result); } @@ -836,12 +838,30 @@ void LogicalSecureView::Serialize(Serializer &serializer) const { LogicalOperator::Serialize(serializer); serializer.WritePropertyWithDefault(200, "view_name", view_name); serializer.WritePropertyWithDefault>(201, "pushed_filters", pushed_filters); + serializer.WritePropertyWithDefault(202, "has_source", has_source); + serializer.WritePropertyWithDefault(203, "source_name", source_name, QualifiedName()); + serializer.WritePropertyWithDefault>(204, "source_types", source_types); + serializer.WritePropertyWithDefault(205, "has_at_clause", has_at_clause); + serializer.WritePropertyWithDefault(206, "at_unit", at_unit); + serializer.WritePropertyWithDefault(207, "at_value", at_value, Value()); + serializer.WritePropertyWithDefault>(208, "output_bindings", output_bindings); + serializer.WritePropertyWithDefault>>(209, "output_expressions", output_expressions); + serializer.WritePropertyWithDefault>>(210, "source_filters", source_filters); } unique_ptr LogicalSecureView::Deserialize(Deserializer &deserializer) { auto result = duckdb::unique_ptr(new LogicalSecureView()); deserializer.ReadPropertyWithDefault(200, "view_name", result->view_name); deserializer.ReadPropertyWithDefault>(201, "pushed_filters", result->pushed_filters); + deserializer.ReadPropertyWithDefault(202, "has_source", result->has_source); + deserializer.ReadPropertyWithExplicitDefault(203, "source_name", result->source_name, QualifiedName()); + deserializer.ReadPropertyWithDefault>(204, "source_types", result->source_types); + deserializer.ReadPropertyWithDefault(205, "has_at_clause", result->has_at_clause); + deserializer.ReadPropertyWithDefault(206, "at_unit", result->at_unit); + deserializer.ReadPropertyWithExplicitDefault(207, "at_value", result->at_value, Value()); + deserializer.ReadPropertyWithDefault>(208, "output_bindings", result->output_bindings); + deserializer.ReadPropertyWithDefault>>(209, "output_expressions", result->output_expressions); + deserializer.ReadPropertyWithDefault>>(210, "source_filters", result->source_filters); return std::move(result); } @@ -882,6 +902,7 @@ void LogicalTopN::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault>(200, "orders", orders); serializer.WritePropertyWithDefault(201, "limit", limit); serializer.WritePropertyWithDefault(202, "offset", offset); + serializer.WritePropertyWithDefault(203, "unpruned_offset", unpruned_offset, optional_idx()); } unique_ptr LogicalTopN::Deserialize(Deserializer &deserializer) { @@ -889,6 +910,7 @@ unique_ptr LogicalTopN::Deserialize(Deserializer &deserializer) auto limit = deserializer.ReadPropertyWithDefault(201, "limit"); auto offset = deserializer.ReadPropertyWithDefault(202, "offset"); auto result = duckdb::unique_ptr(new LogicalTopN(std::move(orders), limit, offset)); + deserializer.ReadPropertyWithExplicitDefault(203, "unpruned_offset", result->unpruned_offset, optional_idx()); return std::move(result); } diff --git a/src/duckdb/src/storage/serialization/serialize_nodes.cpp b/src/duckdb/src/storage/serialization/serialize_nodes.cpp index 7de4eeb38..e0321920d 100644 --- a/src/duckdb/src/storage/serialization/serialize_nodes.cpp +++ b/src/duckdb/src/storage/serialization/serialize_nodes.cpp @@ -357,6 +357,7 @@ void ExtraOperatorInfo::Serialize(Serializer &serializer) const { serializer.WriteProperty(101, "total_files", total_files); serializer.WriteProperty(102, "filtered_files", filtered_files); serializer.WritePropertyWithDefault>(103, "sample_options", sample_options); + serializer.WritePropertyWithDefault>>>(104, "file_filter_expressions", file_filter_expressions); } ExtraOperatorInfo ExtraOperatorInfo::Deserialize(Deserializer &deserializer) { @@ -365,6 +366,7 @@ ExtraOperatorInfo ExtraOperatorInfo::Deserialize(Deserializer &deserializer) { deserializer.ReadProperty(101, "total_files", result.total_files); deserializer.ReadProperty(102, "filtered_files", result.filtered_files); deserializer.ReadPropertyWithDefault>(103, "sample_options", result.sample_options); + deserializer.ReadPropertyWithDefault>>>(104, "file_filter_expressions", result.file_filter_expressions); return result; } @@ -428,6 +430,7 @@ void MultiFileOptions::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault(106, "filename_column", filename_column, MultiFileOptions::DEFAULT_FILENAME_COLUMN); serializer.WritePropertyWithDefault(107, "allow_empty", allow_empty); serializer.WritePropertyWithDefault(108, "maximum_sample_files", maximum_sample_files, 1); + serializer.WritePropertyWithDefault(109, "sampled_schema_is_union", sampled_schema_is_union, true); } MultiFileOptions MultiFileOptions::Deserialize(Deserializer &deserializer) { @@ -441,6 +444,7 @@ MultiFileOptions MultiFileOptions::Deserialize(Deserializer &deserializer) { deserializer.ReadPropertyWithExplicitDefault(106, "filename_column", result.filename_column, MultiFileOptions::DEFAULT_FILENAME_COLUMN); deserializer.ReadPropertyWithDefault(107, "allow_empty", result.allow_empty); deserializer.ReadPropertyWithExplicitDefault(108, "maximum_sample_files", result.maximum_sample_files, 1); + deserializer.ReadPropertyWithExplicitDefault(109, "sampled_schema_is_union", result.sampled_schema_is_union, true); return result; } diff --git a/src/duckdb/src/storage/serialization/serialize_parse_info.cpp b/src/duckdb/src/storage/serialization/serialize_parse_info.cpp index abfead377..f944830f5 100644 --- a/src/duckdb/src/storage/serialization/serialize_parse_info.cpp +++ b/src/duckdb/src/storage/serialization/serialize_parse_info.cpp @@ -241,14 +241,16 @@ void AddColumnInfo::Serialize(Serializer &serializer) const { AlterTableInfo::Serialize(serializer); serializer.WriteProperty(400, "new_column", new_column); serializer.WritePropertyWithDefault(401, "if_column_not_exists", if_column_not_exists); - serializer.WritePropertyWithDefault(402, "add_not_null", add_not_null); + serializer.WritePropertyWithDefault(402, "add_not_null", add_column_constraints.add_not_null); + serializer.WritePropertyWithDefault(403, "add_unique", add_column_constraints.add_unique); } unique_ptr AddColumnInfo::Deserialize(Deserializer &deserializer) { auto new_column = deserializer.ReadProperty(400, "new_column"); auto result = duckdb::unique_ptr(new AddColumnInfo(std::move(new_column))); deserializer.ReadPropertyWithDefault(401, "if_column_not_exists", result->if_column_not_exists); - deserializer.ReadPropertyWithDefault(402, "add_not_null", result->add_not_null); + deserializer.ReadPropertyWithDefault(402, "add_not_null", result->add_column_constraints.add_not_null); + deserializer.ReadPropertyWithDefault(403, "add_unique", result->add_column_constraints.add_unique); return std::move(result); } @@ -305,6 +307,7 @@ void AttachInfo::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault(201, "path", path); serializer.WritePropertyWithDefault>(202, "options", options); serializer.WritePropertyWithDefault(203, "on_conflict", on_conflict, OnCreateConflict::ERROR_ON_CONFLICT); + serializer.WritePropertyWithDefault>(204, "external_resource", external_resource); } unique_ptr AttachInfo::Deserialize(Deserializer &deserializer) { @@ -313,6 +316,7 @@ unique_ptr AttachInfo::Deserialize(Deserializer &deserializer) { deserializer.ReadPropertyWithDefault(201, "path", result->path); deserializer.ReadPropertyWithDefault>(202, "options", result->options); deserializer.ReadPropertyWithExplicitDefault(203, "on_conflict", result->on_conflict, OnCreateConflict::ERROR_ON_CONFLICT); + deserializer.ReadPropertyWithDefault>(204, "external_resource", result->external_resource); return std::move(result); } @@ -363,6 +367,7 @@ void ConnectInfo::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault(201, "name_is_string_literal", name_is_string_literal); serializer.WritePropertyWithDefault(202, "target_is_local", target_is_local); serializer.WritePropertyWithDefault>(203, "options", options); + serializer.WritePropertyWithDefault>(204, "external_resource", external_resource); } unique_ptr ConnectInfo::Deserialize(Deserializer &deserializer) { @@ -371,6 +376,7 @@ unique_ptr ConnectInfo::Deserialize(Deserializer &deserializer) { deserializer.ReadPropertyWithDefault(201, "name_is_string_literal", result->name_is_string_literal); deserializer.ReadPropertyWithDefault(202, "target_is_local", result->target_is_local); deserializer.ReadPropertyWithDefault>(203, "options", result->options); + deserializer.ReadPropertyWithDefault>(204, "external_resource", result->external_resource); return std::move(result); } diff --git a/src/duckdb/src/storage/serialization/serialize_tableref.cpp b/src/duckdb/src/storage/serialization/serialize_tableref.cpp index 3339ef136..15ba6006b 100644 --- a/src/duckdb/src/storage/serialization/serialize_tableref.cpp +++ b/src/duckdb/src/storage/serialization/serialize_tableref.cpp @@ -251,7 +251,7 @@ unique_ptr SubqueryRef::Deserialize(Deserializer &deserializer) { void TableFunctionRef::Serialize(Serializer &serializer) const { TableRef::Serialize(serializer); - serializer.WritePropertyWithDefault>(200, "function", function); + serializer.WritePropertyWithDefault>(200, "function", SerializableFunction()); serializer.WritePropertyWithDefault>(201, "column_name_alias", column_name_alias); serializer.WritePropertyWithDefault(202, "with_ordinality", with_ordinality, OrdinalityType::WITHOUT_ORDINALITY); } diff --git a/src/duckdb/src/storage/standard_buffer_manager.cpp b/src/duckdb/src/storage/standard_buffer_manager.cpp index 12fd87deb..fa56e658b 100644 --- a/src/duckdb/src/storage/standard_buffer_manager.cpp +++ b/src/duckdb/src/storage/standard_buffer_manager.cpp @@ -126,7 +126,7 @@ idx_t StandardBufferManager::GetOperatorMemoryLimit() const { template TempBufferPoolReservation StandardBufferManager::EvictBlocksOrThrow(QueryContext context, MemoryTag tag, idx_t memory_delta, unique_ptr *buffer, - ARGS... args) { + const ARGS &...args) { auto r = buffer_pool.EvictBlocks(context, tag, memory_delta, buffer_pool.maximum_memory, buffer); if (!r.success) { string extra_text = StringUtil::Format(" (%s/%s used)", StringUtil::BytesToHumanReadableString(GetUsedMemory()), @@ -688,13 +688,11 @@ void StandardBufferManager::DeleteTemporaryFile(BlockMemory &memory) { // The file is not in the shared pool of files. auto &fs = FileSystem::GetFileSystem(db); auto path = GetTemporaryPath(id); - if (fs.FileExists(path)) { + auto metadata = fs.GetStatsIfExists(path); + if (metadata) { evicted_data_per_tag[uint8_t(memory.GetMemoryTag())] -= memory.GetMemoryUsage(); - auto handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ); - auto content_size = handle->GetFileSize(); - handle.reset(); fs.RemoveFile(path); - temporary_directory.handle->GetTempFile().DecreaseSizeOnDisk(content_size); + temporary_directory.handle->GetTempFile().DecreaseSizeOnDisk(NumericCast(metadata->file_size)); } } @@ -745,15 +743,15 @@ vector StandardBufferManager::GetTemporaryFiles() { } // Another process or thread can delete the file before we can get its file size. - auto handle = fs.OpenFile(name, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_NULL_IF_NOT_EXISTS); - if (!handle) { + auto path = fs.JoinPath(temporary_directory.path, name); + auto metadata = fs.GetStatsIfExists(path); + if (!metadata) { return; } TemporaryFileInformation info; - info.path = name; - info.size = NumericCast(fs.GetFileSize(*handle)); - handle.reset(); + info.path = std::move(path); + info.size = NumericCast(metadata->file_size); result.push_back(info); }); return result; diff --git a/src/duckdb/src/storage/statistics/numeric_stats.cpp b/src/duckdb/src/storage/statistics/numeric_stats.cpp index b2b49005c..e4f024825 100644 --- a/src/duckdb/src/storage/statistics/numeric_stats.cpp +++ b/src/duckdb/src/storage/statistics/numeric_stats.cpp @@ -9,8 +9,20 @@ #include "duckdb/common/types/vector.hpp" #include "duckdb/storage/statistics/base_statistics.hpp" +#include + namespace duckdb { +namespace { + +template +void InitializeEmptyFloatingPointStats(BaseStatistics &result) { + NumericStats::SetMin(result, std::numeric_limits::quiet_NaN()); + NumericStats::SetMax(result, NumericLimits::Minimum()); +} + +} // namespace + BaseStatistics NumericStats::CreateUnknown(LogicalType type) { BaseStatistics result(std::move(type)); result.InitializeUnknown(); @@ -22,8 +34,18 @@ BaseStatistics NumericStats::CreateUnknown(LogicalType type) { BaseStatistics NumericStats::CreateEmpty(LogicalType type) { BaseStatistics result(std::move(type)); result.InitializeEmpty(); - SetMin(result, Value::MaximumValue(result.GetType())); - SetMax(result, Value::MinimumValue(result.GetType())); + switch (result.GetType().InternalType()) { + case PhysicalType::FLOAT: + InitializeEmptyFloatingPointStats(result); + break; + case PhysicalType::DOUBLE: + InitializeEmptyFloatingPointStats(result); + break; + default: + SetMin(result, Value::MaximumValue(result.GetType())); + SetMax(result, Value::MinimumValue(result.GetType())); + break; + } return result; } @@ -42,6 +64,13 @@ void NumericStats::Merge(BaseStatistics &stats, const BaseStatistics &other) { return; } D_ASSERT(stats.GetType() == other.GetType()); + // If the min and max of the stats are not valid, we need to merge the min and max of the other stats. + if (NumericStats::HasMin(stats) && NumericStats::HasMax(stats) && + NumericStats::Min(stats) > NumericStats::Max(stats)) { + NumericStats::SetMin(stats, NumericStats::HasMin(other) ? NumericStats::Min(other) : Value()); + NumericStats::SetMax(stats, NumericStats::HasMax(other) ? NumericStats::Max(other) : Value()); + return; + } if (NumericStats::HasMin(other) && NumericStats::HasMin(stats)) { auto other_min = NumericStats::Min(other); if (other_min < NumericStats::Min(stats)) { diff --git a/src/duckdb/src/storage/statistics/variant_stats.cpp b/src/duckdb/src/storage/statistics/variant_stats.cpp index 838319468..ad2ed2347 100644 --- a/src/duckdb/src/storage/statistics/variant_stats.cpp +++ b/src/duckdb/src/storage/statistics/variant_stats.cpp @@ -525,7 +525,7 @@ static unique_ptr TryBuildShreddingStats(const LogicalType &type return WrapTypedValue(typed_value, nullptr).ToUnique(); } default: - if (type.IsNested() || type.id() == LogicalTypeId::ENUM) { + if (type.IsNested() || type.id() == LogicalTypeId::ENUM || type.IsJSONType()) { // MAP / UNION / ENUM etc. are not stored in their source representation in the variant return nullptr; } diff --git a/src/duckdb/src/storage/storage_manager.cpp b/src/duckdb/src/storage/storage_manager.cpp index e16e50c45..22c2aae3b 100644 --- a/src/duckdb/src/storage/storage_manager.cpp +++ b/src/duckdb/src/storage/storage_manager.cpp @@ -628,6 +628,7 @@ class SingleFileStorageCommitState : public StorageCommitState { bool HasRowGroupData() override; private: + StorageManager &storage; idx_t initial_wal_size = 0; idx_t initial_written = 0; WriteAheadLog &wal; @@ -636,7 +637,7 @@ class SingleFileStorageCommitState : public StorageCommitState { }; SingleFileStorageCommitState::SingleFileStorageCommitState(StorageManager &storage, WriteAheadLog &wal) - : wal(wal), state(WALCommitState::IN_PROGRESS) { + : storage(storage), wal(wal), state(WALCommitState::IN_PROGRESS) { auto initial_size = storage.GetWALSize(); initial_written = wal.GetTotalWritten(); initial_wal_size = initial_size; @@ -668,6 +669,16 @@ void SingleFileStorageCommitState::RevertCommit() { // remove any entries written into the WAL by truncating it wal.Truncate(initial_wal_size); } + auto &block_manager = storage.GetBlockManager(); + for (auto &entry : optimistically_written_data) { + for (auto &rg_entry : entry.second) { + if (rg_entry.second.row_group_data) { + for (auto &block_id : rg_entry.second.row_group_data->GetBlockIds()) { + block_manager.MarkBlockAsModified(block_id); + } + } + } + } state = WALCommitState::TRUNCATED; } diff --git a/src/duckdb/src/storage/table/column_data.cpp b/src/duckdb/src/storage/table/column_data.cpp index 32803e7b0..e024fb79c 100644 --- a/src/duckdb/src/storage/table/column_data.cpp +++ b/src/duckdb/src/storage/table/column_data.cpp @@ -871,7 +871,7 @@ void ColumnData::CheckpointScan(ColumnSegment &segment, ColumnScanState &state, if (state.scan_options && state.scan_options->force_fetch_row) { for (idx_t i = 0; i < count; i++) { ColumnFetchState fetch_state; - fetch_state.row_group = state.parent->row_group; + fetch_state.row_group = state.parent->GetRowGroup(); segment.FetchRow(fetch_state, UnsafeNumericCast(state.offset_in_column + i), scan_vector, i); } } else { diff --git a/src/duckdb/src/storage/table/row_group.cpp b/src/duckdb/src/storage/table/row_group.cpp index 0ff308ed4..0b3d88839 100644 --- a/src/duckdb/src/storage/table/row_group.cpp +++ b/src/duckdb/src/storage/table/row_group.cpp @@ -393,7 +393,7 @@ bool RowGroup::InitializeScanInternal(CollectionScanState &state, SegmentNode state.max_row ? 0 : MinValue(this->count, state.max_row - row_start); @@ -924,7 +924,7 @@ bool RowGroup::PrepareScan(ScanOptions options, CollectionScanState &state) { continue; } if (rate < 1) { - auto row_group_start = state.row_group->GetRowStart(); + auto row_group_start = state.GetRowGroup()->GetRowStart(); sample_count = SystemRowsSelection(sampling_info, row_group_start + current_row, max_count, sample_sel); if (sample_count == 0) { @@ -946,10 +946,8 @@ bool RowGroup::PrepareScan(ScanOptions options, CollectionScanState &state) { if (!CheckZonemapSegments(state)) { continue; } - auto ¤t_row_group = state.row_group->GetNode(); - // second, scan the version chunk manager to figure out which tuples to load for this transaction - idx_t count = current_row_group.GetSelVector(options, state.vector_index, state.valid_sel, max_count); + idx_t count = GetSelVector(options, state.vector_index, state.valid_sel, max_count); if (count == 0) { // nothing to scan for this vector, skip the entire vector NextVector(state); @@ -1623,7 +1621,7 @@ bool RowGroup::HasUnchangedColumns() const { RowGroupWriteData RowGroup::WriteToDisk(RowGroupWriter &writer) { bool can_reuse_metadata = CanReuseMetadata(writer); - if (can_reuse_metadata && !HasChanges()) { + if (can_reuse_metadata && !HasChanges(writer.GetCheckpointOptions().visibility_bound)) { RowGroupWriteData result; result.write_action = RowGroupWriteAction::REUSE_EXISTING_ROW_GROUP_METADATA; if (GetCollection().SupportsPerColumnWrites()) { @@ -1911,12 +1909,12 @@ RowGroupPointer RowGroup::Checkpoint(RowGroupWriteData write_data, RowGroupWrite return row_group_pointer; } -bool RowGroup::HasChanges() const { +bool RowGroup::HasChanges(VisibilityBound bound) const { if (has_changes) { return true; } auto version_info_loaded = version_info.load(); - if (version_info_loaded && version_info_loaded->HasUnserializedChanges()) { + if (version_info_loaded && version_info_loaded->HasUnserializedChanges(bound)) { // we have deletes return true; } @@ -2044,7 +2042,7 @@ struct DuckDBPartitionRowGroup : public PartitionRowGroup { } bool HasPendingWrites() override { - return row_group->HasChanges(); + return row_group->HasChanges(VisibilityBound::AllCommitted()); } }; diff --git a/src/duckdb/src/storage/table/row_group_collection.cpp b/src/duckdb/src/storage/table/row_group_collection.cpp index cfdd5e2b0..a0ee7fcc1 100644 --- a/src/duckdb/src/storage/table/row_group_collection.cpp +++ b/src/duckdb/src/storage/table/row_group_collection.cpp @@ -3,6 +3,7 @@ #include "duckdb/transaction/commit_state.hpp" #include "duckdb/common/serializer/binary_deserializer.hpp" +#include "duckdb/common/thread.hpp" #include "duckdb/common/vector/flat_vector.hpp" #include "duckdb/execution/expression_executor.hpp" #include "duckdb/execution/index/art/art.hpp" @@ -310,7 +311,6 @@ void RowGroupCollection::InitializeScan(const QueryContext &context, CollectionS optional_ptr table_filters) { state.row_groups = GetRowGroups(); auto row_group = state.GetRootSegment(); - D_ASSERT(row_group); state.max_row = state.row_groups->GetBaseRowId() + next_row_id.load(); state.Initialize(context, GetTypes()); while (row_group && !row_group->GetNode().InitializeScan(state, *row_group)) { @@ -1765,6 +1765,11 @@ void RowGroupCollection::Checkpoint(TableDataWriter &writer, TableStatistics &gl // all tasks have been successfully scheduled - execute tasks until we are done checkpoint_state.executor->WorkOnTasks(); + auto scan_sleep_ms = Settings::Get(writer.GetDatabase()); + if (scan_sleep_ms > 0) { + ThreadUtil::SleepMs(scan_sleep_ms); + } + // no errors - finalize the row groups // if the table already exists on disk - check if all row groups have stayed the same if (Settings::Get(writer.GetDatabase()) && metadata_pointer.IsValid()) { diff --git a/src/duckdb/src/storage/table/row_id_column_data.cpp b/src/duckdb/src/storage/table/row_id_column_data.cpp index dc749bd41..a285c42e4 100644 --- a/src/duckdb/src/storage/table/row_id_column_data.cpp +++ b/src/duckdb/src/storage/table/row_id_column_data.cpp @@ -12,7 +12,7 @@ RowIdColumnData::RowIdColumnData(BlockManager &block_manager, DataTableInfo &inf } idx_t RowIdColumnData::GetRowStart(ColumnScanState &state) { - return state.parent->row_group->GetRowStart(); + return state.parent->GetRowGroup()->GetRowStart(); } FilterPropagateResult RowIdColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filter, diff --git a/src/duckdb/src/storage/table/row_version_manager.cpp b/src/duckdb/src/storage/table/row_version_manager.cpp index 9f9f1f637..3f929410d 100644 --- a/src/duckdb/src/storage/table/row_version_manager.cpp +++ b/src/duckdb/src/storage/table/row_version_manager.cpp @@ -204,8 +204,11 @@ idx_t RowVersionManager::DeleteRows(idx_t vector_idx, transaction_t transaction_ void RowVersionManager::CommitDelete(idx_t vector_idx, transaction_t commit_id, const DeleteInfo &info) { lock_guard lock(version_lock); needs_compression_check = true; - if (!uncheckpointed_delete_commit.IsValid() || commit_id > uncheckpointed_delete_commit.GetIndex()) { - uncheckpointed_delete_commit = commit_id; + if (!newest_uncheckpointed_delete_commit.IsValid() || commit_id > newest_uncheckpointed_delete_commit.GetIndex()) { + newest_uncheckpointed_delete_commit = commit_id; + } + if (!oldest_uncheckpointed_delete_commit.IsValid() || commit_id < oldest_uncheckpointed_delete_commit.GetIndex()) { + oldest_uncheckpointed_delete_commit = commit_id; } GetVectorInfo(vector_idx).CommitDelete(commit_id, info); } @@ -244,8 +247,10 @@ vector RowVersionManager::Checkpoint(RowGroupWriter &writer) { lock_guard lock(version_lock); auto &manager = *writer.GetMetadataManager(); auto options = writer.GetCheckpointOptions(); - if (!uncheckpointed_delete_commit.IsValid()) { - // we can write the current pointer as-is + if (!oldest_uncheckpointed_delete_commit.IsValid() || + oldest_uncheckpointed_delete_commit.GetIndex() >= options.visibility_bound) { + // nothing below the bound changed since the last checkpoint: the blocks on disk are current. A delete that + // committed above the bound, while this checkpoint ran, is written by the next checkpoint // ensure the blocks we are pointing to are not marked as free manager.ClearModifiedBlocks(storage_pointers); // return the current set of pointers @@ -279,10 +284,12 @@ vector RowVersionManager::Checkpoint(RowGroupWriter &writer) { metadata_writer.Flush(); } - if (uncheckpointed_delete_commit.IsValid() && uncheckpointed_delete_commit.GetIndex() < options.visibility_bound) { + if (newest_uncheckpointed_delete_commit.IsValid() && + newest_uncheckpointed_delete_commit.GetIndex() < options.visibility_bound) { // the last checkpointed id was either before or on the transaction we are checkpointing // nothing to checkpoint in future commits until more deletes appear - uncheckpointed_delete_commit = optional_idx(); + newest_uncheckpointed_delete_commit = optional_idx(); + oldest_uncheckpointed_delete_commit = optional_idx(); } return storage_pointers; } @@ -313,13 +320,14 @@ shared_ptr RowVersionManager::Deserialize(MetaBlockPointer de } version_info->vector_info[vector_index] = std::move(info); } - version_info->uncheckpointed_delete_commit = optional_idx(); + version_info->newest_uncheckpointed_delete_commit = optional_idx(); + version_info->oldest_uncheckpointed_delete_commit = optional_idx(); return version_info; } -bool RowVersionManager::HasUnserializedChanges() { +bool RowVersionManager::HasUnserializedChanges(VisibilityBound bound) { lock_guard lock(version_lock); - return uncheckpointed_delete_commit.IsValid(); + return oldest_uncheckpointed_delete_commit.IsValid() && oldest_uncheckpointed_delete_commit.GetIndex() < bound; } bool RowVersionManager::HasDeletes() { @@ -344,7 +352,7 @@ bool RowVersionManager::HasUncommittedChanges() { vector RowVersionManager::GetStoragePointers() { lock_guard lock(version_lock); - D_ASSERT(!uncheckpointed_delete_commit.IsValid()); + D_ASSERT(!newest_uncheckpointed_delete_commit.IsValid()); return storage_pointers; } diff --git a/src/duckdb/src/storage/table/scan_state.cpp b/src/duckdb/src/storage/table/scan_state.cpp index 8cb54810b..a967e9a9d 100644 --- a/src/duckdb/src/storage/table/scan_state.cpp +++ b/src/duckdb/src/storage/table/scan_state.cpp @@ -235,8 +235,17 @@ ParallelCollectionScanState::GetNextRowGroup(RowGroupSegmentTree &row_groups, Se } CollectionScanState::CollectionScanState(TableScanState &parent_p) - : row_group(nullptr), vector_index(0), max_row_group_row(0), row_groups(nullptr), max_row(0), batch_index(0), - valid_sel(STANDARD_VECTOR_SIZE), random(-1), parent(parent_p) { + : vector_index(0), max_row_group_row(0), row_groups(nullptr), max_row(0), batch_index(0), + valid_sel(STANDARD_VECTOR_SIZE), random(-1), row_group(nullptr), parent(parent_p) { +} + +optional_ptr> CollectionScanState::GetRowGroup() const { + return row_group; +} + +void CollectionScanState::SetRowGroup(optional_ptr> row_group_p) { + row_group = row_group_p; + pinned_row_group = row_group ? row_group->ReferenceNode() : nullptr; } optional_ptr> CollectionScanState::GetNextRowGroup(SegmentNode &row_group) const { @@ -265,23 +274,23 @@ bool CollectionScanState::Scan(DuckTransaction &transaction, DataChunk &result) bool CollectionScanState::Scan(ScanOptions options, DataChunk &result, optional_ptr l) { while (row_group) { - row_group->GetNode().Scan(options, *this, result); + pinned_row_group->Scan(options, *this, result); if (result.size() > 0) { return true; } - if (max_row <= row_group->GetRowStart() + row_group->GetNode().count) { - row_group = nullptr; + if (max_row <= row_group->GetRowStart() + pinned_row_group->count) { + SetRowGroup(nullptr); return false; } do { if (l) { - row_group = GetNextRowGroup(*l, *row_group).get(); + SetRowGroup(GetNextRowGroup(*l, *row_group)); } else { - row_group = GetNextRowGroup(*row_group).get(); + SetRowGroup(GetNextRowGroup(*row_group)); } if (row_group) { if (row_group->GetRowStart() >= max_row) { - row_group = nullptr; + SetRowGroup(nullptr); break; } bool scan_row_group = row_group->GetNode().InitializeScan(*this, *row_group); @@ -297,15 +306,15 @@ bool CollectionScanState::Scan(ScanOptions options, DataChunk &result, optional_ bool CollectionScanState::Scan(DataChunk &result, TableScanType type, optional_ptr l) { while (row_group) { - row_group->GetNode().Scan(*this, result, type); + pinned_row_group->Scan(*this, result, type); if (result.size() > 0) { return true; } // move to the next row group if (l) { - row_group = GetNextRowGroup(*l, *row_group).get(); + SetRowGroup(GetNextRowGroup(*l, *row_group)); } else { - row_group = GetNextRowGroup(*row_group).get(); + SetRowGroup(GetNextRowGroup(*row_group)); } if (row_group) { row_group->GetNode().InitializeScan(*this, *row_group); @@ -319,12 +328,12 @@ bool CollectionScanState::PrepareScanIO(DuckTransaction &transaction, vectorGetNode(); + auto ¤t_row_group = *pinned_row_group; ScanOptions options {TransactionData(transaction)}; if (!current_row_group.PrepareScan(options, *this)) { // the assignment is exhausted D_ASSERT(max_row <= row_group->GetRowStart() + current_row_group.count); - row_group = nullptr; + SetRowGroup(nullptr); return false; } if (prepared_vector.prepare_state == VectorPrepareState::IO_REGISTERED) { @@ -345,13 +354,13 @@ vector> CollectionScanState::RegisterAssignmentIO() { D_ASSERT(row_group); D_ASSERT(!assignment_io_registered); assignment_io_registered = true; - auto ¤t_row_group = row_group->GetNode(); + auto ¤t_row_group = *pinned_row_group; return current_row_group.CollectScanIOTasks(*this, current_row_group.PrefetchRowCount(*this)); } void CollectionScanState::InitializeColumnScans() { if (column_scans_pending) { - row_group->GetNode().InitializeColumnScans(*this); + pinned_row_group->InitializeColumnScans(*this); } } @@ -369,7 +378,7 @@ void CollectionScanState::ProcessPreparedScan(DuckTransaction &transaction, Data D_ASSERT(row_group); D_ASSERT(prepared_vector.prepare_state == VectorPrepareState::IO_REGISTERED); ScanOptions options {TransactionData(transaction)}; - row_group->GetNode().ProcessPreparedScan(options, *this, result); + pinned_row_group->ProcessPreparedScan(options, *this, result); } PreparedScanVector::PreparedScanVector() : sample_sel(STANDARD_VECTOR_SIZE) { diff --git a/src/duckdb/src/storage/table_index_list.cpp b/src/duckdb/src/storage/table_index_list.cpp index 1ef7e78eb..9a6008eeb 100644 --- a/src/duckdb/src/storage/table_index_list.cpp +++ b/src/duckdb/src/storage/table_index_list.cpp @@ -82,10 +82,10 @@ TableIndexList::~TableIndexList() { } } -void TableIndexList::AddIndex(unique_ptr index) { +void TableIndexList::AddIndex(unique_ptr index, optional_idx index_oid) { D_ASSERT(index); annotated_lock_guard lock(index_entries_lock); - auto index_entry = make_shared_ptr(std::move(index)); + auto index_entry = make_shared_ptr(std::move(index), index_oid); if (index_entry->GetBindState() != IndexBindState::BOUND) { unbound_count++; } @@ -124,7 +124,7 @@ ErrorData TableIndexList::Append(optional_ptr delete_indexes, Da for (const auto &entry : index_entries) { shared_ptr delete_entry; if (delete_indexes && entry->IsUnique()) { - delete_entry = delete_indexes->FindEntry(entry->GetName()); + delete_entry = delete_indexes->FindEntry(*entry); } error = entry->Append(chunk, row_ids, delete_entry, append_mode, active_checkpoint); if (error.HasError()) { @@ -191,6 +191,28 @@ void TableIndexList::RemoveIndex(const Identifier &name) { } } +void TableIndexList::RemoveIndex(idx_t index_oid) { + shared_ptr removed_entry; + { + annotated_lock_guard lock(index_entries_lock); + for (idx_t i = 0; i < index_entries.size(); i++) { + auto &entry = index_entries[i]; + if (entry->GetCatalogIndexOid() != index_oid) { + continue; + } + if (entry->GetBindState() != IndexBindState::BOUND) { + unbound_count--; + } + removed_entry = std::move(entry); + index_entries.erase_at(i); + break; + } + } + if (removed_entry) { + removed_entry->Retire(); + } +} + bool TableIndexList::HasUniqueIndexes() const { annotated_lock_guard lock(index_entries_lock); for (const auto &entry : index_entries) { @@ -209,7 +231,7 @@ void TableIndexList::VerifyUniqueIndexes(optional_ptr dele if (!entry->IsUnique() || entry->GetIndexType() != ART::TYPE_NAME) { continue; } - auto delete_entry = delete_indexes ? delete_indexes->FindEntry(entry->GetName()) : nullptr; + auto delete_entry = delete_indexes ? delete_indexes->FindEntry(*entry) : nullptr; entry->VerifyAppend(delete_entry, chunk, nullptr); } return; @@ -223,9 +245,8 @@ void TableIndexList::VerifyUniqueIndexes(optional_ptr dele !conflict_info.ConflictTargetMatches(index_info.is_unique, index_info.column_set)) { continue; } - auto index_name = entry->GetName(); - auto delete_entry = delete_indexes ? delete_indexes->FindEntry(index_name) : nullptr; - manager->AddIndex(entry, index_name, std::move(delete_entry)); + auto delete_entry = delete_indexes ? delete_indexes->FindEntry(*entry) : nullptr; + manager->AddIndex(entry, std::move(delete_entry)); } // Verify indexes matching the conflict target. @@ -239,10 +260,10 @@ void TableIndexList::VerifyUniqueIndexes(optional_ptr dele // Scan the other indexes and throw if there are any conflicts. manager->SetMode(ConflictManagerMode::THROW); for (const auto &entry : index_entries) { - if (!entry->IsUnique() || entry->GetIndexType() != ART::TYPE_NAME || manager->IndexMatches(entry->GetName())) { + if (!entry->IsUnique() || entry->GetIndexType() != ART::TYPE_NAME || manager->IndexMatches(entry)) { continue; } - auto delete_entry = delete_indexes ? delete_indexes->FindEntry(entry->GetName()) : nullptr; + auto delete_entry = delete_indexes ? delete_indexes->FindEntry(*entry) : nullptr; entry->VerifyAppend(delete_entry, chunk, manager); } } @@ -317,6 +338,16 @@ bool TableIndexList::AllIndexesBoundOfType(const string &index_type) const { return true; } +bool TableIndexList::HasBufferedReplays() const { + annotated_lock_guard lock(index_entries_lock); + for (const auto &entry : index_entries) { + if (entry->HasBufferedReplays()) { + return true; + } + } + return false; +} + bool TableIndexList::NameIsUnique(const string &name) const { annotated_lock_guard lock(index_entries_lock); // Only covers PK, FK, and UNIQUE indexes. @@ -354,6 +385,24 @@ shared_ptr TableIndexList::FindEntry(const Identifier &name) const { return nullptr; } +shared_ptr TableIndexList::FindEntry(const IndexEntry &index) const { + auto catalog_index_oid = index.GetCatalogIndexOid(); + annotated_lock_guard lock(index_entries_lock); + for (const auto &entry : index_entries) { + if (entry->GetCatalogIndexOid() != catalog_index_oid) { + continue; + } + if (!catalog_index_oid.IsValid() && entry->GetName() != index.GetName()) { + continue; + } + if (entry->GetBindState() != IndexBindState::BOUND) { + throw InternalException("TableIndexList::FindEntry cannot return an unbound index"); + } + return entry; + } + return nullptr; +} + void TableIndexList::Bind(ClientContext &context, DataTableInfo &table_info, const optional &index_type) { { // Early-out, if we have no unbound indexes. @@ -473,7 +522,7 @@ void TableIndexList::VerifyForeignKey(optional_ptr delete_ throw InternalException("TableIndexList::VerifyForeignKey failed to find foreign key index"); } - auto delete_entry = delete_indexes ? delete_indexes->FindEntry(entry->GetName()) : nullptr; + auto delete_entry = delete_indexes ? delete_indexes->FindEntry(*entry) : nullptr; entry->VerifyForeignKey(delete_entry, chunk, conflict_manager); } @@ -531,6 +580,17 @@ IndexSerializationResult TableIndexList::SerializeToDisk(QueryContext context, c return result; } +unique_ptr TableIndexList::SerializeToWAL(idx_t index_oid, + const case_insensitive_map_t &options) { + annotated_lock_guard lock(index_entries_lock); + for (const auto &entry : index_entries) { + if (entry->GetCatalogIndexOid() == index_oid) { + return make_uniq(entry->SerializeToWAL(options)); + } + } + return nullptr; +} + unique_ptr TableIndexList::SerializeToWAL(const Identifier &name, const case_insensitive_map_t &options) { annotated_lock_guard lock(index_entries_lock); diff --git a/src/duckdb/src/storage/temporary_file_manager.cpp b/src/duckdb/src/storage/temporary_file_manager.cpp index c8fde3b5f..87d638399 100644 --- a/src/duckdb/src/storage/temporary_file_manager.cpp +++ b/src/duckdb/src/storage/temporary_file_manager.cpp @@ -340,7 +340,7 @@ TemporaryFileInformation TemporaryFileHandle::GetTemporaryFile() { TemporaryFileLock lock(file_lock); TemporaryFileInformation info; info.path = path; - info.size = GetPositionInFile(index_manager.GetUsedBlockCount()); + info.size = GetPositionInFile(index_manager.GetMaxIndex()); return info; } @@ -361,7 +361,7 @@ void TemporaryFileHandle::RemoveTempBlockIndex(TemporaryFileLock &, idx_t index) #ifndef WIN32 // this ended up causing issues when sorting auto max_index = index_manager.GetMaxIndex(); auto &fs = FileSystem::GetFileSystem(db); - fs.Truncate(*handle, NumericCast(GetPositionInFile(max_index + 1))); + fs.Truncate(*handle, NumericCast(GetPositionInFile(max_index))); #endif } } diff --git a/src/duckdb/src/storage/wal_replay.cpp b/src/duckdb/src/storage/wal_replay.cpp index 2e5d404ab..9bf869562 100644 --- a/src/duckdb/src/storage/wal_replay.cpp +++ b/src/duckdb/src/storage/wal_replay.cpp @@ -64,6 +64,10 @@ class ReplayState { optional_idx checkpoint_end_position; optional_idx expected_checkpoint_id; WALReplayState replay_state; + //! Blocks referenced by ROW_GROUP_DATA entries, collected during the deserialize-only scan. They are marked as used + //! only once we have decided to replay the WAL, so if log replay is not needed, these blocks won't be + //! double-referenced. + vector row_group_blocks; struct ReplayIndexInfo { ReplayIndexInfo(TableIndexList &index_list, unique_ptr index, idx_t table_oid, optional_idx index_oid) @@ -606,6 +610,15 @@ unique_ptr WriteAheadLogReplayer::ReplayLog(unique_ptr(fs, std::move(main_handle)); } + + // Now we have decided to replay this WAL, mark the blocks referenced by ROW_GROUP_DATA entries as used. + // Notice, this must happen before replay, because replaying earlier entries can allocate blocks; without the marks, + // those allocations could hand out blocks that later entries reference. + auto &block_manager = storage_manager.GetBlockManager(); + for (auto &block_id : checkpoint_state.row_group_blocks) { + block_manager.MarkBlockAsUsed(block_id); + } + // we need to recover from the WAL: actually set up the replay state ReplayState state(database, *con.context, replay_state); @@ -627,7 +640,7 @@ unique_ptr WriteAheadLogReplayer::ReplayLog(unique_ptr(); deserializer.Unset(); if (DeserializeOnly()) { - // label blocks in data as used - they will be used after the WAL replay is finished - // we need to do this during the deserialization phase to ensure the blocks will not be overwritten - // by previous deserialization steps for (auto &block_id : data.GetBlockIds()) { - block_manager.MarkBlockAsUsed(block_id); + state.row_group_blocks.push_back(block_id); } return; } if (!state.current_table) { - throw InternalException("Corrupt WAL: insert without table"); + throw DataCorruptionException("Corrupt WAL: insert without table"); } auto &storage = state.current_table->GetStorage(); auto &table_info = storage.GetDataTableInfo(); @@ -1374,7 +1384,7 @@ void WriteAheadLogDeserializer::ReplayDelete() { return; } if (!state.current_table) { - throw SerializationException("delete without a table"); + throw DataCorruptionException("Corrupt WAL: delete without table"); } D_ASSERT(chunk.ColumnCount() == 1 && chunk.data[0].GetType() == LogicalType::ROW_TYPE); @@ -1387,7 +1397,7 @@ void WriteAheadLogDeserializer::ReplayDelete() { auto next_row_id = storage.GetNextRowId(); for (idx_t i = 0; i < chunk.size(); i++) { if (source_ids[i] >= UnsafeNumericCast(next_row_id)) { - throw SerializationException("invalid row ID delete in WAL"); + throw DataCorruptionException("Corrupt WAL: row ID for delete out of bounds"); } } TableDeleteState delete_state; @@ -1404,11 +1414,11 @@ void WriteAheadLogDeserializer::ReplayUpdate() { return; } if (!state.current_table) { - throw InternalException("Corrupt WAL: update without table"); + throw DataCorruptionException("Corrupt WAL: update without table"); } if (column_path[0] >= state.current_table->GetColumns().PhysicalColumnCount()) { - throw InternalException("Corrupt WAL: column index for update out of bounds"); + throw DataCorruptionException("Corrupt WAL: column index for update out of bounds"); } // remove the row id vector from the chunk diff --git a/src/duckdb/src/storage/write_ahead_log.cpp b/src/duckdb/src/storage/write_ahead_log.cpp index 9dbf7d1f7..f59e3943c 100644 --- a/src/duckdb/src/storage/write_ahead_log.cpp +++ b/src/duckdb/src/storage/write_ahead_log.cpp @@ -385,8 +385,7 @@ void WriteAheadLog::WriteDropTableMacro(const TableMacroCatalogEntry &entry) { // Indexes //===--------------------------------------------------------------------===// -void SerializeIndex(AttachedDatabase &db, WriteAheadLogSerializer &serializer, TableIndexList &list, - const Identifier &name) { +case_insensitive_map_t GetIndexSerializationOptions(AttachedDatabase &db) { case_insensitive_map_t options; auto storage_version = db.GetStorageManager().GetStorageVersion(); // Before: serialization version 3 @@ -394,8 +393,10 @@ void SerializeIndex(AttachedDatabase &db, WriteAheadLogSerializer &serializer, T if (!v1_0_0_storage) { options["v1_0_0_storage"] = v1_0_0_storage; } + return options; +} - auto info = list.SerializeToWAL(name, options); +void WriteIndexStorage(WriteAheadLogSerializer &serializer, unique_ptr info) { if (!info) { return; } @@ -408,6 +409,17 @@ void SerializeIndex(AttachedDatabase &db, WriteAheadLogSerializer &serializer, T }); } +void SerializeIndex(AttachedDatabase &db, WriteAheadLogSerializer &serializer, TableIndexList &list, idx_t index_oid) { + auto options = GetIndexSerializationOptions(db); + WriteIndexStorage(serializer, list.SerializeToWAL(index_oid, options)); +} + +void SerializeIndex(AttachedDatabase &db, WriteAheadLogSerializer &serializer, TableIndexList &list, + const Identifier &name) { + auto options = GetIndexSerializationOptions(db); + WriteIndexStorage(serializer, list.SerializeToWAL(name, options)); +} + void WriteAheadLog::WriteCreateIndex(const IndexCatalogEntry &entry) { WriteAheadLogSerializer serializer(*this, WALType::CREATE_INDEX); serializer.WriteProperty(101, "index_catalog_entry", &entry); @@ -416,7 +428,7 @@ void WriteAheadLog::WriteCreateIndex(const IndexCatalogEntry &entry) { auto &index_entry = entry.Cast(); auto &list = index_entry.GetDataTableInfo().GetIndexes(); auto &database = GetDatabase(); - SerializeIndex(database, serializer, list, index_entry.name); + SerializeIndex(database, serializer, list, index_entry.oid); serializer.End(); } diff --git a/src/duckdb/src/transaction/commit_state.cpp b/src/duckdb/src/transaction/commit_state.cpp index c6a58198c..bf5d89452 100644 --- a/src/duckdb/src/transaction/commit_state.cpp +++ b/src/duckdb/src/transaction/commit_state.cpp @@ -39,8 +39,8 @@ void CommitDropState::DropBlock(block_id_t block_id) { dropped_block_ids.push_back(block_id); } -void CommitDropState::RemoveIndex(TableIndexList &indexes, Identifier name) { - pending_index_removals.push_back(PendingIndexRemoval {indexes, std::move(name)}); +void CommitDropState::RemoveIndex(TableIndexList &indexes, idx_t index_oid) { + pending_index_removals.push_back(PendingIndexRemoval {indexes, index_oid}); } void CommitDropState::FinalizeCommit() { @@ -53,7 +53,7 @@ void CommitDropState::FinalizeCommit() { D_ASSERT(block_manager || dropped_block_ids.empty()); for (auto &removal : pending_index_removals) { - removal.indexes.get().RemoveIndex(removal.name); + removal.indexes.get().RemoveIndex(removal.index_oid); } dropped_block_ids.clear(); pending_index_removals.clear(); diff --git a/src/duckdb/src/transaction/duck_transaction_manager.cpp b/src/duckdb/src/transaction/duck_transaction_manager.cpp index d5b6319a9..4dd54f909 100644 --- a/src/duckdb/src/transaction/duck_transaction_manager.cpp +++ b/src/duckdb/src/transaction/duck_transaction_manager.cpp @@ -441,6 +441,10 @@ ErrorData DuckTransactionManager::CommitTransaction(ClientContext &context, Tran CleanupTransactions(); + // A failed commit rolls back inline, queueing teardowns as RollbackTransaction does. Drain here too, + // so the call that fills the queue is the one that empties it. + DatabaseManager::Get(db.GetDatabase()).DrainPendingTeardowns(); + // now perform a checkpoint if (1) we are able to checkpoint, and (2) the WAL has reached sufficient size to // checkpoint if (checkpoint_decision.can_checkpoint) { @@ -485,6 +489,10 @@ void DuckTransactionManager::RollbackTransaction(Transaction &transaction_p) { CleanupTransactions(); + // Run external-resource teardowns the rollback queued (see RollbackState): they execute SQL, so + // they can only run here, after the transaction lock is released. + DatabaseManager::Get(db.GetDatabase()).DrainPendingTeardowns(); + if (error.HasError()) { throw FatalException("Failed to rollback transaction. Cannot continue operation.\nError: %s", error.Message()); } diff --git a/src/duckdb/src/transaction/rollback_state.cpp b/src/duckdb/src/transaction/rollback_state.cpp index e6bcbbc13..370587735 100644 --- a/src/duckdb/src/transaction/rollback_state.cpp +++ b/src/duckdb/src/transaction/rollback_state.cpp @@ -12,6 +12,7 @@ #include "duckdb/storage/table/update_segment.hpp" #include "duckdb/storage/table/row_version_manager.hpp" #include "duckdb/main/attached_database.hpp" +#include "duckdb/main/external_resources_manager.hpp" #include "duckdb/main/database_manager.hpp" namespace duckdb { @@ -48,7 +49,16 @@ void RollbackState::RollbackEntry(UndoFlags type, data_ptr_t data) { case UndoFlags::ATTACHED_DATABASE: { auto db = Load(data); auto &db_manager = DatabaseManager::Get(db->GetDatabase()); - db_manager.DetachInternal(db->name); + auto attached_db = db_manager.DetachInternal(db->name); + if (attached_db) { + // Teardown runs SQL, which cannot happen under the transaction lock: it would need a + // transaction on the same manager, and rollback may not fail. Extracting the deleter is a + // field move, safe here; the DatabaseManager drains the queue once rollback completes. + auto deleter = attached_db->ExtractDeleter(); + if (deleter) { + db_manager.AddPendingTeardown(std::move(deleter)); + } + } break; } case UndoFlags::SEQUENCE_VALUE: diff --git a/src/duckdb/src/transaction/undo_buffer.cpp b/src/duckdb/src/transaction/undo_buffer.cpp index 6dd647d2e..dbc5e290e 100644 --- a/src/duckdb/src/transaction/undo_buffer.cpp +++ b/src/duckdb/src/transaction/undo_buffer.cpp @@ -61,41 +61,25 @@ void UndoBuffer::IterateEntries(UndoBuffer::IteratorState &state, T &&callback) } template -void UndoBuffer::IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback) { +void UndoBuffer::ReverseIterateEntries(UndoBuffer::IteratorState &end_state, T &&callback) { if (!end_state.started) { return; } - // iterate in insertion order: start with the tail - state.current = allocator.tail.get(); - while (state.current) { - state.handle = allocator.buffer_manager.Pin(state.current->block); - state.start = state.handle.GetDataMutable(); - state.end = state.current == end_state.current ? end_state.start : state.start + state.current->position; - while (state.start < state.end) { - auto type = Load(state.start); - state.start += sizeof(UndoFlags); - auto len = Load(state.start); - state.start += sizeof(uint32_t); - callback(type, state.start); - state.start += len; - } - if (state.current == end_state.current) { - // finished executing until the current end state - return; - } - state.current = state.current->prev; + + idx_t end_position = 0; + if (end_state.current) { + auto block_start = end_state.handle.GetDataMutable(); + D_ASSERT(end_state.start >= block_start); + end_position = NumericCast(end_state.start - block_start); + D_ASSERT(end_position <= end_state.current->position); } -} -template -void UndoBuffer::ReverseIterateEntries(T &&callback) { - // iterate in reverse insertion order: start with the head - auto current = allocator.head.get(); + // Start at the newest committed entry and iterate back to the oldest one. + auto current = end_state.current ? end_state.current : allocator.head.get(); while (current) { auto handle = allocator.buffer_manager.Pin(current->block); data_ptr_t start = handle.GetDataMutable(); - data_ptr_t end = start + current->position; - // create a vector with all nodes in this chunk + data_ptr_t end = start + (current == end_state.current ? end_position : current->position); vector> nodes; while (start < end) { auto type = Load(start); @@ -105,7 +89,6 @@ void UndoBuffer::ReverseIterateEntries(T &&callback) { nodes.emplace_back(type, start); start += len; } - // iterate over it in reverse order for (idx_t i = nodes.size(); i > 0; i--) { callback(nodes[i - 1].first, nodes[i - 1].second); } @@ -113,6 +96,13 @@ void UndoBuffer::ReverseIterateEntries(T &&callback) { } } +template +void UndoBuffer::ReverseIterateEntries(T &&callback) { + UndoBuffer::IteratorState state; + state.started = true; + ReverseIterateEntries(state, std::forward(callback)); +} + bool UndoBuffer::ChangesMade() { // we need to search for any index creation entries return allocator.head.get(); @@ -203,8 +193,7 @@ void UndoBuffer::Commit(UndoBuffer::IteratorState &iterator_state, CommitInfo &i void UndoBuffer::RevertCommit(UndoBuffer::IteratorState &end_state, transaction_t transaction_id) { CommitState state(transaction, transaction_id, active_transaction_state, CommitMode::REVERT_COMMIT); - UndoBuffer::IteratorState start_state; - IterateEntries(start_state, end_state, [&](UndoFlags type, data_ptr_t data) { state.RevertCommit(type, data); }); + ReverseIterateEntries(end_state, [&](UndoFlags type, data_ptr_t data) { state.RevertCommit(type, data); }); state.Verify(); } diff --git a/src/duckdb/third_party/parquet/parquet_types.cpp b/src/duckdb/third_party/parquet/parquet_types.cpp index a508a69f2..cc73b3a98 100644 --- a/src/duckdb/third_party/parquet/parquet_types.cpp +++ b/src/duckdb/third_party/parquet/parquet_types.cpp @@ -1317,7 +1317,8 @@ Statistics::Statistics() noexcept max_value(), min_value(), is_max_value_exact(0), - is_min_value_exact(0) { + is_min_value_exact(0), + nan_count(0) { } void Statistics::__set_max(const std::string& val) { @@ -1359,6 +1360,11 @@ void Statistics::__set_is_min_value_exact(const bool val) { this->is_min_value_exact = val; __isset.is_min_value_exact = true; } + +void Statistics::__set_nan_count(const int64_t val) { + this->nan_count = val; +__isset.nan_count = true; +} std::ostream& operator<<(std::ostream& out, const Statistics& obj) { obj.printTo(out); @@ -1451,6 +1457,14 @@ uint32_t Statistics::read(::apache::thrift::protocol::TProtocol* iprot) { xfer += iprot->skip(ftype); } break; + case 9: + if (ftype == ::apache::thrift::protocol::T_I64) { + xfer += iprot->readI64(this->nan_count); + this->__isset.nan_count = true; + } else { + xfer += iprot->skip(ftype); + } + break; default: xfer += iprot->skip(ftype); break; @@ -1508,6 +1522,11 @@ uint32_t Statistics::write(::apache::thrift::protocol::TProtocol* oprot) const { xfer += oprot->writeBool(this->is_min_value_exact); xfer += oprot->writeFieldEnd(); } + if (this->__isset.nan_count) { + xfer += oprot->writeFieldBegin("nan_count", ::apache::thrift::protocol::T_I64, 9); + xfer += oprot->writeI64(this->nan_count); + xfer += oprot->writeFieldEnd(); + } xfer += oprot->writeFieldStop(); xfer += oprot->writeStructEnd(); return xfer; @@ -1523,6 +1542,7 @@ void swap(Statistics &a, Statistics &b) { swap(a.min_value, b.min_value); swap(a.is_max_value_exact, b.is_max_value_exact); swap(a.is_min_value_exact, b.is_min_value_exact); + swap(a.nan_count, b.nan_count); swap(a.__isset, b.__isset); } @@ -1535,6 +1555,7 @@ Statistics::Statistics(const Statistics& other30) { min_value = other30.min_value; is_max_value_exact = other30.is_max_value_exact; is_min_value_exact = other30.is_min_value_exact; + nan_count = other30.nan_count; __isset = other30.__isset; } Statistics::Statistics(Statistics&& other31) noexcept { @@ -1546,6 +1567,7 @@ Statistics::Statistics(Statistics&& other31) noexcept { min_value = std::move(other31.min_value); is_max_value_exact = other31.is_max_value_exact; is_min_value_exact = other31.is_min_value_exact; + nan_count = other31.nan_count; __isset = other31.__isset; } Statistics& Statistics::operator=(const Statistics& other32) { @@ -1557,6 +1579,7 @@ Statistics& Statistics::operator=(const Statistics& other32) { min_value = other32.min_value; is_max_value_exact = other32.is_max_value_exact; is_min_value_exact = other32.is_min_value_exact; + nan_count = other32.nan_count; __isset = other32.__isset; return *this; } @@ -1569,6 +1592,7 @@ Statistics& Statistics::operator=(Statistics&& other33) noexcept { min_value = std::move(other33.min_value); is_max_value_exact = other33.is_max_value_exact; is_min_value_exact = other33.is_min_value_exact; + nan_count = other33.nan_count; __isset = other33.__isset; return *this; } @@ -1583,6 +1607,7 @@ void Statistics::printTo(std::ostream& out) const { out << ", " << "min_value="; (__isset.min_value ? (out << to_string(min_value)) : (out << "")); out << ", " << "is_max_value_exact="; (__isset.is_max_value_exact ? (out << to_string(is_max_value_exact)) : (out << "")); out << ", " << "is_min_value_exact="; (__isset.is_min_value_exact ? (out << to_string(is_min_value_exact)) : (out << "")); + out << ", " << "nan_count="; (__isset.nan_count ? (out << to_string(nan_count)) : (out << "")); out << ")"; } diff --git a/src/duckdb/third_party/parquet/parquet_types.h b/src/duckdb/third_party/parquet/parquet_types.h index 762d3533a..77f709ac6 100644 --- a/src/duckdb/third_party/parquet/parquet_types.h +++ b/src/duckdb/third_party/parquet/parquet_types.h @@ -677,7 +677,7 @@ void swap(GeospatialStatistics &a, GeospatialStatistics &b); std::ostream& operator<<(std::ostream& out, const GeospatialStatistics& obj); typedef struct _Statistics__isset { - _Statistics__isset() : max(false), min(false), null_count(false), distinct_count(false), max_value(false), min_value(false), is_max_value_exact(false), is_min_value_exact(false) {} + _Statistics__isset() : max(false), min(false), null_count(false), distinct_count(false), max_value(false), min_value(false), is_max_value_exact(false), is_min_value_exact(false), nan_count(false) {} bool max :1; bool min :1; bool null_count :1; @@ -686,6 +686,7 @@ typedef struct _Statistics__isset { bool min_value :1; bool is_max_value_exact :1; bool is_min_value_exact :1; + bool nan_count :1; } _Statistics__isset; /** @@ -752,6 +753,13 @@ class Statistics : public virtual ::apache::thrift::TBase { * If true, min_value is the actual minimum value for a column */ bool is_min_value_exact; + /** + * Count of NaN values in the column; only present if physical type is FLOAT + * or DOUBLE, or logical type is FLOAT16. + * If this field is not present, readers MUST assume NaNs may be present + * (i.e. MUST assume nan_count > 0 and MAY NOT assume nan_count == 0). + */ + int64_t nan_count; _Statistics__isset __isset; @@ -771,6 +779,8 @@ class Statistics : public virtual ::apache::thrift::TBase { void __set_is_min_value_exact(const bool val); + void __set_nan_count(const int64_t val); + uint32_t read(::apache::thrift::protocol::TProtocol* iprot) override; uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const override; diff --git a/src/duckdb/third_party/utf8proc/utf8proc_wrapper.cpp b/src/duckdb/third_party/utf8proc/utf8proc_wrapper.cpp index fcc4dd5e4..6d046d112 100644 --- a/src/duckdb/third_party/utf8proc/utf8proc_wrapper.cpp +++ b/src/duckdb/third_party/utf8proc/utf8proc_wrapper.cpp @@ -75,7 +75,18 @@ UnicodeType Utf8Proc::Analyze(const char *s, size_t len, UnicodeInvalidReason *i UnicodeType type = UnicodeType::ASCII; static constexpr uint64_t MASK = 0x8080808080808080U; - for (size_t i = 0; i < len;) { + size_t i = 0; + if (len >= 64) { + // long input: check 32 bytes at a time with a single branch while everything is ASCII + for (; i + 4 * sizeof(uint64_t) <= len; i += 4 * sizeof(uint64_t)) { + auto acc = Load(const_data_ptr_cast(s + i)) | Load(const_data_ptr_cast(s + i + 8)) | + Load(const_data_ptr_cast(s + i + 16)) | Load(const_data_ptr_cast(s + i + 24)); + if (acc & MASK) { + break; + } + } + } + for (; i < len;) { // Check 8 bytes at a time until we hit non-ASCII for (; i + sizeof(uint64_t) <= len; i += sizeof(uint64_t)) { if (Load(const_data_ptr_cast(s + i)) & MASK) { diff --git a/src/duckdb/ub_extension_parquet_reader_variant.cpp b/src/duckdb/ub_extension_parquet_reader_variant.cpp deleted file mode 100644 index b0e0398b5..000000000 --- a/src/duckdb/ub_extension_parquet_reader_variant.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "extension/parquet/reader/variant/parquet_variant_iterator.cpp" - -#include "extension/parquet/reader/variant/parquet_variant_shredding.cpp" - -#include "extension/parquet/reader/variant/variant_binary_decoder.cpp" - diff --git a/src/duckdb/ub_src_common_types_variant.cpp b/src/duckdb/ub_src_common_types_variant.cpp index 31b61b8ee..dc76281e1 100644 --- a/src/duckdb/ub_src_common_types_variant.cpp +++ b/src/duckdb/ub_src_common_types_variant.cpp @@ -1,5 +1,11 @@ +#include "src/common/types/variant/parquet_variant_encoding.cpp" + +#include "src/common/types/variant/parquet_variant_iterator.cpp" + #include "src/common/types/variant/variant.cpp" +#include "src/common/types/variant/variant_binary_decoder.cpp" + #include "src/common/types/variant/variant_comparison.cpp" #include "src/common/types/variant/variant_iterator.cpp" diff --git a/src/duckdb/ub_src_execution.cpp b/src/duckdb/ub_src_execution.cpp index d839e44ca..eb44a6519 100644 --- a/src/duckdb/ub_src_execution.cpp +++ b/src/duckdb/ub_src_execution.cpp @@ -12,6 +12,8 @@ #include "src/execution/expression_executor_state.cpp" +#include "src/execution/ie_join_union.cpp" + #include "src/execution/join_hashtable.cpp" #include "src/execution/mark_join_row_comparison.cpp" diff --git a/src/duckdb/ub_src_execution_operator_csv_scanner_table_function.cpp b/src/duckdb/ub_src_execution_operator_csv_scanner_table_function.cpp index f3f192b22..d280bd1a3 100644 --- a/src/duckdb/ub_src_execution_operator_csv_scanner_table_function.cpp +++ b/src/duckdb/ub_src_execution_operator_csv_scanner_table_function.cpp @@ -1,6 +1,8 @@ #include "src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp" -#include "src/execution/operator/csv_scanner/table_function/csv_multi_file_info.cpp" +#include "src/execution/operator/csv_scanner/table_function/csv_schema_discovery.cpp" #include "src/execution/operator/csv_scanner/table_function/global_csv_state.cpp" +#include "src/execution/operator/csv_scanner/table_function/read_single_csv_file.cpp" + diff --git a/src/duckdb/ub_src_function_scalar_string.cpp b/src/duckdb/ub_src_function_scalar_string.cpp index bd11d492b..a265e244c 100644 --- a/src/duckdb/ub_src_function_scalar_string.cpp +++ b/src/duckdb/ub_src_function_scalar_string.cpp @@ -6,6 +6,8 @@ #include "src/function/scalar/string/contains.cpp" +#include "src/function/scalar/string/hive_partition_component.cpp" + #include "src/function/scalar/string/length.cpp" #include "src/function/scalar/string/like.cpp" diff --git a/src/duckdb/ub_src_main.cpp b/src/duckdb/ub_src_main.cpp index 894eae36c..4e9d6f167 100644 --- a/src/duckdb/ub_src_main.cpp +++ b/src/duckdb/ub_src_main.cpp @@ -46,12 +46,8 @@ #include "src/main/external_resources_manager.cpp" -#include "src/main/materialized_query_result.cpp" - #include "src/main/parse_iterator.cpp" -#include "src/main/pending_query_result.cpp" - #include "src/main/prepared_statement.cpp" #include "src/main/prepared_statement_data.cpp" @@ -60,13 +56,15 @@ #include "src/main/query_result.cpp" +#include "src/main/query_result_stream.cpp" + #include "src/main/relation.cpp" #include "src/main/result_set_manager.cpp" -#include "src/main/statement_iterator.cpp" +#include "src/main/result_unit.cpp" -#include "src/main/stream_query_result.cpp" +#include "src/main/statement_iterator.cpp" #include "src/main/user_settings.cpp" diff --git a/src/duckdb/ub_src_main_capi_v2.cpp b/src/duckdb/ub_src_main_capi_v2.cpp index 7f3ca00ad..ccf9364d3 100644 --- a/src/duckdb/ub_src_main_capi_v2.cpp +++ b/src/duckdb/ub_src_main_capi_v2.cpp @@ -14,8 +14,6 @@ #include "src/main/capi/v2/capi_v2_data_chunk.cpp" -#include "src/main/capi/v2/capi_v2_database.cpp" - #include "src/main/capi/v2/capi_v2_environment.cpp" #include "src/main/capi/v2/capi_v2_error.cpp" @@ -42,6 +40,8 @@ #include "src/main/capi/v2/capi_v2_identifier.cpp" +#include "src/main/capi/v2/capi_v2_instance.cpp" + #include "src/main/capi/v2/capi_v2_logging.cpp" #include "src/main/capi/v2/capi_v2_logical_type.cpp" @@ -64,6 +64,8 @@ #include "src/main/capi/v2/capi_v2_tokenizer.cpp" +#include "src/main/capi/v2/capi_v2_utf8.cpp" + #include "src/main/capi/v2/capi_v2_value.cpp" #include "src/main/capi/v2/capi_v2_vector.cpp" diff --git a/src/duckdb/ub_src_main_chunk_scan_state.cpp b/src/duckdb/ub_src_main_chunk_scan_state.cpp index 9fb6cf644..fd7202dc3 100644 --- a/src/duckdb/ub_src_main_chunk_scan_state.cpp +++ b/src/duckdb/ub_src_main_chunk_scan_state.cpp @@ -2,3 +2,5 @@ #include "src/main/chunk_scan_state/query_result.cpp" +#include "src/main/chunk_scan_state/query_result_stream.cpp" + diff --git a/src/duckdb/ub_src_parallel.cpp b/src/duckdb/ub_src_parallel.cpp index 51cae357a..da29c5c6c 100644 --- a/src/duckdb/ub_src_parallel.cpp +++ b/src/duckdb/ub_src_parallel.cpp @@ -30,6 +30,8 @@ #include "src/parallel/pipeline_schedule.cpp" +#include "src/parallel/progress_verifier.cpp" + #include "src/parallel/scan_read_ahead.cpp" #include "src/parallel/task_executor.cpp" diff --git a/src/duckdb/ub_src_parser_parsed_data.cpp b/src/duckdb/ub_src_parser_parsed_data.cpp index b07703b51..4e788f356 100644 --- a/src/duckdb/ub_src_parser_parsed_data.cpp +++ b/src/duckdb/ub_src_parser_parsed_data.cpp @@ -62,6 +62,8 @@ #include "src/parser/parsed_data/exported_table_data.cpp" +#include "src/parser/parsed_data/external_resource_options.cpp" + #include "src/parser/parsed_data/extra_drop_info.cpp" #include "src/parser/parsed_data/load_info.cpp" diff --git a/src/duckdb/ub_src_parser_peg.cpp b/src/duckdb/ub_src_parser_peg.cpp index 8f3bda2ff..f6656d44d 100644 --- a/src/duckdb/ub_src_parser_peg.cpp +++ b/src/duckdb/ub_src_parser_peg.cpp @@ -16,6 +16,8 @@ #include "src/parser/peg/matcher_stack.cpp" +#include "src/parser/peg/operator_matcher.cpp" + #include "src/parser/peg/parsed_grammar.cpp" #include "src/parser/peg/parser_packrat.cpp" diff --git a/src/duckdb/ub_src_parser_peg_keyword_helper.cpp b/src/duckdb/ub_src_parser_peg_keyword_helper.cpp index 90d3a504a..0e79c89e3 100644 --- a/src/duckdb/ub_src_parser_peg_keyword_helper.cpp +++ b/src/duckdb/ub_src_parser_peg_keyword_helper.cpp @@ -2,5 +2,7 @@ #include "src/parser/peg/keyword_helper/duckdb_keyword_helper.cpp" +#include "src/parser/peg/keyword_helper/grammar_literal_table.cpp" + #include "src/parser/peg/keyword_helper/parsed_grammar_keyword_helper.cpp" diff --git a/src/duckdb/ub_src_parser_peg_transformer.cpp b/src/duckdb/ub_src_parser_peg_transformer.cpp index 08be2d510..79cf09ca8 100644 --- a/src/duckdb/ub_src_parser_peg_transformer.cpp +++ b/src/duckdb/ub_src_parser_peg_transformer.cpp @@ -58,7 +58,7 @@ #include "src/parser/peg/transformer/transform_external_resource.cpp" -#include "src/parser/peg/transformer/transform_generated.cpp" +#include "src/parser/peg/transformer/transform_external_resource_source.cpp" #include "src/parser/peg/transformer/transform_generated_trampoline.cpp" From 7c03b3d565e6fd363fc727210e202357bcdd45b5 Mon Sep 17 00:00:00 2001 From: DuckLabs GitHub Bot Date: Wed, 23 Sep 2026 08:30:04 +0000 Subject: [PATCH 2/6] Update vendored DuckDB sources to 6844d1bd8b --- .../holistic/approximate_quantile.cpp | 4 +- .../aggregate/holistic/reservoir_quantile.cpp | 47 ++-- .../scalar/array/array_value.cpp | 2 +- .../core_functions/scalar/debug/index_key.cpp | 2 +- .../core_functions/scalar/generic/hash.cpp | 2 +- .../core_functions/scalar/generic/least.cpp | 6 +- .../scalar/generic/type_functions.cpp | 2 +- .../scalar/list/list_aggregates.cpp | 2 +- .../core_functions/scalar/list/list_value.cpp | 4 +- .../core_functions/scalar/map/cardinality.cpp | 2 +- .../core_functions/scalar/map/map_concat.cpp | 2 +- .../core_functions/scalar/string/printf.cpp | 4 +- .../scalar/struct/struct_insert.cpp | 20 +- .../scalar/struct/struct_update.cpp | 19 +- .../scalar/union/union_value.cpp | 11 +- .../json/json_functions/json_create.cpp | 10 +- .../json/json_functions/json_deep_merge.cpp | 2 +- .../json/json_functions/json_merge_patch.cpp | 2 +- .../src/catalog/default/default_types.cpp | 57 +---- src/duckdb/src/common/enum_util.cpp | 20 ++ src/duckdb/src/common/identifier.cpp | 5 + .../operator/helper/physical_connect.cpp | 6 +- .../src/function/aggregate_function.cpp | 10 +- .../src/function/builtin_function_lookup.cpp | 21 +- .../src/function/cast/vector_cast_helpers.cpp | 22 +- src/duckdb/src/function/function.cpp | 138 ++++++++++- src/duckdb/src/function/function_binder.cpp | 234 ++++++++++-------- src/duckdb/src/function/function_set.cpp | 19 -- .../src/function/scalar/create_sort_key.cpp | 4 +- .../scalar/generic/constant_or_null.cpp | 2 +- .../src/function/scalar/generic/invoke.cpp | 2 +- .../src/function/scalar/list/list_zip.cpp | 2 +- .../src/function/scalar/string/concat.cpp | 4 +- .../src/function/scalar/string/concat_ws.cpp | 2 +- .../src/function/scalar/string/path_join.cpp | 2 +- .../function/scalar/struct/struct_concat.cpp | 2 +- .../function/scalar/struct/struct_pack.cpp | 54 ++-- .../src/function/scalar/system/write_log.cpp | 19 +- src/duckdb/src/function/scalar_function.cpp | 8 +- src/duckdb/src/function/table/read_duckdb.cpp | 7 +- .../table/system/duckdb_functions.cpp | 51 +++- .../function/table/system/duckdb_types.cpp | 10 +- .../function/table/version/pragma_version.cpp | 6 +- src/duckdb/src/function/type_constructor.cpp | 36 ++- src/duckdb/src/function/window_function.cpp | 9 +- .../src/include/duckdb/common/enum_util.hpp | 8 + .../src/include/duckdb/common/identifier.hpp | 3 + .../duckdb/function/aggregate_function.hpp | 12 + .../src/include/duckdb/function/function.hpp | 145 ++++++++--- .../function/function_serialization.hpp | 116 ++++++++- .../duckdb/function/scalar_function.hpp | 12 + .../duckdb/function/window_function.hpp | 12 + .../src/main/capi/v1/scalar_function-c.cpp | 7 +- .../main/capi/v2/capi_v2_func_signature.cpp | 4 + .../src/main/capi/v2/capi_v2_func_table.cpp | 5 +- .../create_aggregate_function_info.cpp | 4 + .../create_scalar_function_info.cpp | 4 + .../create_window_function_info.cpp | 4 + src/duckdb/src/planner/column_qualifier.cpp | 2 +- 59 files changed, 823 insertions(+), 410 deletions(-) diff --git a/src/duckdb/extension/core_functions/aggregate/holistic/approximate_quantile.cpp b/src/duckdb/extension/core_functions/aggregate/holistic/approximate_quantile.cpp index 23bc8ec38..7b901c30e 100644 --- a/src/duckdb/extension/core_functions/aggregate/holistic/approximate_quantile.cpp +++ b/src/duckdb/extension/core_functions/aggregate/holistic/approximate_quantile.cpp @@ -549,9 +549,9 @@ unique_ptr ApproxQuantileDecimalDeserialize(Deserializer &deserial auto bind_data = ApproximateQuantileBindData::Deserialize(deserializer, function); auto &return_type = deserializer.Get(); if (return_type.id() == LogicalTypeId::LIST) { - function.ReplaceImplementation(ApproxQuantileDecimalListFunction(function.GetArguments()[0])); + ReplaceApproxQuantileDecimal(function, ApproxQuantileDecimalListFunction(function.GetArguments()[0])); } else { - function.ReplaceImplementation(ApproxQuantileDecimalFunction(function.GetArguments()[0])); + ReplaceApproxQuantileDecimal(function, ApproxQuantileDecimalFunction(function.GetArguments()[0])); } return bind_data; } diff --git a/src/duckdb/extension/core_functions/aggregate/holistic/reservoir_quantile.cpp b/src/duckdb/extension/core_functions/aggregate/holistic/reservoir_quantile.cpp index fcaf523e7..b267b5256 100644 --- a/src/duckdb/extension/core_functions/aggregate/holistic/reservoir_quantile.cpp +++ b/src/duckdb/extension/core_functions/aggregate/holistic/reservoir_quantile.cpp @@ -17,6 +17,10 @@ namespace duckdb { namespace { +//! The quantile defaults to the median +constexpr double DEFAULT_QUANTILE = 0.5; +constexpr int32_t DEFAULT_SAMPLE_SIZE = 8192; + template struct ReservoirQuantileState { T *v; @@ -312,8 +316,6 @@ double CheckReservoirQuantile(const Value &quantile_val) { //! Binds the quantile parameter and the sample size into the bind data. They stay part of the expression tree, and //! the aggregate is handed them along with the input - the update callbacks only consume the leading input argument unique_ptr BindReservoirQuantile(BindAggregateFunctionInput &input) { - auto &arguments = input.GetArguments(); - D_ASSERT(arguments.size() >= 2); Value quantile_val = input.GetConstant(1); vector quantiles; if (quantile_val.type().id() != LogicalTypeId::LIST) { @@ -324,19 +326,13 @@ unique_ptr BindReservoirQuantile(BindAggregateFunctionInput &input } } - idx_t sample_size = 8192ULL; - - if (arguments.size() == 3) { - auto sample_size_val = input.GetNonNullConstant(2); - auto sample_size_int = sample_size_val.GetValue(); - - if (sample_size_val.IsNull() || sample_size_int <= 0) { - throw BinderException("Size of the RESERVOIR_QUANTILE sample must be bigger than 0"); - } - sample_size = NumericCast(sample_size_int); + auto sample_size_val = input.GetNonNullConstant(2); + auto sample_size = sample_size_val.GetValue(); + if (sample_size <= 0) { + throw BinderException("Size of the RESERVOIR_QUANTILE sample must be bigger than 0"); } - return make_uniq(quantiles, sample_size); + return make_uniq(quantiles, NumericCast(sample_size)); } static unique_ptr DeserializeReservoirQuantileDecimal(Deserializer &deserializer, @@ -421,7 +417,7 @@ AggregateFunction GetReservoirQuantileAggregate(PhysicalType type) { fun.SetDeserializeCallback(ReservoirQuantileBindData::Deserialize); // temporarily push an argument so we can bind the actual quantile fun.GetSignature().GetParameter(0).SetName("x"); - fun.GetSignature().AddParameter("quantile", LogicalType::DOUBLE); + fun.GetSignature().AddParameter("quantile", LogicalType::DOUBLE, Value::DOUBLE(DEFAULT_QUANTILE)); return fun; } @@ -438,18 +434,14 @@ AggregateFunction GetReservoirQuantileListAggregate(const LogicalType &type) { } void DefineReservoirQuantile(AggregateFunctionSet &set, const LogicalType &type) { - // Four versions: type, scalar/list[, count] + // Two versions: type, scalar/list auto fun = GetReservoirQuantileAggregate(type.InternalType()); + fun.GetSignature().AddParameter("sample_size", LogicalType::INTEGER, Value::INTEGER(DEFAULT_SAMPLE_SIZE)); set.AddFunction(fun); - fun.GetSignature().AddParameter("sample_size", LogicalType::INTEGER); - set.AddFunction(fun); - - // List variants + // List variant fun = GetReservoirQuantileListAggregate(type); - set.AddFunction(fun); - - fun.GetSignature().AddParameter("sample_size", LogicalType::INTEGER); + fun.GetSignature().AddParameter("sample_size", LogicalType::INTEGER, Value::INTEGER(DEFAULT_SAMPLE_SIZE)); set.AddFunction(fun); } @@ -462,11 +454,12 @@ void GetReservoirQuantileDecimalFunction(AggregateFunctionSet &set, const vector fun.SetDeserializeCallback(DeserializeReservoirQuantileDecimal); fun.GetSignature().GetParameter(0).SetName("x"); - fun.GetSignature().AddParameter("quantile", arguments[1]); - - set.AddFunction(fun); - - fun.GetSignature().AddParameter("sample_size", LogicalType::INTEGER); + if (arguments[1].id() == LogicalTypeId::LIST) { + fun.GetSignature().AddParameter("quantile", arguments[1]); + } else { + fun.GetSignature().AddParameter("quantile", arguments[1], Value::DOUBLE(DEFAULT_QUANTILE)); + } + fun.GetSignature().AddParameter("sample_size", LogicalType::INTEGER, Value::INTEGER(DEFAULT_SAMPLE_SIZE)); set.AddFunction(fun); } diff --git a/src/duckdb/extension/core_functions/scalar/array/array_value.cpp b/src/duckdb/extension/core_functions/scalar/array/array_value.cpp index 47b682ba2..83ac4073d 100644 --- a/src/duckdb/extension/core_functions/scalar/array/array_value.cpp +++ b/src/duckdb/extension/core_functions/scalar/array/array_value.cpp @@ -92,7 +92,7 @@ unique_ptr ArrayValueStats(ClientContext &context, FunctionStati ScalarFunction ArrayValueFun::GetFunction() { // the arguments and return types are actually set in the binder function ScalarFunction fun("array_value", {}, LogicalTypeId::ARRAY, ArrayValueFunction, ArrayValueBind, ArrayValueStats); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/debug/index_key.cpp b/src/duckdb/extension/core_functions/scalar/debug/index_key.cpp index 1d5204e03..8345f7856 100644 --- a/src/duckdb/extension/core_functions/scalar/debug/index_key.cpp +++ b/src/duckdb/extension/core_functions/scalar/debug/index_key.cpp @@ -218,7 +218,7 @@ static void IndexKeyFunction(DataChunk &args, ExpressionState &state, Vector &re ScalarFunction IndexKeyFun::GetFunction() { ScalarFunction fun("index_key", {}, LogicalType::BLOB, IndexKeyFunction, IndexKeyBind); fun.GetSignature().AddParameter("path", LogicalTypeId::STRUCT).AddParameter("name", LogicalType::VARCHAR); - fun.SetVarArgs(LogicalTypeId::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalTypeId::ANY); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/generic/hash.cpp b/src/duckdb/extension/core_functions/scalar/generic/hash.cpp index e6d9b26cd..2e4e25465 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/hash.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/hash.cpp @@ -9,7 +9,7 @@ static void HashFunction(DataChunk &args, ExpressionState &state, Vector &result ScalarFunction HashFun::GetFunction() { auto hash_fun = ScalarFunction({}, LogicalType::HASH, HashFunction); hash_fun.GetSignature().AddParameter("value", LogicalType::ANY); - hash_fun.SetVarArgs(LogicalType::ANY); + hash_fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); hash_fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return hash_fun; } diff --git a/src/duckdb/extension/core_functions/scalar/generic/least.cpp b/src/duckdb/extension/core_functions/scalar/generic/least.cpp index 11d5fe262..622067036 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/least.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/least.cpp @@ -305,9 +305,9 @@ unique_ptr BindLeastGreatest(BindScalarFunctionInput &input) { template ScalarFunction GetLeastGreatestFunction() { - ScalarFunction fun({}, LogicalType::ANY, nullptr, BindLeastGreatest, PropagateLeastGreatestStats, nullptr, - LogicalType::ANY, FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING); - fun.GetSignature().AddParameter("arg1", LogicalType::ANY); + ScalarFunction fun({{"arg1", LogicalType::ANY}}, LogicalType::ANY, nullptr, BindLeastGreatest, + PropagateLeastGreatestStats, nullptr, LogicalType::ANY, FunctionStability::CONSISTENT, + FunctionNullHandling::SPECIAL_HANDLING); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/generic/type_functions.cpp b/src/duckdb/extension/core_functions/scalar/generic/type_functions.cpp index e0aeab055..9e83bf820 100644 --- a/src/duckdb/extension/core_functions/scalar/generic/type_functions.cpp +++ b/src/duckdb/extension/core_functions/scalar/generic/type_functions.cpp @@ -128,7 +128,7 @@ ScalarFunction MakeTypeFun::GetFunction() { fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.SetBindExpressionCallback(BindMakeTypeFunctionExpression); fun.GetProperties().SetRequiresExpressionNames(true); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY).AddKwargsParameter("kwargs", LogicalType::ANY); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp b/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp index 17bf7fd03..1df5d823d 100644 --- a/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp +++ b/src/duckdb/extension/core_functions/scalar/list/list_aggregates.cpp @@ -536,7 +536,7 @@ ScalarFunction ListAggregateFun::GetFunction() { .AddParameter("function_name", LogicalType::VARCHAR); result.SetFallible(); result.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); - result.SetVarArgs(LogicalType::ANY); + result.GetSignature().AddArgsParameter("args", LogicalType::ANY); result.SetSerializeCallback(ListAggregatesBindData::SerializeFunction); result.SetDeserializeCallback(ListAggregatesBindData::DeserializeFunction); return result; diff --git a/src/duckdb/extension/core_functions/scalar/list/list_value.cpp b/src/duckdb/extension/core_functions/scalar/list/list_value.cpp index 6040b8bec..4b1436d2f 100644 --- a/src/duckdb/extension/core_functions/scalar/list/list_value.cpp +++ b/src/duckdb/extension/core_functions/scalar/list/list_value.cpp @@ -317,7 +317,7 @@ ScalarFunctionSet ListValueFun::GetFunctions() { ScalarFunction value_fun({element_type}, LogicalType::LIST(element_type), ListValueFunction, ListValueBind, ListValueStats); value_fun.GetSignature().GetParameter(0).SetName("value"); - value_fun.SetVarArgs(element_type); + value_fun.GetSignature().AddArgsParameter("args", element_type); value_fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); set.AddFunction(value_fun); @@ -326,7 +326,7 @@ ScalarFunctionSet ListValueFun::GetFunctions() { ScalarFunction UnpivotListFun::GetFunction() { ScalarFunction fun("unpivot_list", {}, LogicalTypeId::LIST, ListValueFunction, UnpivotBind, ListValueStats); - fun.SetVarArgs(LogicalTypeId::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalTypeId::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/map/cardinality.cpp b/src/duckdb/extension/core_functions/scalar/map/cardinality.cpp index d9e7a3e7e..598538653 100644 --- a/src/duckdb/extension/core_functions/scalar/map/cardinality.cpp +++ b/src/duckdb/extension/core_functions/scalar/map/cardinality.cpp @@ -39,7 +39,7 @@ static unique_ptr CardinalityBind(BindScalarFunctionInput &input) ScalarFunction CardinalityFun::GetFunction() { ScalarFunction fun({}, LogicalType::UBIGINT, CardinalityFunction, CardinalityBind); fun.GetSignature().AddParameter("map", LogicalType::ANY); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::DEFAULT_NULL_HANDLING); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/map/map_concat.cpp b/src/duckdb/extension/core_functions/scalar/map/map_concat.cpp index 37dd202f3..1202bdf05 100644 --- a/src/duckdb/extension/core_functions/scalar/map/map_concat.cpp +++ b/src/duckdb/extension/core_functions/scalar/map/map_concat.cpp @@ -185,7 +185,7 @@ ScalarFunction MapConcatFun::GetFunction() { //! the arguments and return types are actually set in the binder function ScalarFunction fun("map_concat", {}, LogicalTypeId::LIST, MapConcatFunction, MapConcatBind); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); return fun; } diff --git a/src/duckdb/extension/core_functions/scalar/string/printf.cpp b/src/duckdb/extension/core_functions/scalar/string/printf.cpp index c20ee1951..52d9a2339 100644 --- a/src/duckdb/extension/core_functions/scalar/string/printf.cpp +++ b/src/duckdb/extension/core_functions/scalar/string/printf.cpp @@ -187,7 +187,7 @@ ScalarFunction PrintfFun::GetFunction() { ScalarFunction printf_fun({}, LogicalType::VARCHAR, PrintfFunction, BindPrintfFunction); printf_fun.GetSignature().AddParameter("format", LogicalType::VARCHAR); - printf_fun.SetVarArgs(LogicalType::ANY); + printf_fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); printf_fun.SetFallible(); return printf_fun; } @@ -197,7 +197,7 @@ ScalarFunction FormatFun::GetFunction() { ScalarFunction format_fun({}, LogicalType::VARCHAR, PrintfFunction, BindPrintfFunction); format_fun.GetSignature().AddParameter("format", LogicalType::VARCHAR); - format_fun.SetVarArgs(LogicalType::ANY); + format_fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); format_fun.SetFallible(); return format_fun; } diff --git a/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp b/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp index e1fa99a61..28be6cfb5 100644 --- a/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp +++ b/src/duckdb/extension/core_functions/scalar/struct/struct_insert.cpp @@ -33,9 +33,7 @@ static void StructInsertFunction(DataChunk &args, ExpressionState &state, Vector static unique_ptr StructInsertBind(BindScalarFunctionInput &input) { auto &bound_function = input.GetBoundFunction(); auto &arguments = input.GetArguments(); - if (arguments.empty()) { - throw InvalidInputException("Missing required arguments for struct_insert function."); - } + auto &names = *input.GetArgumentNames(); if (LogicalTypeId::STRUCT != arguments[0]->GetReturnType().id()) { throw InvalidInputException("The first argument to struct_insert must be a STRUCT"); } @@ -53,17 +51,13 @@ static unique_ptr StructInsertBind(BindScalarFunctionInput &input) new_children.push_back(make_pair(child.first, child.second)); } - // Loop through the additional arguments (name/value pairs) + // Loop through the fields that are inserted for (idx_t i = 1; i < arguments.size(); i++) { - auto &child = arguments[i]; - if (child->GetAlias().empty()) { - throw BinderException("Need named argument for struct insert, e.g., a := b"); - } - if (name_collision_set.find(child->GetAlias()) != name_collision_set.end()) { - throw BinderException("Duplicate struct entry name \"%s\"", child->GetAlias()); + if (name_collision_set.find(names[i]) != name_collision_set.end()) { + throw BinderException("Duplicate struct entry name \"%s\"", names[i]); } - name_collision_set.insert(child->GetAlias()); - new_children.emplace_back(make_pair(child->GetAlias(), arguments[i]->GetReturnType())); + name_collision_set.insert(names[i]); + new_children.emplace_back(make_pair(names[i], arguments[i]->GetReturnType())); } bound_function.SetReturnType(LogicalType::STRUCT(new_children)); @@ -114,7 +108,7 @@ static unique_ptr StructInsertUnbind(FunctionUnbindInput &inpu ScalarFunction StructInsertFun::GetFunction() { ScalarFunction fun({}, LogicalTypeId::STRUCT, StructInsertFunction, StructInsertBind, StructInsertStats); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddParameter("struct", LogicalType::ANY).AddKwargsParameter("kwargs", LogicalType::ANY); fun.GetProperties().SetRequiresExpressionNames(true); fun.SetSerializeCallback(VariableReturnBindData::Serialize); fun.SetDeserializeCallback(VariableReturnBindData::Deserialize); diff --git a/src/duckdb/extension/core_functions/scalar/struct/struct_update.cpp b/src/duckdb/extension/core_functions/scalar/struct/struct_update.cpp index dc2f0b437..7b3a030a2 100644 --- a/src/duckdb/extension/core_functions/scalar/struct/struct_update.cpp +++ b/src/duckdb/extension/core_functions/scalar/struct/struct_update.cpp @@ -71,15 +71,10 @@ static unique_ptr StructUpdateBind(BindScalarFunctionInput &input) auto incoming_children = identifier_tree_t(); auto is_new_field = vector(arguments.size(), true); - // Validate incoming arguments and record names + // Record the names of the fields that are updated + auto &names = *input.GetArgumentNames(); for (idx_t arg_idx = 1; arg_idx < arguments.size(); arg_idx++) { - auto &child = arguments[arg_idx]; - if (child->GetAlias().empty()) { - throw BinderException("Need named argument for struct update, e.g., a := b"); - } else if (incoming_children.find(child->GetAlias()) != incoming_children.end()) { - throw InvalidInputException("Duplicate named argument provided for %s", child->GetAlias().c_str()); - } - incoming_children.emplace(child->GetAlias(), arg_idx); + incoming_children.emplace(names[arg_idx], arg_idx); } for (idx_t field_idx = 0; field_idx < existing_children.size(); field_idx++) { @@ -91,8 +86,7 @@ static unique_ptr StructUpdateBind(BindScalarFunctionInput &input) } else { // Update the struct with the new data of the same name auto arg_idx = update->second; - auto &new_child = arguments[arg_idx]; - new_children.emplace_back(make_pair(new_child->GetAlias(), new_child->GetReturnType())); + new_children.emplace_back(make_pair(names[arg_idx], arguments[arg_idx]->GetReturnType())); is_new_field[arg_idx] = false; } } @@ -100,8 +94,7 @@ static unique_ptr StructUpdateBind(BindScalarFunctionInput &input) // Loop through the additional arguments (name/value pairs) for (idx_t arg_idx = 1; arg_idx < arguments.size(); arg_idx++) { if (is_new_field[arg_idx]) { - auto &child = arguments[arg_idx]; - new_children.emplace_back(make_pair(child->GetAlias(), child->GetReturnType())); + new_children.emplace_back(make_pair(names[arg_idx], arguments[arg_idx]->GetReturnType())); } } @@ -150,7 +143,7 @@ static unique_ptr StructUpdateStats(ClientContext &context, Func ScalarFunction StructUpdateFun::GetFunction() { ScalarFunction fun({}, LogicalTypeId::STRUCT, StructUpdateFunction, StructUpdateBind, StructUpdateStats); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddParameter("struct", LogicalType::ANY).AddKwargsParameter("kwargs", LogicalType::ANY); fun.GetProperties().SetRequiresExpressionNames(true); fun.SetSerializeCallback(VariableReturnBindData::Serialize); fun.SetDeserializeCallback(VariableReturnBindData::Deserialize); diff --git a/src/duckdb/extension/core_functions/scalar/union/union_value.cpp b/src/duckdb/extension/core_functions/scalar/union/union_value.cpp index 5b081da2a..473d095ca 100644 --- a/src/duckdb/extension/core_functions/scalar/union/union_value.cpp +++ b/src/duckdb/extension/core_functions/scalar/union/union_value.cpp @@ -39,15 +39,8 @@ unique_ptr UnionValueBind(BindScalarFunctionInput &input) { if (arguments.size() != 1) { throw BinderException("union_value takes exactly one argument"); } - auto &child = arguments[0]; - - if (child->GetAlias().empty()) { - throw BinderException("Need named argument for union tag, e.g. UNION_VALUE(a := b)"); - } - child_list_t union_members; - - union_members.emplace_back(make_pair(child->GetAlias(), child->GetReturnType())); + union_members.emplace_back(make_pair(input.GetArgumentNames()->at(0), arguments[0]->GetReturnType())); bound_function.SetReturnType(LogicalType::UNION(std::move(union_members))); return make_uniq(bound_function.GetReturnType()); @@ -57,7 +50,7 @@ unique_ptr UnionValueBind(BindScalarFunctionInput &input) { ScalarFunction UnionValueFun::GetFunction() { ScalarFunction fun("union_value", {}, LogicalTypeId::UNION, UnionValueFunction, UnionValueBind, nullptr, nullptr); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddKwargsParameter("kwargs", LogicalType::ANY); fun.GetProperties().SetRequiresExpressionNames(true); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.SetSerializeCallback(VariableReturnBindData::Serialize); diff --git a/src/duckdb/extension/json/json_functions/json_create.cpp b/src/duckdb/extension/json/json_functions/json_create.cpp index de016cf6d..6aeef4394 100644 --- a/src/duckdb/extension/json/json_functions/json_create.cpp +++ b/src/duckdb/extension/json/json_functions/json_create.cpp @@ -1477,7 +1477,7 @@ unique_ptr JSONFunctions::CreateJSONCopyToJSONExpression(ClientConte ScalarFunctionSet JSONFunctions::GetObjectFunction() { ScalarFunction fun("json_object", {}, LogicalType::JSON(), ObjectFunction, JSONObjectBind, nullptr, JSONFunctionLocalState::Init); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); // throws if a key is NULL fun.SetFallible(); @@ -1487,7 +1487,7 @@ ScalarFunctionSet JSONFunctions::GetObjectFunction() { ScalarFunctionSet JSONFunctions::GetArrayFunction() { ScalarFunction fun("json_array", {}, LogicalType::JSON(), ArrayFunction, JSONArrayBind, nullptr, JSONFunctionLocalState::Init); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return ScalarFunctionSet(fun); } @@ -1495,7 +1495,7 @@ ScalarFunctionSet JSONFunctions::GetArrayFunction() { ScalarFunctionSet JSONFunctions::GetToJSONFunction() { ScalarFunction fun("to_json", {}, LogicalType::JSON(), ToJSONFunction, ToJSONBind, nullptr, JSONFunctionLocalState::Init); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); return ScalarFunctionSet(fun); } @@ -1531,14 +1531,14 @@ ScalarFunction JSONFunctions::GetJSONCopyToGeoJSONFunction() { ScalarFunctionSet JSONFunctions::GetArrayToJSONFunction() { ScalarFunction fun("array_to_json", {}, LogicalType::JSON(), ToJSONFunction, ArrayToJSONBind, nullptr, JSONFunctionLocalState::Init); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); return ScalarFunctionSet(fun); } ScalarFunctionSet JSONFunctions::GetRowToJSONFunction() { ScalarFunction fun("row_to_json", {}, LogicalType::JSON(), ToJSONFunction, RowToJSONBind, nullptr, JSONFunctionLocalState::Init); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); return ScalarFunctionSet(fun); } diff --git a/src/duckdb/extension/json/json_functions/json_deep_merge.cpp b/src/duckdb/extension/json/json_functions/json_deep_merge.cpp index 40ae7836c..797114ff4 100644 --- a/src/duckdb/extension/json/json_functions/json_deep_merge.cpp +++ b/src/duckdb/extension/json/json_functions/json_deep_merge.cpp @@ -144,7 +144,7 @@ ScalarFunctionSet JSONFunctions::GetDeepMergeFunction() { ScalarFunction fun("json_deep_merge", {}, LogicalType::JSON(), DeepMergeFunction, nullptr, nullptr, JSONFunctionLocalState::Init); fun.GetSignature().AddParameter("json1", LogicalType::JSON()).AddParameter("json2", LogicalType::JSON()); - fun.SetVarArgs(LogicalType::JSON()); + fun.GetSignature().AddArgsParameter("args", LogicalType::JSON()); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.SetFallible(); diff --git a/src/duckdb/extension/json/json_functions/json_merge_patch.cpp b/src/duckdb/extension/json/json_functions/json_merge_patch.cpp index f58791112..2dfa8f372 100644 --- a/src/duckdb/extension/json/json_functions/json_merge_patch.cpp +++ b/src/duckdb/extension/json/json_functions/json_merge_patch.cpp @@ -75,7 +75,7 @@ ScalarFunctionSet JSONFunctions::GetMergePatchFunction() { ScalarFunction fun("json_merge_patch", {}, LogicalType::JSON(), MergePatchFunction, nullptr, nullptr, JSONFunctionLocalState::Init); fun.GetSignature().AddParameter("json1", LogicalType::JSON()).AddParameter("json2", LogicalType::JSON()); - fun.SetVarArgs(LogicalType::JSON()); + fun.GetSignature().AddArgsParameter("args", LogicalType::JSON()); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return ScalarFunctionSet(fun); diff --git a/src/duckdb/src/catalog/default/default_types.cpp b/src/duckdb/src/catalog/default/default_types.cpp index 4cbfc0611..813644c09 100644 --- a/src/duckdb/src/catalog/default/default_types.cpp +++ b/src/duckdb/src/catalog/default/default_types.cpp @@ -181,13 +181,7 @@ LogicalType BindEnumType(BindLogicalTypeInput &input) { Vector enum_vector(LogicalType::VARCHAR, NumericCast(arguments.size())); auto string_data = FlatVector::Writer(enum_vector, arguments.size()); - for (idx_t arg_idx = 0; arg_idx < arguments.size(); arg_idx++) { - auto &arg = arguments[arg_idx]; - if (arg.HasName()) { - throw BinderException(input.GetLocation(arg_idx), - "ENUM type arguments cannot have names (argument %d has name \"%s\")", arg_idx + 1, - arg.GetName()); - } + for (auto &arg : arguments) { string_data.WriteValue(string_t(StringValue::Get(arg.GetValue()))); } @@ -196,7 +190,7 @@ LogicalType BindEnumType(BindLogicalTypeInput &input) { void RegisterEnumConstructors(TypeConstructorSet &set) { auto signature = TypeConstructor::Signature(); - signature.SetVarArgs(LogicalType::VARCHAR); + signature.AddArgsParameter("args", LogicalType::VARCHAR); set.AddFunction(TypeConstructor(std::move(signature), BindEnumType)); } @@ -243,24 +237,11 @@ void RegisterArrayConstructors(TypeConstructorSet &set) { LogicalType BindStructType(BindLogicalTypeInput &input) { auto &arguments = input.modifiers; - identifier_set_t name_collision_set; child_list_t children; children.reserve(arguments.size()); - for (idx_t arg_idx = 0; arg_idx < arguments.size(); arg_idx++) { - auto &arg = arguments[arg_idx]; - if (!arg.HasName()) { - throw BinderException(input.GetLocation(arg_idx), "STRUCT type arguments must have names"); - } - - auto name = Identifier(arg.GetName()); - if (name_collision_set.find(name) != name_collision_set.end()) { - throw BinderException(input.GetLocation(arg_idx), "Duplicate STRUCT type argument name \"%s\"", - arg.GetName()); - } - name_collision_set.insert(name); - - children.emplace_back(std::move(name), TypeValue::GetType(arg.GetValue())); + for (auto &arg : arguments) { + children.emplace_back(Identifier(arg.GetName()), TypeValue::GetType(arg.GetValue())); } return LogicalType::STRUCT(std::move(children)); @@ -268,7 +249,7 @@ LogicalType BindStructType(BindLogicalTypeInput &input) { void RegisterStructConstructors(TypeConstructorSet &set) { auto signature = TypeConstructor::Signature(); - signature.SetVarArgs(LogicalType::TYPE()); + signature.AddKwargsParameter("kwargs", LogicalType::TYPE()); set.AddFunction(TypeConstructor(std::move(signature), BindStructType)); } @@ -278,12 +259,7 @@ void RegisterStructConstructors(TypeConstructorSet &set) { LogicalType BindTupleType(BindLogicalTypeInput &input) { vector children; children.reserve(input.modifiers.size()); - for (idx_t arg_idx = 0; arg_idx < input.modifiers.size(); arg_idx++) { - auto &arg = input.modifiers[arg_idx]; - if (arg.HasName()) { - throw BinderException(input.GetLocation(arg_idx), - "TUPLE type arguments cannot have names - use STRUCT for named fields"); - } + for (auto &arg : input.modifiers) { children.push_back(TypeValue::GetType(arg.GetValue())); } return LogicalType::TUPLE(std::move(children)); @@ -291,7 +267,7 @@ LogicalType BindTupleType(BindLogicalTypeInput &input) { void RegisterTupleConstructors(TypeConstructorSet &set) { auto signature = TypeConstructor::Signature(); - signature.SetVarArgs(LogicalType::TYPE()); + signature.AddArgsParameter("args", LogicalType::TYPE()); set.AddFunction(TypeConstructor(std::move(signature), BindTupleType)); } @@ -326,21 +302,8 @@ LogicalType BindUnionType(BindLogicalTypeInput &input) { } child_list_t children; - identifier_set_t name_collision_set; - - for (idx_t arg_idx = 0; arg_idx < arguments.size(); arg_idx++) { - auto &arg = arguments[arg_idx]; - if (!arg.HasName()) { - throw BinderException(input.GetLocation(arg_idx), "UNION type modifiers must have names"); - } - - auto &entry_name = arg.GetName(); - if (name_collision_set.find(Identifier(entry_name)) != name_collision_set.end()) { - throw BinderException(input.GetLocation(arg_idx), "Duplicate UNION type member name \"%s\"", entry_name); - } - name_collision_set.insert(Identifier(entry_name)); - - children.emplace_back(entry_name, TypeValue::GetType(arg.GetValue())); + for (auto &arg : arguments) { + children.emplace_back(arg.GetName(), TypeValue::GetType(arg.GetValue())); } return LogicalType::UNION(std::move(children)); @@ -348,7 +311,7 @@ LogicalType BindUnionType(BindLogicalTypeInput &input) { void RegisterUnionConstructors(TypeConstructorSet &set) { auto signature = TypeConstructor::Signature(); - signature.SetVarArgs(LogicalType::TYPE()); + signature.AddKwargsParameter("kwargs", LogicalType::TYPE()); set.AddFunction(TypeConstructor(std::move(signature), BindUnionType)); } diff --git a/src/duckdb/src/common/enum_util.cpp b/src/duckdb/src/common/enum_util.cpp index 7219f8a9b..efab5c457 100644 --- a/src/duckdb/src/common/enum_util.cpp +++ b/src/duckdb/src/common/enum_util.cpp @@ -2760,6 +2760,26 @@ FunctionNullHandling EnumUtil::FromString(const char *valu return static_cast(StringUtil::StringToEnum(GetFunctionNullHandlingValues(), 2, "FunctionNullHandling", value)); } +const StringUtil::EnumStringLiteral *GetFunctionParameterKindValues() { + static constexpr StringUtil::EnumStringLiteral values[] { + { static_cast(FunctionParameterKind::STANDARD), "STANDARD" }, + { static_cast(FunctionParameterKind::VAR_POSITIONAL), "VAR_POSITIONAL" }, + { static_cast(FunctionParameterKind::VAR_KEYWORD), "VAR_KEYWORD" }, + { static_cast(FunctionParameterKind::KEYWORD_ONLY), "KEYWORD_ONLY" } + }; + return values; +} + +template<> +const char* EnumUtil::ToChars(FunctionParameterKind value) { + return StringUtil::EnumToString(GetFunctionParameterKindValues(), 4, "FunctionParameterKind", static_cast(value)); +} + +template<> +FunctionParameterKind EnumUtil::FromString(const char *value) { + return static_cast(StringUtil::StringToEnum(GetFunctionParameterKindValues(), 4, "FunctionParameterKind", value)); +} + const StringUtil::EnumStringLiteral *GetFunctionStabilityValues() { static constexpr StringUtil::EnumStringLiteral values[] { { static_cast(FunctionStability::CONSISTENT), "CONSISTENT" }, diff --git a/src/duckdb/src/common/identifier.cpp b/src/duckdb/src/common/identifier.cpp index 2907f0fbc..69bda856b 100644 --- a/src/duckdb/src/common/identifier.cpp +++ b/src/duckdb/src/common/identifier.cpp @@ -1,11 +1,16 @@ #include "duckdb/common/identifier.hpp" #include "duckdb/common/string_util.hpp" +#include "duckdb/common/types/uuid.hpp" #include namespace duckdb { +Identifier GenerateInternalName(const char *prefix) { + return Identifier(prefix + UUID::ToString(UUID::GenerateRandomUUID())); +} + bool Identifier::StartsWith(const string &prefix) const { return StringUtil::CIStartsWith(value, prefix); } diff --git a/src/duckdb/src/execution/operator/helper/physical_connect.cpp b/src/duckdb/src/execution/operator/helper/physical_connect.cpp index 5084f30c2..f402d9823 100644 --- a/src/duckdb/src/execution/operator/helper/physical_connect.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_connect.cpp @@ -1,7 +1,7 @@ #include "duckdb/execution/operator/helper/physical_connect.hpp" #include "duckdb/catalog/catalog.hpp" #include "duckdb/common/exception.hpp" -#include "duckdb/common/types/uuid.hpp" +#include "duckdb/common/identifier.hpp" #include "duckdb/execution/operator/helper/launch_external_resource.hpp" #include "duckdb/main/attached_database.hpp" #include "duckdb/main/client_context.hpp" @@ -62,7 +62,7 @@ SourceResultType PhysicalConnect::GetDataInternal(ExecutionContext &context, Dat owns_resource = true; } AttachInfo attach_info; - attach_info.name = Identifier("__connect_" + UUID::ToString(UUID::GenerateRandomUUID())); + attach_info.name = GenerateInternalName("__connect_"); // Applying the resource, parsing its options and the attach can all throw, and by now the // resource exists with nothing owning it. One guard covers the lot; a narrower one strands it. auto reap_if_owned = [&]() { @@ -117,7 +117,7 @@ SourceResultType PhysicalConnect::GetDataInternal(ExecutionContext &context, Dat // (backend-safe), and unguessable, so it is not referenceable in SQL. It is owned by this // connection and detached again by DISCONNECT (see PhysicalDisconnect). AttachInfo attach_info; - attach_info.name = Identifier("__connect_" + UUID::ToString(UUID::GenerateRandomUUID())); + attach_info.name = GenerateInternalName("__connect_"); attach_info.path = info->name.GetIdentifierName(); attach_info.options = info->options; diff --git a/src/duckdb/src/function/aggregate_function.cpp b/src/duckdb/src/function/aggregate_function.cpp index a24b2fe41..257281b02 100644 --- a/src/duckdb/src/function/aggregate_function.cpp +++ b/src/duckdb/src/function/aggregate_function.cpp @@ -124,14 +124,18 @@ BoundAggregateFunction::BoundAggregateFunction(shared_ptr GetBuiltinWindowFunction(ClientContext &context unique_ptr BindBuiltinScalarFunction(ClientContext &context, const Identifier &name, vector> children) { - vector arguments; + auto &catalog = Catalog::GetSystemCatalog(context); + auto &entry = catalog.GetEntry(context, BuiltinName(catalog, name)); + + // Bind the children as the arguments of a call, so that functions that capture the aliases of their arguments + // (e.g. struct_pack) receive them as named arguments + vector>> arguments; arguments.reserve(children.size()); for (auto &child : children) { - arguments.push_back(child->GetReturnType()); + arguments.emplace_back(Identifier(), std::move(child)); + } + + ErrorData error; + FunctionBinder function_binder(context); + auto expr = function_binder.BindScalarFunction(entry, std::move(arguments), error); + if (!expr) { + error.Throw(); + } + if (expr->GetExpressionClass() != ExpressionClass::BOUND_FUNCTION) { + throw InvalidInputException("BindBuiltinScalarFunction did not return a BoundFunctionExpression"); } - return GetBuiltinScalarFunction(context, name, arguments)->Bind(context, std::move(children)); + return unique_ptr_cast(std::move(expr)); } } // namespace duckdb diff --git a/src/duckdb/src/function/cast/vector_cast_helpers.cpp b/src/duckdb/src/function/cast/vector_cast_helpers.cpp index af1a97c56..579b6db8d 100644 --- a/src/duckdb/src/function/cast/vector_cast_helpers.cpp +++ b/src/duckdb/src/function/cast/vector_cast_helpers.cpp @@ -130,23 +130,31 @@ static string_t HandleString(Vector &vec, const char *buf, idx_t start, idx_t en for (idx_t i = 0; i < length; i++) { auto current_char = buf[start + i]; if (!escaped) { - if (scopes.empty() && current_char == '\\') { - if (quoted || (start + i + 1 < end && (buf[start + i + 1] == '\'' || buf[start + i + 1] == '"'))) { + if (current_char == '\\') { + if (quoted || (scopes.empty() && start + i + 1 < end && + (buf[start + i + 1] == '\'' || buf[start + i + 1] == '"'))) { //! Start of escape escaped = true; + if (!scopes.empty()) { + string_data[copied_count++] = current_char; + } continue; } } - if (scopes.empty() && (current_char == '\'' || current_char == '"')) { + if (current_char == '\'' || current_char == '"') { if (quoted && current_char == quote_char) { quoted = false; - //! Skip the ending quote - continue; + if (scopes.empty()) { + //! Skip the ending quote + continue; + } } else if (!quoted) { quoted = true; quote_char = current_char; - //! Skip the starting quote - continue; + if (scopes.empty()) { + //! Skip the starting quote + continue; + } } } if (!quoted && !scopes.empty() && current_char == scopes.top()) { diff --git a/src/duckdb/src/function/function.cpp b/src/duckdb/src/function/function.cpp index 8cdb4addb..c426af1ba 100644 --- a/src/duckdb/src/function/function.cpp +++ b/src/duckdb/src/function/function.cpp @@ -71,6 +71,12 @@ static bool RequiresCatalogAndSchemaNamePrefix(const Identifier &catalog_name, c } string FunctionParameter::ToString() const { + if (kind == FunctionParameterKind::VAR_POSITIONAL) { + return StringUtil::Format("*%s %s", SQLIdentifier(name), type.ToString()); + } + if (kind == FunctionParameterKind::VAR_KEYWORD) { + return StringUtil::Format("**%s %s", SQLIdentifier(name), type.ToString()); + } if (default_value) { return StringUtil::Format("%s %s := %s", SQLIdentifier(name), type.ToString(), default_value->ToString()); } @@ -83,9 +89,6 @@ string FunctionSignature::ToString() const { for (auto ¶m : parameters) { params.push_back(param.ToString()); } - if (varargs.IsValid()) { - params.push_back("[" + varargs.ToString() + "...]"); - } auto head = StringUtil::Format("(%s)", StringUtil::Join(params, ", ")); if (return_type.IsValid()) { return head + " -> " + return_type.ToString(); @@ -141,10 +144,94 @@ hash_t FunctionSignature::Hash() const { hash_t hash = return_type.Hash(); for (auto ¶m : parameters) { hash = duckdb::CombineHash(hash, param.GetType().Hash()); + hash = duckdb::CombineHash(hash, duckdb::Hash(static_cast(param.GetKind()))); } return hash; } +const LogicalType &FunctionSignature::GetVarArgs() const { + static const LogicalType INVALID_TYPE(LogicalTypeId::INVALID); + auto args = GetArgsParameter(); + return args ? args->GetType() : INVALID_TYPE; +} + +void FunctionSignature::SetVarArgs(LogicalType varargs_p) { + for (idx_t i = parameters.size(); i > 0; i--) { + if (parameters[i - 1].IsVariadic()) { + parameters.erase_at(i - 1); + } + } + if (varargs_p.id() == LogicalTypeId::INVALID) { + return; + } + AddArgsParameter("args", varargs_p); + AddKwargsParameter("kwargs", std::move(varargs_p)); +} + +void FunctionSignature::Verify() const { + // Check for duplicate parameter names + identifier_set_t seen_names; + for (const auto ¶m : parameters) { + if (seen_names.find(param.GetName()) != seen_names.end()) { + throw InvalidInputException("Duplicate parameter name: %s", param.GetName()); + } + seen_names.insert(param.GetName()); + } + + // Also check for default values that are not at the end of the positional parameters + bool found_default_value = false; + for (const auto ¶m : parameters) { + if (param.GetKind() != FunctionParameterKind::STANDARD) { + continue; + } + if (param.HasDefaultValue()) { + found_default_value = true; + } else if (found_default_value) { + throw InvalidInputException( + "Parameters with default values must be at the end of the parameter list. Parameter '%s' does not " + "have a default value but follows a parameter with a default value.", + param.GetName()); + } + } + + // And that the parameter kinds are in order: standard parameters, "*args", keyword-only parameters, "**kwargs" + bool found_args = false; + bool found_kwargs = false; + bool found_keyword_only = false; + for (const auto ¶m : parameters) { + if (found_kwargs) { + throw InvalidInputException("Parameter '%s' follows '**kwargs', which must be the last parameter", + param.ToString()); + } + if (param.IsVariadic() && param.HasDefaultValue()) { + throw InvalidInputException("Variadic parameter '%s' cannot have a default value", param.ToString()); + } + switch (param.GetKind()) { + case FunctionParameterKind::STANDARD: + if (found_args || found_keyword_only) { + throw InvalidInputException("Parameter '%s' follows '*args' and must therefore be keyword-only", + param.ToString()); + } + break; + case FunctionParameterKind::VAR_POSITIONAL: + if (found_args) { + throw InvalidInputException("A function signature can only have one '*args' parameter"); + } + if (found_keyword_only) { + throw InvalidInputException("Parameter '%s' cannot follow a keyword-only parameter", param.ToString()); + } + found_args = true; + break; + case FunctionParameterKind::VAR_KEYWORD: + found_kwargs = true; + break; + case FunctionParameterKind::KEYWORD_ONLY: + found_keyword_only = true; + break; + } + } +} + hash_t SimpleFunction::Hash() const { return signature.Hash(); } @@ -209,13 +296,44 @@ hash_t BoundSimpleFunction::Hash() const { return hash; } +idx_t BoundSimpleFunction::GetVarArgsCount(const FunctionSignature &signature) const { + const auto standard_count = signature.GetPositionalParameterCount(); + return positional_arguments > standard_count ? positional_arguments - standard_count : 0; +} + +idx_t BoundSimpleFunction::GetKwargsCount(const FunctionSignature &signature) const { + idx_t result = 0; + for (auto &name : named_arguments) { + if (!signature.GetParameterIndexByName(name).IsValid()) { + result++; + } + } + return result; +} + +FunctionParameterKind BoundSimpleFunction::GetArgumentParameterKind(const FunctionSignature &signature, + idx_t argument_index) const { + if (argument_index >= positional_arguments + named_arguments.size()) { + throw InternalException("%s: Argument index %llu is out of range", GetName(), argument_index); + } + if (argument_index < signature.GetPositionalParameterCount()) { + return FunctionParameterKind::STANDARD; + } + if (argument_index < positional_arguments) { + return FunctionParameterKind::VAR_POSITIONAL; + } + auto &name = named_arguments[argument_index - positional_arguments]; + return signature.GetParameterIndexByName(name).IsValid() ? FunctionParameterKind::KEYWORD_ONLY + : FunctionParameterKind::VAR_KEYWORD; +} + string BoundSimpleFunction::ToString() const { return Function::CallToString(GetCatalogName(), GetSchemaName(), GetName(), arguments, LogicalTypeId::INVALID, return_type); } bool FunctionParameter::operator==(const FunctionParameter &other) const { - return type == other.type && name == other.name; + return type == other.type && name == other.name && kind == other.kind; } bool FunctionParameter::operator!=(const FunctionParameter &other) const { @@ -223,7 +341,7 @@ bool FunctionParameter::operator!=(const FunctionParameter &other) const { } bool FunctionSignature::operator==(const FunctionSignature &other) const { - return parameters == other.parameters && varargs == other.varargs && return_type == other.return_type; + return parameters == other.parameters && return_type == other.return_type; } bool FunctionSignature::operator!=(const FunctionSignature &other) const { @@ -235,13 +353,11 @@ bool FunctionSignature::Equal(const FunctionSignature &other) const { return false; } for (idx_t i = 0; i < parameters.size(); i++) { - if (parameters[i].GetType() != other.parameters[i].GetType()) { + if (parameters[i].GetType() != other.parameters[i].GetType() || + parameters[i].GetKind() != other.parameters[i].GetKind()) { return false; } } - if (varargs != other.varargs) { - return false; - } if (return_type != other.return_type) { return false; } @@ -313,8 +429,8 @@ optional_idx BindFunctionInput::GetArgumentIndex(const Identifier &name) const { throw InternalException("Function '%s' was bound without argument names, cannot look up argument '%s' by name", function.GetName(), name); } - // The binder resolves every argument to a slot and reports its name: the signature parameter name for positional - // slots, or the name the caller used for named varargs. + // The binder resolves every argument to a slot and reports its name: the signature parameter name for standard + // and keyword-only parameters, or the name the caller used for "**kwargs". for (idx_t arg_idx = 0; arg_idx < argument_names->size(); arg_idx++) { if ((*argument_names)[arg_idx] == name) { return optional_idx(arg_idx); diff --git a/src/duckdb/src/function/function_binder.cpp b/src/duckdb/src/function/function_binder.cpp index d61de650f..407ad0677 100644 --- a/src/duckdb/src/function/function_binder.cpp +++ b/src/duckdb/src/function/function_binder.cpp @@ -90,8 +90,14 @@ optional_idx FunctionOverloads::Cost(optional_ptr context, const // And the minimum and maximum number of arguments the function can accept const auto minimum_arg_count = sig.GetRequiredParameterCount(); + const auto positional_count = sig.GetPositionalParameterCount(); + const auto args_param = sig.GetArgsParameter(); + const auto kwargs_param = sig.GetKwargsParameter(); - const auto maximum_arg_count = sig.HasVarArgs() ? NumericLimits::Maximum() : sig.GetParameterCount(); + idx_t maximum_arg_count = NumericLimits::Maximum(); + if (!args_param && !kwargs_param) { + maximum_arg_count = sig.GetParameterCount(); + } if (received_arg_count < minimum_arg_count) { // We have fewer arguments than the function requires, so this function cannot be a match. @@ -103,6 +109,11 @@ optional_idx FunctionOverloads::Cost(optional_ptr context, const return optional_idx(); } + if (arguments.size() > positional_count && !args_param) { + // There is no "*args" to receive the extra positional arguments + return optional_idx(); + } + idx_t cost = 0; bool has_parameter = false; @@ -112,7 +123,7 @@ optional_idx FunctionOverloads::Cost(optional_ptr context, const continue; } - auto arg_type = i < sig.GetParameterCount() ? sig.GetParameter(i).GetType() : sig.GetVarArgs(); + auto &arg_type = i < positional_count ? sig.GetParameter(i).GetType() : args_param->GetType(); int64_t cast_cost = ImplicitCastCost(context, arguments[i], arg_type); if (cast_cost >= 0) { @@ -130,15 +141,12 @@ optional_idx FunctionOverloads::Cost(optional_ptr context, const auto opt_param_idx = sig.GetParameterIndexByName(named_arg.first); if (!opt_param_idx.IsValid()) { - if (!sig.HasVarArgs()) { - // no parameter with this name: continue + if (!kwargs_param) { + // no parameter with this name, and no "**kwargs" to receive it return optional_idx(); } - // This is a named vararg argument, we can skip the parameter index check as varargs are always at the end - // of the argument list - auto &vararg_type = sig.GetVarArgs(); - int64_t cast_cost = ImplicitCastCost(context, named_arg.second, vararg_type); + int64_t cast_cost = ImplicitCastCost(context, named_arg.second, kwargs_param->GetType()); if (cast_cost >= 0) { // we can implicitly cast, add the cost to the total cost cost += static_cast(cast_cost); @@ -147,18 +155,18 @@ optional_idx FunctionOverloads::Cost(optional_ptr context, const return optional_idx(); } } else { - // This parameter index might technically be invalid, in that it may point to a parameter that has already + // This parameter might technically be invalid, in that it may point to a parameter that has already // been filled by a positional argument. However, we will catch that later when we actually bind the // argument expressions to construct the bound function expression. At that point we will also have more // context so we can give a better error message. const auto param_idx = opt_param_idx.GetIndex(); + auto ¶m = sig.GetParameter(param_idx); - if (param_idx < arguments.size()) { + if (param.GetKind() == FunctionParameterKind::STANDARD && param_idx < arguments.size()) { // If already covered by a positional argument, skip the cost check here. continue; } - auto ¶m = sig.GetParameter(param_idx); int64_t cast_cost = ImplicitCastCost(context, named_arg.second, param.GetType()); if (cast_cost >= 0) { cost += idx_t(cast_cost); @@ -384,11 +392,20 @@ optional_idx FunctionBinder::BindFunctionFromArguments(const Identifier &name, c vector positional; vector> named; - if (TrySplitArgumentTypes(arguments, positional, named)) { - return BindFunctionFromArguments(name, functions, positional, named, error); + // Does this call have a valid positional -> named argument shape? + const auto is_valid_call = TrySplitArgumentTypes(arguments, positional, named); + if (is_valid_call) { + // Yes. Let's try to bind + const auto result = BindFunctionFromArguments(name, functions, positional, named, error); + + // We failed binding - does any other overload support implicit argument names? + // If not, this is a hard failure. + if (result.IsValid() || !AnyOverloadSupportsImplicitArgumentNames(functions)) { + return result; + } } - // The split failed because a positional argument follows a named one. + // Either a positional argument follows a named one, or no overload takes the positional arguments. // Check if there is any overload that supports implicit argument names. if (AnyOverloadSupportsImplicitArgumentNames(functions)) { // If so, we can attempt to salvage the call by implicitly naming the positional arguments and retrying again @@ -402,9 +419,18 @@ optional_idx FunctionBinder::BindFunctionFromArguments(const Identifier &name, c named.clear(); if (TrySplitArgumentTypes(arguments, positional, named)) { - return BindFunctionFromArguments(name, functions, positional, named, error); + ErrorData retry_error; + auto result = BindFunctionFromArguments(name, functions, positional, named, retry_error); + if (result.IsValid() || !is_valid_call) { + error = std::move(retry_error); + return result; + } } } + if (is_valid_call) { + // the call only failed to match an overload, which is reported in the error + return optional_idx(); + } // No overload could rescue the positional-after-named call, give a clear error. return PositionalAfterNamedArgumentError(arguments, error); @@ -975,28 +1001,29 @@ void FunctionBinder::CheckTemplateTypesResolved(const BoundSimpleFunction &bound VerifyTemplateType(bound_function.GetReturnType(), bound_function.GetName()); } -// Drain all named argument and insert them in the correct position according to the function signature. -// Also insert default arguments where needed. -// Returns the resolved name of every argument slot: the signature parameter name for positional slots, the -// caller-provided name for named varargs, and an empty identifier for unnamed varargs. -static vector ResolveArguments(const SimpleFunction &function, vector> &arguments, +// Drain all named arguments and lay out the arguments in the order of the function signature: +// [standard parameters | *args | keyword-only parameters | **kwargs], inserting default values where needed. +// The types of the variadic arguments are added to the arguments of the bound function. +// Returns the resolved name of every argument: the parameter name for standard and keyword-only parameters, the +// caller-provided name for "**kwargs" and an empty identifier for "*args". +static vector ResolveArguments(const SimpleFunction &function, BoundSimpleFunction &bound_function, + vector> &arguments, vector>> &named_arguments) { const auto &sig = function.GetSignature(); + const auto positional_count = sig.GetPositionalParameterCount(); + const auto args_param = sig.GetArgsParameter(); + const auto kwargs_param = sig.GetKwargsParameter(); - const auto kwargs_offset = arguments.size(); + // The arguments that were passed by position + auto positional_arguments = std::move(arguments); + const auto passed_count = positional_arguments.size(); - // Reserve space for the named arguments - if (arguments.size() < sig.GetParameterCount()) { - arguments.resize(sig.GetParameterCount()); - } + // The arguments that were passed by name, by the index of their parameter + vector> keyword_arguments(sig.GetParameterCount()); + vector>> kwargs; identifier_set_t seen_names; - - vector>> trailing_kwargs; - - // We now need to reorder them to match the function signature, before appending them to the argument list. - for (idx_t kwarg_idx = 0; kwarg_idx < named_arguments.size(); kwarg_idx++) { - auto &[name, arg] = named_arguments[kwarg_idx]; + for (auto &[name, arg] : named_arguments) { const auto location = arg->GetQueryLocation(); if (name.empty()) { @@ -1011,78 +1038,98 @@ static vector ResolveArguments(const SimpleFunction &function, vecto throw BinderException(location, "Duplicate named argument %s in function call to '%s'", name, function.GetName()); } - seen_names.insert(name); const auto opt_param_idx = sig.GetParameterIndexByName(name); if (!opt_param_idx.IsValid()) { - if (!sig.HasVarArgs()) { + if (!kwargs_param) { throw BinderException(location, "Function '%s' does not have a parameter named '%s'", function.GetName(), name); } - - // This is a named vararg argument, come back for it later - trailing_kwargs.emplace_back(name, std::move(arg)); + kwargs.emplace_back(name, std::move(arg)); continue; } const auto param_idx = opt_param_idx.GetIndex(); - - if (param_idx < kwargs_offset) { + if (sig.GetParameter(param_idx).GetKind() == FunctionParameterKind::STANDARD && param_idx < passed_count) { throw BinderException(location, "Named argument '%s' cannot be used for parameter '%s' because it has already " "been provided as a positional argument in function call to '%s'", arg->ToString(), name, function.GetName()); } - - // Move it into the correct reserved position - arguments[param_idx] = std::move(arg); - } - - // Fill out missing arguments with default values if they exist, otherwise throw an error. - for (idx_t i = 0; i < sig.GetParameterCount(); i++) { - if (arguments[i]) { + keyword_arguments[param_idx] = std::move(arg); + } + + // the arguments in the order of the signature, moved back into "arguments" once they are all resolved + vector> resolved_arguments; + vector resolved_names; + vector named_arguments_names; + auto &bound_arguments = bound_function.GetArguments(); + + auto add_argument = [&](unique_ptr arg, Identifier resolved_name) { + resolved_arguments.push_back(std::move(arg)); + resolved_names.push_back(std::move(resolved_name)); + }; + + for (idx_t param_idx = 0; param_idx < sig.GetParameterCount(); param_idx++) { + const auto ¶m = sig.GetParameter(param_idx); + switch (param.GetKind()) { + case FunctionParameterKind::VAR_POSITIONAL: + for (idx_t i = positional_count; i < passed_count; i++) { + bound_arguments.insert(bound_arguments.begin() + NumericCast(resolved_arguments.size()), + param.GetType()); + add_argument(std::move(positional_arguments[i]), Identifier()); + } continue; + case FunctionParameterKind::VAR_KEYWORD: + for (auto &[name, arg] : kwargs) { + bound_arguments.push_back(param.GetType()); + named_arguments_names.push_back(name); + add_argument(std::move(arg), name); + } + continue; + default: + break; } - const auto ¶m = sig.GetParameter(i); - - if (param.HasDefaultValue()) { - arguments[i] = make_uniq(*param.GetDefaultValue()); - arguments[i]->SetAlias(param.GetName()); - + if (param.GetKind() == FunctionParameterKind::STANDARD && param_idx < passed_count) { + add_argument(std::move(positional_arguments[param_idx]), param.GetName()); + } else if (keyword_arguments[param_idx]) { + add_argument(std::move(keyword_arguments[param_idx]), param.GetName()); + } else if (param.HasDefaultValue()) { + auto default_arg = make_uniq(*param.GetDefaultValue()); + default_arg->SetAlias(param.GetName()); + add_argument(std::move(default_arg), param.GetName()); } else { throw BinderException("Missing value for parameter %s in function call to %s", param.GetName(), function.GetName()); } + if (param.GetKind() == FunctionParameterKind::KEYWORD_ONLY) { + named_arguments_names.push_back(param.GetName()); + } } - // Every slot covered by the signature is now filled, and sits at the position of its parameter. - vector argument_names(arguments.size()); - for (idx_t i = 0; i < MinValue(arguments.size(), sig.GetParameterCount()); i++) { - argument_names[i] = sig.GetParameter(i).GetName(); - } - - // Now spread out any trailing named vararg arguments into the remaining argument slots, wherever they may be - idx_t kwarg_idx = 0; - for (idx_t slot_idx = kwargs_offset; slot_idx < arguments.size(); slot_idx++) { - if (!arguments[slot_idx]) { - argument_names[slot_idx] = trailing_kwargs[kwarg_idx].first; - arguments[slot_idx] = std::move(trailing_kwargs[kwarg_idx].second); - kwarg_idx++; + if (!args_param) { + // Without "*args", positional arguments beyond the signature stay behind the resolved arguments + for (idx_t i = positional_count; i < passed_count; i++) { + add_argument(std::move(positional_arguments[i]), Identifier()); } } - // And if there are still some left, just append them to the end - idx_t kwargs_remaining = trailing_kwargs.size() - kwarg_idx; - while (kwargs_remaining) { - argument_names.push_back(trailing_kwargs[kwarg_idx].first); - arguments.push_back(std::move(trailing_kwargs[kwarg_idx].second)); - kwarg_idx++; - kwargs_remaining--; - } + const auto positional_argument_count = resolved_arguments.size() - named_arguments_names.size(); + bound_function.SetNamedArguments(positional_argument_count, std::move(named_arguments_names)); + arguments = std::move(resolved_arguments); + + return resolved_names; +} - return argument_names; +// The names of the named arguments have to stay parallel to the last arguments +static void VerifyArgumentCount(const BoundSimpleFunction &bound_function, idx_t resolved_count, idx_t argument_count) { + if (resolved_count != argument_count && !bound_function.GetNamedArguments().empty()) { + throw InternalException("Function '%s' cannot add or remove arguments in its bind callback when it is " + "called with keyword-only or '**kwargs' arguments", + bound_function.GetName()); + } } static vector CaptureLogicalArguments(const BoundSimpleFunction &function, @@ -1102,19 +1149,11 @@ pair> FunctionBinder::ResolveFunction(shared_ptr function_p, vector> &arguments, vector>> &named_arguments) { auto &function = *function_p; - // Reorder named args - auto argument_names = ResolveArguments(function, arguments, named_arguments); - // Make a BoundScalarFunction out of the ScalarFunction, so we can store bind info and other properties in it. BoundScalarFunction bound_function(std::move(function_p)); - // Expand varargs if necessary - if (function.HasVarArgs()) { - const auto &varargs_type = function.GetVarArgs(); - for (idx_t i = function.GetSignature().GetParameterCount(); i < arguments.size(); i++) { - bound_function.GetArguments().push_back(varargs_type); - } - } + // Reorder named args and expand the variadic arguments + auto argument_names = ResolveArguments(function, bound_function, arguments, named_arguments); // Attempt to resolve template types, before we call the "Bind" callback. ResolveTemplateTypes(bound_function, arguments); @@ -1125,6 +1164,7 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, vec if (bound_function.HasBindCallback()) { BindScalarFunctionInput input(context, bound_function, arguments, argument_names, binder); bind_info = bound_function.GetBindCallback()(input); + VerifyArgumentCount(bound_function, argument_names.size(), arguments.size()); } // After the "bind" callback, we verify that all template types are bound to concrete types. @@ -1195,19 +1235,11 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, vector> &children, vector>> &named_arguments) { auto &function = *function_p; - // Reorder named args - auto argument_names = ResolveArguments(function, children, named_arguments); - // Make a BoundFunction out of the func BoundAggregateFunction bound_function(std::move(function_p)); - // Expand varargs if necessary - if (function.HasVarArgs()) { - const auto &varargs_type = function.GetVarArgs(); - for (idx_t i = function.GetSignature().GetParameterCount(); i < children.size(); i++) { - bound_function.GetArguments().push_back(varargs_type); - } - } + // Reorder named args and expand the variadic arguments + auto argument_names = ResolveArguments(function, bound_function, children, named_arguments); ResolveTemplateTypes(bound_function, children); bound_function.SetLogicalArguments(CaptureLogicalArguments(bound_function, children)); @@ -1220,6 +1252,7 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, // we may have lost some arguments in the bind children.resize(MinValue(bound_function.GetArguments().size(), children.size())); + VerifyArgumentCount(bound_function, argument_names.size(), children.size()); } CheckTemplateTypesResolved(bound_function); @@ -1292,18 +1325,10 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, vec optional_ptr> order_types, optional_ptr> arg_order_types) { auto &function = *function_p; - // Reorder named args - auto argument_names = ResolveArguments(function, children, named_arguments); - BoundWindowFunction bound_function(std::move(function_p)); - // Expand varargs if necessary - if (function.HasVarArgs()) { - const auto &varargs_type = function.GetVarArgs(); - for (idx_t i = function.GetSignature().GetParameterCount(); i < children.size(); i++) { - bound_function.GetArguments().push_back(varargs_type); - } - } + // Reorder named args and expand the variadic arguments + auto argument_names = ResolveArguments(function, bound_function, children, named_arguments); ResolveTemplateTypes(bound_function, children); auto logical_arguments = CaptureLogicalArguments(bound_function, children); @@ -1316,6 +1341,7 @@ FunctionBinder::ResolveFunction(shared_ptr function_p, vec bind_info = bound_function.GetBindCallback()(input); // we may have lost some arguments in the bind children.resize(MinValue(bound_function.GetArguments().size(), children.size())); + VerifyArgumentCount(bound_function, argument_names.size(), children.size()); } CheckTemplateTypesResolved(bound_function); diff --git a/src/duckdb/src/function/function_set.cpp b/src/duckdb/src/function/function_set.cpp index ae8a5a806..4b6a6c262 100644 --- a/src/duckdb/src/function/function_set.cpp +++ b/src/duckdb/src/function/function_set.cpp @@ -41,25 +41,6 @@ shared_ptr AggregateFunctionSet::GetFunctionByArguments FunctionBinder binder(context); auto index = binder.BindFunction(name, *this, arguments, error); if (!index.IsValid()) { - // check if the arguments are a prefix of any of the arguments - // this is used for functions such as quantile or string_agg that delete part of their arguments during bind - // FIXME: we should come up with a better solution here - for (auto &func : functions) { - auto &sig = func->GetSignature(); - if (arguments.size() >= sig.GetParameters().size()) { - continue; - } - bool is_prefix = true; - for (idx_t k = 0; k < arguments.size(); k++) { - if (arguments[k].id() != sig.GetParameter(k).GetType().id()) { - is_prefix = false; - break; - } - } - if (is_prefix) { - return func; - } - } throw BinderException("Failed to find function %s(%s)\n%s", name, StringUtil::ToString(arguments, ","), error.RawMessage()); } diff --git a/src/duckdb/src/function/scalar/create_sort_key.cpp b/src/duckdb/src/function/scalar/create_sort_key.cpp index d875797ea..cb2a6f647 100644 --- a/src/duckdb/src/function/scalar/create_sort_key.cpp +++ b/src/duckdb/src/function/scalar/create_sort_key.cpp @@ -1490,7 +1490,7 @@ ScalarFunction CreateSortKeyFun::GetFunction() { ScalarFunction sort_key_function("create_sort_key", {LogicalType::ANY}, LogicalType::BLOB, CreateSortKeyFunction, CreateSortKeyBind); sort_key_function.GetSignature().GetParameter(0).SetName("key1"); - sort_key_function.SetVarArgs(LogicalType::ANY); + sort_key_function.GetSignature().AddArgsParameter("args", LogicalType::ANY); sort_key_function.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return sort_key_function; } @@ -1521,7 +1521,7 @@ ScalarFunction DecodeSortKeyFun::GetFunction() { "decode_sort_key", {{"sort_key", LogicalType::ANY}, {"col", LogicalType::VARCHAR}, {"sort_specifier", LogicalType::VARCHAR}}, LogicalType::STRUCT({{"any", LogicalType::ANY}}), DecodeSortKeyFunction, DecodeSortKeyBind); - sort_key_function.SetVarArgs(LogicalType::VARCHAR); + sort_key_function.GetSignature().AddArgsParameter("args", LogicalType::VARCHAR); return sort_key_function; } diff --git a/src/duckdb/src/function/scalar/generic/constant_or_null.cpp b/src/duckdb/src/function/scalar/generic/constant_or_null.cpp index 0c64a79a7..e4025b173 100644 --- a/src/duckdb/src/function/scalar/generic/constant_or_null.cpp +++ b/src/duckdb/src/function/scalar/generic/constant_or_null.cpp @@ -96,7 +96,7 @@ ScalarFunction ConstantOrNullFun::GetFunction() { auto fun = ScalarFunction("constant_or_null", {}, LogicalType::ANY, ConstantOrNullFunction); fun.GetSignature().AddParameter("arg1", LogicalType::ANY).AddParameter("arg2", LogicalType::ANY); fun.SetBindCallback(ConstantOrNullBind); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); return fun; } diff --git a/src/duckdb/src/function/scalar/generic/invoke.cpp b/src/duckdb/src/function/scalar/generic/invoke.cpp index 2c13ca3d4..81652e17a 100644 --- a/src/duckdb/src/function/scalar/generic/invoke.cpp +++ b/src/duckdb/src/function/scalar/generic/invoke.cpp @@ -153,7 +153,7 @@ ScalarFunction InvokeFun::GetFunction() { ScalarFunction fun("invoke", {}, LogicalType::ANY, LambdaInvokeFunction); fun.GetSignature().AddParameter("lambda", LogicalType::LAMBDA).AddParameter("arg1", LogicalType::ANY); fun.SetBindCallback(LambdaInvokeBind); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); fun.SetBindLambdaCallback(LambdaInvokeBindParameters); fun.SetInitStateCallback(LambdaInvokeState::Init); diff --git a/src/duckdb/src/function/scalar/list/list_zip.cpp b/src/duckdb/src/function/scalar/list/list_zip.cpp index 285a5473c..6ab736cd5 100644 --- a/src/duckdb/src/function/scalar/list/list_zip.cpp +++ b/src/duckdb/src/function/scalar/list/list_zip.cpp @@ -175,7 +175,7 @@ static unique_ptr ListZipBind(BindScalarFunctionInput &input) { ScalarFunction ListZipFun::GetFunction() { auto fun = ScalarFunction({}, LogicalType::LIST(LogicalTypeId::STRUCT), ListZipFunction, ListZipBind); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return fun; } diff --git a/src/duckdb/src/function/scalar/string/concat.cpp b/src/duckdb/src/function/scalar/string/concat.cpp index 883806dfd..c08723677 100644 --- a/src/duckdb/src/function/scalar/string/concat.cpp +++ b/src/duckdb/src/function/scalar/string/concat.cpp @@ -341,7 +341,7 @@ ScalarFunction ListConcatFun::GetFunction() { // The arguments and return types are set in the binder function. auto fun = ScalarFunction({}, LogicalType::LIST(LogicalType::ANY), ConcatFunction, BindConcatFunction, ListConcatStats); - fun.SetVarArgs(LogicalType::LIST(LogicalType::ANY)); + fun.GetSignature().AddArgsParameter("args", LogicalType::LIST(LogicalType::ANY)); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return fun; } @@ -357,7 +357,7 @@ ScalarFunction ListConcatFun::GetFunction() { ScalarFunction ConcatFun::GetFunction() { ScalarFunction concat = ScalarFunction("concat", {}, LogicalType::ANY, ConcatFunction, BindConcatFunction); concat.GetSignature().AddParameter("value", LogicalType::ANY); - concat.SetVarArgs(LogicalType::ANY); + concat.GetSignature().AddArgsParameter("args", LogicalType::ANY); concat.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return concat; } diff --git a/src/duckdb/src/function/scalar/string/concat_ws.cpp b/src/duckdb/src/function/scalar/string/concat_ws.cpp index 0dcc8049d..6a86059ba 100644 --- a/src/duckdb/src/function/scalar/string/concat_ws.cpp +++ b/src/duckdb/src/function/scalar/string/concat_ws.cpp @@ -170,7 +170,7 @@ ScalarFunction ConcatWsFun::GetFunction() { ScalarFunction concat_ws = ScalarFunction("concat_ws", {}, LogicalType::VARCHAR, ConcatWSFunction, BindConcatWSFunction); concat_ws.GetSignature().AddParameter("separator", LogicalType::VARCHAR).AddParameter("string", LogicalType::ANY); - concat_ws.SetVarArgs(LogicalType::ANY); + concat_ws.GetSignature().AddArgsParameter("args", LogicalType::ANY); concat_ws.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return ScalarFunction(concat_ws); } diff --git a/src/duckdb/src/function/scalar/string/path_join.cpp b/src/duckdb/src/function/scalar/string/path_join.cpp index 08c3e91a3..15a356da2 100644 --- a/src/duckdb/src/function/scalar/string/path_join.cpp +++ b/src/duckdb/src/function/scalar/string/path_join.cpp @@ -69,7 +69,7 @@ void PathJoinFunction(DataChunk &args, ExpressionState &state, Vector &result) { ScalarFunction PathJoinFun::GetFunction() { ScalarFunction path_join(PathJoinFun::Name, {}, LogicalType::VARCHAR, PathJoinFunction); path_join.GetSignature().AddParameter("path", LogicalType::VARCHAR); - path_join.SetVarArgs(LogicalType::VARCHAR); + path_join.GetSignature().AddArgsParameter("args", LogicalType::VARCHAR); path_join.SetNullHandling(FunctionNullHandling::DEFAULT_NULL_HANDLING); // throws if the paths that are joined are incompatible path_join.SetFallible(); diff --git a/src/duckdb/src/function/scalar/struct/struct_concat.cpp b/src/duckdb/src/function/scalar/struct/struct_concat.cpp index 800549e6d..a51129a3a 100644 --- a/src/duckdb/src/function/scalar/struct/struct_concat.cpp +++ b/src/duckdb/src/function/scalar/struct/struct_concat.cpp @@ -103,7 +103,7 @@ static unique_ptr StructConcatStats(ClientContext &context, Func ScalarFunction StructConcatFun::GetFunction() { ScalarFunction fun("struct_concat", {}, LogicalTypeId::STRUCT, StructConcatFunction, StructConcatBind, StructConcatStats); - fun.SetVarArgs(LogicalType::ANY); + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); return fun; } diff --git a/src/duckdb/src/function/scalar/struct/struct_pack.cpp b/src/duckdb/src/function/scalar/struct/struct_pack.cpp index 46ec492c1..7b611e420 100644 --- a/src/duckdb/src/function/scalar/struct/struct_pack.cpp +++ b/src/duckdb/src/function/scalar/struct/struct_pack.cpp @@ -46,34 +46,21 @@ static void StructPackFunction(DataChunk &args, ExpressionState &state, Vector & template static unique_ptr StructPackBind(BindScalarFunctionInput &input) { auto &bound_function = input.GetBoundFunction(); - auto &arguments = input.GetArguments(); - identifier_set_t name_collision_set; + auto &args = input.GetArguments(); - // collect names and deconflict, construct return type - // note: zero arguments is allowed, producing an empty struct - child_list_t struct_children; - for (idx_t i = 0; i < arguments.size(); i++) { - auto &child = arguments[i]; - string alias; - if (IS_STRUCT_PACK) { - if (child->GetAlias().empty()) { - throw BinderException("Need named argument for struct pack, e.g. STRUCT_PACK(a := b)"); - } - alias = child->GetAlias().GetIdentifierName(); - if (name_collision_set.find(Identifier(alias)) != name_collision_set.end()) { - throw BinderException("Duplicate struct entry name \"%s\"", alias); - } - name_collision_set.insert(Identifier(alias)); - } - struct_children.emplace_back(make_pair(alias, arguments[i]->GetReturnType())); - } - - // this is more for completeness reasons - // row() produces an unnamed TUPLE, struct_pack() produces a named STRUCT if (IS_STRUCT_PACK) { - bound_function.SetReturnType(LogicalType::STRUCT(std::move(struct_children))); + auto &names = *input.GetArgumentNames(); + child_list_t fields; + for (idx_t i = 0; i < args.size(); i++) { + fields.emplace_back(names[i], args[i]->GetReturnType()); + } + bound_function.SetReturnType(LogicalType::STRUCT(std::move(fields))); } else { - bound_function.SetReturnType(LogicalType::TUPLE(std::move(struct_children))); + vector fields; + for (idx_t i = 0; i < args.size(); i++) { + fields.push_back(args[i]->GetReturnType()); + } + bound_function.SetReturnType(LogicalType::TUPLE(std::move(fields))); } return make_uniq(bound_function.GetReturnType()); } @@ -94,12 +81,19 @@ static ScalarFunction GetStructPackFunction() { ScalarFunction fun(IS_STRUCT_PACK ? "struct_pack" : "row", {}, IS_STRUCT_PACK ? LogicalTypeId::STRUCT : LogicalTypeId::TUPLE, StructPackFunction, StructPackBind, StructPackStats); - fun.SetVarArgs(LogicalType::ANY); + + if (IS_STRUCT_PACK) { + // struct_pack derives its field names from argument aliases, so the binder must capture argument expression + // aliases as named-argument names. This also preserves the legacy behavior of allowing positional arguments + // after named ones (the positional arguments simply take their expression's name as the field name). + fun.GetSignature().AddKwargsParameter("kwargs", LogicalType::ANY); + fun.SetCaptureArgumentAliases(true); + } else { + // row produces an unnamed TUPLE, so it ignores the names of its arguments + fun.GetSignature().AddArgsParameter("args", LogicalType::ANY); + } + fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING); - // struct_pack/row derive their (struct field) names from argument aliases, so the binder must capture argument - // expression aliases as named-argument names. This also preserves the legacy behavior of allowing positional - // arguments after named ones (the positional arguments simply take their expression's name as the field name). - fun.SetCaptureArgumentAliases(true); fun.SetSerializeCallback(VariableReturnBindData::Serialize); fun.SetDeserializeCallback(VariableReturnBindData::Deserialize); return fun; diff --git a/src/duckdb/src/function/scalar/system/write_log.cpp b/src/duckdb/src/function/scalar/system/write_log.cpp index 526dd86c3..225023104 100644 --- a/src/duckdb/src/function/scalar/system/write_log.cpp +++ b/src/duckdb/src/function/scalar/system/write_log.cpp @@ -65,37 +65,38 @@ unique_ptr WriteLogBind(BindScalarFunctionInput &input) { // Default return type bound_function.SetReturnType(LogicalType::VARCHAR); + auto &names = *input.GetArgumentNames(); for (idx_t i = 1; i < arguments.size(); i++) { auto &arg = arguments[i]; if (arg->HasParameter()) { throw ParameterNotResolvedException(); } - if (arg->GetAlias() == "disable_logging") { + if (names[i] == "disable_logging") { if (arg->GetReturnType().id() != LogicalTypeId::BOOLEAN) { throw BinderException("write_log: 'disable_logging' argument must be a boolean"); } result->disable_logging = BooleanValue::Get(input.GetConstant(i)); - } else if (arg->GetAlias() == "scope") { + } else if (names[i] == "scope") { if (arg->GetReturnType().id() != LogicalTypeId::VARCHAR) { throw BinderException("write_log: 'scope' argument must be a string"); } result->scope = StringValue::Get(input.GetConstant(i)); - } else if (arg->GetAlias() == "level") { + } else if (names[i] == "level") { if (arg->GetReturnType().id() != LogicalTypeId::VARCHAR) { throw BinderException("write_log: 'level' argument must be a string"); } result->level = EnumUtil::FromString(StringValue::Get(input.GetConstant(i))); - } else if (arg->GetAlias() == "log_type") { + } else if (names[i] == "log_type") { if (arg->GetReturnType().id() != LogicalTypeId::VARCHAR) { throw BinderException("write_log: 'log_type' argument must be a string"); } result->type = StringValue::Get(input.GetConstant(i)); - } else if (arg->GetAlias() == "return_value") { + } else if (names[i] == "return_value") { result->return_type = arg->GetReturnType(); result->output_col = i; bound_function.SetReturnType(result->return_type); } else { - throw BinderException(StringUtil::Format("write_log: Unknown argument '%s'", arg->GetAlias())); + throw BinderException(StringUtil::Format("write_log: Unknown argument '%s'", names[i])); } } @@ -152,9 +153,9 @@ void WriteLogFunction(DataChunk &args, ExpressionState &state, Vector &result) { ScalarFunctionSet WriteLogFun::GetFunctions() { ScalarFunctionSet set("write_log"); - ScalarFunction fun({}, LogicalType::ANY, WriteLogFunction, WriteLogBind, nullptr, nullptr, LogicalType::ANY, - FunctionStability::VOLATILE); - fun.GetSignature().AddParameter("string", LogicalType::VARCHAR); + ScalarFunction fun({{"string", LogicalType::VARCHAR}}, LogicalType::ANY, WriteLogFunction, WriteLogBind, nullptr, + nullptr, LogicalType(LogicalTypeId::INVALID), FunctionStability::VOLATILE); + fun.GetSignature().AddKwargsParameter("kwargs", LogicalType::ANY); fun.GetProperties().SetRequiresExpressionNames(true); set.AddFunction(std::move(fun)); diff --git a/src/duckdb/src/function/scalar_function.cpp b/src/duckdb/src/function/scalar_function.cpp index b70e35504..06daf1ad0 100644 --- a/src/duckdb/src/function/scalar_function.cpp +++ b/src/duckdb/src/function/scalar_function.cpp @@ -145,15 +145,19 @@ BoundScalarFunction::BoundScalarFunction(shared_ptr functi // Try to default bind the function, to fill in any missing information in the BoundScalarFunction (e.g. from the // "bind" callback) for (auto ¶m : function.GetSignature().GetParameters()) { - arguments.push_back(param.GetType()); + if (!param.IsVariadic()) { + arguments.push_back(param.GetType()); + } } + positional_arguments = arguments.size(); logical_arguments = arguments; logical_return_type = return_type; } bool BoundScalarFunction::operator==(const BoundScalarFunction &rhs) const { return callbacks == rhs.callbacks && properties == rhs.properties && GetName() == rhs.GetName() && - return_type == rhs.return_type && arguments == rhs.arguments; + return_type == rhs.return_type && arguments == rhs.arguments && + positional_arguments == rhs.positional_arguments && named_arguments == rhs.named_arguments; } bool BoundScalarFunction::operator!=(const BoundScalarFunction &rhs) const { return !(*this == rhs); diff --git a/src/duckdb/src/function/table/read_duckdb.cpp b/src/duckdb/src/function/table/read_duckdb.cpp index c9988f0db..9687387cb 100644 --- a/src/duckdb/src/function/table/read_duckdb.cpp +++ b/src/duckdb/src/function/table/read_duckdb.cpp @@ -250,10 +250,9 @@ AttachedDatabase &DuckDBReader::GetAttachedDatabase() { auto &db_manager = DatabaseManager::Get(context); AttachInfo info; info.path = file.path; - // use invalid UTF-8 so that a conflicting database name cannot be attached by a user - info.name = Identifier("\x80__duckdb_reader_" + info.path); - - info.on_conflict = OnCreateConflict::IGNORE_ON_CONFLICT; + // a unique name per reader: each reader detaches its own attachment when it finishes + info.name = GenerateInternalName("__duckdb_reader_"); + info.on_conflict = OnCreateConflict::ERROR_ON_CONFLICT; unordered_map attach_kv; AttachOptions attach_options(attach_kv, AccessMode::READ_ONLY); attach_options.visibility = AttachVisibility::HIDDEN; diff --git a/src/duckdb/src/function/table/system/duckdb_functions.cpp b/src/duckdb/src/function/table/system/duckdb_functions.cpp index 70908c2be..1e807837f 100644 --- a/src/duckdb/src/function/table/system/duckdb_functions.cpp +++ b/src/duckdb/src/function/table/system/duckdb_functions.cpp @@ -137,6 +137,15 @@ Value FunctionStabilityToValue(FunctionStability stability) { } } +//! The legacy "varargs" column cannot tell "*args" and "**kwargs" apart - report whichever the function has +Value VariadicTypeValue(const FunctionSignature &signature) { + auto variadic = signature.GetArgsParameter(); + if (!variadic) { + variadic = signature.GetKwargsParameter(); + } + return variadic ? Value(variadic->GetType().ToString()) : Value(); +} + struct ScalarFunctionExtractor { static idx_t FunctionCount(ScalarFunctionCatalogEntry &entry) { return entry.functions.Size(); @@ -153,7 +162,9 @@ struct ScalarFunctionExtractor { static vector GetParameters(ScalarFunctionCatalogEntry &entry, idx_t offset) { vector results; for (auto ¶m : entry.functions.GetFunctionByOffset(offset)->GetSignature().GetParameters()) { - results.emplace_back(param.GetName()); + if (!param.IsVariadic()) { + results.emplace_back(param.GetName()); + } } return results; } @@ -162,7 +173,9 @@ struct ScalarFunctionExtractor { vector results; const auto &fun = *entry.functions.GetFunctionByOffset(offset); for (idx_t i = 0; i < fun.GetSignature().GetParameterCount(); i++) { - results.emplace_back(fun.GetSignature().GetParameter(i).GetType().ToString()); + if (!fun.GetSignature().GetParameter(i).IsVariadic()) { + results.emplace_back(fun.GetSignature().GetParameter(i).GetType().ToString()); + } } return Value::LIST(LogicalType::VARCHAR, std::move(results)); } @@ -171,14 +184,15 @@ struct ScalarFunctionExtractor { const auto &fun = *entry.functions.GetFunctionByOffset(offset); vector results; for (idx_t i = 0; i < fun.GetSignature().GetParameterCount(); i++) { - results.emplace_back(fun.GetSignature().GetParameter(i).GetType()); + if (!fun.GetSignature().GetParameter(i).IsVariadic()) { + results.emplace_back(fun.GetSignature().GetParameter(i).GetType()); + } } return results; } static Value GetVarArgs(ScalarFunctionCatalogEntry &entry, idx_t offset) { - const auto &fun = *entry.functions.GetFunctionByOffset(offset); - return !fun.HasVarArgs() ? Value() : Value(fun.GetVarArgs().ToString()); + return VariadicTypeValue(entry.functions.GetFunctionByOffset(offset)->GetSignature()); } static Value GetMacroDefinition(ScalarFunctionCatalogEntry &entry, idx_t offset) { @@ -211,7 +225,9 @@ struct WindowFunctionExtractor { static vector GetParameters(WindowFunctionCatalogEntry &entry, idx_t offset) { vector results; for (auto ¶m : entry.functions.GetFunctionByOffset(offset)->GetSignature().GetParameters()) { - results.emplace_back(param.GetName()); + if (!param.IsVariadic()) { + results.emplace_back(param.GetName()); + } } return results; } @@ -220,7 +236,9 @@ struct WindowFunctionExtractor { vector results; const auto &fun = *entry.functions.GetFunctionByOffset(offset); for (idx_t i = 0; i < fun.GetSignature().GetParameterCount(); i++) { - results.emplace_back(fun.GetSignature().GetParameter(i).GetType().ToString()); + if (!fun.GetSignature().GetParameter(i).IsVariadic()) { + results.emplace_back(fun.GetSignature().GetParameter(i).GetType().ToString()); + } } return Value::LIST(LogicalType::VARCHAR, std::move(results)); } @@ -229,7 +247,9 @@ struct WindowFunctionExtractor { const auto &fun = *entry.functions.GetFunctionByOffset(offset); vector results; for (idx_t i = 0; i < fun.GetSignature().GetParameterCount(); i++) { - results.emplace_back(fun.GetSignature().GetParameter(i).GetType()); + if (!fun.GetSignature().GetParameter(i).IsVariadic()) { + results.emplace_back(fun.GetSignature().GetParameter(i).GetType()); + } } return results; } @@ -267,7 +287,9 @@ struct AggregateFunctionExtractor { static vector GetParameters(AggregateFunctionCatalogEntry &entry, idx_t offset) { vector results; for (auto ¶m : entry.functions.GetFunctionByOffset(offset)->GetSignature().GetParameters()) { - results.emplace_back(param.GetName()); + if (!param.IsVariadic()) { + results.emplace_back(param.GetName()); + } } return results; } @@ -276,7 +298,9 @@ struct AggregateFunctionExtractor { vector results; const auto &fun = *entry.functions.GetFunctionByOffset(offset); for (idx_t i = 0; i < fun.GetSignature().GetParameterCount(); i++) { - results.emplace_back(fun.GetSignature().GetParameter(i).GetType().ToString()); + if (!fun.GetSignature().GetParameter(i).IsVariadic()) { + results.emplace_back(fun.GetSignature().GetParameter(i).GetType().ToString()); + } } return Value::LIST(LogicalType::VARCHAR, std::move(results)); } @@ -285,14 +309,15 @@ struct AggregateFunctionExtractor { const auto &fun = *entry.functions.GetFunctionByOffset(offset); vector results; for (idx_t i = 0; i < fun.GetSignature().GetParameterCount(); i++) { - results.emplace_back(fun.GetSignature().GetParameter(i).GetType()); + if (!fun.GetSignature().GetParameter(i).IsVariadic()) { + results.emplace_back(fun.GetSignature().GetParameter(i).GetType()); + } } return results; } static Value GetVarArgs(AggregateFunctionCatalogEntry &entry, idx_t offset) { - const auto &fun = *entry.functions.GetFunctionByOffset(offset); - return !fun.HasVarArgs() ? Value() : Value(fun.GetVarArgs().ToString()); + return VariadicTypeValue(entry.functions.GetFunctionByOffset(offset)->GetSignature()); } static Value GetMacroDefinition(AggregateFunctionCatalogEntry &entry, idx_t offset) { diff --git a/src/duckdb/src/function/table/system/duckdb_types.cpp b/src/duckdb/src/function/table/system/duckdb_types.cpp index d7d057028..b6d07a40a 100644 --- a/src/duckdb/src/function/table/system/duckdb_types.cpp +++ b/src/duckdb/src/function/table/system/duckdb_types.cpp @@ -240,12 +240,20 @@ void DuckDBTypesFunction(ClientContext &context, TableFunctionInput &data_p, Dat vector parameter_names; vector parameter_type_names; for (auto ¶m : signature.GetParameters()) { + if (param.IsVariadic()) { + continue; + } parameter_names.emplace_back(param.GetName()); parameter_type_names.emplace_back(param.GetType().ToString()); } parameters.Append(Value::LIST(LogicalType::VARCHAR, std::move(parameter_names))); parameter_types.Append(Value::LIST(LogicalType::VARCHAR, std::move(parameter_type_names))); - varargs.Append(signature.HasVarArgs() ? Value(signature.GetVarArgs().ToString()) : Value()); + auto variadic = signature.GetArgsParameter(); + if (!variadic) { + variadic = signature.GetKwargsParameter(); + } + // the legacy "varargs" column cannot tell "*args" and "**kwargs" apart + varargs.Append(variadic ? Value(variadic->GetType().ToString()) : Value()); count++; } diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index fda09db01..8126c8080 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "0-alpha42986" +#define DUCKDB_PATCH_VERSION "0-alpha43089" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 0 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 2 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v2.0.0-alpha42986" +#define DUCKDB_VERSION "v2.0.0-alpha43089" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "d4e72566aa" +#define DUCKDB_SOURCE_ID "6844d1bd8b" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/function/type_constructor.cpp b/src/duckdb/src/function/type_constructor.cpp index ba9ff64c0..ab30af74d 100644 --- a/src/duckdb/src/function/type_constructor.cpp +++ b/src/duckdb/src/function/type_constructor.cpp @@ -34,7 +34,7 @@ TypeConstructor TypeConstructor::Identity(Identifier name) { TypeConstructor TypeConstructor::Unchecked(Identifier name, bind_logical_type_function_t bind) { // accepts anything, the bind function validates the arguments itself auto signature = Signature(); - signature.SetVarArgs(LogicalType::ANY); + signature.AddArgsParameter("args", LogicalType::ANY).AddKwargsParameter("kwargs", LogicalType::ANY); return TypeConstructor(std::move(name), std::move(signature), bind); } @@ -66,15 +66,22 @@ string ConstructorToString(const Identifier &type_name, const TypeConstructor &c const auto &sig = constructor.GetSignature(); vector parts; for (auto ¶m : sig.GetParameters()) { + switch (param.GetKind()) { + case FunctionParameterKind::VAR_POSITIONAL: + parts.push_back(param.GetType().ToString() + "..."); + continue; + case FunctionParameterKind::VAR_KEYWORD: + parts.push_back(param.GetName().GetIdentifierName() + " := " + param.GetType().ToString() + "..."); + continue; + default: + break; + } string part = param.GetName().GetIdentifierName() + " " + param.GetType().ToString(); if (param.HasDefaultValue()) { part += " := " + param.GetDefaultValue()->ToString(); } parts.push_back(std::move(part)); } - if (sig.HasVarArgs()) { - parts.push_back(sig.GetVarArgs().ToString() + "..."); - } return type_name.GetIdentifierName() + "(" + StringUtil::Join(parts, ", ") + ")"; } @@ -133,7 +140,7 @@ Value CastArgument(const Identifier &type_name, const string &arg_name, const Va vector NormalizeArguments(const Identifier &type_name, const TypeConstructor &constructor, const vector &arguments, QueryLocation type_location) { const auto &sig = constructor.GetSignature(); - const auto param_count = sig.GetParameterCount(); + const auto param_count = sig.GetPositionalParameterCount(); vector result; vector> slots(param_count); @@ -154,12 +161,20 @@ vector NormalizeArguments(const Identifier &type_name, const TypeC positional_count++; } + identifier_set_t seen_names; for (idx_t i = 0; i < arguments.size(); i++) { auto &arg = arguments[i]; if (!arg.HasName()) { continue; } - auto param_idx = sig.GetParameterIndexByName(Identifier(arg.GetName())); + auto name = Identifier(arg.GetName()); + if (seen_names.find(name) != seen_names.end()) { + throw BinderException(arg.GetQueryLocation(), "Duplicate type parameter %s for type %s", arg.GetName(), + type_name); + } + seen_names.insert(name); + + auto param_idx = sig.GetParameterIndexByName(name); if (!param_idx.IsValid()) { // not a declared parameter - it can only be a named vararg varargs.emplace_back(i, arg); @@ -192,8 +207,11 @@ vector NormalizeArguments(const Identifier &type_name, const TypeC auto &arg = entry.second.get(); auto arg_name = ArgumentName(Identifier(arg.GetName()), entry.first); auto location = arg.GetQueryLocation(); - result.emplace_back(arg.GetName(), - CastArgument(type_name, arg_name, arg.GetValue(), sig.GetVarArgs(), location), location); + // a named modifier is received by "**kwargs", an unnamed one by "*args" + auto param = arg.HasName() ? sig.GetKwargsParameter() : sig.GetArgsParameter(); + auto &target = param ? param->GetType() : LogicalType::ANY; + result.emplace_back(arg.GetName(), CastArgument(type_name, arg_name, arg.GetValue(), target, location), + location); } return result; } @@ -208,7 +226,7 @@ LogicalType TypeConstructorSet::Bind(optional_ptr context, const // parameterised. It also gets a dedicated error, as the generic one would list a single empty candidate. if (functions.size() == 1) { const auto &sig = functions[0]->GetSignature(); - if (sig.GetParameterCount() == 0 && !sig.HasVarArgs()) { + if (sig.GetParameterCount() == 0) { if (!arguments.empty()) { throw BinderException(query_location, "Type %s does not take any type parameters", name); } diff --git a/src/duckdb/src/function/window_function.cpp b/src/duckdb/src/function/window_function.cpp index 4a205038f..11fe6b1fd 100644 --- a/src/duckdb/src/function/window_function.cpp +++ b/src/duckdb/src/function/window_function.cpp @@ -36,14 +36,19 @@ BoundWindowFunction::BoundWindowFunction(shared_ptr base_p // Try to default bind the function, to fill in any missing information in the BoundScalarFunction (e.g. from the // "bind" callback) for (auto ¶m : base.GetSignature().GetParameters()) { - arguments.push_back(param.GetType()); + if (!param.IsVariadic()) { + arguments.push_back(param.GetType()); + } } + positional_arguments = arguments.size(); logical_arguments = arguments; logical_return_type = return_type; } bool BoundWindowFunction::operator==(const BoundWindowFunction &rhs) const { - return window_enum == rhs.window_enum && arguments == rhs.arguments && return_type == rhs.return_type; + return window_enum == rhs.window_enum && arguments == rhs.arguments && + positional_arguments == rhs.positional_arguments && named_arguments == rhs.named_arguments && + return_type == rhs.return_type; } bool BoundWindowFunction::operator!=(const BoundWindowFunction &rhs) const { diff --git a/src/duckdb/src/include/duckdb/common/enum_util.hpp b/src/duckdb/src/include/duckdb/common/enum_util.hpp index 1983731f4..124c0d8e6 100644 --- a/src/duckdb/src/include/duckdb/common/enum_util.hpp +++ b/src/duckdb/src/include/duckdb/common/enum_util.hpp @@ -266,6 +266,8 @@ enum class FunctionErrors : uint8_t; enum class FunctionNullHandling : uint8_t; +enum class FunctionParameterKind : uint8_t; + enum class FunctionStability : uint8_t; enum class GateStatus : uint8_t; @@ -1004,6 +1006,9 @@ const char* EnumUtil::ToChars(FunctionErrors value); template<> const char* EnumUtil::ToChars(FunctionNullHandling value); +template<> +const char* EnumUtil::ToChars(FunctionParameterKind value); + template<> const char* EnumUtil::ToChars(FunctionStability value); @@ -1935,6 +1940,9 @@ FunctionErrors EnumUtil::FromString(const char *value); template<> FunctionNullHandling EnumUtil::FromString(const char *value); +template<> +FunctionParameterKind EnumUtil::FromString(const char *value); + template<> FunctionStability EnumUtil::FromString(const char *value); diff --git a/src/duckdb/src/include/duckdb/common/identifier.hpp b/src/duckdb/src/include/duckdb/common/identifier.hpp index c0023b6c7..195c54154 100644 --- a/src/duckdb/src/include/duckdb/common/identifier.hpp +++ b/src/duckdb/src/include/duckdb/common/identifier.hpp @@ -93,6 +93,9 @@ class Identifier { string value; }; +//! Generate an internal name: the given prefix followed by a random UUID +Identifier GenerateInternalName(const char *prefix); + //! Equality (case-insensitive) DUCKDB_API bool operator==(const Identifier &a, const Identifier &b); DUCKDB_API bool operator==(const Identifier &a, const string &b); diff --git a/src/duckdb/src/include/duckdb/function/aggregate_function.hpp b/src/duckdb/src/include/duckdb/function/aggregate_function.hpp index dcd12f078..b02e818c5 100644 --- a/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +++ b/src/duckdb/src/include/duckdb/function/aggregate_function.hpp @@ -856,6 +856,18 @@ class BoundAggregateFunction : public BaseAggregateFunction, public BoundSimpleF const shared_ptr &GetDefinition() const { return definition; } + //! The number of arguments that were received by "*args", they directly follow the standard parameters + idx_t GetVarArgsCount() const { + return BoundSimpleFunction::GetVarArgsCount(definition->GetSignature()); + } + //! The number of arguments that were received by "**kwargs", they are the last arguments + idx_t GetKwargsCount() const { + return BoundSimpleFunction::GetKwargsCount(definition->GetSignature()); + } + //! The kind of the parameter that received the argument at the given index + FunctionParameterKind GetArgumentParameterKind(idx_t argument_index) const { + return BoundSimpleFunction::GetArgumentParameterKind(definition->GetSignature(), argument_index); + } //! Restore the definition after the bound function has been replaced wholesale, together with the //! qualification it carries - the replacement is a specialized implementation, not a different function void SetDefinition(shared_ptr definition_p) { diff --git a/src/duckdb/src/include/duckdb/function/function.hpp b/src/duckdb/src/include/duckdb/function/function.hpp index 7cf2b7a9d..f051e6842 100644 --- a/src/duckdb/src/include/duckdb/function/function.hpp +++ b/src/duckdb/src/include/duckdb/function/function.hpp @@ -118,14 +118,23 @@ struct FunctionParameters { named_parameter_map_t named_parameters; }; +//! How a parameter receives its arguments, mirroring Python's parameter kinds +//! STANDARD -> can be passed by position or by name +//! VAR_POSITIONAL -> "*args", receives all remaining positional arguments +//! VAR_KEYWORD -> "**kwargs", receives all named arguments that do not match another parameter +//! KEYWORD_ONLY -> declared after "*args", can only be passed by name +enum class FunctionParameterKind : uint8_t { STANDARD = 0, VAR_POSITIONAL = 1, VAR_KEYWORD = 2, KEYWORD_ONLY = 3 }; + class FunctionParameter { public: - FunctionParameter(Identifier name, LogicalType type) - : name(std::move(name)), type(std::move(type)), default_value(nullptr) { + FunctionParameter(Identifier name, LogicalType type, FunctionParameterKind kind = FunctionParameterKind::STANDARD) + : name(std::move(name)), type(std::move(type)), default_value(nullptr), kind(kind) { } - FunctionParameter(Identifier name, LogicalType type, Value value) - : name(std::move(name)), type(std::move(type)), default_value(make_shared_ptr(std::move(value))) { + FunctionParameter(Identifier name, LogicalType type, Value value, + FunctionParameterKind kind = FunctionParameterKind::STANDARD) + : name(std::move(name)), type(std::move(type)), default_value(make_shared_ptr(std::move(value))), + kind(kind) { } string ToString() const; @@ -157,10 +166,19 @@ class FunctionParameter { return default_value != nullptr; } + auto GetKind() const -> FunctionParameterKind { + return kind; + } + //! Whether this is a "*args" or "**kwargs" parameter + auto IsVariadic() const -> bool { + return kind == FunctionParameterKind::VAR_POSITIONAL || kind == FunctionParameterKind::VAR_KEYWORD; + } + private: Identifier name; LogicalType type; shared_ptr default_value; + FunctionParameterKind kind; }; class FunctionSignature { @@ -168,16 +186,22 @@ class FunctionSignature { FunctionSignature() = default; FunctionSignature(vector arguments, LogicalType varargs, LogicalType return_type) - : varargs(std::move(varargs)), return_type(std::move(return_type)) { + : return_type(std::move(return_type)) { for (auto &arg : arguments) { AddParameter(std::move(arg)); } + if (varargs.id() != LogicalTypeId::INVALID) { + SetVarArgs(std::move(varargs)); + } } FunctionSignature(vector parameters, LogicalType return_type) - : parameters(std::move(parameters)), varargs(LogicalTypeId::INVALID), return_type(std::move(return_type)) { + : parameters(std::move(parameters)), return_type(std::move(return_type)) { } FunctionSignature(vector parameters, LogicalType varargs, LogicalType return_type) - : parameters(std::move(parameters)), varargs(std::move(varargs)), return_type(std::move(return_type)) { + : parameters(std::move(parameters)), return_type(std::move(return_type)) { + if (varargs.id() != LogicalTypeId::INVALID) { + SetVarArgs(std::move(varargs)); + } } FunctionSignature(vector arguments, LogicalType return_type) : FunctionSignature(std::move(arguments), LogicalType(LogicalTypeId::INVALID), std::move(return_type)) { @@ -211,81 +235,105 @@ class FunctionSignature { return_type = std::move(return_type_p); } + //! Whether the signature has a "*args" parameter auto HasVarArgs() const -> bool { - return varargs.id() != LogicalTypeId::INVALID; + return GetArgsParameter() != nullptr; } - auto GetVarArgs() const -> const LogicalType & { - return varargs; + //! The type of the "*args" parameter, or INVALID if there is none + DUCKDB_API auto GetVarArgs() const -> const LogicalType &; + //! Replaces the variadic parameters by an "*args" and "**kwargs" of the given type, so that any trailing argument + //! is accepted. Removes the variadic parameters if the type is INVALID. + DUCKDB_API auto SetVarArgs(LogicalType varargs_p) -> void; + + auto GetArgsParameter() const -> optional_ptr { + return GetParameterByKind(FunctionParameterKind::VAR_POSITIONAL); } - auto SetVarArgs(LogicalType varargs_p) -> void { - varargs = std::move(varargs_p); + auto GetKwargsParameter() const -> optional_ptr { + return GetParameterByKind(FunctionParameterKind::VAR_KEYWORD); } + //! A parameter added after "*args" is keyword-only auto AddParameter(Identifier name, LogicalType type, Value default_value) -> FunctionSignature & { - parameters.emplace_back(std::move(name), std::move(type), std::move(default_value)); + parameters.emplace_back(std::move(name), std::move(type), std::move(default_value), GetNextKind()); return *this; } auto AddParameter(Identifier name, LogicalType type) -> FunctionSignature & { - parameters.emplace_back(std::move(name), std::move(type)); + parameters.emplace_back(std::move(name), std::move(type), GetNextKind()); return *this; } auto AddParameter(LogicalType type) -> FunctionSignature & { auto name = StringUtil::Format("col%d", parameters.size()); - parameters.emplace_back(Identifier(name), std::move(type)); + return AddParameter(Identifier(name), std::move(type)); + } + + //! Adds a "*args" parameter, receiving all remaining positional arguments + auto AddArgsParameter(Identifier name, LogicalType type) -> FunctionSignature & { + parameters.emplace_back(std::move(name), std::move(type), FunctionParameterKind::VAR_POSITIONAL); return *this; } + //! Adds a "**kwargs" parameter, receiving all named arguments that do not match another parameter + auto AddKwargsParameter(Identifier name, LogicalType type) -> FunctionSignature & { + parameters.emplace_back(std::move(name), std::move(type), FunctionParameterKind::VAR_KEYWORD); + return *this; + } + + //! Returns the index of the non-variadic parameter with the given name auto GetParameterIndexByName(const Identifier &name) const -> optional_idx { // Parameter names are matched case-insensitively, consistent with SQL identifier semantics. for (idx_t i = 0; i < parameters.size(); i++) { - if (parameters[i].GetName() == name) { + if (!parameters[i].IsVariadic() && parameters[i].GetName() == name) { return i; } } return optional_idx(); } + //! The number of leading parameters that can be passed by position + auto GetPositionalParameterCount() const -> idx_t { + idx_t result = 0; + while (result < parameters.size() && parameters[result].GetKind() == FunctionParameterKind::STANDARD) { + result++; + } + return result; + } + auto GetRequiredParameterCount() const -> idx_t { idx_t result = 0; for (const auto ¶m : parameters) { - if (!param.HasDefaultValue()) { + if (!param.IsVariadic() && !param.HasDefaultValue()) { result++; } } return result; } - void Verify() const { - // Check for duplicate parameter names - identifier_set_t seen_names; + DUCKDB_API void Verify() const; + + hash_t Hash() const; + +private: + auto GetParameterByKind(FunctionParameterKind kind) const -> optional_ptr { for (const auto ¶m : parameters) { - if (seen_names.find(param.GetName()) != seen_names.end()) { - throw InvalidInputException("Duplicate parameter name: %s", param.GetName()); + if (param.GetKind() == kind) { + return param; } - seen_names.insert(param.GetName()); } - - // Also check for default values that are not at the end of the parameter list - bool found_default_value = false; + return nullptr; + } + auto GetNextKind() const -> FunctionParameterKind { for (const auto ¶m : parameters) { - if (param.HasDefaultValue()) { - found_default_value = true; - } else if (found_default_value) { - throw InvalidInputException( - "Parameters with default values must be at the end of the parameter list. Parameter '%s' does not " - "have a default value but follows a parameter with a default value.", - param.GetName()); + if (param.GetKind() != FunctionParameterKind::STANDARD) { + return FunctionParameterKind::KEYWORD_ONLY; } } + return FunctionParameterKind::STANDARD; } - hash_t Hash() const; - private: vector parameters; - LogicalType varargs; LogicalType return_type; }; @@ -521,6 +569,10 @@ class BoundSimpleFunction { //! The set of arguments of the function vector arguments; + //! The number of leading arguments that are matched to the parameters by position + idx_t positional_arguments = 0; + //! The names of the remaining arguments, which are matched to the parameters by name + vector named_arguments; //! Return type of the function LogicalType return_type; @@ -560,6 +612,26 @@ class BoundSimpleFunction { return arguments; } + auto GetPositionalArgumentCount() const -> idx_t { + return positional_arguments; + } + auto GetNamedArguments() const -> const vector & { + return named_arguments; + } + auto SetNamedArguments(idx_t positional_arguments_p, vector named_arguments_p) -> void { + positional_arguments = positional_arguments_p; + named_arguments = std::move(named_arguments_p); + } + +protected: + //! The arguments are laid out as [standard | *args | keyword-only | **kwargs], these need the signature of the + //! function to tell them apart + DUCKDB_API auto GetVarArgsCount(const FunctionSignature &signature) const -> idx_t; + DUCKDB_API auto GetKwargsCount(const FunctionSignature &signature) const -> idx_t; + DUCKDB_API auto GetArgumentParameterKind(const FunctionSignature &signature, idx_t argument_index) const + -> FunctionParameterKind; + +public: auto GetReturnType() const -> const LogicalType & { return return_type; } @@ -621,7 +693,6 @@ class BindFunctionInput { private: ClientContext &context; - //! Only used to name the function in error messages const BoundSimpleFunction &function; vector> &arguments; optional_ptr> argument_names; diff --git a/src/duckdb/src/include/duckdb/function/function_serialization.hpp b/src/duckdb/src/include/duckdb/function/function_serialization.hpp index 386642779..93b490154 100644 --- a/src/duckdb/src/include/duckdb/function/function_serialization.hpp +++ b/src/duckdb/src/include/duckdb/function/function_serialization.hpp @@ -96,6 +96,9 @@ class FunctionSerializer { bool has_serialize = function.HasSerializationCallbacks(); serializer.WriteProperty(503, "has_serialize", has_serialize); + if constexpr (std::is_base_of_v) { + SerializeNamedArguments(serializer, function); + } if (has_serialize) { serializer.WriteObject(504, "function_data", [&](Serializer &obj) { function.GetSerializeCallback()(obj, bind_info, function); }); @@ -103,6 +106,26 @@ class FunctionSerializer { } } + //! Only written if the function was called with keyword-only or "**kwargs" arguments + template + static void SerializeNamedArguments(Serializer &serializer, const FUNC &function) { + auto &named_arguments = function.GetNamedArguments(); + if (named_arguments.empty()) { + return; + } + if (!serializer.ShouldSerialize(StorageVersion::V2_0_0)) { + if (named_arguments.size() > function.GetKwargsCount()) { + throw SerializationException("Function %s has keyword-only parameters, which cannot be serialized " + "to a storage version older than v2.0.0", + function.GetName()); + } + // the "**kwargs" arguments are matched to "*args" instead, or named after their alias + return; + } + serializer.WriteProperty(508, "positional_arguments", function.GetPositionalArgumentCount()); + serializer.WriteProperty(509, "named_arguments", named_arguments); + } + //! Plans written by versions whose binds erased the arguments they folded into their bind data record the //! pre-erase list separately - use that as the argument list, so that the function looks the same either way static void RestoreErasedArguments(vector &arguments, vector &original_arguments) { @@ -202,6 +225,34 @@ class FunctionSerializer { } } + //! Plans written before the argument names were serialized hold the names of the named arguments in the aliases + //! of the trailing arguments. Only the arguments behind the standard parameters can have been named. + template + static void RestoreNamesFromAliases(const FUNCTION_SET &functions, const vector> &children, + idx_t &positional_count, vector &named_arguments) { + bool takes_named = false; + idx_t standard_count = 0; + for (auto &function : functions.functions) { + auto &signature = function->GetSignature(); + if (!signature.GetKwargsParameter()) { + continue; + } + takes_named = true; + standard_count = MaxValue(standard_count, signature.GetPositionalParameterCount()); + } + if (!takes_named || children.size() != positional_count) { + return; + } + idx_t named_offset = children.size(); + while (named_offset > standard_count && !children[named_offset - 1]->GetAlias().empty()) { + named_offset--; + } + for (idx_t i = named_offset; i < children.size(); i++) { + named_arguments.push_back(children[i]->GetAlias()); + } + positional_count = named_offset; + } + template static pair> Deserialize(Deserializer &deserializer, CatalogType catalog_type, vector> &children, @@ -213,6 +264,8 @@ class FunctionSerializer { auto original_arguments = deserializer.ReadPropertyWithDefault>(502, "original_arguments"); auto qualified_name = DeserializeQualifiedName(deserializer, std::move(name)); auto has_serialize = deserializer.ReadProperty(503, "has_serialize"); + auto positional_count = deserializer.ReadPropertyWithDefault(508, "positional_arguments"); + auto named_arguments = deserializer.ReadPropertyWithDefault>(509, "named_arguments"); RestoreErasedArguments(arguments, original_arguments); @@ -233,16 +286,65 @@ class FunctionSerializer { throw InternalException("DeserializeFunction - cant find catalog entry for function %s", qualified_name.Name().GetIdentifierName()); } - auto &functions = func_catalog.Cast(); - const auto function = functions.functions.GetFunctionByArguments(context, arguments); + + auto &functions = func_catalog.Cast().functions; + + // If there are no argument names serialized, treat all arguments as positional + if (named_arguments.empty()) { + positional_count = arguments.size(); + RestoreNamesFromAliases(functions, children, positional_count, named_arguments); + } + + // Sanity check: The named arguments are the last arguments, so the number of arguments has to add up + const auto has_valid_count = positional_count + named_arguments.size() == arguments.size(); + if (!has_valid_count || (!named_arguments.empty() && children.size() != arguments.size())) { + throw SerializationException( + "Function %s has %llu argument types and %llu arguments, but %llu positional and %llu named arguments", + qualified_name.ToString(), arguments.size(), children.size(), positional_count, named_arguments.size()); + } + + // Split types by positional and keyword arguments + vector positional_types; + vector> keyword_types; + + for (idx_t arg_idx = 0; arg_idx < arguments.size(); arg_idx++) { + if (arg_idx < positional_count) { + positional_types.push_back(arguments[arg_idx]); + } else { + const auto kw_idx = arg_idx - positional_count; + keyword_types.emplace_back(named_arguments[kw_idx], arguments[arg_idx]); + } + } + + // Lookup the function (and the correct overload) + FunctionBinder binder(context); + ErrorData error; + const auto func_idx = + binder.BindFunction(qualified_name.Name(), functions, positional_types, keyword_types, error); + + // Ensure the function overload was found + if (!func_idx.IsValid()) { + throw SerializationException("Failed to find function %s(%s)\n%s", qualified_name.ToString(), + StringUtil::ToString(arguments, ","), error.RawMessage()); + } + + const auto function = functions.GetFunctionByOffset(func_idx.GetIndex()); // Does this function support serializing its bound data? if (!has_serialize) { // No, then just rebind the function try { - FunctionBinder binder(context); + // Split children into positional and keyword args expression + vector>> keyword_args; + if (!named_arguments.empty()) { + for (idx_t i = positional_count; i < children.size(); i++) { + keyword_args.emplace_back(named_arguments[i - positional_count], std::move(children[i])); + } + children.resize(positional_count); + } - auto [bound_function, bound_data] = binder.ResolveFunction(function, children); + // Resolve function + auto [bound_function, bound_data] = binder.ResolveFunction(function, children, keyword_args); if (TypeRequiresAssignment(bound_function.GetReturnType())) { bound_function.SetReturnType(std::move(return_type)); @@ -250,15 +352,17 @@ class FunctionSerializer { return make_pair(std::move(bound_function), std::move(bound_data)); } catch (std::exception &ex) { - ErrorData error(ex); + ErrorData inner_error(ex); throw SerializationException("Error during bind of function in deserialization: %s", - error.RawMessage()); + inner_error.RawMessage()); } } // Otherwise, construct the bound function from its parts FUNC bound_function(function); bound_function.GetArguments() = std::move(arguments); + + bound_function.SetNamedArguments(positional_count, std::move(named_arguments)); RestoreLogicalSignature(bound_function, children, return_type); // Invoke deserialization function diff --git a/src/duckdb/src/include/duckdb/function/scalar_function.hpp b/src/duckdb/src/include/duckdb/function/scalar_function.hpp index 52faf2319..0df23f0da 100644 --- a/src/duckdb/src/include/duckdb/function/scalar_function.hpp +++ b/src/duckdb/src/include/duckdb/function/scalar_function.hpp @@ -598,6 +598,18 @@ class BoundScalarFunction : public BaseScalarFunction, publ const shared_ptr &GetDefinition() const { return definition; } + //! The number of arguments that were received by "*args", they directly follow the standard parameters + idx_t GetVarArgsCount() const { + return BoundSimpleFunction::GetVarArgsCount(definition->GetSignature()); + } + //! The number of arguments that were received by "**kwargs", they are the last arguments + idx_t GetKwargsCount() const { + return BoundSimpleFunction::GetKwargsCount(definition->GetSignature()); + } + //! The kind of the parameter that received the argument at the given index + FunctionParameterKind GetArgumentParameterKind(idx_t argument_index) const { + return BoundSimpleFunction::GetArgumentParameterKind(definition->GetSignature(), argument_index); + } //! Restore the definition after the bound function has been replaced wholesale, together with the //! qualification it carries - the replacement is a specialized implementation, not a different function void SetDefinition(shared_ptr definition_p) { diff --git a/src/duckdb/src/include/duckdb/function/window_function.hpp b/src/duckdb/src/include/duckdb/function/window_function.hpp index 49244638d..25995ff3a 100644 --- a/src/duckdb/src/include/duckdb/function/window_function.hpp +++ b/src/duckdb/src/include/duckdb/function/window_function.hpp @@ -378,6 +378,18 @@ class BoundWindowFunction : public BaseWindowFunction, public BoundSimpleFunctio const shared_ptr &GetDefinition() const { return definition; } + //! The number of arguments that were received by "*args", they directly follow the standard parameters + idx_t GetVarArgsCount() const { + return BoundSimpleFunction::GetVarArgsCount(definition->GetSignature()); + } + //! The number of arguments that were received by "**kwargs", they are the last arguments + idx_t GetKwargsCount() const { + return BoundSimpleFunction::GetKwargsCount(definition->GetSignature()); + } + //! The kind of the parameter that received the argument at the given index + FunctionParameterKind GetArgumentParameterKind(idx_t argument_index) const { + return BoundSimpleFunction::GetArgumentParameterKind(definition->GetSignature(), argument_index); + } const vector &GetLogicalArguments() const { return logical_arguments; } diff --git a/src/duckdb/src/main/capi/v1/scalar_function-c.cpp b/src/duckdb/src/main/capi/v1/scalar_function-c.cpp index d272d9346..600a62261 100644 --- a/src/duckdb/src/main/capi/v1/scalar_function-c.cpp +++ b/src/duckdb/src/main/capi/v1/scalar_function-c.cpp @@ -276,7 +276,12 @@ void duckdb_scalar_function_add_parameter(duckdb_scalar_function function, duckd } auto &scalar_function = GetCScalarFunction(function); auto logical_type = reinterpret_cast(type); - scalar_function.GetSignature().AddParameter(*logical_type); + // the varargs can be set before the parameters, but they come after them in the signature + auto &signature = scalar_function.GetSignature(); + auto varargs = signature.GetVarArgs(); + signature.SetVarArgs(duckdb::LogicalType(duckdb::LogicalTypeId::INVALID)); + signature.AddParameter(*logical_type); + signature.SetVarArgs(std::move(varargs)); } void duckdb_scalar_function_set_return_type(duckdb_scalar_function function, duckdb_logical_type type) { diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp index 7f6fd71a3..9a241a193 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp @@ -12,11 +12,15 @@ DUCKDB_V2_ERROR duckdb_v2_function_signature_add_parameter(duckdb_v2_function_si return WithErrorHandler(err, [&]() { auto &signature = *Convert(sig); + // the varargs can be set before the parameters, but they come after them in the signature + auto varargs = signature.GetVarArgs(); + signature.SetVarArgs(duckdb::LogicalType(duckdb::LogicalTypeId::INVALID)); if (value) { signature.AddParameter(duckdb::Identifier(Convert(name)), *Convert(type), *Convert(value)); } else { signature.AddParameter(duckdb::Identifier(Convert(name)), *Convert(type)); } + signature.SetVarArgs(std::move(varargs)); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp index 596a0119e..51b59c0e8 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp @@ -663,7 +663,7 @@ class CV2TableFunction { vector positional; for (idx_t i = 0; i < signature.GetParameterCount(); i++) { const auto ¶m = signature.GetParameter(i); - if (!param.HasDefaultValue()) { + if (!param.IsVariadic() && !param.HasDefaultValue()) { positional.push_back(param.GetType()); } } @@ -694,6 +694,9 @@ class CV2TableFunction { auto function_info = make_shared_ptr(std::move(info)); for (idx_t i = 0; i < signature.GetParameterCount(); i++) { const auto ¶m = signature.GetParameter(i); + if (param.IsVariadic()) { + continue; + } if (param.HasDefaultValue()) { function.named_parameters[param.GetName()] = param.GetType(); function_info->named_parameter_defaults[param.GetName()] = *param.GetDefaultValue(); diff --git a/src/duckdb/src/parser/parsed_data/create_aggregate_function_info.cpp b/src/duckdb/src/parser/parsed_data/create_aggregate_function_info.cpp index b00a7e4ee..9d6ebf245 100644 --- a/src/duckdb/src/parser/parsed_data/create_aggregate_function_info.cpp +++ b/src/duckdb/src/parser/parsed_data/create_aggregate_function_info.cpp @@ -5,6 +5,7 @@ namespace duckdb { CreateAggregateFunctionInfo::CreateAggregateFunctionInfo(AggregateFunction function) : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION_ENTRY), functions(function.name) { SetFunctionName(function.name); + function.GetSignature().Verify(); functions.AddFunction(std::move(function)); internal = true; } @@ -12,6 +13,9 @@ CreateAggregateFunctionInfo::CreateAggregateFunctionInfo(AggregateFunction funct CreateAggregateFunctionInfo::CreateAggregateFunctionInfo(AggregateFunctionSet set) : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION_ENTRY), functions(std::move(set)) { SetFunctionName(functions.name); + for (auto &func : functions.functions) { + func->GetSignature().Verify(); + } functions.ApplyToFunctions([&](AggregateFunction &func) { func.name = functions.name; }); internal = true; } diff --git a/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp b/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp index 7df28cbd1..76b2c1ec1 100644 --- a/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +++ b/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp @@ -6,12 +6,16 @@ namespace duckdb { CreateScalarFunctionInfo::CreateScalarFunctionInfo(ScalarFunction function) : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION_ENTRY), functions(function.name) { SetFunctionName(function.name); + function.GetSignature().Verify(); functions.AddFunction(std::move(function)); internal = true; } CreateScalarFunctionInfo::CreateScalarFunctionInfo(ScalarFunctionSet set) : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION_ENTRY), functions(std::move(set)) { SetFunctionName(functions.name); + for (auto &func : functions.functions) { + func->GetSignature().Verify(); + } functions.ApplyToFunctions([&](ScalarFunction &func) { func.name = functions.name; }); internal = true; } diff --git a/src/duckdb/src/parser/parsed_data/create_window_function_info.cpp b/src/duckdb/src/parser/parsed_data/create_window_function_info.cpp index 545848358..0801d76b9 100644 --- a/src/duckdb/src/parser/parsed_data/create_window_function_info.cpp +++ b/src/duckdb/src/parser/parsed_data/create_window_function_info.cpp @@ -5,6 +5,7 @@ namespace duckdb { CreateWindowFunctionInfo::CreateWindowFunctionInfo(WindowFunction function) : CreateFunctionInfo(CatalogType::WINDOW_FUNCTION_ENTRY), functions(function.name) { SetFunctionName(function.name); + function.GetSignature().Verify(); functions.AddFunction(std::move(function)); internal = true; } @@ -12,6 +13,9 @@ CreateWindowFunctionInfo::CreateWindowFunctionInfo(WindowFunction function) CreateWindowFunctionInfo::CreateWindowFunctionInfo(WindowFunctionSet set) : CreateFunctionInfo(CatalogType::WINDOW_FUNCTION_ENTRY), functions(std::move(set)) { SetFunctionName(functions.name); + for (auto &func : functions.functions) { + func->GetSignature().Verify(); + } functions.ApplyToFunctions([&](WindowFunction &func) { func.name = functions.name; }); internal = true; } diff --git a/src/duckdb/src/planner/column_qualifier.cpp b/src/duckdb/src/planner/column_qualifier.cpp index c2359e1ca..a735129c1 100644 --- a/src/duckdb/src/planner/column_qualifier.cpp +++ b/src/duckdb/src/planner/column_qualifier.cpp @@ -225,7 +225,7 @@ void ColumnQualifier::QualifyColumnNames(unique_ptr &expr, vec } case ExpressionType::POSITIONAL_REFERENCE: { auto &ref = expr->Cast(); - if (ref.GetAlias().empty()) { + if (ref.GetAlias().empty() && !within_function_expression) { Identifier table_name, column_name; auto error = binder.bind_context.BindColumn(ref, table_name, column_name); if (error.empty()) { From 6be214880a463a1f71144d24006dd1c11212b119 Mon Sep 17 00:00:00 2001 From: DuckLabs GitHub Bot Date: Thu, 24 Sep 2026 14:33:44 +0000 Subject: [PATCH 3/6] Update vendored DuckDB sources to 233847abfa --- CMakeLists.txt | 2 + .../aggregate/holistic/approx_top_k.cpp | 4 +- .../icu/datetime/generated/tz_data.cpp | 3731 ++++++++--------- src/duckdb/extension/icu/icu-table-range.cpp | 53 +- .../extension/json/include/json_reader.hpp | 4 + .../json/json_functions/json_table_in_out.cpp | 50 +- src/duckdb/extension/json/json_reader.cpp | 28 +- .../loader/dummy_static_extension_loader.cpp | 20 - .../loader/static_extension_autoregister.cpp | 16 + ...nerated_extension_loader_package_build.cpp | 187 +- src/duckdb/src/catalog/catalog.cpp | 1 - .../src/common/compressed_file_system.cpp | 12 +- src/duckdb/src/common/sort/full_sort.cpp | 23 +- src/duckdb/src/common/sort/hashed_sort.cpp | 23 +- src/duckdb/src/common/sort/natural_sort.cpp | 8 +- src/duckdb/src/common/sort/sort.cpp | 40 +- .../src/common/sort/sorted_run_merger.cpp | 20 +- .../src/execution/aggregate_hashtable.cpp | 8 +- src/duckdb/src/execution/join_hashtable.cpp | 1 + .../physical_perfecthash_aggregate.cpp | 2 +- .../operator/aggregate/physical_window.cpp | 10 +- .../buffer_manager/csv_file_handle.cpp | 2 +- .../table_function/csv_file_scanner.cpp | 33 +- .../operator/helper/physical_limit.cpp | 22 + .../helper/physical_limit_percent.cpp | 29 +- .../helper/physical_reservoir_sample.cpp | 22 +- .../operator/join/outer_join_marker.cpp | 2 +- .../operator/join/physical_asof_join.cpp | 27 +- .../operator/join/physical_hash_join.cpp | 17 +- .../operator/join/physical_iejoin.cpp | 37 +- .../join/physical_piecewise_merge_join.cpp | 2 +- .../operator/order/physical_top_n.cpp | 2 +- .../persistent/physical_copy_to_file.cpp | 32 +- .../operator/persistent/physical_delete.cpp | 15 +- .../persistent/physical_merge_into.cpp | 4 +- .../operator/persistent/physical_update.cpp | 15 +- .../operator/scan/physical_table_scan.cpp | 4 +- .../execution/operator/set/physical_cte.cpp | 11 +- .../operator/set/physical_recursive_cte.cpp | 105 +- .../execution/radix_partitioned_hashtable.cpp | 62 +- .../src/function/cast/variant/to_variant.cpp | 14 +- .../src/function/scalar/string/like.cpp | 68 +- src/duckdb/src/function/table/glob.cpp | 30 +- src/duckdb/src/function/table/range.cpp | 106 +- .../function/table/system/duckdb_columns.cpp | 18 +- .../table/system/duckdb_extensions.cpp | 15 +- .../system/duckdb_external_file_cache.cpp | 20 +- .../table/system/duckdb_functions.cpp | 19 +- .../src/function/table/system/duckdb_log.cpp | 23 + .../table/system/pragma_storage_info.cpp | 25 + .../table/system/test_vector_types.cpp | 15 +- src/duckdb/src/function/table/table_scan.cpp | 80 +- .../function/table/version/pragma_version.cpp | 6 +- .../duckdb/common/compressed_file_system.hpp | 6 +- .../include/duckdb/common/sorting/sort.hpp | 6 + .../common/sorting/sorted_run_merger.hpp | 2 + .../duckdb/execution/aggregate_hashtable.hpp | 3 +- .../duckdb/execution/join_hashtable.hpp | 4 +- .../operator/csv_scanner/csv_file_handle.hpp | 7 +- .../operator/csv_scanner/csv_file_scanner.hpp | 3 + .../operator/helper/physical_limit.hpp | 1 + .../operator/persistent/physical_delete.hpp | 1 + .../operator/persistent/physical_update.hpp | 1 + .../operator/set/physical_recursive_cte.hpp | 3 + .../set/physical_recursive_cte_state.hpp | 41 +- .../duckdb/execution/progress_data.hpp | 87 + .../function/cast/variant/json_to_variant.hpp | 33 +- .../function/cast/variant/to_variant_fwd.hpp | 7 +- .../function/function_serialization.hpp | 2 +- .../include/duckdb/logging/log_storage.hpp | 3 + .../duckdb/main/capi_v2/capi_v2_internal.hpp | 6 +- .../duckdb/main/capi_v2/extension_api_v2.hpp | 8 +- src/duckdb/src/include/duckdb/main/config.hpp | 5 +- .../src/include/duckdb/main/database.hpp | 48 +- .../extension/generated_extension_loader.hpp | 25 - .../extension/linked_extension_registry.hpp | 45 + .../include/duckdb/main/extension_entries.hpp | 4 +- .../include/duckdb/main/extension_helper.hpp | 5 +- .../include/duckdb/main/query_profiler.hpp | 8 + .../src/include/duckdb/main/settings.hpp | 8 +- .../duckdb/parser/peg/inlined_grammar.hpp | 2450 +++++------ .../peg/transformer/peg_transformer.hpp | 30 +- .../src/include/duckdb/planner/binder.hpp | 4 +- .../storage/table/row_group_reorderer.hpp | 2 + .../duckdb/storage/table/scan_state.hpp | 2 + src/duckdb/src/include/duckdb_extension_v2.h | 8 +- .../src/include/duckdb_static_extension.h | 79 + src/duckdb/src/include/duckdb_v2.h | 29 +- src/duckdb/src/logging/log_storage.cpp | 8 + src/duckdb/src/main/capi/v2/capi_v2_arrow.cpp | 2 +- .../src/main/capi/v2/capi_v2_connection.cpp | 6 +- .../src/main/capi/v2/capi_v2_custom_type.cpp | 2 +- .../main/capi/v2/capi_v2_func_aggregate.cpp | 2 +- .../src/main/capi/v2/capi_v2_func_copy.cpp | 2 +- .../src/main/capi/v2/capi_v2_func_scalar.cpp | 2 +- .../main/capi/v2/capi_v2_func_signature.cpp | 5 +- .../src/main/capi/v2/capi_v2_func_table.cpp | 4 +- .../src/main/capi/v2/capi_v2_identifier.cpp | 2 +- .../src/main/capi/v2/capi_v2_instance.cpp | 8 +- .../src/main/capi/v2/capi_v2_logical_type.cpp | 4 +- .../src/main/capi/v2/capi_v2_option.cpp | 2 +- src/duckdb/src/main/capi/v2/capi_v2_qname.cpp | 7 +- .../main/capi/v2/capi_v2_replacement_scan.cpp | 7 +- src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp | 12 + src/duckdb/src/main/capi/v2/capi_v2_value.cpp | 2 +- .../src/main/extension/extension_helper.cpp | 152 +- .../src/main/extension/extension_load.cpp | 38 +- .../extension/linked_extension_registry.cpp | 132 + .../rule/arithmetic_simplification.cpp | 20 +- .../rule/comparison_simplification.cpp | 40 +- .../parallel/pipeline_broadcast_exchange.cpp | 25 +- src/duckdb/src/parser/peg/matcher_factory.cpp | 22 +- .../peg/transformer/transform_expression.cpp | 53 +- .../transform_generated_trampoline.cpp | 118 +- .../peg/transformer/transform_select.cpp | 12 + .../binder/tableref/bind_named_parameters.cpp | 2 +- .../src/planner/operator/logical_get.cpp | 2 +- .../storage/table/row_group_collection.cpp | 11 + .../src/storage/table/row_group_reorderer.cpp | 9 + src/duckdb/src/storage/table/scan_state.cpp | 2 +- .../transaction/duck_transaction_manager.cpp | 16 +- 121 files changed, 5095 insertions(+), 3737 deletions(-) delete mode 100644 src/duckdb/extension/loader/dummy_static_extension_loader.cpp create mode 100644 src/duckdb/extension/loader/static_extension_autoregister.cpp delete mode 100644 src/duckdb/src/include/duckdb/main/extension/generated_extension_loader.hpp create mode 100644 src/duckdb/src/include/duckdb/main/extension/linked_extension_registry.hpp create mode 100644 src/duckdb/src/include/duckdb_static_extension.h create mode 100644 src/duckdb/src/main/extension/linked_extension_registry.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ca5e677c1..13d50919e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,6 +142,7 @@ set(DUCKDB_SRC_FILES src/duckdb/extension/json/json_scan.cpp src/duckdb/extension/json/json_serializer.cpp src/duckdb/extension/json/serialize_json.cpp + src/duckdb/extension/loader/static_extension_autoregister.cpp src/duckdb/extension/parquet/column_reader.cpp src/duckdb/extension/parquet/column_writer.cpp src/duckdb/extension/parquet/parquet_column_schema.cpp @@ -226,6 +227,7 @@ set(DUCKDB_SRC_FILES src/duckdb/src/main/extension/extension_load.cpp src/duckdb/src/main/extension/extension_loader.cpp src/duckdb/src/main/extension/extension_repository_manager.cpp + src/duckdb/src/main/extension/linked_extension_registry.cpp src/duckdb/src/optimizer/matcher/expression_matcher.cpp src/duckdb/third_party/brotli/common/constants.cpp src/duckdb/third_party/brotli/common/context.cpp diff --git a/src/duckdb/extension/core_functions/aggregate/holistic/approx_top_k.cpp b/src/duckdb/extension/core_functions/aggregate/holistic/approx_top_k.cpp index 3eb96ad80..990124038 100644 --- a/src/duckdb/extension/core_functions/aggregate/holistic/approx_top_k.cpp +++ b/src/duckdb/extension/core_functions/aggregate/holistic/approx_top_k.cpp @@ -49,7 +49,7 @@ struct ApproxTopKValue { //! Allocated data char *dataptr = nullptr; uint32_t size = 0; - uint32_t capacity = 0; + idx_t capacity = 0; }; struct InternalApproxTopKState { @@ -94,7 +94,7 @@ struct InternalApproxTopKState { value.size = UnsafeNumericCast(input.str.GetSize()); if (value.size > value.capacity) { // need to re-allocate for this value - value.capacity = UnsafeNumericCast(NextPowerOfTwo(value.size)); + value.capacity = NextPowerOfTwo(value.size); value.dataptr = char_ptr_cast(allocator.Allocate(value.capacity)); } // copy over the data diff --git a/src/duckdb/extension/icu/datetime/generated/tz_data.cpp b/src/duckdb/extension/icu/datetime/generated/tz_data.cpp index fb36e4a57..4c4d232f9 100644 --- a/src/duckdb/extension/icu/datetime/generated/tz_data.cpp +++ b/src/duckdb/extension/icu/datetime/generated/tz_data.cpp @@ -4,7 +4,7 @@ // tz_data.cpp // // This file is generated by scripts/generate_tz_data.py - do not edit. -// Source: Unicode Consortium time zone dataset (IANA release 2026c) +// Source: Unicode Consortium time zone dataset (IANA release 2026d) //===----------------------------------------------------------------------===// #include "tz_data.hpp" @@ -19,1873 +19,1872 @@ namespace datetime { // zone on its own, because the block is kept once it has been decompressed. const uint8_t TZ_COMPRESSED[] = { - 0x28, 0xB5, 0x2F, 0xFD, 0xA4, 0x39, 0x23, 0x03, 0x00, 0x8C, 0x26, 0x03, 0xAE, 0x54, 0xC4, 0x09, 0x11, 0x29, 0x10, 0x38, 0x7C, 0x31, 0xFF, 0xDA, - 0x6A, 0x32, 0xFE, 0x0B, 0x93, 0xDA, 0x5F, 0x09, 0x3F, 0x85, 0x72, 0xAC, 0x0F, 0x10, 0x62, 0xF1, 0x22, 0x18, 0x87, 0x6E, 0xF6, 0x41, 0xB9, 0x72, - 0x52, 0xE9, 0xAD, 0x49, 0xF3, 0xA9, 0x8F, 0xD6, 0x5E, 0xB9, 0x53, 0xD2, 0x10, 0x1D, 0x11, 0xEA, 0x10, 0x8F, 0xB9, 0x9A, 0xBD, 0xBE, 0x99, 0xA2, - 0x9F, 0x99, 0x1A, 0x19, 0x97, 0xBE, 0xFA, 0x4B, 0x97, 0x5F, 0xCB, 0x0D, 0xE9, 0x15, 0x4D, 0x1A, 0x95, 0x39, 0x2F, 0x94, 0x69, 0x35, 0x93, 0x57, - 0x4B, 0x92, 0x77, 0x51, 0x91, 0x71, 0x66, 0x90, 0x83, 0x6B, 0x77, 0x3C, 0xA6, 0x47, 0xC9, 0x29, 0x15, 0x84, 0x67, 0x8E, 0xAE, 0x6C, 0x8D, 0x9C, - 0x0F, 0x52, 0xC0, 0xA0, 0x80, 0x22, 0xF7, 0x03, 0x8A, 0x93, 0x12, 0x8B, 0xD2, 0x92, 0x8B, 0x44, 0x99, 0x8A, 0x28, 0x21, 0x12, 0xC5, 0x68, 0x4F, - 0xB4, 0xD1, 0x22, 0x56, 0xB5, 0x1E, 0x5E, 0x58, 0x36, 0x71, 0x5A, 0xF7, 0x49, 0xD8, 0xCE, 0xF5, 0x46, 0xE8, 0x98, 0xCD, 0xF3, 0x44, 0x1F, 0x3A, - 0x5B, 0xDA, 0xFE, 0xF8, 0xD7, 0xAA, 0xFB, 0xBF, 0xE4, 0x1E, 0x4F, 0xAA, 0x69, 0xBC, 0xE5, 0xF4, 0xB4, 0x27, 0x3C, 0xC0, 0x0D, 0xA3, 0x00, 0xC0, - 0xB9, 0xB2, 0x88, 0x61, 0x2C, 0x0F, 0x31, 0x3E, 0x4D, 0x72, 0x7B, 0x2D, 0xF0, 0xFF, 0x7F, 0x06, 0x7B, 0xAD, 0x62, 0x31, 0x15, 0xF7, 0x5F, 0x69, - 0xF1, 0x2E, 0x67, 0xCD, 0xBE, 0x65, 0x65, 0xA0, 0x5C, 0x31, 0x5F, 0xB8, 0xB2, 0x21, 0xB2, 0x22, 0x81, 0xAB, 0xA2, 0x02, 0xA3, 0x0A, 0xCA, 0x9B, - 0x72, 0x9B, 0x93, 0xFA, 0x32, 0x11, 0x95, 0xC7, 0x01, 0x3E, 0x87, 0x87, 0x12, 0x9C, 0x3F, 0xF9, 0xE5, 0x3A, 0x65, 0x76, 0x68, 0x7A, 0x84, 0x66, - 0xAA, 0xFC, 0xDC, 0xC7, 0xC8, 0xA0, 0x03, 0xEF, 0x39, 0x5E, 0xFE, 0x10, 0xEA, 0x1C, 0xF4, 0xCB, 0x8D, 0x72, 0x7A, 0xF6, 0x61, 0xC2, 0xF3, 0x2B, - 0xB3, 0xCF, 0xA0, 0x63, 0x1E, 0xE7, 0xE0, 0xAF, 0x3C, 0x40, 0xCD, 0x6B, 0xF0, 0xFD, 0x95, 0xB5, 0xF2, 0x9E, 0x8F, 0x8A, 0x5A, 0x40, 0xF5, 0x9D, - 0xAB, 0x00, 0x2D, 0xC3, 0xF0, 0xD9, 0x2E, 0xAE, 0x19, 0xE3, 0x87, 0xD9, 0xFA, 0xB9, 0x54, 0xE7, 0x5D, 0xC3, 0x32, 0x16, 0x6C, 0x35, 0x36, 0x85, - 0x24, 0xF6, 0x77, 0xC2, 0xDA, 0xC8, 0xC0, 0xDC, 0x57, 0xF1, 0x0B, 0x0C, 0xBE, 0xB2, 0xEC, 0x5E, 0x24, 0xCA, 0xE4, 0x17, 0xEE, 0x98, 0x75, 0x5B, - 0x74, 0xC3, 0x10, 0x18, 0x56, 0x1C, 0x5E, 0x95, 0x04, 0x56, 0xE9, 0x9F, 0xBB, 0xD8, 0xF0, 0xCB, 0x2D, 0xDE, 0x2A, 0xD1, 0xEF, 0xBD, 0x0D, 0x38, - 0x90, 0x1E, 0x0A, 0x30, 0xC4, 0x4B, 0xFA, 0x0E, 0x5A, 0x08, 0x9F, 0x7B, 0xB9, 0x97, 0x8A, 0xE0, 0xFD, 0x96, 0x8E, 0x56, 0x1D, 0x1C, 0xB9, 0x7F, - 0x92, 0x08, 0x10, 0x6D, 0xD8, 0xC1, 0x08, 0x78, 0xD3, 0xF7, 0x82, 0xAC, 0x26, 0x81, 0xEC, 0x27, 0x7E, 0xE0, 0x5A, 0x7D, 0xF0, 0x2C, 0xE0, 0x07, - 0xE0, 0x77, 0x61, 0x97, 0x9D, 0xC0, 0x11, 0x9B, 0xC7, 0x39, 0x33, 0x30, 0x37, 0xAF, 0xB0, 0x37, 0x49, 0xBF, 0x66, 0x17, 0xAF, 0xC6, 0x2C, 0x26, - 0x42, 0x91, 0x00, 0xB6, 0x46, 0x46, 0x46, 0x70, 0xFC, 0xD9, 0x74, 0xEF, 0x2B, 0xFD, 0x3F, 0x7E, 0x67, 0xBD, 0xC3, 0x8D, 0x6B, 0x88, 0x9C, 0xC1, - 0xF5, 0x47, 0xDA, 0x7E, 0xD3, 0xD3, 0x1E, 0x48, 0x7E, 0xEE, 0xAA, 0x60, 0x84, 0xDA, 0x66, 0x2E, 0x89, 0x16, 0xBF, 0x3D, 0x14, 0x05, 0xE1, 0xC5, - 0x01, 0x49, 0x86, 0xFD, 0x10, 0x62, 0xF0, 0x71, 0x9D, 0xF7, 0x70, 0x1E, 0xF2, 0x08, 0x8F, 0xED, 0xE4, 0x7A, 0xEE, 0x7C, 0xD0, 0xE5, 0x48, 0xB7, - 0xC8, 0xE1, 0xA9, 0xE3, 0xA0, 0xB0, 0xB8, 0xD1, 0x52, 0x61, 0x63, 0xA4, 0x5B, 0x63, 0x00, 0x95, 0x86, 0x6C, 0x7A, 0xA6, 0xC2, 0xA3, 0xDB, 0x01, - 0x8C, 0x8C, 0x61, 0x6A, 0x0C, 0xA4, 0x30, 0x8C, 0xE7, 0x8B, 0x97, 0xD6, 0x0E, 0x97, 0x5D, 0x8F, 0x16, 0x64, 0x9C, 0x96, 0x75, 0x0E, 0x8B, 0xC7, - 0xC7, 0x0A, 0x4D, 0x95, 0xCA, 0x8E, 0x4E, 0x8A, 0xD2, 0x0E, 0x4A, 0x96, 0x15, 0x80, 0xB3, 0xAB, 0x13, 0x39, 0x37, 0x13, 0x08, 0x6F, 0x25, 0x7C, - 0x16, 0xDA, 0x23, 0x2E, 0x90, 0x30, 0xDA, 0x47, 0x2E, 0x0D, 0x45, 0xF0, 0x17, 0x42, 0x68, 0x3B, 0x3F, 0x88, 0xDE, 0xF0, 0x63, 0x6F, 0xC2, 0xC3, - 0x11, 0xD2, 0xA3, 0x8D, 0xE7, 0x88, 0x94, 0xE1, 0x78, 0xE7, 0x6E, 0xC0, 0x9F, 0x35, 0xE2, 0xD0, 0x19, 0x6C, 0x2C, 0x75, 0xF6, 0x82, 0x16, 0xFA, - 0xFA, 0x81, 0x7A, 0x4F, 0xFA, 0x8B, 0x70, 0x99, 0x5E, 0x7C, 0x91, 0xB6, 0x54, 0x8A, 0x26, 0x5D, 0x82, 0x9E, 0x0D, 0xF0, 0x0C, 0x6C, 0xE6, 0xCC, - 0xDC, 0xA0, 0xDD, 0xCA, 0xB6, 0xF2, 0x4F, 0xF9, 0x42, 0x16, 0xAD, 0xB8, 0xDC, 0x86, 0x24, 0x96, 0xED, 0x7A, 0x3C, 0x85, 0x99, 0x28, 0x75, 0xC2, - 0x44, 0x2C, 0x7B, 0x46, 0x0B, 0xBE, 0x44, 0xFD, 0xA3, 0x5D, 0xDE, 0xA7, 0x31, 0xEB, 0x3D, 0x75, 0x7C, 0x3C, 0x6C, 0x06, 0x71, 0x11, 0x66, 0x64, - 0xF3, 0x51, 0x77, 0x30, 0x4C, 0x8B, 0x63, 0xB8, 0xA5, 0x87, 0x77, 0xEC, 0xFD, 0x3F, 0x80, 0x7F, 0xDC, 0xFB, 0x9F, 0xC2, 0x7F, 0x17, 0xF7, 0x3F, - 0x08, 0xBD, 0x61, 0xC3, 0xF3, 0x30, 0x00, 0x67, 0xC6, 0x0D, 0xE7, 0x0F, 0xFD, 0x12, 0xDC, 0x47, 0x19, 0x4F, 0x27, 0x42, 0x04, 0x3F, 0x16, 0xF5, - 0xC6, 0x5D, 0x84, 0x0B, 0x0E, 0xBF, 0x9F, 0x6B, 0xE0, 0x97, 0x71, 0x6F, 0x16, 0x63, 0xFC, 0x70, 0x07, 0x3C, 0x49, 0x13, 0x9E, 0x6B, 0xE1, 0x7D, - 0x2C, 0x05, 0x8F, 0xF6, 0xBA, 0x93, 0x04, 0xD8, 0x53, 0xD0, 0xCF, 0x7C, 0x8E, 0x0E, 0xC7, 0x95, 0x14, 0x48, 0x2B, 0x6C, 0x0B, 0xE4, 0x1C, 0x97, - 0x79, 0x0E, 0x02, 0xB6, 0xD0, 0x74, 0x26, 0x9E, 0x51, 0xFB, 0x9C, 0x01, 0xF1, 0xCD, 0xBC, 0x73, 0xCC, 0x91, 0xB9, 0xCC, 0x6C, 0x0E, 0xCA, 0xAD, - 0xD0, 0xCA, 0x35, 0x29, 0x92, 0x83, 0x5B, 0x24, 0x4F, 0x95, 0xC2, 0xF0, 0x88, 0x46, 0x6E, 0xFB, 0x3D, 0xE6, 0x71, 0xD9, 0xE7, 0x69, 0x18, 0x6B, - 0x29, 0x15, 0x93, 0x08, 0x26, 0x36, 0x10, 0x60, 0x38, 0x93, 0xE3, 0x85, 0x86, 0x06, 0xC2, 0xB6, 0x37, 0xC1, 0x86, 0x67, 0xC0, 0xCF, 0x53, 0xBF, - 0x9E, 0x0F, 0x7E, 0x5D, 0xD8, 0x5C, 0xE8, 0x7E, 0x70, 0x31, 0x44, 0xD5, 0xAB, 0x96, 0xE4, 0x0D, 0x23, 0xB0, 0x3B, 0xC3, 0xAA, 0x4B, 0x47, 0xD7, - 0x47, 0x19, 0xB7, 0x00, 0x24, 0xCC, 0x35, 0x6B, 0xC5, 0x8D, 0xD4, 0xBC, 0xB5, 0xDB, 0xDB, 0xB6, 0xD6, 0xD6, 0x8E, 0x18, 0xA1, 0x0D, 0xE6, 0x9C, - 0xBD, 0xF4, 0x99, 0xF5, 0xB8, 0x8D, 0xA5, 0xD5, 0x8A, 0xDD, 0x71, 0x6E, 0x15, 0x5D, 0x10, 0x47, 0x85, 0xD3, 0x9C, 0xD6, 0x41, 0x4D, 0x75, 0x19, - 0x94, 0x2A, 0x2A, 0x96, 0xAA, 0xFF, 0x46, 0x47, 0x43, 0x47, 0x67, 0x1E, 0x43, 0x7F, 0x79, 0x43, 0x93, 0x3C, 0x80, 0x76, 0xA8, 0x59, 0x98, 0x41, - 0x7E, 0xEA, 0xC8, 0x78, 0xDA, 0xAD, 0xE2, 0xA1, 0xD8, 0x9D, 0x22, 0x88, 0x39, 0xD7, 0x66, 0x36, 0x2F, 0x41, 0x34, 0x29, 0x40, 0x65, 0xD2, 0xEE, - 0x60, 0x16, 0x0E, 0xB8, 0xDC, 0x87, 0x58, 0x76, 0x4A, 0xB0, 0x6C, 0xF3, 0x54, 0xB6, 0x18, 0x51, 0xF9, 0xC6, 0x9A, 0x54, 0xBE, 0x9B, 0x8C, 0xC3, - 0x49, 0xA6, 0x90, 0x88, 0x9C, 0xE7, 0x41, 0x1E, 0x59, 0xDE, 0xF7, 0x0A, 0x3C, 0x96, 0xC5, 0xAA, 0x50, 0xD4, 0x73, 0x74, 0x90, 0xDC, 0x38, 0x8A, - 0x98, 0x22, 0x84, 0x09, 0x8A, 0xDF, 0x4F, 0x46, 0x47, 0x65, 0x46, 0x0E, 0xBD, 0xA2, 0x2A, 0x00, 0xC5, 0x1C, 0x69, 0x79, 0xF1, 0xD0, 0x89, 0x27, - 0x5D, 0xC4, 0x91, 0xF8, 0xA1, 0xDA, 0xB4, 0x1E, 0x48, 0x81, 0x99, 0x21, 0x05, 0x18, 0x7B, 0x15, 0xD8, 0x6C, 0x61, 0x21, 0x93, 0xDE, 0x83, 0x1A, - 0xED, 0x9D, 0xED, 0xFF, 0xDF, 0x57, 0x57, 0x07, 0xF3, 0x47, 0xDA, 0x9F, 0xA3, 0x83, 0xD4, 0x05, 0xC0, 0xFB, 0x29, 0x7E, 0xB2, 0x36, 0x2D, 0x37, - 0x19, 0x8B, 0x97, 0x38, 0xD8, 0x6D, 0xD7, 0x29, 0x20, 0x09, 0xF1, 0xF5, 0x81, 0x7D, 0x23, 0x1F, 0x39, 0xFF, 0x66, 0x40, 0xBE, 0x2A, 0x98, 0xA8, - 0x7A, 0xD7, 0x95, 0x1A, 0x4B, 0x83, 0x1A, 0x68, 0x41, 0xCF, 0x7B, 0x9A, 0x07, 0x84, 0x33, 0xBE, 0x91, 0xFC, 0xFF, 0xD9, 0x19, 0xEC, 0x14, 0xF6, - 0xE9, 0xE9, 0x12, 0x6D, 0x6A, 0x6E, 0x02, 0x59, 0x63, 0x6C, 0x78, 0x4F, 0x72, 0x39, 0xBA, 0xB5, 0x0F, 0x34, 0x6A, 0x7C, 0xF5, 0x01, 0x94, 0xF0, - 0x34, 0x46, 0x15, 0x5F, 0x00, 0xAC, 0x1A, 0x1A, 0xFE, 0xEF, 0x2C, 0xC6, 0x9D, 0x99, 0xFE, 0xD1, 0x0C, 0x85, 0xC4, 0x3C, 0xC0, 0x4F, 0x2D, 0xF3, - 0x99, 0x40, 0xE6, 0x7E, 0x31, 0xC6, 0x25, 0x28, 0x16, 0xE5, 0x11, 0x86, 0xE0, 0x12, 0x8C, 0x2D, 0x27, 0xDE, 0x27, 0xFB, 0x65, 0x07, 0xE2, 0xD5, - 0x18, 0xA3, 0x4B, 0xC4, 0x0E, 0x57, 0xEA, 0xC9, 0x7E, 0xCB, 0x92, 0x4C, 0xAB, 0x57, 0x23, 0x6B, 0x96, 0x41, 0x56, 0x46, 0xCD, 0x15, 0xF3, 0x5F, - 0xFB, 0xCA, 0x26, 0xCA, 0x8A, 0xA4, 0xAE, 0x8A, 0x6A, 0x8D, 0x2A, 0x08, 0x70, 0xCA, 0x6D, 0x82, 0xD4, 0xD7, 0x3D, 0x2A, 0x4F, 0x10, 0x3E, 0xA7, - 0x0A, 0x25, 0x48, 0xE1, 0xFB, 0x0D, 0xD7, 0x33, 0x4B, 0xFC, 0xFB, 0x47, 0xBD, 0x92, 0xF5, 0xC7, 0x30, 0xA9, 0x3F, 0xD3, 0x26, 0xFD, 0x86, 0x24, - 0xB9, 0x2C, 0x7F, 0x24, 0x0E, 0x9E, 0xA3, 0xA1, 0x5A, 0xA3, 0x1C, 0xAC, 0x76, 0x18, 0x33, 0xFD, 0x0A, 0xAE, 0xCD, 0x20, 0x85, 0x1E, 0x97, 0xD7, - 0x3E, 0x15, 0x5E, 0x60, 0x19, 0xAD, 0xB7, 0xB7, 0x0C, 0x39, 0x5A, 0x11, 0xE5, 0x54, 0x09, 0x57, 0x26, 0x7F, 0x3C, 0xEE, 0x39, 0x51, 0x09, 0x3C, - 0xD7, 0xF8, 0xDF, 0xB6, 0xF7, 0x2B, 0x0B, 0xD0, 0x8B, 0x04, 0xD6, 0x3D, 0xC8, 0x2A, 0x11, 0xC8, 0x1E, 0xE2, 0x07, 0x0E, 0xD4, 0x07, 0x4F, 0xF9, - 0x3E, 0x30, 0x64, 0x17, 0x16, 0xB9, 0x07, 0x6E, 0xD8, 0xE4, 0xCD, 0x99, 0x21, 0x39, 0xF0, 0xE2, 0xF4, 0xD9, 0xA5, 0xFB, 0x38, 0x91, 0xDA, 0xB8, - 0x35, 0xC8, 0xDB, 0x74, 0x88, 0xB7, 0x95, 0x62, 0x37, 0x19, 0xCA, 0x36, 0xA5, 0x10, 0x02, 0x50, 0xAE, 0x6C, 0x67, 0x3C, 0xF2, 0xB5, 0xE3, 0x35, - 0x08, 0x58, 0x6A, 0x0E, 0x5E, 0x07, 0x8C, 0x80, 0x4B, 0x03, 0x81, 0x2C, 0xE0, 0x32, 0x0F, 0x6D, 0x45, 0xFB, 0x2C, 0x5F, 0xC0, 0x4C, 0x16, 0x28, - 0xC0, 0x5E, 0xAF, 0x6C, 0x99, 0xAB, 0xAC, 0x8D, 0x48, 0x36, 0xF2, 0x1E, 0x7B, 0x7F, 0x8A, 0x01, 0x79, 0x85, 0xC5, 0xF5, 0x60, 0x5E, 0x08, 0xE2, - 0x73, 0xE9, 0x2F, 0xFA, 0xB4, 0xD7, 0x9E, 0x6E, 0x97, 0x21, 0x0C, 0x97, 0xE2, 0xF4, 0x96, 0x27, 0xD3, 0xBB, 0x16, 0xD0, 0xF9, 0xDE, 0xA2, 0x5A, - 0x05, 0x63, 0x5E, 0x25, 0x14, 0x49, 0x75, 0xD2, 0x61, 0x0A, 0x2C, 0x2F, 0x45, 0xD4, 0x18, 0xB5, 0xA0, 0x18, 0x3E, 0x17, 0x01, 0x0A, 0xCD, 0xF1, - 0xC9, 0x4F, 0x84, 0xD3, 0x82, 0x7A, 0xD3, 0x63, 0x25, 0x53, 0xA7, 0xEB, 0x92, 0xE1, 0xA3, 0x52, 0x6C, 0x65, 0x92, 0x67, 0x2A, 0x92, 0xF2, 0xEB, - 0x91, 0xEE, 0x8B, 0xA3, 0x14, 0xE4, 0x22, 0xE6, 0xD5, 0x22, 0xA4, 0x36, 0x11, 0x49, 0xE4, 0x50, 0x00, 0x20, 0xA1, 0xA3, 0x02, 0x6F, 0x05, 0x26, - 0x41, 0x5F, 0xC5, 0x40, 0x7D, 0xB9, 0x3F, 0xF3, 0x10, 0x9F, 0x14, 0x29, 0xE0, 0x97, 0x1E, 0xEF, 0xD5, 0x4D, 0x7C, 0xB1, 0x86, 0x1C, 0x65, 0x13, - 0x39, 0x1B, 0x9D, 0x38, 0x28, 0x0A, 0x6E, 0xA2, 0x98, 0x6C, 0x8A, 0x98, 0x6A, 0xA8, 0xCC, 0x68, 0xC4, 0x38, 0x66, 0xD8, 0x5C, 0xDD, 0x73, 0x0B, - 0x32, 0xF4, 0xC2, 0x18, 0xBF, 0x2F, 0x98, 0x42, 0x04, 0x2F, 0x2A, 0x5C, 0x5C, 0x38, 0x93, 0x5A, 0x50, 0x81, 0x59, 0x6C, 0x25, 0x57, 0x84, 0xDB, - 0x54, 0x9C, 0xE9, 0x2A, 0x1E, 0x41, 0x29, 0x2C, 0x5C, 0x28, 0x39, 0xD0, 0x00, 0x92, 0x58, 0x4E, 0xAC, 0x48, 0x4D, 0xC8, 0x02, 0x4B, 0xDC, 0xA6, - 0xDA, 0x75, 0x72, 0x12, 0x34, 0xA1, 0x11, 0x0F, 0x3F, 0x70, 0x11, 0x3B, 0xE9, 0x77, 0x08, 0x64, 0x33, 0x48, 0x08, 0xD3, 0x8F, 0xD5, 0x3A, 0x3C, - 0x07, 0xF4, 0x5E, 0xA3, 0xA7, 0x16, 0xAE, 0x12, 0xA3, 0x1E, 0xC7, 0x7C, 0xE9, 0x95, 0xC1, 0xE9, 0xDF, 0xC2, 0x4F, 0x59, 0x11, 0xA1, 0xFE, 0x47, - 0xD5, 0x62, 0x35, 0xCB, 0x92, 0x2C, 0xC2, 0x3A, 0x76, 0x00, 0x77, 0x0D, 0xBB, 0x7B, 0x80, 0xB6, 0xEB, 0x5C, 0xB9, 0x44, 0x9F, 0x98, 0xEC, 0x04, - 0x8D, 0x62, 0xBF, 0xE1, 0x98, 0x85, 0x77, 0x48, 0xCD, 0xDF, 0xF8, 0xCA, 0xF4, 0x3B, 0x5F, 0xDC, 0x9C, 0xFE, 0x3F, 0xFC, 0x56, 0x9D, 0x77, 0x51, - 0x65, 0x4F, 0xF0, 0xFB, 0x89, 0x2E, 0xFC, 0x8E, 0x75, 0x77, 0x8E, 0xC3, 0xA7, 0xB2, 0x60, 0x29, 0x82, 0x47, 0x66, 0x38, 0x65, 0x78, 0x1E, 0xBF, - 0x71, 0x70, 0x72, 0x52, 0x29, 0xEF, 0x3E, 0x4F, 0x3F, 0x43, 0x83, 0xBD, 0xFE, 0xFB, 0x54, 0xA4, 0x3A, 0xC5, 0x1A, 0x76, 0x6D, 0xEF, 0x3C, 0x01, - 0xF0, 0x2A, 0x2C, 0xD7, 0xFF, 0x33, 0xFD, 0xB5, 0x9A, 0xF4, 0xC3, 0xFD, 0xA9, 0x69, 0x78, 0xD3, 0x7A, 0xED, 0x4B, 0xFD, 0xA8, 0xCF, 0x31, 0x38, - 0x2C, 0x08, 0x1E, 0x9E, 0x79, 0xFC, 0x9E, 0x86, 0x3F, 0xFA, 0xB0, 0xD1, 0x3E, 0xFC, 0xAF, 0x47, 0xDA, 0xA3, 0xF8, 0xCF, 0xA2, 0xB4, 0x28, 0x4B, - 0x93, 0x0D, 0xCB, 0xD9, 0xC4, 0xD5, 0x2D, 0x85, 0xAB, 0x07, 0x1E, 0xF7, 0x4E, 0x9E, 0x7B, 0xCF, 0x88, 0x00, 0x6E, 0x1E, 0xBD, 0xEB, 0xCE, 0x7D, - 0x69, 0xE7, 0x1F, 0xE7, 0xE4, 0xCD, 0x72, 0x66, 0x48, 0xDE, 0x37, 0x7B, 0x07, 0x37, 0x48, 0xC8, 0x36, 0xED, 0xC0, 0x9A, 0x40, 0xCA, 0x7B, 0x87, - 0xCD, 0x1C, 0xC7, 0xA1, 0xD6, 0x74, 0x5F, 0x91, 0xF4, 0xA0, 0x51, 0x74, 0x63, 0x18, 0xB4, 0xA6, 0xD8, 0x33, 0x0B, 0x23, 0x67, 0xD7, 0xA3, 0xE6, - 0xE4, 0x07, 0xCC, 0xA3, 0xAE, 0xCC, 0x27, 0x53, 0xCA, 0xBE, 0x85, 0xCA, 0x43, 0xED, 0x18, 0x1A, 0x08, 0x92, 0x0B, 0x95, 0x93, 0x9D, 0x3A, 0x5E, - 0xA7, 0xDC, 0x5C, 0x77, 0x8C, 0x54, 0xEF, 0xC4, 0xAA, 0x5D, 0xD3, 0xA6, 0xC5, 0x7A, 0xA6, 0x5D, 0x86, 0xA4, 0x15, 0x02, 0x47, 0xF5, 0x8F, 0xA3, - 0x51, 0x48, 0xA1, 0xD2, 0x3C, 0xA1, 0xF2, 0x0C, 0xD0, 0x17, 0x65, 0x16, 0x78, 0xF9, 0x4F, 0x26, 0x16, 0x9E, 0x25, 0x4A, 0xE0, 0xD1, 0xFC, 0x3A, - 0x33, 0x57, 0x38, 0xED, 0x3E, 0x36, 0x69, 0x7B, 0x35, 0x41, 0xC8, 0x66, 0x32, 0x43, 0x62, 0x52, 0x1E, 0x62, 0xAA, 0x4C, 0xC0, 0x5B, 0xBE, 0xCE, - 0x2D, 0x63, 0xFC, 0x56, 0xB4, 0x94, 0xDE, 0x2B, 0x25, 0x84, 0xC1, 0x4D, 0x00, 0xFA, 0xBD, 0xE9, 0x06, 0x17, 0xB9, 0x36, 0x60, 0xA7, 0xA7, 0x5B, - 0xF3, 0x60, 0x6E, 0xA5, 0xF8, 0x85, 0xB7, 0x27, 0xAF, 0xBD, 0x13, 0xE8, 0x5F, 0xD3, 0xDC, 0x08, 0x13, 0xE9, 0xF4, 0x92, 0x9F, 0x8F, 0x52, 0x0B, - 0xDE, 0x24, 0x4B, 0x0C, 0x48, 0xCA, 0xA2, 0x47, 0xAB, 0x05, 0x8E, 0xDC, 0x32, 0x45, 0xCC, 0x9E, 0x45, 0x49, 0x63, 0x44, 0x1B, 0x06, 0x86, 0x02, - 0xB8, 0x85, 0x60, 0xBA, 0xDE, 0x74, 0x08, 0x37, 0xAF, 0xA3, 0x37, 0x48, 0xC8, 0x35, 0xBB, 0x73, 0x77, 0x8D, 0x59, 0x9B, 0x06, 0x84, 0x74, 0xA6, - 0x82, 0xDC, 0xDB, 0x4D, 0xB4, 0x2A, 0x63, 0x37, 0xBA, 0xC7, 0xD8, 0xC9, 0xC2, 0x94, 0x76, 0x80, 0xDE, 0x30, 0xE1, 0x79, 0x78, 0xC3, 0x79, 0x91, - 0xD9, 0xF9, 0xA3, 0x95, 0x79, 0x34, 0x94, 0x19, 0xCC, 0x67, 0x79, 0x24, 0x46, 0x19, 0xEF, 0x16, 0x43, 0x43, 0x2D, 0x39, 0xC4, 0xB4, 0x7E, 0x8C, - 0xA8, 0x05, 0x2E, 0x89, 0x5C, 0xC1, 0x5C, 0xDC, 0x67, 0x94, 0xDB, 0xCB, 0xB3, 0x5B, 0x16, 0xDD, 0xFB, 0x0B, 0xE7, 0xDA, 0x24, 0x15, 0x98, 0xB9, - 0x75, 0xEE, 0xCB, 0xE3, 0x22, 0xCB, 0x68, 0xB8, 0xDD, 0x92, 0x24, 0x4B, 0x0F, 0x02, 0x45, 0xDD, 0x9B, 0x68, 0x8D, 0xE0, 0x37, 0xFD, 0x0C, 0x3B, - 0x50, 0xE6, 0x2F, 0xC2, 0xFD, 0x75, 0xDF, 0x54, 0x12, 0xEC, 0x41, 0x2A, 0xEE, 0x6E, 0x23, 0xEC, 0x5F, 0xA8, 0xF7, 0xBC, 0x15, 0xF6, 0x39, 0xE1, - 0xBB, 0xA0, 0xA0, 0xBB, 0xDE, 0x71, 0xCF, 0xBC, 0x74, 0xDF, 0x71, 0xEE, 0xB6, 0xB2, 0xEE, 0xD1, 0x8F, 0xF7, 0x73, 0x0C, 0xF7, 0xAF, 0xCE, 0xFB, - 0xE5, 0xC4, 0xCD, 0x61, 0xF5, 0x1E, 0x52, 0xB6, 0x7F, 0xB7, 0xF7, 0x07, 0x60, 0xFF, 0x16, 0xDE, 0x7F, 0xC8, 0xFE, 0xED, 0xEF, 0x1F, 0xB7, 0xFF, - 0x0B, 0xF7, 0xAF, 0xC0, 0xFE, 0x0D, 0xEF, 0xBF, 0xCF, 0xFE, 0x3B, 0xEF, 0xC2, 0x73, 0x77, 0x2E, 0xEE, 0xFD, 0xA3, 0x83, 0x5B, 0xFA, 0xF9, 0xCE, - 0xD3, 0xE8, 0x46, 0x69, 0xF1, 0xD6, 0x32, 0x75, 0x1B, 0x45, 0xBF, 0x3F, 0xB0, 0xFB, 0xBB, 0xBC, 0xFF, 0xA9, 0xFD, 0x2B, 0xBD, 0x7F, 0xB0, 0xFD, - 0x6F, 0xDC, 0x3F, 0x87, 0xFD, 0xDB, 0xDC, 0xFF, 0x8D, 0xFD, 0x4B, 0xDD, 0x3F, 0xD8, 0xFD, 0x17, 0xC1, 0xFF, 0xDC, 0xFD, 0x87, 0xC1, 0xBF, 0xD8, - 0xFB, 0xCF, 0xE1, 0x7F, 0xC1, 0xFB, 0x77, 0x80, 0x7F, 0xBF, 0xF7, 0x6F, 0x84, 0x7F, 0xC7, 0xF7, 0x37, 0x85, 0xFF, 0xD3, 0xF7, 0x77, 0xC4, 0xFF, - 0xE0, 0xF7, 0x3F, 0xC5, 0x7F, 0xD4, 0xFB, 0xB7, 0x85, 0x7F, 0xE1, 0xFB, 0x5F, 0xC3, 0xFF, 0x8E, 0xFB, 0xBF, 0xC1, 0x7F, 0x9C, 0xFB, 0x9F, 0xC2, - 0x7F, 0xAA, 0xFB, 0xCF, 0x81, 0x7F, 0x9D, 0xF7, 0xAF, 0x82, 0x2F, 0x5A, 0xBD, 0x2D, 0xDB, 0xE0, 0x6C, 0x52, 0x6F, 0xBE, 0x23, 0xFC, 0x5E, 0x14, - 0x56, 0x85, 0xB9, 0x46, 0xC6, 0x3A, 0xC1, 0x8F, 0x7F, 0xA6, 0xFF, 0xFF, 0x48, 0xFB, 0x6D, 0x7A, 0x1A, 0x8D, 0xC0, 0x4F, 0xB1, 0x7B, 0xF5, 0x93, - 0x58, 0x05, 0xC3, 0xB8, 0x8A, 0x8A, 0x8F, 0x2A, 0x48, 0x73, 0xCA, 0x4D, 0x51, 0xEA, 0xAB, 0x36, 0x2A, 0x2F, 0x14, 0x3E, 0xC7, 0x0C, 0x25, 0xC8, - 0xF8, 0x54, 0x4F, 0x71, 0xCA, 0x1C, 0x6D, 0xBA, 0x17, 0x31, 0xD9, 0xBA, 0x58, 0x1A, 0x5D, 0x51, 0x82, 0x66, 0x27, 0xFD, 0x1E, 0x25, 0xBD, 0xCC, - 0x20, 0x71, 0x8C, 0x1D, 0x11, 0x65, 0x18, 0xE5, 0xD0, 0x15, 0x89, 0xD1, 0x10, 0x5D, 0xD5, 0x87, 0x18, 0xC0, 0x85, 0xE2, 0x54, 0xBC, 0x3D, 0xA8, - 0x05, 0xE1, 0xFD, 0x01, 0x49, 0xDE, 0xFD, 0x10, 0x3E, 0xFA, 0xB8, 0x92, 0xE8, 0xE1, 0x4C, 0xE5, 0x11, 0xC6, 0xDB, 0xC9, 0x7D, 0xB1, 0xF3, 0x31, - 0x98, 0x33, 0xED, 0x91, 0xC3, 0x83, 0x89, 0x83, 0x42, 0x7C, 0xA3, 0x35, 0x6B, 0x73, 0x04, 0x52, 0x63, 0x40, 0xF9, 0x4D, 0x53, 0xB6, 0x33, 0x53, - 0x81, 0xD6, 0xED, 0xE0, 0x4A, 0xC6, 0x70, 0x39, 0x26, 0x12, 0x00, 0xCC, 0x27, 0xCA, 0x4B, 0xEB, 0x90, 0xCB, 0x2E, 0xD1, 0x1D, 0x39, 0xDE, 0xB2, - 0x5E, 0x63, 0xF1, 0x90, 0x5A, 0xA1, 0x99, 0xA0, 0xB2, 0x23, 0x4F, 0x51, 0x62, 0x43, 0xC9, 0xC2, 0x03, 0x70, 0x46, 0xE1, 0x44, 0x6E, 0xD0, 0x04, - 0x42, 0x89, 0x12, 0x3E, 0xCC, 0xF6, 0x88, 0x4C, 0x12, 0xC6, 0xD9, 0x91, 0x4B, 0x5A, 0x11, 0x7C, 0x66, 0x08, 0xED, 0x32, 0x88, 0x9E, 0xF6, 0x63, - 0x5F, 0xEB, 0xE1, 0x18, 0xEC, 0xD1, 0x66, 0xE6, 0xE0, 0x90, 0x80, 0x43, 0x28, 0x65, 0x23, 0x8A, 0x48, 0x03, 0xAC, 0x28, 0x83, 0x0D, 0x2C, 0xCF, - 0x5E, 0x10, 0x86, 0x5F, 0xDB, 0x19, 0xC5, 0xD5, 0x19, 0x8E, 0xE0, 0x5F, 0x84, 0xD8, 0xF4, 0xE2, 0x98, 0xB4, 0xE5, 0x82, 0x38, 0x5B, 0x1C, 0xCE, - 0x47, 0x95, 0x9F, 0xB0, 0x87, 0xA6, 0x06, 0xF5, 0x19, 0xCD, 0xFA, 0xFF, 0x3F, 0xF9, 0x9F, 0x63, 0x76, 0x7A, 0x9A, 0x81, 0xFC, 0x87, 0xFD, 0xFF, - 0x33, 0xD8, 0xED, 0x8E, 0x62, 0x38, 0xF9, 0x59, 0x8A, 0x31, 0x33, 0x3D, 0x54, 0x80, 0x53, 0xBA, 0x00, 0x7F, 0x00, 0xD9, 0x8B, 0x3A, 0x99, 0x5B, - 0xC2, 0x18, 0x88, 0x0A, 0x31, 0xF8, 0x88, 0x30, 0x9A, 0x3F, 0x30, 0xF9, 0x8A, 0xB8, 0xD4, 0xE3, 0xD7, 0x03, 0x12, 0x5E, 0x04, 0x52, 0x2D, 0xBC, - 0xD8, 0x5A, 0x11, 0xAB, 0x75, 0xE8, 0x91, 0x25, 0x9B, 0x8C, 0xC5, 0x22, 0xE7, 0x8A, 0xD9, 0xC4, 0xAA, 0x16, 0xC4, 0x6A, 0x44, 0x99, 0xCA, 0x79, - 0x87, 0x2A, 0x08, 0xC0, 0x54, 0xCB, 0x95, 0xD4, 0xD7, 0x50, 0xD4, 0xD2, 0x1B, 0x7C, 0x2E, 0x0E, 0x85, 0x76, 0xE1, 0xC9, 0x4F, 0x81, 0xD3, 0x02, - 0xB8, 0xA6, 0xC7, 0x3E, 0xA6, 0xBF, 0xBC, 0x25, 0xD1, 0x39, 0x25, 0x48, 0x13, 0x49, 0xBE, 0x1C, 0x90, 0x58, 0xF1, 0x48, 0x1B, 0x29, 0x8C, 0x8E, - 0x73, 0x8D, 0x70, 0x4A, 0x8B, 0x4A, 0xA0, 0xEB, 0x44, 0x56, 0xBF, 0x43, 0x3A, 0x7A, 0xA1, 0x38, 0x0D, 0xFA, 0x1B, 0x4B, 0x3A, 0x68, 0x42, 0x30, - 0x90, 0xDC, 0xCB, 0x4F, 0xDF, 0xA8, 0x7C, 0xCB, 0xCE, 0xE8, 0xF7, 0x65, 0xB1, 0x3D, 0xAF, 0x8A, 0x7D, 0xAF, 0x6A, 0x5A, 0x58, 0x69, 0x94, 0x56, - 0x4D, 0x45, 0xB7, 0xA9, 0x6E, 0x7E, 0xEB, 0x53, 0x4D, 0xF4, 0x2F, 0x55, 0x27, 0x92, 0xA3, 0x91, 0xF3, 0xF2, 0x61, 0xE3, 0xC3, 0x52, 0xD3, 0xA4, - 0x43, 0x73, 0xB8, 0xD4, 0xAE, 0x6B, 0xE1, 0x6B, 0x1C, 0x6D, 0xB1, 0xF7, 0x4A, 0x91, 0xF3, 0xF1, 0xEA, 0x55, 0x4D, 0x18, 0x7D, 0xD4, 0x7B, 0xFB, - 0x33, 0xE5, 0xA7, 0x32, 0xAA, 0xD4, 0x51, 0x7F, 0xB7, 0xDA, 0xA7, 0x8E, 0x72, 0x7B, 0xD3, 0xDD, 0xB1, 0x51, 0x5B, 0x9A, 0x51, 0x33, 0x42, 0xB9, - 0xE8, 0x52, 0x06, 0xFD, 0x99, 0xD5, 0x49, 0x32, 0xCD, 0x5F, 0xF9, 0x49, 0xFF, 0xC5, 0x1D, 0x92, 0x16, 0x26, 0x37, 0x09, 0x36, 0x46, 0x1B, 0x2F, - 0x31, 0xE2, 0x17, 0x19, 0x19, 0x20, 0xA2, 0x3A, 0x1A, 0xF2, 0x3A, 0x96, 0xC3, 0x57, 0xEC, 0x6F, 0x90, 0xE4, 0x45, 0xEB, 0xFD, 0x67, 0xD3, 0x84, - 0xAD, 0xE2, 0xE9, 0xE7, 0x5A, 0x16, 0x8A, 0xE5, 0x1E, 0x40, 0xE6, 0x85, 0x2A, 0xFA, 0xC9, 0x08, 0xFB, 0xCD, 0x5E, 0x39, 0xEA, 0xE3, 0x9A, 0x7C, - 0x45, 0x98, 0x47, 0xC5, 0xB9, 0x47, 0xAF, 0xD2, 0xB1, 0x9C, 0x02, 0x28, 0xF5, 0xC2, 0x4B, 0x74, 0xCF, 0x88, 0xEA, 0x22, 0x08, 0x6A, 0xFE, 0xFB, - 0xA6, 0xD7, 0xB5, 0x6B, 0xCD, 0xAD, 0x71, 0x94, 0xE3, 0x66, 0x42, 0x1A, 0x22, 0x7B, 0xDA, 0xAC, 0x97, 0xDB, 0xFE, 0x46, 0x3C, 0x8D, 0x27, 0xB3, - 0x8E, 0x96, 0x95, 0xA1, 0x03, 0x5D, 0xAD, 0x29, 0xFA, 0xFD, 0xFF, 0x7F, 0xC1, 0xC9, 0x85, 0x5B, 0x30, 0x07, 0xF4, 0xA5, 0xBB, 0xB5, 0xD7, 0x20, - 0x6B, 0x0E, 0xB5, 0xDF, 0x7F, 0x7F, 0xA0, 0xEF, 0xFE, 0x2B, 0x5F, 0xE5, 0x7F, 0x7C, 0x8F, 0xCF, 0x81, 0xD3, 0xF8, 0x6B, 0x74, 0x3E, 0x4D, 0x1E, - 0x2A, 0x82, 0x08, 0xAF, 0x9E, 0xC4, 0x8E, 0x93, 0xA3, 0x7A, 0xC8, 0xE2, 0x5A, 0xB3, 0x0D, 0xD3, 0xAC, 0xD0, 0x21, 0xFF, 0x6B, 0xC4, 0x00, 0x9C, - 0x8E, 0xD1, 0x6B, 0x8A, 0xA6, 0xC0, 0xBE, 0x86, 0x60, 0x50, 0xAD, 0x9E, 0xF0, 0x7B, 0xFE, 0xCE, 0xD7, 0xF9, 0x34, 0x1F, 0xE6, 0xBF, 0xFC, 0x92, - 0x4F, 0xA2, 0x81, 0x83, 0x14, 0xAC, 0x83, 0xFF, 0xD7, 0xEB, 0xAF, 0xFE, 0x46, 0x7F, 0xE8, 0xF3, 0xFC, 0x9C, 0x7F, 0xF3, 0x6D, 0x7E, 0xCD, 0x67, - 0xF9, 0xED, 0x1F, 0xC2, 0xD1, 0xF1, 0xD9, 0x41, 0x86, 0x60, 0xC6, 0x76, 0x20, 0x50, 0x4C, 0xF5, 0xC5, 0xE5, 0x5F, 0x2F, 0xC5, 0x9C, 0xF5, 0xE3, - 0xFF, 0x8C, 0x18, 0xFA, 0x19, 0x73, 0xEF, 0xFF, 0x6A, 0xF6, 0xE7, 0x79, 0x23, 0xCA, 0x55, 0x5A, 0x92, 0xE8, 0x55, 0x6E, 0x48, 0xBC, 0x3C, 0x6B, - 0x02, 0x7D, 0x7E, 0x2B, 0x7E, 0xBC, 0x41, 0x4F, 0x2C, 0x1A, 0xEF, 0x98, 0x5B, 0x09, 0x01, 0xCC, 0xEB, 0x70, 0x90, 0xF7, 0xAC, 0xC5, 0xB1, 0x52, - 0xC8, 0xB5, 0x7A, 0xF2, 0x05, 0x4A, 0xE5, 0x71, 0x89, 0xF9, 0x0C, 0xBF, 0x72, 0x3D, 0x06, 0x71, 0x46, 0x0D, 0xF9, 0x09, 0xA8, 0x7C, 0x27, 0xB0, - 0x1E, 0x34, 0x24, 0xAE, 0xDF, 0xD0, 0xEB, 0xEE, 0xC5, 0xBF, 0x8D, 0xC7, 0x17, 0xCB, 0xBB, 0xA5, 0xF4, 0x32, 0xEE, 0x38, 0x5C, 0xAE, 0x77, 0x1A, - 0xCE, 0xCB, 0xF1, 0xF4, 0x02, 0xE2, 0xF2, 0x13, 0x9A, 0xF5, 0x11, 0x8A, 0xE2, 0x84, 0x2A, 0xFA, 0xCA, 0xC3, 0xDA, 0xDB, 0x1A, 0xF5, 0xFF, 0xF9, - 0x3E, 0x3F, 0x06, 0x65, 0xE5, 0xB7, 0xAC, 0xE2, 0x81, 0xA9, 0x76, 0x50, 0x90, 0x4A, 0x38, 0x87, 0xAA, 0xC2, 0x82, 0xD5, 0x6A, 0x81, 0x04, 0x12, - 0xA2, 0xE0, 0xEC, 0xFF, 0x37, 0xD8, 0xC7, 0xFB, 0x69, 0x18, 0x76, 0x10, 0xD6, 0x7B, 0x5D, 0x13, 0x6B, 0xAF, 0x6F, 0xFA, 0xFF, 0xFF, 0x0C, 0xF6, - 0x73, 0xC6, 0x10, 0xDD, 0xA4, 0xD0, 0x00, 0xDA, 0xB7, 0x9B, 0x63, 0x50, 0x9D, 0x26, 0x50, 0xDE, 0xE9, 0x4F, 0x60, 0xAD, 0x0F, 0x62, 0x70, 0xCF, - 0x24, 0x33, 0x4F, 0x28, 0xC7, 0x0E, 0x6C, 0x8A, 0x8E, 0x8B, 0x9B, 0x9C, 0x18, 0x45, 0x39, 0x1A, 0x53, 0x75, 0x9C, 0x90, 0x95, 0x9B, 0x97, 0x1C, - 0x1B, 0x9F, 0xA3, 0x9A, 0xA6, 0x2A, 0x1A, 0xAE, 0xB1, 0x99, 0xB4, 0x36, 0x37, 0x02, 0x3A, 0x99, 0xBB, 0x0A, 0xED, 0xBE, 0x7A, 0x3B, 0x72, 0xFE, - 0xA6, 0x43, 0xF2, 0x45, 0xB8, 0xEF, 0x01, 0x78, 0xB4, 0x7F, 0xA9, 0x50, 0x1C, 0x72, 0x2C, 0x55, 0xDC, 0xFF, 0x2A, 0xF8, 0x28, 0x34, 0x8C, 0x0B, - 0x0D, 0x15, 0xC8, 0x09, 0x63, 0x1B, 0xE0, 0x1D, 0x51, 0xFE, 0xCF, 0x91, 0xEA, 0xC3, 0x66, 0xEE, 0x35, 0xF0, 0xF8, 0x6E, 0x77, 0x76, 0xC9, 0xFD, - 0xE9, 0xC4, 0x1D, 0xEB, 0xE3, 0x30, 0x2B, 0xC0, 0xB9, 0x24, 0xBD, 0x11, 0x03, 0x70, 0xA3, 0xFA, 0x73, 0x4B, 0x41, 0x40, 0xE0, 0x81, 0x0D, 0x01, - 0xA8, 0x50, 0xB9, 0xFD, 0x4E, 0x4E, 0x67, 0xA6, 0xE6, 0x4A, 0xA2, 0x26, 0x78, 0x4F, 0x83, 0x2E, 0x90, 0xA6, 0x3A, 0x25, 0xE0, 0x06, 0x8F, 0xB6, - 0x3C, 0x88, 0xB6, 0x62, 0x6D, 0x8F, 0x71, 0xE4, 0x36, 0x13, 0x3B, 0x73, 0x27, 0x9B, 0xC9, 0xBA, 0xCD, 0x50, 0xC6, 0x02, 0x54, 0x68, 0x0C, 0x20, - 0xB6, 0x57, 0xB6, 0xFC, 0x54, 0xE6, 0x83, 0x44, 0x96, 0x22, 0x83, 0xEC, 0x4E, 0x4F, 0xA6, 0x92, 0x36, 0xC6, 0x45, 0x26, 0x76, 0x6B, 0x25, 0xA6, - 0x62, 0x46, 0x0C, 0x29, 0x42, 0x18, 0x02, 0x06, 0x61, 0x1A, 0x84, 0x60, 0xB3, 0xA7, 0x60, 0x77, 0x16, 0xE2, 0x14, 0xED, 0x42, 0x24, 0xDC, 0xF1, - 0x8E, 0xCC, 0xAF, 0x41, 0xBB, 0xDD, 0xAB, 0xA8, 0xAF, 0x2B, 0x84, 0x25, 0xD7, 0x00, 0x17, 0x5B, 0xB7, 0x78, 0x3A, 0x07, 0x58, 0xAD, 0x9A, 0x96, - 0x9F, 0x49, 0x83, 0x15, 0xE5, 0x1B, 0xB3, 0x32, 0xD7, 0xB2, 0x22, 0xF1, 0xB7, 0x73, 0x0E, 0x49, 0x5C, 0xC1, 0x46, 0x3A, 0x20, 0xCF, 0x45, 0x4A, - 0xA1, 0xE8, 0x21, 0x6C, 0x57, 0x20, 0xC0, 0x21, 0x5F, 0x34, 0x41, 0xC7, 0x81, 0xBC, 0xE7, 0x4F, 0xE3, 0xE7, 0x1B, 0x3A, 0x78, 0x71, 0x8E, 0xAD, - 0x11, 0xE2, 0x6F, 0x35, 0x1C, 0xDA, 0xD3, 0x12, 0x8F, 0x9A, 0x35, 0xCE, 0x45, 0xA7, 0x01, 0xD0, 0x41, 0x80, 0x35, 0x0F, 0xFE, 0x9F, 0xF1, 0xFF, - 0xBF, 0xFA, 0x6B, 0xB5, 0x3A, 0xF0, 0x9B, 0xFC, 0x17, 0xF7, 0x87, 0x21, 0x7B, 0x5B, 0x72, 0x75, 0xD3, 0xDA, 0x8F, 0xD9, 0x58, 0x10, 0xAB, 0xD5, - 0x14, 0x6B, 0xE4, 0x13, 0x6B, 0x90, 0xC4, 0x85, 0xE8, 0xCC, 0xC5, 0x67, 0xC6, 0xC5, 0xB6, 0xB9, 0x55, 0xAB, 0xD6, 0xE2, 0x70, 0x99, 0xB5, 0xEF, - 0xC5, 0x5A, 0x51, 0x82, 0x55, 0xB2, 0xB6, 0xD2, 0x1B, 0xB0, 0x12, 0x72, 0x57, 0x99, 0x44, 0x53, 0x81, 0x3D, 0x4D, 0x35, 0x91, 0x49, 0x2D, 0x48, - 0x8B, 0x4A, 0x63, 0x00, 0xFF, 0x8B, 0x00, 0xC5, 0x20, 0xC0, 0xD3, 0xA2, 0x9A, 0x93, 0x87, 0x06, 0x4D, 0xA4, 0x77, 0x4C, 0x92, 0x1E, 0x96, 0x80, - 0x49, 0x28, 0xB9, 0x42, 0x2A, 0x75, 0x58, 0x22, 0xC1, 0x58, 0x8D, 0x23, 0xE9, 0xC4, 0xCA, 0x8F, 0x3E, 0x22, 0x8D, 0xA0, 0x2E, 0x8B, 0x78, 0xF2, - 0x44, 0x6B, 0xB2, 0x43, 0x5A, 0xC5, 0x42, 0x14, 0x62, 0xBC, 0x0F, 0x84, 0xE4, 0x83, 0xEC, 0x27, 0x7A, 0xA0, 0xBE, 0xC4, 0x9F, 0xCF, 0x5D, 0x9F, - 0x14, 0x0C, 0x7A, 0x74, 0x1F, 0x79, 0x4C, 0xA1, 0x78, 0xBE, 0x04, 0x9D, 0x5F, 0x4C, 0x1D, 0x18, 0xE5, 0x9C, 0x8D, 0x3D, 0x9C, 0x26, 0x16, 0x37, - 0x37, 0x62, 0x36, 0x04, 0x72, 0x6A, 0xA8, 0xDC, 0x34, 0x11, 0xD2, 0x66, 0xD8, 0x04, 0xDD, 0x21, 0x64, 0x65, 0xE8, 0x71, 0x31, 0x95, 0x87, 0x30, - 0x85, 0x45, 0x2F, 0xB0, 0x73, 0x17, 0xCE, 0xDF, 0x92, 0xDC, 0xC4, 0x62, 0x2B, 0x81, 0x65, 0x7E, 0xA8, 0xE2, 0x8C, 0xA5, 0x62, 0xF7, 0x90, 0xC2, - 0x02, 0x00, 0xE5, 0x2B, 0x0E, 0x00, 0x49, 0xF7, 0x44, 0x01, 0x8C, 0x09, 0x59, 0x5A, 0xC9, 0x06, 0x11, 0xED, 0x3A, 0x1D, 0x12, 0x14, 0x6E, 0x23, - 0x80, 0x31, 0x44, 0x4A, 0x85, 0x42, 0x20, 0x3D, 0x41, 0x7E, 0xA3, 0x3F, 0x56, 0x9B, 0x3E, 0x34, 0xEC, 0x3A, 0x8A, 0x3D, 0x3A, 0x6C, 0xAA, 0x38, - 0x42, 0x60, 0x37, 0xA6, 0x4A, 0xF6, 0x1A, 0x3D, 0x26, 0x32, 0xD8, 0x72, 0xD9, 0x59, 0x30, 0x6B, 0x0A, 0x67, 0x73, 0x75, 0x5C, 0xF0, 0x27, 0xBC, - 0x99, 0xD6, 0xAB, 0x94, 0xD6, 0x44, 0x8E, 0x3E, 0x61, 0x01, 0xDA, 0x96, 0xF3, 0xF9, 0x33, 0xDA, 0xB9, 0x59, 0xA9, 0x59, 0xD7, 0xB4, 0x79, 0x65, - 0x63, 0x79, 0xBA, 0x6A, 0xF9, 0xA8, 0x55, 0x39, 0xA6, 0x24, 0x06, 0x59, 0x61, 0x32, 0x53, 0x1F, 0x0C, 0x06, 0x2D, 0xC8, 0x68, 0x67, 0xC7, 0x7F, - 0xBE, 0x7B, 0x08, 0x37, 0x74, 0xE3, 0xBB, 0xE4, 0xBC, 0x38, 0x04, 0x32, 0xF1, 0x2A, 0x85, 0x61, 0xCA, 0x04, 0xFF, 0xC5, 0xB0, 0xF3, 0x1E, 0x56, - 0x2E, 0x0C, 0x72, 0x09, 0x9C, 0xFC, 0x03, 0x7C, 0xD4, 0xD6, 0xAA, 0xC1, 0x31, 0xCE, 0x9A, 0x27, 0xCF, 0x33, 0x42, 0x58, 0xF5, 0x83, 0x53, 0x15, - 0x4D, 0x4E, 0x6D, 0xD4, 0x45, 0x6D, 0xB1, 0x73, 0x7A, 0xAA, 0x42, 0x6E, 0x3A, 0x0A, 0x5C, 0x0A, 0x6D, 0xAC, 0x77, 0x96, 0x90, 0x27, 0xF5, 0x30, - 0xA9, 0x9F, 0xB0, 0xD9, 0x95, 0xE2, 0xFF, 0xFF, 0xF1, 0x3F, 0x07, 0xF0, 0xFF, 0x2F, 0xEE, 0x5F, 0xE1, 0xAF, 0xD5, 0xFB, 0xE9, 0xE9, 0x63, 0x37, - 0x8F, 0x38, 0xB6, 0xB6, 0xEF, 0x60, 0x9D, 0x9D, 0xA1, 0xD6, 0xC8, 0x58, 0xAB, 0xD9, 0x42, 0xFF, 0x8F, 0xB4, 0xFF, 0xFA, 0x16, 0xE5, 0x6B, 0xED, - 0x03, 0x58, 0xBB, 0x3B, 0x81, 0x93, 0xA2, 0x9B, 0x38, 0x98, 0x9A, 0xB7, 0x0B, 0x9C, 0xB5, 0x49, 0xEC, 0xD0, 0x46, 0x1C, 0xA9, 0x44, 0x56, 0x65, - 0x3F, 0x7B, 0x8A, 0x74, 0xBF, 0xB6, 0xF3, 0x84, 0x91, 0x76, 0x77, 0xA1, 0xEA, 0xFA, 0x5F, 0xB7, 0x38, 0x5A, 0xBD, 0x6C, 0x58, 0xE9, 0x52, 0xF2, - 0x1A, 0xFE, 0x5F, 0x05, 0x2C, 0x6A, 0xD7, 0x7A, 0xD8, 0x47, 0xCD, 0x30, 0xE9, 0xA2, 0xD3, 0x96, 0x1B, 0x88, 0x46, 0x15, 0x0E, 0x23, 0x70, 0x99, - 0x00, 0x32, 0x31, 0xA4, 0x87, 0xD8, 0xE5, 0x27, 0x0A, 0xED, 0x3C, 0x84, 0x7C, 0xD2, 0x25, 0xF0, 0x58, 0x83, 0x9A, 0x7F, 0xB2, 0x3E, 0x73, 0xC1, - 0x2B, 0xBB, 0xFD, 0x9F, 0x3C, 0xFE, 0x75, 0xA0, 0x54, 0xD0, 0x66, 0xE3, 0xFF, 0x4F, 0xB3, 0xDE, 0x50, 0xAB, 0xA9, 0xD3, 0x3E, 0xD2, 0x2F, 0xFA, - 0x44, 0x1F, 0xE7, 0xBB, 0xFC, 0x94, 0x8F, 0xF2, 0x45, 0x3E, 0xC8, 0xDF, 0xF8, 0x1A, 0x7F, 0x7A, 0x1A, 0x3A, 0x09, 0xD0, 0x17, 0x10, 0x6B, 0xFA, - 0x8F, 0xFC, 0xFF, 0xD7, 0xFF, 0x7F, 0xF5, 0x5F, 0x77, 0x26, 0xFD, 0x5F, 0x14, 0xE0, 0x7F, 0x75, 0xF2, 0xFF, 0x1F, 0xE5, 0x7F, 0x75, 0xDB, 0xFF, - 0x6B, 0x0A, 0x01, 0xAF, 0xC2, 0x1B, 0xC7, 0xC1, 0x29, 0xC8, 0xC0, 0x39, 0x24, 0xBF, 0x48, 0x6D, 0xDF, 0xAB, 0x1F, 0x17, 0x01, 0x80, 0x7A, 0xD5, - 0x4A, 0x78, 0xB3, 0x74, 0x76, 0xF1, 0x82, 0x74, 0xE5, 0xAC, 0xF4, 0x84, 0x5D, 0x2D, 0xF8, 0xDC, 0x72, 0x39, 0x0F, 0xE0, 0x32, 0x5A, 0xB8, 0xCD, - 0xE5, 0xB3, 0xC5, 0xBF, 0xD5, 0x4A, 0x2B, 0xD2, 0xEA, 0x2F, 0xD0, 0xA2, 0x68, 0x88, 0x75, 0x77, 0xC2, 0x92, 0x89, 0xBE, 0xC2, 0x71, 0x5D, 0x1B, - 0xF4, 0x9A, 0xCE, 0x2A, 0x99, 0x8A, 0xC0, 0x49, 0x99, 0x03, 0x90, 0xFE, 0xA8, 0x8D, 0x92, 0x2C, 0x89, 0x76, 0xDD, 0x85, 0x06, 0x99, 0x81, 0xBA, - 0xAD, 0xB1, 0xF8, 0x72, 0xF0, 0x99, 0x37, 0xC1, 0x73, 0x2E, 0x10, 0x8F, 0x28, 0xD8, 0xE9, 0x17, 0xC9, 0x09, 0x7A, 0xB9, 0xF9, 0x98, 0xD7, 0xEC, - 0x95, 0xCD, 0x14, 0x9D, 0xCC, 0xCC, 0x88, 0x71, 0xE9, 0xDB, 0x7A, 0xE9, 0x42, 0x6B, 0xB9, 0xB1, 0x5F, 0xC1, 0xB4, 0x5C, 0x99, 0x33, 0x42, 0x99, - 0x86, 0x32, 0x79, 0xE5, 0x23, 0x79, 0x47, 0x14, 0x19, 0xA7, 0x05, 0x39, 0x08, 0x76, 0xC7, 0xFB, 0x79, 0x94, 0x2C, 0x52, 0x41, 0xB8, 0xE5, 0xE8, - 0x1A, 0xD6, 0xC8, 0x29, 0x97, 0x02, 0xC6, 0x1C, 0x45, 0xEE, 0x1E, 0x8A, 0x93, 0x0E, 0x8B, 0xD2, 0x27, 0x16, 0x89, 0x1A, 0x15, 0x51, 0xF8, 0x12, - 0xC5, 0x4C, 0xF7, 0x27, 0x8C, 0x14, 0x11, 0x0D, 0xA8, 0x38, 0xBC, 0x10, 0xAC, 0x7F, 0xDB, 0x9D, 0x93, 0x48, 0x95, 0xEB, 0xFD, 0xF9, 0x0B, 0x79, - 0x62, 0xCC, 0x9C, 0xBD, 0xAF, 0x3F, 0xFE, 0xFF, 0x39, 0x36, 0x32, 0x36, 0xD4, 0xFF, 0xA3, 0xAC, 0x70, 0x74, 0xA8, 0x92, 0x76, 0x3D, 0x97, 0xC2, - 0xDF, 0xF9, 0xB8, 0xCB, 0x2F, 0x3C, 0x5E, 0x1C, 0x6F, 0xD2, 0x80, 0x2F, 0x08, 0x89, 0xA7, 0xD5, 0xC0, 0xF7, 0x8C, 0xF3, 0x77, 0x51, 0xF0, 0x45, - 0x91, 0xFC, 0xE0, 0x1A, 0x9C, 0xB4, 0x27, 0x2F, 0x29, 0x85, 0x05, 0x9C, 0x95, 0x77, 0x95, 0xE3, 0x3B, 0xE2, 0xF0, 0xF0, 0x27, 0x83, 0x78, 0xAC, - 0xC3, 0xBC, 0x55, 0x10, 0x9E, 0x4B, 0xF9, 0x5D, 0x7F, 0xF9, 0xE8, 0xF9, 0x6D, 0xBA, 0xD1, 0x8A, 0x33, 0xEC, 0xA5, 0xC9, 0xB1, 0x9B, 0x61, 0x31, - 0x76, 0x22, 0x64, 0xA2, 0x84, 0xEF, 0xA7, 0x04, 0x6A, 0xAB, 0x4D, 0x1B, 0x4B, 0xB2, 0x26, 0x37, 0xF2, 0x4B, 0xE1, 0x4D, 0x61, 0x4F, 0xA4, 0xC5, - 0xE4, 0x6D, 0xCB, 0xC0, 0x03, 0xCD, 0xEB, 0x2D, 0x5A, 0xA8, 0xD3, 0xA2, 0x56, 0x04, 0x07, 0x08, 0x97, 0x0C, 0xD1, 0x25, 0x7B, 0x46, 0x00, 0x0D, - 0xF7, 0x3F, 0x1B, 0xF6, 0x41, 0x34, 0x88, 0x56, 0x2E, 0x81, 0x96, 0x7E, 0x5A, 0x76, 0x76, 0x59, 0x3E, 0xA1, 0x23, 0xC6, 0x10, 0xEB, 0x26, 0xAE, - 0xD2, 0x1A, 0x46, 0x36, 0x1A, 0x06, 0xC1, 0x90, 0xFA, 0x01, 0x4E, 0x27, 0x35, 0x46, 0xD4, 0x74, 0x43, 0x61, 0x29, 0x70, 0x4C, 0x29, 0x4C, 0x0C, - 0x69, 0x47, 0xD3, 0xE8, 0x4A, 0x98, 0xA8, 0x8C, 0x4C, 0xE8, 0x00, 0x34, 0x50, 0x28, 0xA7, 0x09, 0x76, 0x49, 0x6B, 0x02, 0x3C, 0x03, 0x05, 0xE0, - 0x29, 0x40, 0xE8, 0x9C, 0x84, 0xC0, 0x59, 0x18, 0x62, 0xF3, 0x35, 0x84, 0x66, 0x27, 0x65, 0x66, 0x32, 0xA5, 0xA3, 0xA4, 0x83, 0x46, 0x16, 0x7D, - 0x96, 0x29, 0x5A, 0xA7, 0x50, 0xEC, 0x9E, 0x25, 0x31, 0x1E, 0x93, 0x2C, 0x4E, 0xDB, 0xEE, 0x49, 0x92, 0xFD, 0x6F, 0x98, 0xFC, 0xF4, 0x3F, 0x9B, - 0x05, 0xD5, 0xBE, 0x50, 0xD1, 0xF8, 0x11, 0xB4, 0xB8, 0x33, 0x94, 0x58, 0x54, 0x71, 0x38, 0x76, 0x51, 0x59, 0x34, 0x38, 0xA5, 0xD7, 0x85, 0x0E, - 0x74, 0xAF, 0x1A, 0xDB, 0x16, 0x1F, 0xA0, 0x56, 0x7A, 0x44, 0xEC, 0x29, 0xDE, 0x34, 0x45, 0x8D, 0x94, 0xF8, 0x91, 0x14, 0xEB, 0x78, 0x54, 0x24, - 0x55, 0x74, 0xCE, 0x1C, 0x7A, 0xC2, 0x01, 0x54, 0xD0, 0x04, 0x0B, 0xA2, 0x14, 0x9F, 0x99, 0x78, 0x4F, 0xB1, 0x52, 0xBC, 0x6D, 0x6E, 0x27, 0x83, - 0x5F, 0xCE, 0x67, 0xE8, 0xCD, 0x40, 0x8D, 0xCD, 0x97, 0x96, 0xFC, 0x64, 0x0D, 0x3C, 0xB3, 0x29, 0xA9, 0x32, 0xAE, 0x16, 0x43, 0xAC, 0x69, 0xF6, - 0x33, 0x95, 0x43, 0x15, 0x84, 0x36, 0xE5, 0x56, 0x25, 0xF5, 0x65, 0x17, 0x95, 0xD7, 0x06, 0x9F, 0x03, 0x01, 0x25, 0x68, 0xE5, 0x66, 0xC1, 0xCE, - 0x89, 0xB4, 0x71, 0x7C, 0x34, 0x64, 0xC2, 0x28, 0x87, 0xA4, 0x28, 0x0C, 0x4F, 0x97, 0x0B, 0x08, 0x2D, 0xD9, 0xE2, 0x9A, 0xB4, 0xF3, 0xA1, 0xC4, - 0x13, 0x40, 0xAB, 0x81, 0x8D, 0xD1, 0x62, 0x8D, 0x01, 0x0F, 0x78, 0x32, 0xD1, 0x7C, 0x83, 0xDE, 0x13, 0x05, 0x6D, 0xF8, 0xBF, 0x16, 0x2A, 0x3A, - 0xB0, 0xF9, 0xEF, 0x23, 0xF3, 0x15, 0x0F, 0x43, 0x6C, 0x1D, 0x5C, 0xC8, 0xD7, 0x8E, 0x40, 0x59, 0x5D, 0x51, 0xB6, 0xBA, 0x16, 0x2D, 0x15, 0xC6, - 0x2D, 0x25, 0x3B, 0xD6, 0x87, 0x28, 0x8A, 0x87, 0xE6, 0xDE, 0xA9, 0xF2, 0x12, 0x63, 0x71, 0x06, 0x70, 0x9E, 0x48, 0xCB, 0x2B, 0x4E, 0xA3, 0xB2, - 0x12, 0x90, 0xCB, 0x02, 0xED, 0x44, 0xC8, 0x99, 0xB4, 0xAE, 0x59, 0x28, 0x8F, 0x59, 0xCC, 0xB4, 0xDB, 0x05, 0xD6, 0xBB, 0xCC, 0x68, 0xF7, 0xDD, - 0xD2, 0xEB, 0x93, 0x02, 0x3A, 0x67, 0xE9, 0xDB, 0xD4, 0xCE, 0x71, 0x5B, 0xB0, 0x3D, 0xC8, 0x6A, 0x0B, 0x8B, 0xF9, 0x26, 0x9A, 0x10, 0x45, 0xC4, - 0x7A, 0xCD, 0x07, 0x43, 0xD0, 0x6D, 0x45, 0x01, 0x14, 0xA5, 0xDC, 0xBB, 0x14, 0xC0, 0xFF, 0x0E, 0x49, 0xA9, 0xEE, 0x3E, 0xA1, 0x26, 0x95, 0x4C, - 0x86, 0x9A, 0xFD, 0xB8, 0xF2, 0x22, 0x73, 0x36, 0xA6, 0x80, 0x3E, 0x05, 0x25, 0x27, 0x65, 0x86, 0x1F, 0x2A, 0x35, 0xEE, 0x99, 0xC2, 0xE5, 0xF1, - 0xDC, 0xDA, 0x61, 0xFB, 0x73, 0x4F, 0x82, 0x9D, 0x08, 0xD5, 0x96, 0xBC, 0xCE, 0x95, 0x80, 0x31, 0xEB, 0x3D, 0x10, 0x9F, 0x36, 0xA6, 0xEA, 0x36, - 0x7F, 0xB0, 0x80, 0xE5, 0xF6, 0x7C, 0xDC, 0xDA, 0xB9, 0x79, 0x05, 0xEE, 0x76, 0x1E, 0xAC, 0x1D, 0xAC, 0x79, 0xD6, 0x3B, 0x7F, 0xC4, 0x1F, 0x4E, - 0x60, 0x64, 0xBE, 0x5E, 0x5C, 0x6F, 0xDD, 0x8F, 0xF8, 0x68, 0xB5, 0x7F, 0xB6, 0xE4, 0xF6, 0x4E, 0xD4, 0x59, 0xCC, 0xD2, 0x1D, 0x63, 0xA5, 0xEB, - 0xD2, 0xFC, 0xE8, 0x7F, 0xC2, 0x8A, 0xC6, 0xE9, 0x15, 0xA0, 0x3F, 0x82, 0x83, 0x3F, 0x37, 0xEC, 0x38, 0x0E, 0xCA, 0xDD, 0x0D, 0x21, 0xAF, 0x7B, - 0x5E, 0x97, 0x69, 0x5E, 0xCE, 0xFB, 0xC5, 0xAC, 0x80, 0x8E, 0x4E, 0x93, 0x90, 0xF8, 0xE4, 0x65, 0x7E, 0xF0, 0x41, 0x5A, 0xF9, 0x2A, 0xDE, 0x55, - 0xAD, 0x78, 0x5F, 0x1D, 0x5C, 0x6E, 0xAF, 0x46, 0xB3, 0xFD, 0xA7, 0xF1, 0x2F, 0xC5, 0xB0, 0xAF, 0x96, 0x31, 0x20, 0x7A, 0xEF, 0x75, 0x01, 0xFE, - 0x27, 0xF1, 0x3D, 0x90, 0x88, 0xA9, 0xBB, 0x22, 0x7A, 0xCC, 0x1B, 0xC8, 0xBE, 0x9C, 0x48, 0x29, 0x41, 0x64, 0xB0, 0xDC, 0x60, 0xFD, 0xEC, 0x2A, - 0xA1, 0xCD, 0xDD, 0xE9, 0x9E, 0x1A, 0x0A, 0x45, 0xF9, 0x75, 0x94, 0xB5, 0xFA, 0x5F, 0x7E, 0xBF, 0x0E, 0xB7, 0x27, 0x2A, 0x02, 0x43, 0x2D, 0xFD, - 0x86, 0x57, 0x96, 0x8A, 0xD5, 0x35, 0xFD, 0xDB, 0xF1, 0x78, 0x01, 0x21, 0xCF, 0x1D, 0x0E, 0xE0, 0x33, 0xFE, 0x9B, 0xAF, 0xE2, 0x27, 0xCE, 0x49, - 0x4F, 0xAB, 0x24, 0x12, 0xB8, 0xD7, 0x88, 0xEB, 0x33, 0xE4, 0xD1, 0x73, 0xF6, 0x5C, 0x7A, 0xFD, 0x40, 0xBF, 0xFF, 0xD3, 0x84, 0xAC, 0x35, 0x29, - 0xDA, 0x59, 0xE1, 0xF9, 0x6C, 0x06, 0xFF, 0xC3, 0xD7, 0x53, 0x61, 0xEA, 0x60, 0x9E, 0xBC, 0xB6, 0xC7, 0xCA, 0xCC, 0xFE, 0x7F, 0xC0, 0x7C, 0x9D, - 0xF1, 0x39, 0x7C, 0x0C, 0xFF, 0xC1, 0xE3, 0x92, 0x7A, 0xEF, 0x87, 0x90, 0x9E, 0x56, 0x9C, 0xD6, 0x4B, 0x5B, 0xBE, 0x08, 0x73, 0x7C, 0x60, 0xE4, - 0x94, 0x00, 0x34, 0x74, 0x9C, 0xFF, 0x7F, 0x08, 0x66, 0x11, 0x75, 0x87, 0x7F, 0x21, 0x92, 0x34, 0xAC, 0xC1, 0x2C, 0x58, 0xD3, 0xC9, 0x03, 0xBD, - 0x57, 0xA7, 0x57, 0x17, 0x06, 0x3E, 0x2E, 0xD4, 0xE5, 0xAD, 0xC1, 0x04, 0x5A, 0xBC, 0xB6, 0x59, 0x92, 0xF1, 0x2C, 0x76, 0xF3, 0xD5, 0x2D, 0x63, - 0xDC, 0x46, 0x25, 0xFE, 0xFB, 0xE0, 0x04, 0x4C, 0xB6, 0x52, 0xBA, 0x1E, 0x45, 0xAF, 0x80, 0x81, 0x8D, 0xC3, 0xCF, 0xE2, 0x57, 0x3F, 0xF9, 0x00, - 0x4D, 0xF9, 0xB8, 0xAD, 0xFC, 0x03, 0xB4, 0x3C, 0x5E, 0x50, 0x3C, 0x84, 0x5D, 0x9E, 0xB0, 0x2B, 0xBE, 0x02, 0x44, 0x9E, 0xF3, 0x40, 0x5C, 0x76, - 0x32, 0x9F, 0xCB, 0x17, 0x5F, 0x6E, 0xCD, 0x4B, 0x2B, 0xE6, 0xA8, 0xEC, 0xE2, 0xA0, 0x68, 0xB8, 0x01, 0x12, 0xB5, 0xA9, 0x21, 0x9A, 0x02, 0x43, - 0x33, 0x8A, 0x20, 0x16, 0xB7, 0xFD, 0x78, 0xD6, 0x61, 0x71, 0xB1, 0x52, 0x61, 0x72, 0x13, 0x60, 0x41, 0x08, 0x15, 0x4C, 0x38, 0xDF, 0x9E, 0x20, - 0x48, 0x12, 0x69, 0x62, 0xE4, 0xB2, 0x80, 0x08, 0x7E, 0x2B, 0x84, 0x56, 0x0F, 0x44, 0x2F, 0xF7, 0xB1, 0x37, 0xF0, 0xF1, 0xF7, 0x3A, 0x96, 0x25, - 0x74, 0xB8, 0x4F, 0x70, 0xA4, 0x60, 0x6D, 0xC0, 0x59, 0x68, 0x18, 0x01, 0xC8, 0x90, 0xEB, 0xC6, 0xD9, 0xF3, 0x5D, 0xF8, 0xFA, 0x01, 0xA8, 0x7A, - 0x2F, 0xF4, 0x87, 0xD8, 0x9D, 0x56, 0xE4, 0x95, 0xB6, 0xFC, 0xD1, 0x7B, 0x05, 0xA0, 0x43, 0x19, 0x9F, 0x15, 0xF5, 0x9C, 0x6D, 0x99, 0x9A, 0x79, - 0xC5, 0x9A, 0x9D, 0xA8, 0x96, 0xA7, 0x27, 0x2C, 0xCB, 0x35, 0x5E, 0x5D, 0x64, 0x5D, 0x0F, 0x89, 0x5B, 0x99, 0x62, 0xB0, 0x82, 0x82, 0xA0, 0x0E, - 0x7E, 0xA1, 0xDA, 0xBC, 0xC5, 0x35, 0x13, 0xE0, 0x4D, 0x99, 0xB0, 0x48, 0x5D, 0xC1, 0x48, 0x05, 0xC0, 0xE5, 0xEB, 0x06, 0xC0, 0x5D, 0x03, 0xE3, - 0x8D, 0x04, 0x3E, 0xE9, 0x7B, 0x3A, 0x96, 0x9F, 0x23, 0xF7, 0x5F, 0xF8, 0x16, 0x40, 0xE5, 0x3A, 0x72, 0xCB, 0x41, 0x5C, 0xCA, 0x50, 0x5D, 0x31, - 0xBE, 0x0C, 0x24, 0xAF, 0x1D, 0x80, 0x31, 0x97, 0x01, 0x99, 0x02, 0xDF, 0xB1, 0x5F, 0xE2, 0x30, 0x24, 0xE7, 0x0B, 0xDF, 0x50, 0x61, 0xD6, 0x5B, - 0xE1, 0x0D, 0x5E, 0xE0, 0x63, 0x67, 0xE0, 0x1C, 0xF5, 0xAF, 0xC9, 0x8A, 0xEF, 0x95, 0x0C, 0x6F, 0x56, 0xCB, 0x2E, 0xDE, 0x4C, 0x0B, 0xBE, 0xB2, - 0x5C, 0xCE, 0x01, 0xB8, 0x8C, 0x75, 0xF1, 0xDB, 0x5C, 0x09, 0xB4, 0xFA, 0x06, 0xB4, 0x28, 0x77, 0xB3, 0xDF, 0x83, 0xAC, 0x11, 0x89, 0x58, 0x37, - 0x24, 0x2C, 0x99, 0xE5, 0x2B, 0x7C, 0xD5, 0xB5, 0x41, 0xAC, 0xDE, 0x94, 0x56, 0x6E, 0x9A, 0x12, 0x27, 0x6D, 0xC6, 0x23, 0x3D, 0x52, 0x30, 0xDA, - 0x26, 0x20, 0x4A, 0xD7, 0x14, 0xFA, 0xA6, 0x83, 0x26, 0x98, 0xB3, 0x88, 0x13, 0x7E, 0x72, 0xE8, 0xE0, 0xA9, 0x76, 0x85, 0x77, 0xFD, 0xED, 0xAC, - 0xD7, 0x72, 0x22, 0x4F, 0x6E, 0x96, 0x10, 0xDA, 0xFC, 0x03, 0x32, 0x59, 0x53, 0x32, 0x33, 0x4E, 0x2F, 0x7F, 0x9B, 0x2F, 0x6D, 0x82, 0xF1, 0x96, - 0x1D, 0x2A, 0x2B, 0xBC, 0xA4, 0x2A, 0x51, 0xF0, 0x94, 0x0A, 0xE4, 0x93, 0x36, 0x99, 0x92, 0x1D, 0xF0, 0x22, 0xB7, 0xE6, 0x90, 0x2A, 0x06, 0xEF, - 0x14, 0xC8, 0x1E, 0x35, 0xAB, 0x54, 0xF4, 0x49, 0x3B, 0x16, 0xCF, 0x36, 0x76, 0xFE, 0xA5, 0x80, 0xAE, 0x80, 0x22, 0x75, 0x09, 0xC5, 0x4B, 0xE1, - 0xE2, 0x6D, 0xD1, 0x62, 0xD3, 0x66, 0x22, 0x74, 0xD8, 0x3D, 0x51, 0xCC, 0x7E, 0xC2, 0x45, 0x06, 0x31, 0x42, 0xD9, 0xE1, 0x1B, 0xD2, 0x44, 0x09, - 0x15, 0xB8, 0x60, 0xEC, 0xC9, 0x9B, 0x44, 0x6F, 0x2E, 0xFE, 0x38, 0x85, 0x7D, 0xFD, 0xBF, 0xA2, 0xFA, 0x94, 0x0A, 0xC2, 0x0E, 0x2C, 0x1C, 0xFF, - 0x41, 0x41, 0x43, 0x53, 0x04, 0xAD, 0x04, 0x38, 0x20, 0x0C, 0xC9, 0x5E, 0x65, 0x81, 0x69, 0x4A, 0x9D, 0x05, 0xBE, 0xF0, 0x14, 0xE8, 0x7C, 0x25, - 0xA2, 0xD4, 0xCA, 0x1E, 0x8E, 0x59, 0x0A, 0x9B, 0x2A, 0x99, 0x2D, 0xAA, 0xB1, 0x30, 0x1D, 0xD2, 0x34, 0xE1, 0x62, 0x3D, 0xCB, 0x6A, 0x2F, 0x8B, - 0x8F, 0x1D, 0x47, 0x2A, 0x88, 0x3C, 0x07, 0x59, 0x63, 0x61, 0x09, 0xE1, 0xDB, 0x0C, 0xCB, 0xCD, 0xB8, 0x80, 0x5C, 0x0D, 0x68, 0x88, 0xAE, 0x63, - 0xCF, 0x30, 0xC6, 0xC8, 0x48, 0xC5, 0x5E, 0x4A, 0xC2, 0x1A, 0xF8, 0x82, 0x35, 0x05, 0xC5, 0x41, 0x64, 0x7C, 0xA5, 0x75, 0x79, 0x55, 0xD2, 0x74, - 0xDD, 0x1D, 0xE0, 0x8A, 0x85, 0x6F, 0x0D, 0xF2, 0x69, 0x11, 0xD7, 0x64, 0x49, 0x22, 0xC8, 0x12, 0x89, 0xD2, 0xBB, 0x6A, 0xD8, 0x7B, 0x20, 0x99, - 0x94, 0x96, 0xDB, 0x8B, 0x79, 0xF3, 0x76, 0x71, 0x6C, 0x64, 0x68, 0x64, 0x90, 0xAA, 0x06, 0xA6, 0xC5, 0x3F, 0x28, 0x7F, 0xA5, 0x41, 0xC9, 0xBD, - 0x2A, 0x01, 0xC4, 0xBB, 0xEE, 0xA2, 0xB8, 0x62, 0x53, 0xB6, 0x06, 0xD7, 0xB4, 0x86, 0x9B, 0xB3, 0x24, 0xA5, 0xB2, 0x44, 0x54, 0xAE, 0x5C, 0xE5, - 0xD0, 0x3F, 0x46, 0xC3, 0x30, 0xF0, 0xA0, 0xA9, 0x58, 0x10, 0x04, 0x71, 0xDD, 0xB9, 0x21, 0x21, 0xF8, 0x32, 0x70, 0x97, 0x47, 0x86, 0x60, 0x2E, - 0xC3, 0x9D, 0x60, 0xD2, 0xB0, 0x5F, 0xE2, 0x5D, 0x66, 0xD9, 0xF0, 0x23, 0xE8, 0x9D, 0x6D, 0xDD, 0xB0, 0xA8, 0x22, 0xF4, 0x33, 0xE0, 0xB0, 0x6F, - 0x28, 0xB4, 0xCB, 0x7D, 0x78, 0x83, 0x17, 0x7A, 0x28, 0x10, 0x41, 0x8E, 0x1A, 0x3A, 0x2C, 0x12, 0xC1, 0x95, 0x0C, 0x34, 0x5D, 0x1E, 0x41, 0x9C, - 0x13, 0x34, 0x60, 0x31, 0x02, 0xBC, 0x99, 0x3B, 0xC9, 0x10, 0x04, 0x84, 0x50, 0x77, 0xAE, 0x3C, 0x08, 0x38, 0x07, 0xDC, 0x09, 0x8B, 0x0C, 0xE7, - 0x4A, 0xB8, 0xFB, 0xE8, 0x19, 0x96, 0x1E, 0x71, 0xC7, 0x93, 0x35, 0x8C, 0x72, 0x07, 0xAD, 0x15, 0x37, 0x6C, 0x44, 0x02, 0xDA, 0xC0, 0x83, 0x5B, - 0x32, 0x4B, 0xE8, 0x0A, 0x72, 0x08, 0x1A, 0xC4, 0x42, 0xB3, 0xE7, 0xFB, 0xF8, 0xFA, 0x41, 0xAB, 0x5E, 0xBD, 0xE7, 0xFA, 0x43, 0xEC, 0xA7, 0x15, - 0x8F, 0xA5, 0x2D, 0x47, 0xA2, 0x49, 0x49, 0xA0, 0x67, 0x7D, 0x9E, 0x81, 0x7F, 0x9C, 0x99, 0xB5, 0xF4, 0xCE, 0x1D, 0x5B, 0xF9, 0x66, 0x12, 0x20, - 0x39, 0x73, 0xED, 0x01, 0x66, 0x1D, 0x02, 0xCB, 0x41, 0x55, 0xCA, 0x50, 0x56, 0x31, 0xBE, 0xDA, 0x92, 0xD7, 0xDC, 0x60, 0xCC, 0x55, 0x40, 0xA6, - 0x60, 0xE1, 0xD8, 0xAF, 0x70, 0x5F, 0x68, 0x37, 0x7E, 0xDC, 0x2C, 0xEE, 0xE4, 0x24, 0x16, 0xB5, 0x0F, 0x43, 0xAE, 0x78, 0xE1, 0xCB, 0x29, 0xCC, - 0x0A, 0x2B, 0xBC, 0x71, 0x0B, 0x7C, 0x0C, 0x03, 0x18, 0xC7, 0xF9, 0xD7, 0xA4, 0xC4, 0xF7, 0x6A, 0xC5, 0x85, 0x4E, 0x8C, 0xDE, 0x01, 0xD0, 0xBC, - 0x59, 0x27, 0xBB, 0x78, 0x2D, 0xBA, 0x72, 0x42, 0x7A, 0xC2, 0xA4, 0x16, 0x7C, 0x5F, 0xB9, 0x9C, 0x65, 0xB8, 0x8C, 0x09, 0x6E, 0x73, 0xEB, 0x6C, - 0x5B, 0x43, 0x6D, 0x4B, 0x38, 0xCC, 0x68, 0x83, 0x19, 0x69, 0x73, 0x84, 0x67, 0x3D, 0x46, 0x65, 0xB1, 0x3A, 0x62, 0x77, 0x5C, 0xC0, 0x16, 0xC0, - 0x79, 0xD5, 0x62, 0x63, 0xB9, 0x66, 0xA0, 0x9A, 0x95, 0xFB, 0x92, 0xA2, 0xFE, 0x15, 0xA6, 0xBB, 0x81, 0xA6, 0x6E, 0xD8, 0xD2, 0x75, 0xA4, 0x0E, - 0x29, 0x1C, 0xC6, 0x28, 0xCB, 0x07, 0x51, 0xB6, 0x12, 0xCB, 0x50, 0x25, 0x49, 0xD0, 0x07, 0x31, 0x58, 0x9C, 0xB1, 0x7E, 0x8A, 0x38, 0xF1, 0x84, - 0x60, 0xBC, 0x88, 0xB7, 0x14, 0x4A, 0xE2, 0x24, 0xEC, 0x42, 0x80, 0x19, 0x7B, 0x67, 0x89, 0xD7, 0xA7, 0xE6, 0xD4, 0x64, 0x83, 0xFB, 0x47, 0xFC, - 0x51, 0xD4, 0xAB, 0x1F, 0xB0, 0x2A, 0x18, 0x24, 0xAA, 0xA8, 0x8C, 0xA8, 0x82, 0x0A, 0x4C, 0xB9, 0x89, 0x49, 0x7D, 0xE9, 0x45, 0xE5, 0x2D, 0x80, - 0xCF, 0x21, 0x42, 0x09, 0x8E, 0x3D, 0xF9, 0x7D, 0x3A, 0x65, 0xD2, 0x35, 0x3D, 0xEA, 0x99, 0x6C, 0xEB, 0x4B, 0xA2, 0x2C, 0x94, 0x9E, 0x55, 0x24, - 0xF9, 0xEA, 0x26, 0xB9, 0xA0, 0x22, 0x6D, 0x4C, 0x1F, 0x0D, 0xDD, 0x8D, 0x72, 0x60, 0x8A, 0xC2, 0x54, 0x89, 0xAE, 0x98, 0x86, 0xE8, 0x86, 0x85, - 0xE2, 0xCE, 0xDE, 0x1E, 0x3E, 0x82, 0xF0, 0x9C, 0x80, 0x24, 0x75, 0x7E, 0x08, 0x05, 0xF8, 0xB8, 0x5A, 0xF5, 0x70, 0x42, 0xE0, 0x11, 0xDE, 0xD9, - 0xC9, 0x0D, 0xB1, 0xF3, 0x71, 0x95, 0x23, 0x4D, 0x99, 0xC3, 0xF3, 0x86, 0x83, 0x22, 0xE2, 0x46, 0xEB, 0x82, 0x8D, 0x51, 0x65, 0x8D, 0x01, 0x43, - 0x1A, 0xB2, 0xD7, 0x06, 0xC8, 0x32, 0x86, 0x87, 0x31, 0x90, 0x78, 0x18, 0x4F, 0xCF, 0x17, 0xD6, 0x5C, 0x17, 0xDD, 0x16, 0x2D, 0xC7, 0xD0, 0x2D, - 0xEA, 0x68, 0x96, 0x8E, 0x16, 0x2B, 0x34, 0x2E, 0x2A, 0x3A, 0xD1, 0x29, 0x49, 0xD2, 0x28, 0x59, 0x2E, 0x00, 0xCE, 0x5E, 0x4E, 0xE4, 0x94, 0x4C, - 0x20, 0x2C, 0x95, 0xF0, 0x05, 0x68, 0x8F, 0x30, 0x23, 0x61, 0x6C, 0xA0, 0x1F, 0xB9, 0x74, 0x20, 0x82, 0x3F, 0x0B, 0xA1, 0x0D, 0xCC, 0x83, 0xE8, - 0x1F, 0x7C, 0xEC, 0xED, 0x3E, 0xFE, 0x07, 0x8F, 0x36, 0x88, 0x0E, 0xB7, 0x24, 0xC7, 0x7B, 0x72, 0x03, 0xCE, 0x2A, 0xD7, 0x88, 0xB7, 0xC6, 0x33, - 0xE4, 0xC6, 0xBA, 0x72, 0x49, 0x7A, 0x42, 0xA8, 0x56, 0x39, 0x71, 0xFE, 0x34, 0xC3, 0x6E, 0x21, 0x26, 0x6E, 0x9C, 0xD0, 0x12, 0x83, 0x9C, 0x7E, - 0xBC, 0x58, 0x34, 0x8A, 0xFF, 0x5F, 0x1F, 0x58, 0x09, 0x59, 0x6B, 0x25, 0xE7, 0x7F, 0x76, 0x5F, 0xB3, 0x09, 0x04, 0x06, 0x25, 0x7C, 0xF5, 0xF6, - 0x88, 0x3F, 0x12, 0x46, 0x15, 0x23, 0x97, 0x8F, 0x22, 0xF8, 0xBF, 0x10, 0xDA, 0x54, 0x10, 0xFD, 0xE3, 0xC7, 0xFE, 0xFE, 0xF1, 0x53, 0x3D, 0xDA, - 0xAA, 0x1D, 0xEE, 0x17, 0x1B, 0x51, 0x1E, 0x76, 0xB0, 0x0F, 0x07, 0x7B, 0x1D, 0xFE, 0xFF, 0x8D, 0xF2, 0x9A, 0xA6, 0x09, 0x11, 0x38, 0xF5, 0x69, - 0x82, 0x24, 0x6E, 0xF5, 0x87, 0xB0, 0x89, 0x6E, 0x8D, 0xFF, 0x39, 0xE9, 0x61, 0x14, 0x32, 0xB0, 0xE4, 0x14, 0x7E, 0xE0, 0xF4, 0x70, 0x1F, 0x3C, - 0x2B, 0x0D, 0x48, 0xEF, 0x4C, 0x05, 0x0C, 0x71, 0x37, 0xD1, 0x0B, 0x19, 0x7B, 0x8C, 0x1D, 0x0C, 0x98, 0x52, 0x14, 0xD0, 0x1B, 0x46, 0x3C, 0x0F, - 0xD3, 0x38, 0x33, 0x02, 0x70, 0xFE, 0x28, 0x66, 0x1E, 0xD5, 0x65, 0x06, 0xC3, 0x5A, 0x1E, 0x59, 0x52, 0xC6, 0xD3, 0x63, 0x68, 0x44, 0x48, 0x16, - 0xE1, 0xA2, 0x1F, 0xFB, 0x6A, 0x81, 0x5B, 0x99, 0x2B, 0xE8, 0x8C, 0xFB, 0x2C, 0x14, 0xBF, 0x6C, 0x70, 0xCB, 0x12, 0x9D, 0x1F, 0x4E, 0xA9, 0x4D, - 0x32, 0xC5, 0xCC, 0xAD, 0x5F, 0x1E, 0xC7, 0x2D, 0x49, 0xE0, 0x3E, 0x8A, 0x0C, 0xF4, 0x99, 0xFF, 0xFF, 0x7A, 0xEF, 0xF3, 0x7E, 0xBA, 0x0F, 0x76, - 0x03, 0xBE, 0xC7, 0x72, 0x8E, 0x4B, 0x72, 0x1C, 0x24, 0x71, 0xA9, 0x66, 0x71, 0x39, 0x3F, 0x6F, 0xC4, 0x0E, 0xE2, 0xE4, 0x88, 0xE1, 0x59, 0x92, - 0x7C, 0x59, 0x22, 0x6A, 0xDF, 0x55, 0xB1, 0x1D, 0xEB, 0xBE, 0x85, 0x25, 0xE3, 0x95, 0xFE, 0x5C, 0x24, 0x2A, 0x55, 0x44, 0x39, 0x91, 0x28, 0xF6, - 0xDB, 0x3E, 0x61, 0xC4, 0x02, 0xD1, 0x80, 0xA9, 0x06, 0x60, 0x7B, 0x2B, 0x06, 0xBB, 0x88, 0x3F, 0xCB, 0xC7, 0x7A, 0x86, 0x5C, 0xD5, 0xBA, 0x3F, - 0x8F, 0xBC, 0xB9, 0xFA, 0x59, 0xAB, 0x82, 0xB1, 0x58, 0x45, 0x35, 0x45, 0x15, 0xE4, 0x60, 0xCA, 0x8D, 0x4D, 0xEA, 0x2B, 0x30, 0x2A, 0x8F, 0x02, - 0x7C, 0x2E, 0x12, 0x4A, 0x90, 0xC0, 0x93, 0x5F, 0xDE, 0x29, 0x93, 0xDE, 0xF4, 0x58, 0xCC, 0x64, 0x4B, 0xB8, 0x24, 0xCA, 0xAA, 0xF4, 0xAC, 0x99, - 0xE4, 0x6B, 0x9C, 0xE4, 0x52, 0x8B, 0xC4, 0x21, 0x72, 0x34, 0xC4, 0x79, 0x4B, 0x74, 0x95, 0x35, 0x44, 0xE7, 0x2C, 0x14, 0x17, 0xF7, 0xF6, 0xB0, - 0x12, 0x84, 0xB7, 0x05, 0x24, 0x79, 0xF4, 0x43, 0x28, 0xE7, 0xE3, 0x3A, 0xD6, 0xC3, 0xB9, 0xC7, 0x23, 0x8C, 0xB4, 0x93, 0x7B, 0x62, 0xE7, 0x83, - 0x2C, 0x47, 0x9A, 0x45, 0x0E, 0x0F, 0x03, 0x1C, 0x94, 0xC4, 0x1B, 0xAD, 0x3F, 0x1B, 0x23, 0xD0, 0x1A, 0x03, 0x8F, 0x34, 0x64, 0xBB, 0x33, 0x15, - 0x3C, 0xB8, 0x1D, 0x7C, 0x19, 0x43, 0xC8, 0x18, 0x48, 0x55, 0x18, 0xCF, 0xD5, 0x17, 0xD6, 0x61, 0x17, 0x5D, 0xE2, 0x16, 0xE4, 0x8F, 0x96, 0x35, - 0x08, 0x4B, 0x07, 0xF1, 0x0A, 0xCD, 0x8E, 0xCA, 0x0E, 0x48, 0x8A, 0x52, 0x08, 0x4A, 0xD6, 0x0E, 0x80, 0x33, 0x9E, 0x13, 0xB9, 0x2B, 0x13, 0x08, - 0x58, 0x25, 0x7C, 0x6F, 0xED, 0x11, 0x70, 0x24, 0x8C, 0x17, 0xF6, 0x23, 0x97, 0x79, 0x22, 0xF8, 0xB8, 0x10, 0x5A, 0x13, 0x7A, 0x10, 0x3D, 0x86, - 0x8F, 0xBD, 0xDE, 0xC7, 0x3F, 0xF4, 0x68, 0x23, 0x72, 0x70, 0xF8, 0x1C, 0xEF, 0x0D, 0x78, 0x8B, 0x68, 0x52, 0x18, 0xE8, 0xD9, 0xA5, 0x67, 0x60, - 0xA6, 0x67, 0xA2, 0x7A, 0xDF, 0xEC, 0x37, 0x94, 0x35, 0x5A, 0xDC, 0xCB, 0x9F, 0xF5, 0x19, 0xF6, 0xF3, 0x11, 0x4D, 0x81, 0x1F, 0xC3, 0x26, 0x8D, - 0x80, 0xCB, 0xFB, 0x8F, 0x37, 0x58, 0xDB, 0xAC, 0x5F, 0xFE, 0xEA, 0x9F, 0x0B, 0xE4, 0x60, 0xE4, 0xDC, 0xE1, 0xA0, 0x99, 0xC4, 0x2C, 0xF0, 0x23, - 0xFA, 0x25, 0x22, 0x56, 0xE9, 0x0F, 0xF3, 0x36, 0xBE, 0x89, 0x37, 0xE9, 0x3A, 0x89, 0x60, 0xBA, 0xDE, 0x4B, 0x3D, 0x93, 0x83, 0x9E, 0xB8, 0x54, - 0xCF, 0x08, 0xB9, 0x6B, 0xF8, 0x61, 0x69, 0xA8, 0xF7, 0x19, 0x6C, 0x39, 0x76, 0xF6, 0x02, 0x9D, 0xB5, 0x1D, 0x88, 0x5B, 0x9D, 0xE1, 0x8B, 0xD8, - 0x99, 0x5E, 0xE4, 0x91, 0xB6, 0xBC, 0x8A, 0x26, 0xC5, 0x82, 0x9E, 0x7D, 0x7B, 0x06, 0x86, 0x73, 0x66, 0xBE, 0xE0, 0xDC, 0x91, 0xD7, 0x4C, 0x02, - 0x97, 0xA7, 0x0C, 0x85, 0x21, 0xC6, 0x97, 0x89, 0xE4, 0xB5, 0x43, 0x18, 0x73, 0x78, 0x64, 0x0A, 0x9E, 0xC7, 0x7E, 0xB9, 0xFB, 0x05, 0x99, 0xC6, - 0x8F, 0xD0, 0xC5, 0x7F, 0xB4, 0xC4, 0xA2, 0xFA, 0x61, 0xC8, 0xE5, 0x17, 0xBE, 0xD2, 0xC2, 0xAD, 0x28, 0xC2, 0x1C, 0x2F, 0xC0, 0xC8, 0x44, 0xC0, - 0x39, 0x4B, 0xBF, 0x26, 0x60, 0xBE, 0x57, 0x66, 0x2E, 0x76, 0x8A, 0x7A, 0xD5, 0x98, 0x78, 0xB3, 0xC2, 0x76, 0xF1, 0xCE, 0x74, 0xE5, 0xE6, 0x7A, - 0xC2, 0x07, 0x2D, 0xF8, 0x3A, 0xE4, 0x72, 0x7E, 0xC0, 0x65, 0x6C, 0xBC, 0xCD, 0x95, 0xB4, 0xC5, 0xD7, 0x6B, 0xA5, 0x59, 0x69, 0xF5, 0x2A, 0x68, - 0x51, 0x28, 0x67, 0x3F, 0xAA, 0xAC, 0x91, 0x6B, 0xAC, 0x5B, 0x18, 0x96, 0xEC, 0xB8, 0x95, 0x0D, 0xA7, 0x7D, 0xCA, 0xD7, 0x62, 0xB9, 0x69, 0x57, - 0x73, 0xAA, 0x4B, 0x52, 0xFA, 0x2F, 0xEE, 0x09, 0x5C, 0x6B, 0x84, 0x69, 0x7B, 0x35, 0xB7, 0xCF, 0x01, 0x9C, 0x21, 0xD2, 0xF2, 0xF4, 0x02, 0x72, - 0x29, 0xD1, 0x10, 0xA5, 0xCF, 0xA4, 0x5D, 0xCD, 0x42, 0x5F, 0xCC, 0x62, 0x8E, 0xCB, 0x5C, 0x2C, 0x95, 0x19, 0xBD, 0x8E, 0x41, 0xC3, 0x8C, 0x91, - 0x21, 0x8B, 0xBD, 0x30, 0x85, 0x39, 0x68, 0x83, 0x35, 0x9D, 0xC5, 0x41, 0x00, 0x7D, 0xA5, 0x3D, 0xF0, 0xAA, 0xE4, 0xEA, 0xBA, 0xFB, 0xC0, 0x15, - 0x6B, 0x60, 0x6B, 0x50, 0x52, 0x8B, 0xD8, 0x2B, 0x4B, 0x32, 0x44, 0x96, 0x08, 0x82, 0x2B, 0x57, 0xCA, 0xAB, 0x1F, 0x0D, 0x55, 0x30, 0x5C, 0xAB, - 0xA8, 0x12, 0x50, 0x05, 0xD9, 0xA7, 0xDC, 0x36, 0x48, 0x7D, 0x71, 0x46, 0xE5, 0x31, 0xC2, 0xE7, 0x6E, 0xA1, 0x04, 0x39, 0x3C, 0xF9, 0x39, 0x3B, - 0x65, 0xA6, 0x68, 0xBA, 0xAF, 0x30, 0xD9, 0x96, 0x2E, 0x89, 0x42, 0x2B, 0x3D, 0xFF, 0x26, 0xFD, 0xB6, 0x24, 0xBD, 0x68, 0x20, 0x71, 0x24, 0x1D, - 0x0D, 0x01, 0x1B, 0xE5, 0x94, 0x15, 0x89, 0x6D, 0x10, 0x5D, 0xD5, 0x0D, 0x31, 0xB0, 0x11, 0x8A, 0x03, 0x74, 0x7B, 0x90, 0x0A, 0xC2, 0x6B, 0x00, - 0x24, 0x29, 0xFF, 0x21, 0xF4, 0xE0, 0xE3, 0x8A, 0xD7, 0xC3, 0x09, 0xC9, 0x23, 0x4C, 0x60, 0x27, 0x77, 0x75, 0xE7, 0x83, 0xDE, 0x96, 0x26, 0xB6, - 0xF3, 0x10, 0xE2, 0xA0, 0xB0, 0xDE, 0x68, 0x69, 0xDA, 0x18, 0x19, 0xD7, 0x18, 0xA8, 0x2D, 0x13, 0x71, 0x57, 0xD8, 0xAC, 0x3B, 0xE8, 0x71, 0x1B, - 0xDA, 0xC6, 0x40, 0x32, 0xC3, 0x78, 0x36, 0xBF, 0xB4, 0xA6, 0xB8, 0xEC, 0xAA, 0xB4, 0x20, 0x17, 0xD9, 0x5B, 0xD6, 0x46, 0x2C, 0x1E, 0x2B, 0x2B, - 0x34, 0x62, 0x3B, 0x47, 0x6E, 0x25, 0xA4, 0x76, 0xD6, 0x98, 0xFB, 0x8C, 0xAC, 0x2D, 0x47, 0xE7, 0xE6, 0x78, 0x0F, 0x33, 0xEB, 0x98, 0x68, 0x2F, - 0x07, 0x39, 0x28, 0x72, 0x9F, 0xF2, 0xE9, 0x18, 0x9A, 0x68, 0xA5, 0xDB, 0xF3, 0x21, 0x85, 0x99, 0x35, 0x76, 0x42, 0xCB, 0xD3, 0xFB, 0x04, 0xBD, - 0x0E, 0x93, 0x69, 0xBF, 0x98, 0xFE, 0xEB, 0xF5, 0x1E, 0x2C, 0x6C, 0x37, 0xAA, 0x68, 0x6B, 0x6E, 0xB6, 0x59, 0xFC, 0xB1, 0xB8, 0xDA, 0x57, 0x78, - 0x1F, 0x55, 0x60, 0x70, 0xAA, 0xB0, 0x53, 0xEB, 0x27, 0xB7, 0xF5, 0x9A, 0x17, 0x75, 0x22, 0xE7, 0x7A, 0xD7, 0x5D, 0x5C, 0x90, 0x9E, 0xF5, 0xFF, - 0xFF, 0xA7, 0x08, 0x24, 0x04, 0x9E, 0xFD, 0xFF, 0x37, 0x32, 0xD4, 0x19, 0x6A, 0xF6, 0x66, 0xA6, 0xE6, 0x3C, 0xCE, 0x36, 0x0F, 0x0E, 0x77, 0x06, - 0xCE, 0x24, 0xC4, 0x2D, 0x39, 0xC3, 0x4D, 0xC7, 0xB8, 0x0D, 0x66, 0x00, 0x81, 0x2C, 0x11, 0xB6, 0x22, 0xB8, 0x5C, 0xAE, 0x67, 0x6D, 0x4C, 0x4D, - 0x8D, 0x2F, 0x6B, 0x40, 0xDD, 0x5D, 0x1A, 0x63, 0x9C, 0x80, 0xB9, 0x3B, 0xDA, 0x32, 0x8A, 0x33, 0x3F, 0xD5, 0x33, 0x15, 0xD2, 0x00, 0x8F, 0xC3, - 0x01, 0x90, 0x7C, 0xC7, 0x40, 0x66, 0xC5, 0xD2, 0xE8, 0xC2, 0x7A, 0x94, 0xC1, 0xEE, 0xEA, 0x52, 0xB4, 0xF8, 0x41, 0x15, 0xF7, 0xB8, 0x05, 0x51, - 0x8E, 0x37, 0xE4, 0x12, 0xDC, 0xF2, 0x6B, 0xCE, 0x19, 0xAF, 0xB1, 0x3E, 0x14, 0x90, 0x84, 0x8B, 0x99, 0x42, 0x65, 0x60, 0x7D, 0x32, 0xA0, 0xC2, - 0x69, 0xD1, 0xB8, 0x49, 0x03, 0x2A, 0x0A, 0x61, 0xA5, 0xE0, 0x9E, 0xA4, 0xD3, 0x8E, 0xA4, 0x4F, 0x82, 0xB4, 0x01, 0x7B, 0x24, 0x62, 0x69, 0x04, - 0x42, 0x55, 0x04, 0xDF, 0x22, 0x72, 0x92, 0x95, 0xCB, 0xC1, 0xA5, 0xAA, 0x08, 0xB4, 0x01, 0x85, 0x30, 0xF0, 0x63, 0xA1, 0x82, 0xCF, 0x8A, 0x0C, - 0x3D, 0x26, 0x0A, 0x79, 0x64, 0x13, 0x77, 0x3E, 0x37, 0x75, 0x96, 0x41, 0x73, 0x68, 0x0D, 0x71, 0x90, 0x99, 0x6F, 0x9A, 0x3B, 0x6D, 0x58, 0x70, - 0x6B, 0xBC, 0x7A, 0x69, 0x94, 0x9E, 0x67, 0xE6, 0xD6, 0x6E, 0x0A, 0x6C, 0x19, 0x3F, 0x77, 0xCC, 0x1C, 0x1A, 0xE6, 0xF1, 0xE9, 0xE5, 0xAF, 0xC5, - 0x65, 0x35, 0xAD, 0x05, 0x32, 0x89, 0xC5, 0x17, 0x6A, 0x85, 0xB5, 0x6C, 0x65, 0x63, 0x40, 0xCA, 0x71, 0x5D, 0x0A, 0x8E, 0x04, 0x94, 0x12, 0x40, - 0x00, 0x56, 0x23, 0x4E, 0x74, 0x1C, 0x98, 0xC0, 0xAD, 0x28, 0xC1, 0x0A, 0x6C, 0xEB, 0xC1, 0x92, 0x14, 0x88, 0x1C, 0x29, 0x71, 0x29, 0x92, 0x21, - 0x1F, 0xB2, 0x29, 0x0B, 0xB2, 0x58, 0xFC, 0xFE, 0xC0, 0x8D, 0xE1, 0xD1, 0xC9, 0xDA, 0x21, 0x7D, 0xC2, 0xD1, 0xC2, 0x98, 0x03, 0x44, 0x73, 0xE3, - 0x8B, 0x68, 0x3C, 0x7D, 0xC1, 0x33, 0xDC, 0x3D, 0x6C, 0xB2, 0xA1, 0x35, 0x3C, 0xEB, 0xAE, 0x6E, 0x10, 0xFF, 0x74, 0xB7, 0xD3, 0xA8, 0xA9, 0xD2, - 0x80, 0xCE, 0xF7, 0x68, 0xD6, 0x26, 0x58, 0x07, 0x80, 0xB0, 0x44, 0x64, 0xAF, 0x2A, 0xBC, 0xA8, 0x08, 0x7E, 0x51, 0x5F, 0x14, 0x5C, 0x8E, 0xBA, - 0x2D, 0xA3, 0xD3, 0x56, 0xF4, 0x0A, 0xAE, 0x68, 0x91, 0xAD, 0x64, 0xC7, 0x51, 0x2A, 0x21, 0x4E, 0xD2, 0x14, 0x49, 0x9A, 0xCD, 0x23, 0xA3, 0x7E, - 0x1E, 0xF2, 0x81, 0x13, 0xFC, 0xAE, 0xF6, 0xC0, 0xF0, 0x2F, 0xC0, 0x17, 0xDE, 0xED, 0x86, 0x0A, 0xA6, 0xB9, 0x88, 0xFB, 0xBD, 0xAF, 0xAA, 0xE4, - 0xF6, 0x64, 0xDA, 0x1C, 0xFF, 0x7F, 0x0C, 0x90, 0x44, 0x9F, 0xB4, 0x3B, 0x0F, 0x3E, 0x75, 0x14, 0x54, 0xE6, 0x73, 0x42, 0xE8, 0xE5, 0x21, 0xE2, - 0xF1, 0x94, 0x1E, 0xF9, 0x0A, 0x05, 0xF1, 0xA3, 0x2C, 0xF9, 0x21, 0x70, 0x4A, 0x97, 0xC7, 0xF7, 0x79, 0xBB, 0xDA, 0x72, 0x13, 0x09, 0x6C, 0xD3, - 0x3B, 0x96, 0xFF, 0x44, 0xD6, 0xF7, 0xF6, 0xE8, 0x5D, 0xF9, 0x3A, 0xE1, 0x81, 0xEF, 0x36, 0xC9, 0xC9, 0xF7, 0xF3, 0x5A, 0x73, 0x15, 0x3F, 0xE2, - 0xBE, 0x2D, 0x1D, 0xFA, 0x43, 0x47, 0xDA, 0x31, 0xBC, 0xDF, 0x85, 0x4F, 0xDB, 0x48, 0x74, 0x0C, 0x9A, 0x64, 0x8C, 0xAC, 0x57, 0xEC, 0xE5, 0x27, - 0xCC, 0xC1, 0x1A, 0xAC, 0x69, 0x0B, 0x84, 0x9B, 0x9E, 0x26, 0x57, 0xAF, 0x7C, 0xA2, 0xDF, 0xED, 0xD5, 0x63, 0xD3, 0xE8, 0x83, 0x27, 0xEA, 0xC0, - 0x50, 0xFF, 0xFF, 0xC1, 0xBE, 0x1F, 0xF4, 0x3F, 0x81, 0xF6, 0xEF, 0xFA, 0x9F, 0xDE, 0xFE, 0x6F, 0x3A, 0x1F, 0x61, 0x9B, 0xD2, 0x8B, 0xCE, 0xA8, - 0xD9, 0x86, 0x45, 0x40, 0xC7, 0x17, 0xD6, 0x63, 0x68, 0xA0, 0xEB, 0x37, 0xEB, 0x28, 0x8B, 0xF4, 0x6F, 0x5B, 0xF7, 0xE9, 0xFB, 0xEE, 0xE6, 0x3A, - 0x17, 0x8A, 0x1F, 0xA5, 0x52, 0x47, 0x40, 0xFA, 0xD9, 0x8C, 0xEA, 0x7D, 0xBE, 0xDF, 0x8E, 0xA5, 0xED, 0x98, 0xF1, 0x45, 0x20, 0xB5, 0x53, 0x69, - 0x7E, 0xD3, 0x9F, 0x53, 0x57, 0x50, 0xD3, 0x3F, 0x01, 0xC7, 0xD7, 0x9F, 0x04, 0x7B, 0x18, 0x2B, 0xBE, 0x6D, 0xA3, 0xA8, 0xFE, 0xE7, 0x2C, 0xBD, - 0x3D, 0xE0, 0x04, 0xE1, 0x9D, 0x01, 0x49, 0x52, 0xFD, 0x10, 0x3E, 0xF0, 0x71, 0x25, 0xD0, 0xC3, 0xF9, 0x81, 0x47, 0xB8, 0x6A, 0x27, 0x57, 0x72, - 0xE7, 0xA3, 0x2D, 0x47, 0x9A, 0x35, 0x87, 0xA7, 0x02, 0x0E, 0x0A, 0xE5, 0x8D, 0x56, 0xA1, 0x8D, 0x91, 0x6B, 0x8D, 0x81, 0x4D, 0x1A, 0xB2, 0xE3, - 0x99, 0x0A, 0x86, 0x6E, 0x07, 0x24, 0x32, 0x86, 0x9D, 0x31, 0x90, 0xB7, 0x30, 0x9E, 0xB8, 0x2F, 0xAC, 0xCE, 0x2E, 0xBA, 0xCF, 0x2D, 0xC8, 0x2B, - 0x2D, 0x6B, 0x16, 0x96, 0x0E, 0xE8, 0x15, 0x1A, 0x24, 0x95, 0x9D, 0x96, 0x14, 0xA5, 0x16, 0x94, 0xAC, 0x24, 0x00, 0x67, 0x49, 0x27, 0x72, 0x65, - 0x26, 0x10, 0xCA, 0x4A, 0xF8, 0xEA, 0xDA, 0x23, 0xEA, 0x48, 0x18, 0x01, 0xFF, 0xC8, 0x25, 0xA0, 0x08, 0xBE, 0x41, 0x08, 0xED, 0x1D, 0x44, 0xEF, - 0xE1, 0x63, 0x1F, 0xE8, 0xE1, 0x78, 0xF8, 0x3D, 0xDA, 0x91, 0x1C, 0x1C, 0x72, 0x38, 0xDE, 0xF9, 0x0D, 0x38, 0xB1, 0x46, 0xBC, 0x38, 0x83, 0x0D, - 0x84, 0xCE, 0x5E, 0x10, 0x32, 0x5F, 0x3F, 0x30, 0x56, 0xEF, 0x19, 0x7F, 0x11, 0x22, 0xD3, 0x8B, 0x22, 0xD2, 0x96, 0x3D, 0xD1, 0xA4, 0x3D, 0xD0, - 0xB3, 0x59, 0xCF, 0xC0, 0x59, 0xCE, 0xCC, 0x71, 0xCE, 0x1D, 0x71, 0xCD, 0x24, 0x5A, 0xCC, 0x3A, 0x18, 0x96, 0x83, 0x0A, 0x28, 0x43, 0xC9, 0xC5, - 0xF8, 0xD2, 0x4B, 0x5E, 0xDB, 0x83, 0x31, 0x87, 0x88, 0x4C, 0xE1, 0xC4, 0xB1, 0xDF, 0xE7, 0xBE, 0x90, 0x85, 0xF1, 0xA3, 0xBE, 0xB8, 0x53, 0x97, - 0x58, 0x14, 0x74, 0x38, 0x16, 0xF4, 0x85, 0xEF, 0xAE, 0xB0, 0xF2, 0xAE, 0x30, 0xC7, 0x0F, 0x56, 0xF9, 0xC0, 0x39, 0x31, 0xBF, 0x48, 0x31, 0xBE, - 0x57, 0x4D, 0x2E, 0x02, 0x34, 0xF5, 0xAA, 0xC9, 0xF0, 0x66, 0x1D, 0xED, 0xE2, 0x39, 0xE9, 0xCA, 0x8D, 0xE9, 0x09, 0x05, 0xB4, 0xE0, 0xA3, 0xCB, - 0xE5, 0x84, 0x80, 0xCB, 0x58, 0xBF, 0xCD, 0x0D, 0x61, 0x8B, 0x67, 0x50, 0x2B, 0x4D, 0x49, 0xAB, 0xFF, 0xA3, 0x45, 0x19, 0x31, 0xFB, 0x1F, 0x65, - 0x8D, 0x56, 0xC4, 0xBA, 0x53, 0x61, 0xC9, 0x60, 0x5F, 0xE1, 0x2F, 0x5C, 0x1B, 0xC0, 0x68, 0x65, 0xF3, 0x38, 0xCD, 0x20, 0x6D, 0x3A, 0x7B, 0x65, - 0x2A, 0xE2, 0x45, 0xCA, 0xFC, 0x46, 0xFA, 0x83, 0x60, 0x94, 0x04, 0x4B, 0xB4, 0x4B, 0x43, 0x68, 0x10, 0x1C, 0xA8, 0x9B, 0x02, 0x16, 0x5F, 0x79, - 0x9F, 0x79, 0x7D, 0x9E, 0xF7, 0x26, 0x3C, 0x5A, 0x6C, 0xA7, 0x1F, 0x9E, 0x13, 0x94, 0x74, 0x33, 0x44, 0x1E, 0xCA, 0xC2, 0xF2, 0xE8, 0xFB, 0xDD, - 0x06, 0x7D, 0x8E, 0x54, 0xFC, 0x15, 0x01, 0x88, 0xEB, 0xDB, 0xBD, 0x55, 0x83, 0x2C, 0x6B, 0xDE, 0x84, 0x3C, 0x23, 0xE2, 0xAA, 0xDF, 0x05, 0xD5, - 0x51, 0x99, 0xD4, 0x46, 0x69, 0x54, 0x17, 0x2F, 0x4A, 0x93, 0x06, 0xE9, 0xCE, 0x89, 0xA4, 0x67, 0xAB, 0x7F, 0xC2, 0x26, 0xC9, 0xFF, 0x1D, 0x3A, - 0x6A, 0x23, 0x99, 0xD7, 0x00, 0x79, 0x0A, 0xF9, 0x61, 0x62, 0x16, 0x71, 0x2C, 0xAE, 0x05, 0x56, 0x78, 0x31, 0xA8, 0xC0, 0xD0, 0x53, 0x61, 0x1F, - 0xA6, 0x9C, 0x20, 0xA2, 0xD4, 0x78, 0x02, 0x20, 0xFA, 0x3C, 0xE9, 0x62, 0x31, 0x11, 0xD3, 0x97, 0xB4, 0x45, 0xB7, 0x1B, 0x7C, 0x91, 0xE4, 0xB9, - 0x8C, 0x68, 0xD0, 0x15, 0x41, 0x54, 0x0A, 0xE1, 0x04, 0x71, 0x76, 0xD3, 0x7F, 0xE0, 0x02, 0x7A, 0x10, 0x3F, 0x3E, 0x88, 0xF1, 0xF9, 0x1C, 0xBC, - 0x66, 0x70, 0xBA, 0xA9, 0xDF, 0x05, 0xFA, 0x4A, 0xC9, 0x5A, 0x44, 0xDD, 0xA3, 0x0E, 0x21, 0x9A, 0x35, 0x44, 0x1E, 0xB1, 0x88, 0x57, 0x6F, 0xA0, - 0xC9, 0x62, 0xC4, 0x17, 0x7E, 0xCF, 0x47, 0x0C, 0xED, 0x01, 0x7D, 0x63, 0xBE, 0x86, 0x5A, 0x63, 0xAD, 0xB6, 0x53, 0x7F, 0xA8, 0x3B, 0xC2, 0xF2, - 0x63, 0xA0, 0x4D, 0xB3, 0x4C, 0xA0, 0x6D, 0xDC, 0xC5, 0x56, 0x11, 0x1F, 0x86, 0x16, 0x51, 0x35, 0x16, 0xAC, 0x98, 0xDA, 0xEA, 0xDD, 0xE5, 0xF4, - 0xF4, 0x34, 0x39, 0xFE, 0x67, 0xD3, 0x74, 0x1C, 0xC7, 0x9B, 0x82, 0x49, 0x7E, 0xE2, 0x6D, 0x20, 0x2E, 0x03, 0x65, 0xC9, 0x6D, 0x65, 0x43, 0x19, - 0x12, 0xF3, 0x72, 0x1A, 0xC0, 0xC6, 0x36, 0xE3, 0x7C, 0x8B, 0xA2, 0xBD, 0x71, 0x4A, 0x15, 0xB9, 0xF0, 0x3A, 0x0E, 0xB2, 0x20, 0x1F, 0x43, 0x4C, - 0xCE, 0xF3, 0x64, 0x12, 0x1D, 0xFF, 0x49, 0x94, 0x3B, 0x29, 0xC6, 0xD3, 0x18, 0xC0, 0x0F, 0x40, 0x41, 0x28, 0xCE, 0x67, 0xC0, 0x14, 0x91, 0x19, - 0x57, 0xD4, 0xD3, 0xAF, 0xD8, 0xCB, 0x8B, 0x8A, 0x29, 0xC5, 0x8E, 0x25, 0xB9, 0x90, 0x81, 0xB1, 0x1A, 0x5F, 0x93, 0xD0, 0x9B, 0x08, 0x1A, 0xC5, - 0x80, 0x0A, 0x15, 0x88, 0x3F, 0xED, 0x0E, 0xC5, 0x8B, 0x84, 0xD6, 0x7E, 0x82, 0xC7, 0xFC, 0x9D, 0x04, 0xA0, 0xBE, 0xBB, 0xC3, 0xB5, 0x7C, 0x4F, - 0x64, 0x0F, 0x8F, 0x29, 0xCA, 0xCE, 0xAE, 0xCB, 0x6F, 0x3D, 0xAE, 0x2C, 0x40, 0x8F, 0x42, 0x75, 0x73, 0x53, 0x65, 0x33, 0xD4, 0x59, 0x73, 0x80, - 0x90, 0xA6, 0xA9, 0x6E, 0x86, 0x8F, 0xC5, 0x7D, 0x15, 0x41, 0x46, 0x83, 0x8B, 0x18, 0xB2, 0x1A, 0x97, 0x4D, 0xE4, 0x16, 0x59, 0x2D, 0x16, 0xDB, - 0x04, 0x2B, 0xC9, 0xA1, 0x6D, 0x2E, 0x0E, 0x24, 0x28, 0x18, 0x8C, 0x1C, 0x38, 0x13, 0x29, 0x85, 0x0A, 0x81, 0x94, 0x04, 0x01, 0x0E, 0xF9, 0x58, - 0x05, 0xFA, 0xD0, 0xD8, 0xFB, 0x1D, 0xC4, 0xCE, 0x1D, 0x36, 0x62, 0x1C, 0x21, 0xA3, 0x1B, 0x53, 0xEE, 0xAF, 0xD1, 0xE3, 0x21, 0x83, 0x6D, 0x98, - 0x9D, 0x35, 0xB2, 0x5F, 0x53, 0x88, 0x53, 0xC7, 0xD9, 0x7E, 0xC2, 0xA2, 0x69, 0x3D, 0x45, 0xE9, 0xCD, 0x1F, 0x7D, 0xA2, 0x0E, 0xDA, 0x36, 0xF5, - 0x3B, 0x37, 0x63, 0x35, 0xEB, 0x66, 0x36, 0x8F, 0xD4, 0x2E, 0x4F, 0x1F, 0x2D, 0x1F, 0xE9, 0x2A, 0xCB, 0x8C, 0xC5, 0x20, 0x73, 0x4C, 0x66, 0xC2, - 0x83, 0xC1, 0x40, 0x07, 0x59, 0xC0, 0xE0, 0xB1, 0x5F, 0xD8, 0x67, 0xE4, 0x98, 0xB0, 0x5F, 0x74, 0xC3, 0x2A, 0xC6, 0xB0, 0x25, 0xC2, 0x61, 0x9C, - 0x78, 0xA2, 0x80, 0xC8, 0x56, 0x72, 0xA8, 0x56, 0xC2, 0x44, 0x85, 0x20, 0x3A, 0x72, 0x0A, 0x3B, 0x08, 0x6B, 0x8D, 0x8D, 0x2F, 0xA0, 0x00, 0x47, - 0x47, 0x97, 0xD9, 0xD7, 0xEA, 0xFD, 0x5A, 0xB7, 0x50, 0xC2, 0x3A, 0x43, 0x0B, 0xBE, 0x50, 0xE2, 0x6F, 0x6D, 0x40, 0x4F, 0x42, 0xFD, 0xD0, 0x63, - 0x3F, 0x45, 0x7B, 0xD1, 0xD9, 0x2B, 0xB1, 0xF9, 0x52, 0x39, 0xC2, 0xA6, 0xE3, 0xB3, 0xD5, 0x1A, 0x78, 0xF5, 0x39, 0xFD, 0x1B, 0x90, 0x2B, 0xAB, - 0xBA, 0xB7, 0x4A, 0x7F, 0x57, 0x07, 0x17, 0x2E, 0xD4, 0xAF, 0x2D, 0x15, 0x4A, 0x5A, 0xBC, 0x43, 0x59, 0xAA, 0x01, 0xB2, 0xD8, 0xF1, 0xAB, 0xE2, - 0x06, 0x57, 0x35, 0x0A, 0xAC, 0x34, 0xCE, 0xAA, 0xA6, 0xFA, 0xA8, 0x6E, 0x1E, 0x4C, 0xB5, 0xA1, 0x90, 0xAA, 0xFA, 0xD0, 0xBE, 0x40, 0x5A, 0x97, - 0x6C, 0x37, 0xB6, 0x31, 0xB0, 0xB6, 0x31, 0x4D, 0xDB, 0x27, 0x8C, 0xDB, 0xB5, 0xC0, 0x6D, 0xCD, 0xD6, 0xFA, 0xF3, 0x46, 0xFB, 0x76, 0x5F, 0x77, - 0xB1, 0x69, 0x47, 0x8F, 0xD4, 0x87, 0x38, 0xEA, 0x30, 0x3E, 0xF5, 0xB0, 0x9B, 0xBA, 0x93, 0x56, 0x7D, 0xAA, 0x5E, 0xA0, 0xEE, 0xE6, 0xD4, 0xAE, - 0xE3, 0x6A, 0xE7, 0x09, 0x68, 0x07, 0x1A, 0x68, 0x23, 0x42, 0x68, 0x4F, 0x66, 0x68, 0x83, 0x86, 0x68, 0x27, 0xB6, 0xED, 0x0E, 0xB8, 0x7B, 0x59, - 0xB8, 0x41, 0xDB, 0x19, 0xAE, 0x6D, 0x10, 0xC5, 0xBA, 0x4B, 0x65, 0xBD, 0x27, 0xB4, 0xCE, 0xF4, 0x5A, 0xDF, 0xE2, 0xAD, 0x0B, 0x40, 0xAE, 0xAB, - 0xEB, 0x77, 0xED, 0x7A, 0x9F, 0x4C, 0x7D, 0x10, 0xA8, 0xEE, 0x54, 0xD7, 0xE4, 0xAA, 0xA3, 0x42, 0xCD, 0x6B, 0x8B, 0xF5, 0x98, 0xF3, 0xE6, 0x4C, - 0x79, 0x87, 0xDE, 0x7E, 0x65, 0x4F, 0x9F, 0x23, 0x36, 0x3F, 0x0C, 0xFD, 0x86, 0xB6, 0xCD, 0x76, 0xA9, 0xAA, 0xFD, 0x33, 0xA0, 0x5B, 0xAA, 0xEA, - 0x35, 0xEA, 0x42, 0x33, 0xFC, 0x0D, 0x19, 0x8A, 0x04, 0xEE, 0x93, 0x5E, 0xDB, 0x09, 0xF3, 0xB9, 0x29, 0x11, 0xC8, 0x8C, 0xC9, 0x96, 0x65, 0x69, - 0xB3, 0x44, 0xE9, 0x19, 0x09, 0x0B, 0x37, 0x68, 0xD6, 0x85, 0x0C, 0x2B, 0xBA, 0x6B, 0x76, 0x28, 0x89, 0x14, 0xE6, 0xC0, 0x6C, 0x58, 0x19, 0xA9, - 0x13, 0xDF, 0x6C, 0x57, 0x9C, 0x5D, 0x08, 0xAE, 0xF3, 0xED, 0xB6, 0xE5, 0xD6, 0xC3, 0x95, 0x73, 0x27, 0x3E, 0xEF, 0xB9, 0x47, 0x59, 0x4E, 0xB8, - 0x7F, 0x91, 0xDE, 0x9C, 0x87, 0x78, 0xBC, 0x36, 0x96, 0x4B, 0x5A, 0x5C, 0x84, 0xEC, 0x87, 0x41, 0xD7, 0xDF, 0x5D, 0x95, 0x47, 0xD5, 0x83, 0xE7, - 0x27, 0xD0, 0x79, 0x2E, 0xD3, 0x81, 0x01, 0xCE, 0x69, 0xA9, 0xC1, 0x69, 0xA2, 0xBC, 0x49, 0x32, 0xB6, 0x89, 0x5B, 0xAB, 0x09, 0xA0, 0x49, 0x73, - 0xE8, 0x33, 0xD3, 0x00, 0xC9, 0x1D, 0xA2, 0x54, 0x26, 0x90, 0x1D, 0x53, 0xF9, 0x01, 0x26, 0x32, 0xFF, 0x02, 0x4B, 0xC0, 0x85, 0x75, 0xB0, 0x25, - 0x19, 0x48, 0x0F, 0x19, 0x22, 0x3E, 0xC5, 0xD6, 0xF7, 0x3C, 0xC8, 0x27, 0xAA, 0xC9, 0x23, 0x70, 0xE5, 0xEF, 0x27, 0xE4, 0x23, 0x58, 0xE2, 0xAB, - 0x0B, 0xF4, 0x95, 0x81, 0xF1, 0xE1, 0x61, 0x3D, 0x0F, 0x06, 0xFD, 0x8B, 0xC8, 0xF8, 0x0E, 0x0C, 0x7D, 0x0E, 0x85, 0xFC, 0x4D, 0x8E, 0x1E, 0x6A, - 0x32, 0xEF, 0x45, 0x97, 0x4B, 0xB0, 0x10, 0x7F, 0x6B, 0xD3, 0x97, 0x55, 0x7E, 0x5A, 0xFE, 0xCF, 0x91, 0x8F, 0x62, 0xE7, 0x95, 0x29, 0x0B, 0x8F, - 0x6D, 0xC1, 0x78, 0x77, 0x75, 0xA8, 0xE2, 0x42, 0x85, 0xB0, 0xA5, 0xA2, 0x4D, 0x8B, 0x37, 0x2D, 0x4B, 0xB5, 0x42, 0x16, 0x3B, 0xC2, 0x55, 0x71, - 0xE1, 0x55, 0x8D, 0x08, 0x2B, 0x8D, 0x0B, 0x55, 0x53, 0x95, 0x54, 0x37, 0x86, 0x53, 0x6D, 0xAF, 0x52, 0x55, 0x9D, 0xF0, 0x51, 0xAE, 0xA0, 0xBA, - 0x02, 0x40, 0x79, 0x0F, 0x7E, 0x02, 0xF5, 0x7C, 0x10, 0x3F, 0xF4, 0x4C, 0x22, 0xF2, 0x80, 0x4A, 0xBE, 0x7E, 0xBE, 0xED, 0xF6, 0xE0, 0xBD, 0x2D, - 0xE0, 0xC9, 0xFA, 0x77, 0x86, 0xF1, 0x1B, 0x84, 0xC5, 0xDD, 0xA5, 0xF5, 0xDE, 0xA3, 0x7B, 0x67, 0xDA, 0xDF, 0xB7, 0xA6, 0xEF, 0x69, 0x23, 0x77, - 0x04, 0x30, 0xF7, 0x3B, 0x9F, 0x7B, 0x1F, 0xD3, 0x7D, 0x50, 0xEB, 0xDE, 0x78, 0x76, 0xD7, 0x2C, 0x70, 0x47, 0x15, 0x50, 0xB7, 0x05, 0xF9, 0xC1, - 0xB1, 0xF5, 0x66, 0x59, 0x7A, 0xC7, 0x61, 0x7B, 0x05, 0xF1, 0xE7, 0xCC, 0xD5, 0x29, 0x0F, 0x75, 0xDD, 0x86, 0xB0, 0x13, 0xA0, 0xA7, 0x3C, 0xD4, - 0x5E, 0x6A, 0xA1, 0x1F, 0xAD, 0xD6, 0x64, 0x20, 0x0E, 0x34, 0x03, 0x48, 0xD3, 0xC7, 0x85, 0xAE, 0x02, 0xA7, 0x73, 0x29, 0xD1, 0x91, 0xD4, 0xE8, - 0x08, 0x02, 0xD0, 0xEF, 0xE8, 0x7D, 0x0D, 0xE8, 0xF2, 0xDF, 0xE8, 0x81, 0x8E, 0xF7, 0x51, 0x21, 0xE9, 0x2A, 0x06, 0xFF, 0x87, 0x8F, 0xF9, 0xD9, - 0x92, 0xBF, 0x78, 0xF6, 0xD7, 0xB0, 0x7E, 0x8D, 0x4C, 0xFA, 0x94, 0xF1, 0xBF, 0xA1, 0xA5, 0xBB, 0x89, 0xFC, 0xAA, 0x65, 0x7A, 0x5E, 0xCF, 0x87, - 0x43, 0xA1, 0x0B, 0x8E, 0xD0, 0xF5, 0x88, 0xE8, 0x99, 0x3E, 0x74, 0x30, 0xBA, 0xAD, 0x16, 0x7D, 0xD3, 0xE8, 0x3F, 0x17, 0xA0, 0xE3, 0x8A, 0x7D, - 0x17, 0x3D, 0x7A, 0xF4, 0x82, 0x3F, 0x64, 0xE0, 0xC3, 0xF8, 0xFD, 0xB0, 0x0C, 0xDF, 0x11, 0xF4, 0xC5, 0xFC, 0xD5, 0x79, 0xEE, 0xC2, 0x63, 0x1E, - 0xE3, 0x43, 0x7E, 0x41, 0xAF, 0x09, 0xA8, 0x47, 0xC5, 0x80, 0xB7, 0x35, 0x7A, 0x0B, 0x7F, 0xBC, 0xB3, 0xFA, 0xDE, 0x91, 0x0A, 0x5F, 0x51, 0x7D, - 0xE7, 0x8C, 0xC0, 0xFF, 0xD6, 0x86, 0xC4, 0x59, 0x3E, 0x50, 0x49, 0xFD, 0xBF, 0x63, 0xFF, 0x3B, 0x88, 0x5F, 0x46, 0xE3, 0xFF, 0x7C, 0xD2, 0x9D, - 0x58, 0xE9, 0x5C, 0x7E, 0x3F, 0x8D, 0xF0, 0x1F, 0x10, 0x40, 0x8F, 0xC0, 0xF2, 0x33, 0xC4, 0xD2, 0x45, 0xB8, 0xA0, 0x2B, 0x1E, 0xFE, 0x15, 0x91, - 0x5F, 0x74, 0x8E, 0x1E, 0x8B, 0x47, 0x77, 0xD1, 0xF4, 0x61, 0x34, 0xD3, 0xD7, 0x2B, 0xBE, 0x89, 0xE8, 0x9F, 0xB9, 0x40, 0x17, 0x02, 0xA4, 0xC3, - 0xE3, 0x3F, 0xBE, 0xF6, 0xD7, 0x5E, 0xE8, 0x09, 0x6A, 0xFF, 0x5D, 0x08, 0x7A, 0x5F, 0x22, 0x5D, 0xD0, 0xED, 0xA7, 0x60, 0xF0, 0x31, 0xDF, 0x74, - 0x53, 0x28, 0xFA, 0x6C, 0xF4, 0xFF, 0xC5, 0xA4, 0x2B, 0xDB, 0x7D, 0x0D, 0x16, 0x39, 0x08, 0xB1, 0xDE, 0x05, 0x5A, 0xEF, 0x03, 0xA2, 0x6F, 0x6A, - 0xD1, 0x73, 0xED, 0xE8, 0xD3, 0x92, 0xF4, 0x08, 0xAE, 0xF4, 0x77, 0x65, 0xFA, 0xBE, 0x37, 0xFD, 0x60, 0x9D, 0xDE, 0x71, 0x34, 0xBE, 0x49, 0x8A, - 0xEA, 0x21, 0x6F, 0x3B, 0x05, 0x07, 0xDE, 0x8C, 0x3B, 0x93, 0x14, 0x20, 0x7C, 0x37, 0xC9, 0xE9, 0x41, 0xDE, 0x1E, 0xFD, 0x8C, 0x8D, 0x0C, 0x9E, - 0xF7, 0x7F, 0xDF, 0x55, 0x11, 0x41, 0xE2, 0x2C, 0x1E, 0xE2, 0x43, 0xFF, 0x7F, 0xE6, 0xBF, 0x7C, 0xA4, 0xD9, 0xF9, 0xE6, 0x40, 0xC5, 0x92, 0x61, - 0x24, 0x22, 0xEF, 0xE7, 0xDF, 0x5E, 0xC4, 0x7B, 0xE3, 0x7A, 0x1E, 0xF1, 0xCC, 0x75, 0x3C, 0x31, 0x27, 0x6E, 0xEB, 0x8E, 0x6F, 0x7E, 0xE4, 0x9F, - 0x9F, 0xE2, 0xB8, 0x3A, 0x79, 0x97, 0xB4, 0x78, 0xB4, 0x55, 0x7E, 0x08, 0x2A, 0x0F, 0xE3, 0x96, 0x0F, 0x1B, 0x90, 0x77, 0xB2, 0x90, 0xA7, 0x93, - 0x90, 0x1F, 0x60, 0xCF, 0xBB, 0x35, 0x88, 0xD7, 0xE5, 0xC5, 0xF1, 0x28, 0x39, 0x1B, 0xEE, 0x1D, 0x0A, 0x10, 0xFD, 0x91, 0x76, 0x12, 0xFC, 0xFF, - 0xA0, 0xBC, 0x11, 0xFD, 0x5B, 0xB3, 0x1C, 0x59, 0xAE, 0xA7, 0x22, 0xCF, 0x6C, 0xCB, 0x13, 0x8D, 0xE4, 0xB6, 0x40, 0xF2, 0xCD, 0x15, 0xFD, 0x33, - 0x97, 0x1C, 0xF7, 0x48, 0xEF, 0x62, 0x40, 0x1E, 0x3D, 0xA6, 0x1F, 0xEA, 0xD2, 0xC3, 0xD0, 0xE9, 0xC3, 0x0E, 0xE8, 0x9D, 0xEA, 0x7A, 0x3A, 0x3E, - 0xFD, 0x00, 0x15, 0x7A, 0xB7, 0x0B, 0xF2, 0x3A, 0x40, 0x79, 0x9E, 0x87, 0x78, 0xA0, 0x89, 0x38, 0x22, 0x64, 0x7C, 0x12, 0x1F, 0x07, 0x5D, 0x8D, - 0xBF, 0xE6, 0xC6, 0xED, 0x0E, 0xE5, 0xBD, 0xCF, 0xF2, 0x64, 0xE8, 0xB8, 0x06, 0x48, 0x1C, 0xA4, 0x45, 0xDE, 0xA5, 0x38, 0xDF, 0x13, 0x9D, 0x6F, - 0x0A, 0xC9, 0x73, 0xB9, 0xE4, 0xD3, 0x78, 0xF2, 0x08, 0x94, 0xF2, 0x77, 0x58, 0xF9, 0xBE, 0x00, 0xF9, 0x41, 0xB8, 0x7C, 0x63, 0x83, 0xBC, 0x66, - 0x5E, 0x1E, 0xF5, 0xC1, 0xDD, 0x36, 0xC7, 0x1D, 0x8C, 0x7C, 0x6F, 0x86, 0x61, 0x57, 0x8D, 0x86, 0xB3, 0x04, 0xEA, 0x87, 0x34, 0x36, 0x34, 0x2A, - 0xF3, 0xFF, 0x2F, 0x26, 0xBA, 0x71, 0x98, 0x9E, 0xA3, 0x0E, 0xED, 0xB7, 0x54, 0x90, 0x68, 0xF1, 0x76, 0x64, 0xA9, 0xFE, 0x64, 0xB1, 0x71, 0xAE, - 0x8A, 0xB7, 0xAE, 0x6A, 0xA8, 0xAC, 0x34, 0x80, 0xAA, 0xA6, 0x08, 0x50, 0xDD, 0x70, 0x4D, 0xB5, 0xD1, 0xA5, 0xAA, 0x0C, 0xE8, 0x09, 0xE5, 0x6F, - 0x19, 0xF4, 0x15, 0xF4, 0x89, 0xFA, 0x42, 0xFD, 0x09, 0x50, 0x7D, 0xED, 0xA6, 0x5E, 0x73, 0x51, 0xEE, 0x6C, 0xAB, 0xBF, 0x15, 0x95, 0xB7, 0x34, - 0xEB, 0xA1, 0x7B, 0xE5, 0x42, 0xB8, 0x72, 0x98, 0xB5, 0x1C, 0xEC, 0x59, 0xEE, 0xE4, 0x96, 0xD3, 0xB1, 0xC8, 0x07, 0x3C, 0xC9, 0xDD, 0x4C, 0xF4, - 0x75, 0x33, 0xFA, 0xBC, 0xB7, 0x3E, 0x10, 0x4A, 0x8F, 0xE8, 0xA5, 0x9F, 0x1C, 0xA0, 0x07, 0x45, 0xA0, 0x7F, 0x95, 0xA0, 0xB7, 0x83, 0xEF, 0x7B, - 0x45, 0xEC, 0x93, 0x47, 0xE8, 0x33, 0x16, 0xF5, 0x20, 0x13, 0xE4, 0x2E, 0x7D, 0xF2, 0x1E, 0x41, 0x39, 0x13, 0x0A, 0xF9, 0xD6, 0xA5, 0x5C, 0x00, - 0xA9, 0xFC, 0x80, 0xAC, 0x5C, 0x82, 0xAF, 0x7C, 0x43, 0x0C, 0xF9, 0x60, 0x86, 0xBC, 0xF1, 0x44, 0xAE, 0x49, 0x23, 0x47, 0x45, 0x81, 0xD7, 0x82, - 0xDE, 0x83, 0xEB, 0xF0, 0xE6, 0xBF, 0x77, 0x87, 0xD7, 0x7D, 0xE5, 0xCB, 0x9E, 0xE3, 0xF2, 0x3E, 0xEC, 0xC3, 0xB3, 0xC0, 0x0C, 0xC2, 0x3F, 0x7B, - 0xE6, 0xDE, 0x86, 0x36, 0x4D, 0x40, 0x65, 0x9A, 0x4D, 0x02, 0x8C, 0x7C, 0x00, 0xC7, 0x9A, 0x20, 0x93, 0xDA, 0x84, 0x9B, 0x01, 0x91, 0x31, 0x69, - 0x25, 0xA6, 0x04, 0xB4, 0x36, 0xA1, 0x6D, 0xB2, 0x9D, 0x21, 0xA3, 0x99, 0xE1, 0x52, 0x30, 0x33, 0xB1, 0x2B, 0x8B, 0x2E, 0x51, 0x36, 0x04, 0x82, - 0x0C, 0x40, 0x85, 0xB1, 0xB0, 0x49, 0xB1, 0xA2, 0xC2, 0x30, 0x49, 0xB5, 0xF8, 0x57, 0x9D, 0xAD, 0x17, 0xE3, 0x6B, 0x57, 0x60, 0x33, 0x57, 0x29, - 0xF2, 0x56, 0x8A, 0x5B, 0x2D, 0xE1, 0x76, 0xD6, 0xA9, 0x73, 0xD6, 0x07, 0xD0, 0xD5, 0xF0, 0xCA, 0xD5, 0x4C, 0x89, 0x55, 0xC8, 0x51, 0x55, 0x54, - 0x10, 0x95, 0xCF, 0xD8, 0x54, 0x53, 0x9B, 0x14, 0x17, 0x5D, 0x94, 0x02, 0x65, 0x78, 0x5B, 0x19, 0x94, 0x88, 0xAF, 0xA7, 0x0B, 0x75, 0x4E, 0x1E, - 0x2E, 0x34, 0x1D, 0x02, 0x32, 0x49, 0x1A, 0x2E, 0x7D, 0xAA, 0x29, 0xB9, 0x76, 0x26, 0xED, 0xDE, 0x21, 0x09, 0x9B, 0x40, 0x8A, 0xE0, 0xE1, 0x48, - 0xAD, 0x67, 0x64, 0xF3, 0x51, 0x34, 0x83, 0x48, 0x44, 0xA5, 0x33, 0x14, 0xF5, 0x29, 0xE4, 0x66, 0xF5, 0x36, 0x3B, 0x11, 0x94, 0xE7, 0x06, 0x64, - 0x47, 0xF9, 0x23, 0x78, 0xE5, 0x93, 0x02, 0xAB, 0x27, 0xF3, 0x8D, 0xE7, 0x14, 0x6E, 0xA7, 0x97, 0x53, 0x67, 0x57, 0x4B, 0x07, 0x84, 0x81, 0x3E, - 0x07, 0xC4, 0x04, 0x0E, 0xD2, 0xDC, 0x4D, 0x0F, 0xDE, 0xC6, 0x4D, 0xB3, 0x66, 0x2B, 0x97, 0x26, 0xCC, 0x73, 0x86, 0xC0, 0xA7, 0x9B, 0xAE, 0x85, - 0x8C, 0x05, 0x7D, 0x0C, 0x60, 0x34, 0x4C, 0xA1, 0xC7, 0x8B, 0x23, 0x6C, 0x9B, 0xAE, 0x91, 0x84, 0x51, 0x63, 0x04, 0xD0, 0x54, 0xA4, 0xB4, 0x26, - 0xA4, 0xB6, 0x01, 0xC8, 0xAF, 0xF1, 0xC7, 0xAA, 0xC9, 0x87, 0x86, 0x01, 0x7D, 0x07, 0x71, 0x6E, 0x87, 0x0D, 0x12, 0x47, 0x48, 0x8A, 0x0D, 0x3A, - 0x08, 0xFA, 0xCA, 0xC3, 0xD8, 0x7C, 0x00, 0x2C, 0x1B, 0xBD, 0xA8, 0x3B, 0xEA, 0x02, 0x32, 0xFC, 0x0D, 0x17, 0x8A, 0x44, 0xEC, 0x13, 0x86, 0x67, - 0x27, 0xCC, 0xE4, 0xA6, 0x44, 0x16, 0x26, 0x5B, 0x93, 0x25, 0x4D, 0x68, 0xA5, 0xE7, 0x77, 0x12, 0x6E, 0x4B, 0x92, 0x8B, 0xD7, 0x51, 0x74, 0xD2, - 0xD1, 0x90, 0x90, 0x11, 0x4C, 0x59, 0x51, 0xD8, 0x17, 0x91, 0x53, 0xDD, 0x10, 0x5D, 0x02, 0xA1, 0x01, 0x80, 0x6F, 0xB7, 0xB8, 0xA0, 0x3A, 0x07, - 0x40, 0x79, 0x18, 0x7E, 0x02, 0x03, 0x7D, 0x10, 0x0F, 0x7B, 0x26, 0x23, 0x79, 0x40, 0x3D, 0x77, 0x5E, 0xF3, 0x3B, 0x76, 0x1F, 0x74, 0x7A, 0x89, - 0xE3, 0xC9, 0xC5, 0x39, 0x19, 0xD1, 0x70, 0x1C, 0x10, 0xD6, 0x1B, 0x17, 0xBD, 0x4D, 0x8F, 0x71, 0x0D, 0x93, 0x34, 0x0D, 0x97, 0xC8, 0x4C, 0xDA, - 0x8B, 0x1B, 0x41, 0x8F, 0xCC, 0xDD, 0x52, 0x4C, 0x5F, 0x16, 0xCC, 0xA0, 0xD9, 0x4B, 0x63, 0x9C, 0x8B, 0xA6, 0x03, 0x7C, 0x0B, 0xAA, 0x1C, 0x8B, - 0x2D, 0xCB, 0x4A, 0x70, 0xAF, 0xBD, 0xD9, 0x45, 0xBD, 0x03, 0xD2, 0xBD, 0x12, 0xD9, 0xCE, 0x99, 0x60, 0xA7, 0x3C, 0x34, 0x46, 0xC1, 0x22, 0xE1, - 0xB6, 0xE8, 0x8D, 0x42, 0xD5, 0x1B, 0x88, 0x12, 0xC3, 0x4F, 0x97, 0x52, 0x3B, 0xD8, 0x8C, 0x2F, 0xE3, 0xC5, 0x6D, 0x22, 0xB2, 0xFE, 0x51, 0x79, - 0x6B, 0x8A, 0x70, 0xFC, 0x61, 0x7F, 0x4C, 0x4E, 0x03, 0xDF, 0x75, 0x0F, 0x79, 0xED, 0x29, 0x75, 0x85, 0xC0, 0xD2, 0x1A, 0x6D, 0x90, 0x25, 0x9B, - 0x87, 0xF5, 0xEB, 0xE1, 0x6A, 0xD9, 0xC4, 0x15, 0x07, 0xA4, 0x95, 0xC6, 0xD6, 0xAF, 0x8A, 0x09, 0xA4, 0x02, 0x3A, 0x9C, 0x7A, 0x8A, 0x94, 0xAA, - 0xDA, 0x8B, 0x52, 0xCB, 0xC3, 0xDF, 0x4E, 0x40, 0xE1, 0x15, 0x3F, 0x61, 0x60, 0xE1, 0x54, 0x18, 0xD2, 0x74, 0x42, 0x97, 0xA9, 0x93, 0x67, 0x49, - 0x13, 0x54, 0x49, 0x31, 0x38, 0xE9, 0x76, 0x17, 0x49, 0xD9, 0xE7, 0x28, 0xFA, 0x1F, 0xA5, 0x68, 0x19, 0xC1, 0xC4, 0x14, 0x1D, 0x15, 0x20, 0x72, - 0x6A, 0x1A, 0x2A, 0xD3, 0x13, 0x1A, 0x80, 0xF6, 0x4E, 0x20, 0x17, 0x54, 0xF7, 0x04, 0xC4, 0x61, 0xEF, 0x27, 0x30, 0xCD, 0xC7, 0xF1, 0x44, 0xCF, - 0x64, 0x04, 0x9E, 0x54, 0x16, 0x3B, 0xAF, 0x22, 0x74, 0x88, 0x75, 0x73, 0x92, 0x2B, 0x73, 0x76, 0x1E, 0x71, 0xD6, 0x6B, 0x37, 0x59, 0xA9, 0x36, - 0x34, 0x13, 0x6A, 0xE4, 0x5E, 0xD0, 0x48, 0x09, 0xCE, 0xD0, 0x55, 0xDD, 0x67, 0x78, 0x32, 0x21, 0x22, 0x63, 0xE2, 0x72, 0x60, 0x3C, 0x3F, 0x5E, - 0xF6, 0xAA, 0x5C, 0x74, 0x75, 0x5A, 0x14, 0xDB, 0x5A, 0xD4, 0x56, 0x2B, 0xBC, 0x42, 0x2B, 0x33, 0x6E, 0x2A, 0xEC, 0xAF, 0x94, 0x24, 0x2C, 0x00, - 0xD2, 0x17, 0x00, 0x98, 0xC1, 0x9D, 0xC4, 0x18, 0x9A, 0xD8, 0xE5, 0x95, 0x3C, 0x75, 0xB6, 0x45, 0x98, 0x20, 0x51, 0xC3, 0x1D, 0xB1, 0xC4, 0x8B, - 0xE0, 0x3D, 0x87, 0xCC, 0xE6, 0x82, 0x14, 0xB2, 0xFC, 0x0F, 0x63, 0x4F, 0x0F, 0x4A, 0x68, 0x0F, 0x92, 0x16, 0x1C, 0xB1, 0x2D, 0x1C, 0x41, 0xD1, - 0x1A, 0xCA, 0x49, 0x1A, 0x71, 0x97, 0x0C, 0x91, 0x17, 0xF6, 0x5C, 0x89, 0xBE, 0x86, 0x7A, 0x54, 0xEF, 0xC1, 0xFC, 0x32, 0xC0, 0x69, 0x45, 0x26, - 0x69, 0x07, 0xF7, 0xE8, 0xD1, 0x33, 0xE8, 0x48, 0xBC, 0xE7, 0x4F, 0x0E, 0xB2, 0x21, 0x05, 0xFE, 0xDE, 0xA4, 0x7C, 0x50, 0x33, 0xE8, 0x0B, 0xC2, - 0xDA, 0xDD, 0x69, 0xA4, 0xFC, 0xDF, 0x67, 0xFF, 0x69, 0xFF, 0xAF, 0x3F, 0x81, 0xF9, 0xB7, 0x8A, 0x2F, 0xE3, 0x19, 0x51, 0xBC, 0x43, 0x38, 0xC3, - 0x6B, 0x01, 0xBC, 0xA5, 0xAF, 0x52, 0x28, 0x5F, 0xB5, 0x68, 0xFF, 0x0E, 0xC2, 0xFF, 0x27, 0x71, 0xFF, 0x73, 0xBA, 0x5B, 0x07, 0xE4, 0x6F, 0x4B, - 0x72, 0x23, 0xE0, 0x33, 0x82, 0xCD, 0xCC, 0x82, 0x9C, 0x6B, 0x45, 0x7C, 0xCD, 0xCE, 0xDE, 0xA4, 0xD6, 0x16, 0xFA, 0x07, 0x80, 0xA8, 0x7A, 0xA7, - 0x71, 0x80, 0x11, 0x70, 0x09, 0x00, 0x8E, 0x86, 0x48, 0xD2, 0x36, 0xFB, 0x60, 0xFA, 0x9A, 0x4A, 0xAD, 0x7B, 0x31, 0x0E, 0x6E, 0xF9, 0x69, 0xD5, - 0x6E, 0xC4, 0xA0, 0xD2, 0x4B, 0xD4, 0x13, 0xD4, 0x5F, 0xB5, 0xC2, 0x94, 0xDD, 0x03, 0xE7, 0x4D, 0xC3, 0x66, 0xDF, 0xA1, 0x7A, 0x2B, 0x55, 0xB9, - 0xB3, 0x08, 0xBC, 0xE9, 0xEF, 0x0A, 0x6E, 0x3E, 0xC2, 0xF7, 0x88, 0x42, 0x37, 0xA3, 0xE6, 0xFB, 0x72, 0xD3, 0x8D, 0x2F, 0xBC, 0xD3, 0xDA, 0xBA, - 0xF5, 0x9B, 0xF7, 0x3D, 0xA7, 0xDD, 0x31, 0xF5, 0xDD, 0xBE, 0xB5, 0x83, 0xDD, 0xDF, 0xCE, 0xF6, 0x28, 0x95, 0x3B, 0xD8, 0x8A, 0x9D, 0xCD, 0xE8, - 0xBE, 0xE0, 0xC8, 0x6E, 0xC7, 0xF2, 0x6E, 0x71, 0x23, 0xBD, 0x17, 0x93, 0xDC, 0x96, 0x64, 0x6F, 0xA4, 0xCE, 0xBC, 0xAF, 0xFB, 0x3F, 0x11, 0x87, - 0xCD, 0xBE, 0x83, 0x9F, 0x2C, 0x44, 0x00, 0xC6, 0x1C, 0x62, 0x2C, 0x28, 0x69, 0x9A, 0x98, 0xDC, 0x35, 0x43, 0x01, 0x3B, 0x93, 0xA5, 0x21, 0x9D, - 0x05, 0xA6, 0xFA, 0x59, 0xEF, 0xD6, 0x7B, 0x0F, 0x54, 0x6F, 0xF8, 0xFA, 0x0A, 0x6E, 0xA1, 0x79, 0x1A, 0x06, 0xD7, 0x7C, 0x3F, 0x37, 0xD0, 0x80, - 0xEF, 0xB4, 0x9C, 0x23, 0x96, 0x1C, 0x07, 0x4C, 0x5C, 0x2A, 0x5C, 0x5C, 0x0E, 0xD3, 0x1B, 0x71, 0xDE, 0xDB, 0xD5, 0x99, 0x9B, 0x88, 0x89, 0xB6, - 0xB8, 0x07, 0x04, 0x7E, 0xF0, 0x6C, 0x7B, 0x1F, 0xE4, 0x5D, 0xB9, 0x76, 0x42, 0x08, 0xED, 0xD7, 0xA8, 0x0E, 0x57, 0x07, 0x24, 0xC3, 0x8A, 0x5F, - 0xAD, 0xF7, 0x6F, 0x7F, 0xED, 0xBF, 0x7F, 0x15, 0xBF, 0x91, 0x32, 0xD0, 0x04, 0x67, 0xE7, 0xE3, 0xF6, 0xA4, 0x4E, 0x5E, 0x4B, 0x04, 0x28, 0xD7, - 0x9C, 0x9B, 0x7F, 0x28, 0x91, 0xDF, 0x72, 0x98, 0x53, 0x06, 0xC9, 0xA1, 0x53, 0xCC, 0x61, 0xBB, 0xE4, 0x2F, 0xA5, 0xF3, 0xE1, 0xF7, 0xA2, 0xD5, - 0x4C, 0x88, 0x97, 0x1E, 0x0E, 0x4A, 0xC7, 0x4E, 0x6F, 0xC0, 0x9E, 0x8C, 0x11, 0x1E, 0xB8, 0xB1, 0x87, 0x84, 0xEF, 0x01, 0x91, 0x5A, 0x7A, 0x98, - 0xD3, 0x15, 0xDB, 0x0D, 0x6F, 0xFC, 0x9F, 0x82, 0xBD, 0x86, 0xF9, 0xB6, 0xBF, 0xF4, 0x37, 0x00, 0xE4, 0xEA, 0x3D, 0xC9, 0x9A, 0xAD, 0x90, 0x95, - 0x21, 0x74, 0xC5, 0x5C, 0x78, 0x65, 0xF3, 0x65, 0x45, 0x62, 0xC1, 0xCE, 0xC0, 0xF6, 0x73, 0xCC, 0xFE, 0x4D, 0xCA, 0xBA, 0x9C, 0xFD, 0xD6, 0x12, - 0x2A, 0x4E, 0x85, 0x39, 0xD0, 0x3F, 0x90, 0x57, 0xB8, 0xB4, 0x7F, 0x25, 0x9C, 0xDB, 0xE3, 0xB1, 0x12, 0x9D, 0x11, 0xC2, 0x97, 0x6D, 0x5E, 0x67, - 0x5E, 0x28, 0xD4, 0x0E, 0x6C, 0x9A, 0x8E, 0x8B, 0x01, 0x39, 0x31, 0x22, 0x08, 0xD2, 0x1F, 0x40, 0xD7, 0x7C, 0x15, 0x4D, 0xB1, 0xA4, 0x79, 0xAA, - 0x01, 0x7D, 0x7A, 0x44, 0xAE, 0x2D, 0x0E, 0x12, 0xC0, 0x8E, 0xFF, 0xF4, 0x07, 0xAB, 0x90, 0x38, 0x50, 0x83, 0x58, 0x49, 0xC9, 0x60, 0xAF, 0xBF, - 0x5A, 0x9D, 0x41, 0x4D, 0xE1, 0xB7, 0xC6, 0x3F, 0x18, 0x7F, 0xA5, 0x25, 0x99, 0x79, 0x55, 0x8A, 0x60, 0x75, 0xDD, 0x2D, 0x71, 0xC5, 0x92, 0x6C, - 0x0D, 0x9A, 0x69, 0x0D, 0x23, 0x67, 0x49, 0x32, 0x65, 0x89, 0xB4, 0xAF, 0x5C, 0xCF, 0xAE, 0x7E, 0x80, 0xAA, 0x60, 0x3C, 0xA8, 0xA2, 0x32, 0xA1, - 0x0A, 0xAA, 0x9A, 0x72, 0x7B, 0x4B, 0x7D, 0xB5, 0x45, 0xE5, 0x79, 0xC1, 0xE7, 0x2A, 0x40, 0x09, 0x0A, 0x3D, 0xF9, 0x15, 0x3A, 0x65, 0x7E, 0x35, - 0x3D, 0x6E, 0x32, 0xD9, 0x26, 0x58, 0x12, 0xB5, 0x2B, 0x3D, 0x6F, 0x48, 0xF2, 0xE5, 0x4C, 0x72, 0x61, 0x44, 0xDA, 0xB8, 0x3D, 0x1A, 0xE2, 0x60, - 0x84, 0xE3, 0x5C, 0x14, 0x96, 0x82, 0xE8, 0x6A, 0x65, 0x88, 0xAE, 0x54, 0x28, 0xEE, 0xE8, 0x0D, 0xF8, 0x1B, 0x84, 0xD7, 0x02, 0x24, 0xA9, 0xF1, - 0x43, 0x98, 0xE4, 0xE3, 0x5A, 0xD3, 0xC3, 0x59, 0xC6, 0x23, 0xBC, 0xB1, 0x93, 0x5B, 0xB7, 0xF3, 0x61, 0x93, 0x23, 0x0D, 0x58, 0x97, 0xC3, 0x23, - 0x85, 0x83, 0xD2, 0xE0, 0x46, 0x4B, 0xDE, 0x6B, 0x63, 0xE4, 0xA1, 0xC6, 0xC0, 0xFC, 0x95, 0x86, 0x0C, 0x72, 0xA6, 0x02, 0x01, 0x37, 0x77, 0x83, - 0xD5, 0x64, 0x19, 0xC3, 0xC1, 0x18, 0xC8, 0x4B, 0x18, 0x4F, 0xCC, 0x17, 0x56, 0x59, 0x17, 0xDD, 0xD9, 0x96, 0xE3, 0x18, 0x2D, 0x6A, 0x65, 0x96, - 0x8E, 0xD9, 0x15, 0x1A, 0x00, 0x2A, 0x3A, 0xCA, 0x29, 0x49, 0xCB, 0x28, 0x59, 0x00, 0x00, 0x9C, 0xA1, 0x9C, 0xC8, 0x0D, 0x99, 0x40, 0x20, 0x2A, - 0xE1, 0x8B, 0xB7, 0x47, 0x80, 0x91, 0x30, 0x2A, 0x18, 0xB9, 0x9C, 0x13, 0xC1, 0x87, 0x85, 0xD0, 0x72, 0x00, 0xD1, 0xCF, 0x3F, 0xF6, 0x0B, 0x3E, - 0x7E, 0x07, 0x8F, 0xB6, 0x5F, 0x87, 0xBB, 0x91, 0xE3, 0xED, 0xB8, 0x01, 0x37, 0xD5, 0x88, 0x9F, 0x66, 0xC8, 0x81, 0xCD, 0xD8, 0xF3, 0x60, 0xAC, - 0xF5, 0x83, 0xD3, 0x59, 0xF5, 0x1E, 0xEA, 0x0F, 0x11, 0x3C, 0xAD, 0x28, 0x2C, 0x6D, 0xC9, 0x11, 0x4D, 0xDA, 0x01, 0x3D, 0x7B, 0xF3, 0x0C, 0x8C, - 0xE3, 0xCC, 0x3C, 0xE5, 0xDC, 0x41, 0xD5, 0x4C, 0x92, 0xD3, 0x49, 0xF9, 0xB8, 0xB2, 0xBA, 0xB1, 0xB8, 0x09, 0x9B, 0xAA, 0x69, 0x6C, 0x93, 0x19, - 0xE3, 0x45, 0x26, 0x89, 0x14, 0x66, 0x8A, 0xC7, 0x25, 0x0E, 0x8E, 0xA5, 0xCF, 0xF0, 0x0A, 0x2B, 0xAA, 0xCA, 0xAE, 0x0F, 0x4A, 0x38, 0x02, 0x93, - 0x09, 0x74, 0x24, 0xF5, 0xE8, 0x91, 0x1C, 0xAC, 0x20, 0x13, 0x09, 0xEF, 0x8E, 0x6E, 0x8F, 0x9B, 0x15, 0x54, 0xA4, 0x5A, 0x40, 0x75, 0xC4, 0x2D, - 0x6C, 0xEC, 0x85, 0x4B, 0x11, 0xBD, 0x99, 0x22, 0x23, 0x0F, 0x05, 0x8C, 0x2D, 0xA3, 0x8D, 0x89, 0x45, 0xA7, 0x66, 0x45, 0x2A, 0x7C, 0xA2, 0x9A, - 0xCA, 0x09, 0xB7, 0x5C, 0xC4, 0xBA, 0xE7, 0xC3, 0x3C, 0x68, 0x13, 0x1F, 0x58, 0xD2, 0x0C, 0x93, 0xA6, 0xB9, 0xEC, 0x95, 0x19, 0x6E, 0x4B, 0x20, - 0xFA, 0x42, 0x0F, 0xAE, 0x12, 0x08, 0x61, 0xFF, 0x9F, 0x99, 0xF3, 0x5B, 0x15, 0x89, 0x46, 0xA8, 0xD7, 0xC7, 0xFB, 0x17, 0x05, 0xDE, 0x9C, 0x54, - 0x34, 0xDB, 0x8B, 0x6C, 0xF0, 0x5C, 0x2B, 0x12, 0xD4, 0x0F, 0x7E, 0xEA, 0x2B, 0x17, 0xDE, 0x9D, 0x2B, 0xBF, 0xE7, 0xBA, 0x77, 0x57, 0xDF, 0x8B, - 0xD0, 0xEE, 0x35, 0xF1, 0xBB, 0xB4, 0xC5, 0x5D, 0x03, 0xF2, 0x0E, 0x4E, 0x72, 0x4F, 0xED, 0xBC, 0xBF, 0x8B, 0xBD, 0xED, 0xEA, 0xDD, 0xC0, 0x0E, - 0x77, 0xA7, 0x7B, 0xB0, 0xD7, 0xE6, 0xDD, 0x43, 0x3C, 0xF8, 0xE0, 0x2E, 0xD1, 0x7B, 0xEB, 0x89, 0xED, 0x5D, 0x62, 0xF7, 0x65, 0x56, 0x37, 0xD8, - 0xE7, 0x5B, 0xC5, 0xD8, 0xAD, 0xC7, 0xFC, 0x06, 0x6A, 0xB5, 0xFF, 0x49, 0xBF, 0xD1, 0x3C, 0xDE, 0x74, 0x93, 0x6A, 0x8D, 0x0C, 0x4E, 0x39, 0x47, - 0x07, 0xA7, 0xDD, 0x8E, 0xAE, 0x9C, 0xC3, 0xAE, 0x49, 0xAA, 0xD1, 0xC9, 0x87, 0xC5, 0xC6, 0xCD, 0xC0, 0x52, 0x3B, 0x53, 0xC0, 0x9A, 0x92, 0x40, - 0xAA, 0xC8, 0x02, 0x8E, 0xD9, 0x42, 0x4A, 0xDE, 0x51, 0xF2, 0xFF, 0x67, 0x7F, 0xB5, 0xBA, 0xEF, 0x9F, 0x66, 0xC2, 0xBE, 0x5D, 0x6F, 0xFD, 0xF0, - 0x9F, 0x03, 0xD8, 0x02, 0xAA, 0x25, 0x96, 0x7C, 0x41, 0x04, 0xAC, 0x18, 0x35, 0x84, 0x3F, 0xFA, 0x39, 0xF1, 0x73, 0xBD, 0xBA, 0x0C, 0x1B, 0xF6, - 0xB9, 0x02, 0xFD, 0xAB, 0x35, 0xA8, 0x31, 0xFC, 0xD0, 0xDE, 0x58, 0xD7, 0x9B, 0xA9, 0x8F, 0x43, 0x45, 0x80, 0x4E, 0x48, 0xB7, 0xF0, 0x69, 0xF5, - 0x76, 0x5A, 0x14, 0xC5, 0xD9, 0xCF, 0x29, 0x6B, 0x14, 0xFA, 0x2A, 0x36, 0xE7, 0xDA, 0xD6, 0x67, 0x2A, 0xAC, 0xA2, 0xD4, 0xF9, 0xB4, 0xF4, 0x03, - 0x95, 0xB4, 0x25, 0x78, 0x2E, 0x2A, 0x84, 0x0A, 0x26, 0xCC, 0x82, 0xED, 0xC5, 0x27, 0x5D, 0xC7, 0xBE, 0xD8, 0x24, 0x73, 0xB5, 0x38, 0x73, 0xE4, - 0x3D, 0xBF, 0xBC, 0x39, 0xD9, 0xAF, 0xA8, 0x12, 0xDA, 0x53, 0xBE, 0x7D, 0xED, 0xF5, 0xA2, 0x3D, 0xBC, 0x14, 0xB5, 0xC0, 0x0A, 0x26, 0xB1, 0xC7, - 0x59, 0xE6, 0x7C, 0x7C, 0x48, 0x7A, 0x87, 0x7B, 0xF5, 0xB7, 0x4F, 0x41, 0xD6, 0x66, 0x9E, 0xD9, 0x94, 0xDE, 0x1D, 0x06, 0xBA, 0x81, 0xCE, 0x6F, - 0xF1, 0x71, 0x7F, 0xEC, 0x87, 0xFD, 0xAF, 0xDF, 0xF5, 0xB3, 0x7E, 0xFC, 0xDF, 0xFC, 0x8E, 0xBF, 0xF0, 0x0B, 0x7E, 0x10, 0x1F, 0xEF, 0x4F, 0xF8, - 0x0B, 0xFE, 0x81, 0x5F, 0xF6, 0xBB, 0xFE, 0xD3, 0x77, 0xFA, 0xE4, 0x50, 0x1E, 0xC2, 0x47, 0xF0, 0xFD, 0x70, 0x99, 0xB2, 0x62, 0x01, 0xF8, 0x4F, - 0x6B, 0x52, 0x69, 0x2E, 0xEA, 0x41, 0x8F, 0xF7, 0x46, 0x28, 0xE4, 0x0F, 0xDC, 0x7F, 0x81, 0x32, 0x86, 0x1F, 0x62, 0x20, 0x23, 0x61, 0x3C, 0x25, - 0x5F, 0x58, 0x5D, 0x74, 0x59, 0x5B, 0x8E, 0x7F, 0x8B, 0x7A, 0x50, 0xC1, 0x02, 0xE8, 0x3D, 0x99, 0xF8, 0xE7, 0xD8, 0x05, 0x52, 0xB0, 0xC6, 0x59, - 0xBB, 0xFC, 0xCC, 0x2F, 0x07, 0xA2, 0x38, 0x5F, 0xA1, 0xE5, 0xC5, 0xCF, 0x45, 0xE3, 0xAA, 0x4A, 0x8B, 0x17, 0x90, 0x0C, 0x54, 0xAE, 0x69, 0xD4, - 0xA6, 0x69, 0x54, 0x2C, 0x17, 0x4E, 0xA1, 0x56, 0x02, 0x3E, 0x93, 0x9C, 0x3C, 0x5B, 0xA0, 0x7F, 0x1A, 0x1D, 0x2C, 0x35, 0xD4, 0x6A, 0xC0, 0x6F, - 0xF9, 0xDF, 0x3E, 0xDB, 0xFF, 0xA2, 0x5C, 0x99, 0xA6, 0x9C, 0x6F, 0x48, 0x66, 0xC3, 0x69, 0x6B, 0xFC, 0xBF, 0x26, 0x7C, 0x79, 0xBB, 0x72, 0x9A, - 0x8B, 0xE8, 0xD1, 0x9F, 0x2A, 0x7F, 0x84, 0x55, 0x7A, 0x1C, 0x4C, 0x1D, 0xAE, 0x83, 0xD2, 0x4D, 0x66, 0x44, 0xDB, 0x00, 0x54, 0x02, 0x50, 0x2B, - 0xD8, 0x26, 0x08, 0xCB, 0xD7, 0x60, 0xD7, 0x02, 0x55, 0xD5, 0x28, 0xC0, 0x18, 0x30, 0x39, 0x9C, 0x66, 0x2F, 0x11, 0x00, 0xFB, 0x81, 0x56, 0x99, - 0x7C, 0x16, 0x43, 0xC7, 0x4C, 0xD6, 0xC4, 0x0C, 0xC5, 0xAA, 0xBD, 0xFC, 0x2E, 0xF3, 0xD9, 0x21, 0x53, 0xF1, 0x1A, 0xE3, 0xBA, 0x12, 0x43, 0x42, - 0x10, 0x86, 0xE0, 0x0D, 0x2C, 0x80, 0x86, 0x78, 0xDF, 0x85, 0x2F, 0x05, 0x0A, 0xBC, 0x1A, 0x0D, 0xBB, 0x3A, 0xF4, 0x71, 0xA1, 0x76, 0x6E, 0xA9, - 0x40, 0xA1, 0xC5, 0x7B, 0x98, 0xA5, 0x4A, 0xEA, 0xD2, 0xB6, 0xD2, 0xA8, 0xE7, 0x29, 0xB5, 0xE1, 0x6A, 0xA0, 0x04, 0x5F, 0x9E, 0xF4, 0xA2, 0x96, - 0x9A, 0x12, 0xD7, 0xCC, 0xEA, 0x9B, 0x53, 0x0E, 0xEA, 0xB8, 0x6C, 0x81, 0xF5, 0x68, 0x0A, 0x47, 0x43, 0x76, 0x46, 0x30, 0x25, 0x8A, 0xC2, 0x40, - 0x10, 0x39, 0x65, 0xB6, 0x0B, 0x70, 0x04, 0xFF, 0xBF, 0xFE, 0x1F, 0x8D, 0xD8, 0xB0, 0xE3, 0xCC, 0xFE, 0xA1, 0xF2, 0x3D, 0xBF, 0x83, 0x40, 0xBF, - 0x65, 0x53, 0x47, 0xF8, 0x91, 0xBC, 0xFA, 0xE9, 0x69, 0xDD, 0xC1, 0xA6, 0xB9, 0xCF, 0x44, 0x7A, 0xAC, 0x14, 0xAC, 0x56, 0x6A, 0x01, 0x9B, 0x64, - 0xF9, 0x00, 0x49, 0xD9, 0xD2, 0xFE, 0x7A, 0xD9, 0x46, 0xEA, 0xB5, 0xEF, 0x12, 0x68, 0x9B, 0xAD, 0xED, 0x20, 0x98, 0xF5, 0x0A, 0x02, 0xDC, 0x44, - 0x9E, 0x75, 0x7B, 0x8E, 0xDD, 0xAE, 0xB4, 0x5E, 0x4A, 0x77, 0xCF, 0xD5, 0x5F, 0x30, 0xBB, 0x17, 0x85, 0xEB, 0x1F, 0xA0, 0xF6, 0xD1, 0x15, 0x6D, - 0xB0, 0x18, 0xF7, 0x48, 0xBB, 0x8E, 0x2F, 0x73, 0x6B, 0xC4, 0xDB, 0x21, 0x8E, 0xED, 0x63, 0x37, 0x6D, 0xDC, 0x3E, 0xB7, 0x60, 0xBE, 0xFD, 0xCC, - 0xE1, 0xBE, 0xDC, 0x6A, 0xB3, 0xB8, 0xDA, 0x5F, 0x0C, 0xBB, 0x93, 0xEC, 0xEE, 0x5C, 0xB8, 0xF6, 0x31, 0x8E, 0x3B, 0x7A, 0xA8, 0x4E, 0xC2, 0x94, - 0x7F, 0x73, 0xCB, 0x71, 0x2B, 0xFE, 0x95, 0x0A, 0xBE, 0x5A, 0xD5, 0xEB, 0x05, 0x6A, 0x0F, 0xFF, 0x91, 0x10, 0x51, 0xEE, 0xCC, 0x6C, 0xE6, 0xDC, - 0x71, 0xD6, 0x4C, 0xD2, 0xC4, 0xAC, 0xF3, 0x60, 0x39, 0x08, 0x4D, 0x19, 0x4A, 0x40, 0x8C, 0x2F, 0xBB, 0xE4, 0x35, 0x08, 0x30, 0xE6, 0x40, 0x20, - 0x53, 0x08, 0x71, 0xEC, 0x37, 0xB9, 0x2F, 0xA4, 0x34, 0x7E, 0x6C, 0x2D, 0xEE, 0x74, 0x25, 0x16, 0xA5, 0x1C, 0x8E, 0xAD, 0x7C, 0xE1, 0xEB, 0x2A, - 0xAC, 0x1C, 0xFF, 0xFF, 0x7F, 0x63, 0x2C, 0xBC, 0x43, 0xB7, 0x33, 0xF8, 0x57, 0xF4, 0x32, 0xFA, 0x1B, 0x5D, 0xF2, 0x07, 0xFD, 0x4F, 0x3A, 0x1D, - 0x71, 0x61, 0xC7, 0xFA, 0x2F, 0x50, 0xB3, 0x55, 0x18, 0xC6, 0xFA, 0x25, 0xB1, 0xCC, 0x78, 0x55, 0x13, 0x67, 0xA5, 0x11, 0x56, 0x35, 0x85, 0x81, - 0x0A, 0x08, 0xC5, 0x54, 0xDB, 0xA1, 0x54, 0x55, 0x87, 0xA8, 0x0B, 0x9E, 0xF0, 0xB7, 0x46, 0x28, 0x12, 0x27, 0x9E, 0x30, 0x98, 0x3A, 0x61, 0xB2, - 0x68, 0x3A, 0x01, 0xCC, 0x54, 0xAB, 0xBB, 0xA4, 0x79, 0xAA, 0xE4, 0x3C, 0x9D, 0x74, 0x1B, 0x9C, 0xE4, 0x02, 0x73, 0x14, 0xCD, 0x71, 0x34, 0xF4, - 0x8D, 0x60, 0x6E, 0x8A, 0xC2, 0x62, 0x88, 0x9C, 0xA6, 0x86, 0xE8, 0x9A, 0x84, 0x06, 0xB0, 0xBD, 0x01, 0xD1, 0x82, 0xEA, 0xAA, 0x80, 0x22, 0xED, - 0x7E, 0x36, 0xE8, 0xF8, 0xB4, 0x82, 0xE8, 0x11, 0xC1, 0xCA, 0x13, 0x1C, 0x61, 0xE7, 0xD4, 0x6D, 0xC7, 0x43, 0xC4, 0xAA, 0x6B, 0xCE, 0x4E, 0x25, - 0xCE, 0x1A, 0xEE, 0x26, 0xEB, 0xD5, 0x86, 0x26, 0xAF, 0x46, 0x0E, 0x99, 0x46, 0xCA, 0xC4, 0x0C, 0x1D, 0xD6, 0x7D, 0x86, 0x41, 0x26, 0xC4, 0x65, - 0x0C, 0x84, 0x43, 0x18, 0xCF, 0x92, 0x97, 0x3D, 0x2E, 0x17, 0xDD, 0x20, 0x45, 0x03, 0x2D, 0xEA, 0xAE, 0xD1, 0x0C, 0x2B, 0x33, 0x07, 0x7E, 0x13, - 0x53, 0x92, 0xBE, 0xA4, 0x35, 0x00, 0x30, 0x4B, 0x70, 0x12, 0xB3, 0x68, 0x62, 0xB7, 0xA1, 0xE4, 0x49, 0xB4, 0x2D, 0x82, 0x91, 0x44, 0xAD, 0x77, - 0xC4, 0x72, 0x54, 0x84, 0xC2, 0x3A, 0x64, 0xD6, 0x05, 0x48, 0xA1, 0xFB, 0xC3, 0x98, 0xB4, 0x92, 0xED, 0x41, 0xE2, 0x1B, 0x3B, 0xC3, 0xF1, 0xCE, - 0x50, 0x86, 0xD2, 0x88, 0xD3, 0x64, 0x88, 0xD4, 0xB0, 0xE7, 0xF0, 0xD5, 0xBD, 0xB7, 0xAA, 0x3D, 0x42, 0xAA, 0xA2, 0x17, 0xEA, 0x8A, 0x01, 0xA3, - 0x08, 0x4E, 0xC7, 0x30, 0x35, 0x8F, 0x3A, 0x06, 0xBD, 0x4A, 0x33, 0x48, 0x30, 0x61, 0xCF, 0x19, 0xA4, 0x6C, 0x00, 0xF0, 0x39, 0x68, 0xC9, 0x4A, - 0x41, 0x2F, 0x08, 0x6D, 0x99, 0xFE, 0x69, 0x1D, 0x7E, 0x65, 0x09, 0x3F, 0x62, 0xB1, 0x48, 0x80, 0xF5, 0x91, 0x6A, 0x55, 0x0B, 0x66, 0x35, 0x03, - 0x49, 0xE5, 0x3C, 0x47, 0x15, 0xB5, 0x3A, 0xD5, 0xC2, 0x41, 0x8A, 0x8D, 0x38, 0x6A, 0x29, 0x05, 0xDC, 0x02, 0x08, 0x5A, 0xA9, 0xDC, 0xC4, 0x8E, - 0xD3, 0x82, 0xC6, 0xA6, 0xCF, 0xAB, 0x3F, 0x53, 0xFD, 0x12, 0x2D, 0x4F, 0x5E, 0x29, 0x93, 0x23, 0xA9, 0xD9, 0x07, 0xC9, 0xF6, 0x06, 0x89, 0x45, - 0xCB, 0xE8, 0x79, 0xCA, 0x48, 0xA9, 0x40, 0x91, 0x0B, 0x1B, 0xD1, 0x99, 0xDE, 0x9D, 0x89, 0x02, 0x1C, 0x02, 0xE2, 0x3D, 0x8C, 0x00, 0xBE, 0x9E, - 0xE1, 0x4D, 0x47, 0xC7, 0xDF, 0x13, 0xDF, 0x80, 0x84, 0xF8, 0x3C, 0xE8, 0x3B, 0x52, 0x13, 0xBF, 0xDF, 0x7D, 0xB7, 0xD6, 0xE2, 0x4B, 0xFE, 0x3B, - 0x98, 0x13, 0x2E, 0x14, 0xF3, 0xF6, 0xB8, 0x85, 0x63, 0xA9, 0xEF, 0x3B, 0xCE, 0xF0, 0x02, 0x32, 0x77, 0xAD, 0x15, 0x78, 0x06, 0xA7, 0xBB, 0x81, - 0x23, 0xF8, 0xA2, 0x80, 0xBB, 0x06, 0xAB, 0x37, 0x6B, 0xA2, 0x1B, 0x85, 0xDB, 0xFB, 0x18, 0xD4, 0xED, 0xAA, 0x79, 0x67, 0x29, 0x91, 0x4E, 0x3D, - 0xAA, 0x80, 0xBA, 0x62, 0xFA, 0x94, 0x33, 0xD4, 0x74, 0x16, 0xA6, 0x34, 0x97, 0x97, 0x94, 0x99, 0x69, 0x74, 0x5A, 0x3D, 0xBA, 0x72, 0x06, 0x17, - 0x45, 0x71, 0x11, 0x1A, 0xD4, 0x04, 0x7A, 0xC4, 0x66, 0xF1, 0x85, 0xE6, 0x81, 0x6A, 0xAD, 0xA9, 0x0A, 0x57, 0x4E, 0x2F, 0x1A, 0xFF, 0xE2, 0xDE, - 0xEB, 0x58, 0xF8, 0x7F, 0xDF, 0xFE, 0x1F, 0x3F, 0x8B, 0x0B, 0x2C, 0xAE, 0x80, 0x2B, 0xBC, 0x86, 0x30, 0xEE, 0x21, 0xCE, 0xBF, 0x99, 0xB7, 0x0A, - 0xC6, 0x18, 0x33, 0xBB, 0x6D, 0xF9, 0x84, 0x4E, 0xB9, 0xA6, 0x42, 0x0C, 0xA2, 0x7A, 0xF2, 0x54, 0x21, 0x0C, 0x31, 0x15, 0xC8, 0x6D, 0x9B, 0xC7, - 0x06, 0x00, 0xF7, 0x11, 0x0C, 0x8D, 0x35, 0xDC, 0x8B, 0x49, 0x74, 0x12, 0xA3, 0x50, 0x1D, 0xC6, 0xC4, 0x7D, 0x61, 0x3A, 0x2C, 0x5C, 0xFB, 0x1C, - 0xFC, 0xE2, 0xE3, 0x99, 0x05, 0x18, 0x44, 0xE7, 0xD7, 0x05, 0xC9, 0x97, 0x06, 0xC4, 0xC5, 0x50, 0x4B, 0xAF, 0xD4, 0x0E, 0x6F, 0x58, 0xD2, 0x2E, - 0x81, 0x2B, 0x5D, 0xBA, 0xB2, 0xBB, 0x85, 0xB7, 0x3B, 0x60, 0xDD, 0xDD, 0xC4, 0x85, 0x7B, 0x24, 0xE0, 0xDD, 0xB6, 0xD4, 0x41, 0x2D, 0x2D, 0x06, - 0xDA, 0xE0, 0xC0, 0xE6, 0xC3, 0x59, 0x8F, 0x48, 0x59, 0x16, 0xCF, 0xD8, 0x9D, 0x3C, 0xAC, 0x52, 0x8B, 0xF7, 0x6B, 0x16, 0xA8, 0xEB, 0x99, 0x6B, - 0x2B, 0x86, 0xBF, 0xD6, 0xA1, 0x3A, 0xD6, 0xBE, 0x00, 0xAC, 0x64, 0x1C, 0xF9, 0x13, 0x8F, 0xF9, 0x30, 0xC0, 0xC6, 0x06, 0xAB, 0x0D, 0x6E, 0x54, - 0x43, 0x53, 0x55, 0xE9, 0xEE, 0x7B, 0x16, 0x67, 0xF3, 0xD4, 0x0F, 0x53, 0xB7, 0xA8, 0xF4, 0xB3, 0x61, 0x48, 0x4A, 0x36, 0xD3, 0xDD, 0x05, 0xFF, - 0x18, 0x88, 0xAD, 0xA7, 0x63, 0x8A, 0x2E, 0x9D, 0x08, 0x4D, 0x82, 0x02, 0x85, 0x32, 0x1B, 0xF0, 0x59, 0x00, 0x81, 0xA7, 0x9D, 0x04, 0x3C, 0x89, - 0xE9, 0x4E, 0x11, 0x23, 0x38, 0x0B, 0x13, 0x6C, 0x5A, 0xAE, 0xD0, 0x24, 0x15, 0xFD, 0x97, 0xC6, 0x96, 0xD3, 0xA3, 0x96, 0x24, 0xB1, 0x2B, 0x86, - 0xD0, 0x26, 0xE3, 0x26, 0x92, 0x74, 0x20, 0xE8, 0x03, 0xE8, 0x95, 0xD1, 0x27, 0xBE, 0x20, 0x11, 0x6B, 0x76, 0x0E, 0x15, 0x4C, 0x30, 0x11, 0x15, - 0xC3, 0x70, 0x03, 0xB3, 0x7D, 0x6D, 0x5E, 0x88, 0x22, 0xF4, 0x13, 0xE2, 0x39, 0xB5, 0x4B, 0x94, 0xFE, 0x0D, 0x96, 0xF0, 0x90, 0x86, 0xAD, 0x0B, - 0x6E, 0x5D, 0x50, 0x9F, 0xA9, 0xCD, 0x9A, 0x17, 0x37, 0x24, 0x40, 0x34, 0x5B, 0x07, 0x27, 0xAB, 0x2C, 0xC3, 0x5B, 0xEB, 0xEE, 0x3E, 0x0C, 0xBA, - 0x8F, 0xEB, 0x47, 0xFF, 0x35, 0x6A, 0xD9, 0x9D, 0x98, 0x61, 0xF3, 0x97, 0x7E, 0x91, 0xD6, 0xBE, 0x08, 0x3C, 0x5A, 0x24, 0x48, 0xCC, 0xE5, 0xBD, - 0xC2, 0xCD, 0xD3, 0x80, 0xCB, 0x7E, 0xB3, 0x45, 0x5C, 0xB4, 0xAD, 0xB9, 0x40, 0x0B, 0x2A, 0x4A, 0xBB, 0x04, 0x27, 0xDB, 0xDB, 0x2B, 0x8B, 0x96, - 0x17, 0x3B, 0xD2, 0x04, 0xBB, 0xA0, 0x40, 0xAB, 0x9F, 0x09, 0x2B, 0x99, 0x80, 0xFC, 0xE3, 0x3B, 0x0E, 0x41, 0xAE, 0x2A, 0x7A, 0x92, 0x4A, 0xC8, - 0x8A, 0xEA, 0xAA, 0x79, 0x4A, 0x20, 0x51, 0x3F, 0xC9, 0x02, 0xC6, 0x37, 0xCF, 0xF2, 0xC8, 0x32, 0x81, 0xE8, 0x8A, 0xAD, 0xA3, 0x41, 0x54, 0x15, - 0x27, 0x6B, 0xFF, 0x77, 0x70, 0xB8, 0xF8, 0xDD, 0xFB, 0xC8, 0x7C, 0xF6, 0x4C, 0x32, 0x3B, 0x8D, 0xB8, 0x9B, 0x79, 0xC5, 0x60, 0x10, 0x60, 0x66, - 0x2F, 0x58, 0x3E, 0xA1, 0x2B, 0xD7, 0xF8, 0xC5, 0x20, 0x22, 0x4C, 0x9E, 0x72, 0x84, 0x21, 0xA6, 0x89, 0xDC, 0x76, 0x7A, 0x6C, 0xC0, 0xBE, 0x8F, - 0xF0, 0x68, 0xAC, 0x81, 0xB3, 0x98, 0x44, 0x2A, 0x31, 0x8A, 0xDB, 0x61, 0xCC, 0x17, 0x2F, 0x4C, 0x9D, 0x85, 0x6D, 0x3D, 0x82, 0x5F, 0xAC, 0x3C, - 0xE7, 0x00, 0x83, 0x1C, 0xFD, 0xBA, 0x54, 0xF9, 0xD2, 0xB0, 0xB8, 0x18, 0xD2, 0xE9, 0x95, 0x42, 0xE2, 0x0D, 0xB3, 0xDA, 0x25, 0x40, 0xA6, 0x4B, - 0xE7, 0x86, 0xB7, 0xC0, 0x00, 0x0F, 0x68, 0x01, 0x6F, 0xE2, 0x0F, 0x1F, 0x69, 0xC7, 0xDB, 0x96, 0xE6, 0xD5, 0xD2, 0x7A, 0xA0, 0x0D, 0x36, 0xD1, - 0x0C, 0x39, 0xEB, 0x81, 0x97, 0x65, 0x59, 0x8D, 0xDD, 0xC9, 0x85, 0x55, 0x22, 0x86, 0xBF, 0x66, 0xB5, 0xBA, 0x9E, 0xE9, 0xB6, 0x62, 0x28, 0x6C, - 0x1D, 0xBA, 0xC0, 0xDA, 0x07, 0xC7, 0x4A, 0x86, 0x92, 0x3F, 0xB1, 0x99, 0x0F, 0x33, 0x6C, 0xCC, 0x5B, 0x6D, 0x40, 0xA4, 0x1A, 0x6A, 0xAB, 0x4A, - 0xD7, 0xF9, 0x59, 0xC4, 0xD1, 0x53, 0x3F, 0x80, 0xDD, 0x76, 0xA2, 0xD2, 0x0B, 0x0C, 0xE3, 0xFF, 0x29, 0xE5, 0x9C, 0xE9, 0x2E, 0x85, 0xD2, 0xE3, - 0xA6, 0x52, 0x76, 0x31, 0xED, 0xF3, 0xA8, 0x19, 0xA9, 0xE8, 0x92, 0x64, 0x68, 0x52, 0x17, 0x28, 0xD4, 0x0C, 0x0B, 0xB3, 0x03, 0x9F, 0x05, 0x22, - 0x78, 0xDA, 0xF1, 0xE1, 0x05, 0x45, 0x3A, 0x45, 0x28, 0x72, 0x16, 0x4A, 0xD8, 0xB4, 0x0C, 0xD5, 0x24, 0x7D, 0xBD, 0x34, 0x16, 0xB5, 0x9C, 0x86, - 0xB5, 0x24, 0xE9, 0x5D, 0x31, 0x54, 0x60, 0x32, 0xEE, 0x96, 0xA4, 0x43, 0x8C, 0x9C, 0x3F, 0x41, 0xF2, 0x65, 0xB8, 0xEF, 0xD1, 0x3C, 0xDA, 0x0F, - 0xA8, 0x50, 0x84, 0x3B, 0x96, 0x82, 0xA2, 0xF8, 0xBD, 0x43, 0xB1, 0x01, 0x72, 0xE2, 0xAB, 0x13, 0xB1, 0x06, 0xE9, 0x50, 0xC1, 0x06, 0x13, 0x52, - 0x6C, 0xC3, 0xBE, 0x0D, 0xFB, 0x1A, 0x5E, 0x21, 0x0A, 0xD7, 0x36, 0x21, 0xDE, 0x96, 0xBB, 0x44, 0x69, 0xE1, 0x60, 0x09, 0x15, 0x69, 0x5E, 0xC1, - 0x2D, 0x3E, 0x40, 0x5F, 0x14, 0x5F, 0xCF, 0xAD, 0x16, 0xB3, 0xF4, 0x6A, 0x7C, 0xD0, 0xD5, 0x81, 0x8D, 0x0B, 0xF5, 0xC3, 0x96, 0x0A, 0x0A, 0x5A, - 0xBC, 0x76, 0xAA, 0x25, 0xB2, 0xD8, 0x20, 0x8A, 0x33, 0xAF, 0x6A, 0x26, 0xAD, 0x34, 0x0A, 0xAB, 0xA6, 0x5A, 0xA9, 0x6E, 0x36, 0xA7, 0xDA, 0xF6, - 0x52, 0x55, 0xB6, 0xF2, 0xB7, 0xDB, 0x5F, 0x50, 0x9D, 0x1D, 0x28, 0xEF, 0xF1, 0x27, 0x90, 0xD3, 0x07, 0x31, 0xB5, 0x67, 0xF2, 0x76, 0x4E, 0xE2, - 0xE9, 0x67, 0x6C, 0xAC, 0x8B, 0x3C, 0x7F, 0x12, 0x2D, 0x97, 0x1A, 0xDE, 0xD5, 0x41, 0x8C, 0x0B, 0x75, 0x6F, 0x4B, 0xC5, 0x02, 0x2D, 0x5E, 0x03, - 0xAA, 0x7E, 0x59, 0xEC, 0x0C, 0xC5, 0x8E, 0x57, 0x35, 0x89, 0x56, 0x1A, 0x7F, 0x55, 0x53, 0xA0, 0x54, 0x37, 0x8F, 0x53, 0x6D, 0xBB, 0x52, 0x55, - 0xA9, 0x71, 0x43, 0x13, 0xC8, 0x69, 0xC1, 0x35, 0x8F, 0x1C, 0xA9, 0x0F, 0x35, 0x98, 0x1A, 0x09, 0x2D, 0x88, 0x95, 0x44, 0xDC, 0x29, 0x32, 0xF4, - 0x0A, 0x32, 0x03, 0x30, 0x36, 0x04, 0x13, 0xC2, 0x6A, 0x51, 0x12, 0x0E, 0x8D, 0x06, 0x50, 0xB6, 0x85, 0xE4, 0xFA, 0x7C, 0xA3, 0xDC, 0x31, 0x6E, - 0xA7, 0x87, 0x90, 0xAF, 0x92, 0x57, 0xEE, 0x15, 0xCF, 0xAE, 0x06, 0xB0, 0x35, 0x38, 0x34, 0x36, 0xD6, 0x7A, 0x56, 0x5E, 0x09, 0x92, 0xE1, 0xB8, - 0x98, 0x52, 0x5C, 0x6A, 0x98, 0x97, 0xBB, 0x34, 0xA6, 0xDB, 0x96, 0x5A, 0x4B, 0x9D, 0x51, 0x14, 0xC0, 0xC5, 0x54, 0x59, 0x8C, 0xBB, 0x32, 0x0D, - 0x36, 0x32, 0x14, 0x12, 0x55, 0x30, 0x60, 0x6D, 0x2A, 0x1B, 0xA2, 0xA9, 0xA2, 0x22, 0x29, 0x2A, 0xB0, 0xA8, 0xB1, 0x30, 0xB8, 0xDB, 0x1C, 0x54, - 0xDD, 0xFC, 0x29, 0x8F, 0x83, 0x53, 0x60, 0x87, 0x3A, 0x62, 0x0A, 0xFB, 0x64, 0x63, 0x3D, 0x58, 0xD2, 0x2E, 0xA2, 0x8E, 0xA1, 0xFF, 0xC8, 0x34, - 0xD1, 0xBB, 0x9C, 0xD0, 0xE8, 0x4F, 0x3F, 0xED, 0x47, 0xF8, 0x22, 0x7E, 0xE5, 0x08, 0xFA, 0x0A, 0x3A, 0x2C, 0x0C, 0x7A, 0x09, 0x3D, 0x88, 0xFE, - 0x9E, 0x93, 0x80, 0xDC, 0xBA, 0x16, 0x73, 0x0D, 0x7D, 0x29, 0x66, 0x31, 0xE3, 0x55, 0x83, 0xEF, 0x2E, 0xBC, 0x68, 0x53, 0xD6, 0x00, 0xD4, 0x57, - 0xEC, 0x69, 0x18, 0x5B, 0x8E, 0xCF, 0xB4, 0x27, 0x3E, 0xDB, 0xCB, 0x3E, 0xAD, 0xDF, 0x3E, 0x11, 0xE7, 0x1E, 0x56, 0xEA, 0x2A, 0xB3, 0x3F, 0x16, - 0x32, 0xC3, 0xD6, 0xB5, 0x08, 0xEB, 0x8B, 0x52, 0x67, 0xA2, 0x9E, 0x12, 0xFA, 0xFF, 0xDD, 0xD6, 0x03, 0x47, 0x20, 0x49, 0xCF, 0xA6, 0x35, 0x24, - 0x0F, 0xD0, 0xB8, 0x16, 0xE7, 0xA8, 0xD6, 0x20, 0x67, 0x80, 0x5E, 0x84, 0x34, 0x0F, 0xC9, 0x02, 0x4E, 0x58, 0xA1, 0x45, 0xE2, 0xCF, 0x40, 0x4F, - 0xCC, 0x58, 0x39, 0x04, 0xD0, 0xED, 0x50, 0x66, 0xDC, 0x51, 0xF6, 0xD1, 0xC8, 0x44, 0x5E, 0xC7, 0x64, 0x72, 0xC4, 0x7C, 0x0C, 0xC3, 0x9C, 0x60, - 0x80, 0x6D, 0x25, 0x88, 0x0B, 0x50, 0xF0, 0x55, 0x00, 0xD8, 0x2B, 0x02, 0x53, 0xD7, 0x1E, 0x25, 0xD7, 0x08, 0x8E, 0xAD, 0xC4, 0x0A, 0x5A, 0x2B, - 0x5E, 0xB3, 0x42, 0xBD, 0xB0, 0x60, 0xBF, 0xAE, 0x76, 0x4B, 0xA7, 0x84, 0x26, 0xA5, 0xA0, 0x80, 0xA2, 0xBE, 0x82, 0xE0, 0x69, 0x8C, 0x50, 0x09, - 0xA0, 0x9F, 0x24, 0x38, 0x70, 0xEA, 0x23, 0x6D, 0x22, 0x21, 0xC5, 0x94, 0xE2, 0xC3, 0xD2, 0x25, 0x89, 0x52, 0x69, 0x3B, 0x29, 0x56, 0x03, 0xD2, - 0xEF, 0xED, 0x51, 0x8C, 0xB2, 0xA3, 0x0D, 0x46, 0x23, 0x00, 0x35, 0x45, 0x37, 0x0D, 0x88, 0x86, 0x8C, 0x87, 0xA4, 0xF6, 0x42, 0x71, 0x03, 0x6F, - 0xB6, 0xCD, 0xA0, 0x39, 0x24, 0x20, 0x3A, 0xDF, 0x4F, 0x07, 0xB6, 0x4F, 0x61, 0x59, 0x52, 0x4F, 0x63, 0x9E, 0x87, 0x93, 0x66, 0xE7, 0x74, 0x50, - 0xC7, 0xB6, 0x84, 0x8E, 0xDB, 0x01, 0x80, 0x1F, 0x94, 0x13, 0xA4, 0x61, 0x52, 0x93, 0x2A, 0xAD, 0x12, 0x47, 0x4D, 0x2C, 0xC6, 0x68, 0xBC, 0x8E, - 0x29, 0x1E, 0x02, 0x03, 0xB8, 0xE3, 0x89, 0x65, 0x20, 0x55, 0x52, 0xE7, 0x47, 0xC5, 0xB2, 0xDA, 0x99, 0xAE, 0x0A, 0x7E, 0xD9, 0xC3, 0x71, 0x47, - 0xCB, 0xCE, 0xDE, 0xB9, 0x71, 0x12, 0xEA, 0xA1, 0xE5, 0x0B, 0x1E, 0x67, 0x6A, 0xF8, 0x02, 0x60, 0x93, 0x31, 0xDC, 0x12, 0x5B, 0xC3, 0x0F, 0xD5, - 0xCD, 0xBD, 0x07, 0x2E, 0x1F, 0xBD, 0x83, 0x58, 0x03, 0x07, 0x74, 0xD9, 0x87, 0xC0, 0x3C, 0xA7, 0x0D, 0xA2, 0x8B, 0x00, 0xDD, 0x2F, 0x43, 0xFF, - 0x4A, 0xA8, 0x7D, 0x28, 0x08, 0x1D, 0x36, 0x64, 0xCE, 0x3B, 0xFB, 0x61, 0xCC, 0x02, 0xAF, 0x11, 0xE9, 0x26, 0x27, 0xE6, 0x33, 0x0B, 0xFE, 0xDB, - 0xFD, 0x34, 0xFC, 0x1F, 0x9C, 0xCE, 0x07, 0x58, 0xD2, 0xEF, 0x30, 0xB4, 0xA0, 0x74, 0xCB, 0xA5, 0x63, 0x80, 0x8B, 0xE2, 0xDF, 0xEA, 0xCF, 0x6C, - 0x49, 0x53, 0xE7, 0xB4, 0xBF, 0x23, 0xC6, 0xCE, 0x58, 0x90, 0x65, 0xD5, 0xA9, 0xEE, 0x57, 0x76, 0xEA, 0x2F, 0x44, 0xBD, 0x1A, 0x19, 0x1B, 0x69, - 0xEA, 0x27, 0x75, 0xCD, 0x80, 0xBF, 0xE2, 0xBF, 0xD6, 0x61, 0x2A, 0xE9, 0x02, 0xFF, 0xD1, 0x2B, 0xC7, 0x8C, 0xF3, 0xAA, 0xEB, 0x5D, 0xC0, 0x70, - 0xC8, 0x91, 0xA3, 0xB6, 0xA0, 0x76, 0x52, 0xB7, 0xD5, 0x1B, 0x6A, 0x8D, 0x05, 0xB2, 0xAD, 0x70, 0x1D, 0x8E, 0x2B, 0x37, 0xB2, 0x5A, 0xCE, 0x9B, - 0xDB, 0xE4, 0xAE, 0x7D, 0x75, 0xC1, 0xBD, 0xB3, 0x16, 0x67, 0xE8, 0xCE, 0x9A, 0x80, 0x97, 0x67, 0x97, 0x13, 0xC4, 0x0C, 0x73, 0x47, 0xDD, 0xC1, - 0x20, 0xD3, 0x37, 0xE0, 0xE6, 0x4D, 0x9D, 0x9F, 0xAB, 0xB3, 0x8A, 0x66, 0x83, 0x04, 0xFA, 0xE9, 0x1D, 0xFC, 0x54, 0x43, 0xC3, 0xDE, 0x75, 0xF3, - 0x97, 0x7A, 0x34, 0xCF, 0x49, 0xCF, 0xD4, 0x0C, 0x21, 0x64, 0xEC, 0xED, 0x21, 0x4C, 0xD0, 0xF1, 0x8E, 0xA6, 0x76, 0xD6, 0x68, 0xEA, 0xA6, 0x07, - 0x1D, 0x5E, 0x59, 0x17, 0xA4, 0x14, 0xC4, 0x1D, 0xCA, 0xEB, 0x7B, 0xA3, 0x05, 0xC5, 0x7B, 0x24, 0x88, 0x57, 0x53, 0x86, 0x15, 0x2D, 0x5F, 0x18, - 0x17, 0x09, 0x8F, 0xC6, 0x0A, 0x93, 0x84, 0x01, 0xFF, 0x26, 0x03, 0x07, 0xCD, 0x7F, 0x4B, 0xB8, 0x80, 0x7D, 0x09, 0xB0, 0x5D, 0x9C, 0xAC, 0x14, - 0xE8, 0x3D, 0xB0, 0xA2, 0xEF, 0x58, 0xEF, 0xBB, 0xBB, 0x77, 0x24, 0xD1, 0xCB, 0x6A, 0xD8, 0xD3, 0xA6, 0xFE, 0xE8, 0x65, 0x8B, 0x4B, 0xC8, 0x65, - 0xDF, 0xFC, 0xF6, 0x76, 0x2F, 0xEC, 0xF5, 0x53, 0x29, 0x06, 0xA4, 0x0C, 0xBC, 0xFA, 0xC7, 0x40, 0x5A, 0xA6, 0x1C, 0x89, 0xB9, 0x27, 0xD4, 0xAC, - 0xFD, 0xCE, 0xCC, 0x3F, 0x45, 0xA8, 0x59, 0x85, 0xDE, 0xFA, 0x8E, 0xDC, 0xEB, 0xED, 0x53, 0x2D, 0xD5, 0x49, 0xEA, 0x9B, 0x7F, 0xFC, 0x89, 0x7B, - 0x50, 0x61, 0x5D, 0x8E, 0x26, 0x35, 0xD8, 0x4E, 0xF2, 0x34, 0x97, 0x59, 0xBB, 0x9E, 0x9D, 0x09, 0x31, 0x43, 0x5A, 0x51, 0xD1, 0x7F, 0x8E, 0x67, - 0x68, 0x00, 0xC4, 0x97, 0x78, 0x3F, 0xC8, 0xF0, 0x1B, 0xF4, 0xA2, 0x0D, 0x37, 0x20, 0x53, 0x5D, 0xCF, 0x01, 0x7D, 0x53, 0x98, 0x37, 0xC8, 0x1E, - 0x0F, 0x66, 0x10, 0x98, 0x7F, 0x38, 0x7A, 0x6D, 0x1D, 0x1D, 0x02, 0x62, 0x07, 0x66, 0x4A, 0x8B, 0xCF, 0x91, 0xB1, 0xA1, 0x61, 0x63, 0x28, 0xEF, - 0x94, 0xE3, 0xCA, 0x6F, 0x89, 0xA8, 0x4C, 0x0D, 0x25, 0xE1, 0x95, 0x5D, 0x9A, 0x01, 0x3C, 0xA0, 0xE2, 0xA5, 0xBD, 0x6C, 0x59, 0x6C, 0xC0, 0xF0, - 0x28, 0x56, 0xDC, 0x78, 0x5C, 0xB5, 0x0F, 0x96, 0x07, 0x51, 0xC6, 0x82, 0x02, 0xD3, 0xD3, 0x32, 0xC0, 0x90, 0x8B, 0xF3, 0xB2, 0xCE, 0x3F, 0xA2, - 0x27, 0x22, 0x08, 0xFD, 0x25, 0x05, 0x20, 0x50, 0xFA, 0xAD, 0x90, 0x2E, 0x58, 0xB7, 0xBA, 0x4E, 0xFB, 0xD8, 0x7B, 0x28, 0xC1, 0xFF, 0xA9, 0x5E, - 0xF1, 0x1C, 0x4C, 0x96, 0x90, 0x19, 0x01, 0x0E, 0x40, 0xF7, 0x76, 0x65, 0x44, 0x9D, 0xA5, 0xDE, 0x99, 0xDB, 0x67, 0x80, 0x49, 0x81, 0xAD, 0xB3, - 0x39, 0x04, 0x70, 0x19, 0xFC, 0x8D, 0x7A, 0x98, 0x79, 0xCA, 0x9C, 0x69, 0x5E, 0x34, 0x3F, 0x9B, 0x87, 0xCD, 0x9B, 0xF6, 0xF3, 0x39, 0xDA, 0xBE, - 0xC3, 0xDC, 0x6E, 0xDF, 0x38, 0x07, 0xB1, 0xF7, 0xDB, 0x4F, 0xEE, 0x1D, 0xF7, 0xAD, 0xFB, 0xD3, 0x7D, 0xE5, 0xDC, 0x39, 0x78, 0xFF, 0x3A, 0xE7, - 0xD8, 0x43, 0x23, 0xCF, 0x85, 0x5E, 0xCC, 0xDB, 0x73, 0x8F, 0x39, 0xD0, 0x3C, 0x67, 0xCE, 0x35, 0x77, 0xEF, 0x83, 0xF6, 0x4F, 0xFB, 0xAE, 0x7D, - 0xDA, 0xFE, 0xC0, 0x3E, 0xC2, 0x9E, 0x6F, 0x6F, 0xF7, 0xF5, 0x15, 0xF7, 0x19, 0x95, 0xFB, 0x0D, 0x73, 0x17, 0x12, 0x73, 0xC6, 0xB9, 0xE5, 0x7C, - 0x74, 0x1E, 0x3B, 0x3F, 0xE0, 0x62, 0x2E, 0x21, 0x79, 0xCE, 0x9E, 0x9B, 0xCC, 0x67, 0xE6, 0xEF, 0x39, 0x6A, 0x4D, 0xBC, 0x15, 0x4F, 0x18, 0x2F, - 0x84, 0x77, 0x18, 0xC8, 0xAF, 0x1C, 0xC0, 0xE7, 0x20, 0xC5, 0x17, 0xF5, 0x28, 0x58, 0x8E, 0xD4, 0x39, 0x6A, 0x1C, 0x3A, 0xA3, 0x15, 0xB1, 0x95, - 0x11, 0x62, 0x17, 0x6B, 0x20, 0x7A, 0x83, 0x40, 0x78, 0x1D, 0x40, 0xD8, 0xFD, 0xDA, 0xD1, 0x05, 0x11, 0x42, 0x5F, 0x41, 0xB3, 0x45, 0x25, 0x65, - 0xAE, 0x61, 0x2D, 0xAE, 0xAA, 0xF0, 0xAD, 0x25, 0xA7, 0x2D, 0xF1, 0x8A, 0xD9, 0xDB, 0x5A, 0x11, 0xD8, 0x59, 0x66, 0xE7, 0xD9, 0x20, 0x2A, 0x59, - 0x28, 0xB1, 0xD8, 0x3A, 0x2E, 0xD8, 0xAD, 0x14, 0xAF, 0x52, 0x8E, 0xAE, 0x76, 0xCC, 0xAD, 0x6C, 0x11, 0xE6, 0xAA, 0x25, 0x4E, 0xE4, 0x53, 0x5D, - 0xA5, 0xE5, 0xA8, 0xCF, 0x98, 0xA7, 0xC8, 0xA6, 0xFA, 0xD3, 0xAB, 0x06, 0x18, 0xE4, 0x04, 0x74, 0xB8, 0xFA, 0x5F, 0xAD, 0xB6, 0x51, 0xFF, 0x8C, - 0xFB, 0x1C, 0x2B, 0xC1, 0xFE, 0xCF, 0xEC, 0xB4, 0x09, 0x86, 0x29, 0xE8, 0x74, 0xA9, 0x80, 0x4E, 0x52, 0x5E, 0xD4, 0x51, 0x08, 0x4B, 0xA3, 0xEA, - 0xAB, 0x50, 0x11, 0x1C, 0xA1, 0xEE, 0x13, 0x7A, 0xA5, 0x6B, 0x9E, 0xC5, 0x93, 0xFE, 0xC3, 0xDA, 0x3D, 0x07, 0x34, 0xD2, 0x61, 0xB8, 0xC4, 0x3B, - 0x25, 0xE4, 0xD0, 0xE3, 0xAE, 0x32, 0x38, 0x6A, 0xD8, 0x30, 0x99, 0xD3, 0x03, 0x8C, 0xB8, 0x70, 0x23, 0xDD, 0x51, 0x0F, 0xBC, 0xC9, 0xEE, 0x5E, - 0x77, 0x06, 0x77, 0x36, 0x82, 0xFB, 0xDF, 0xBD, 0x46, 0xC3, 0x5D, 0xA3, 0xC1, 0x7B, 0x6A, 0xF1, 0xEE, 0xE1, 0x2D, 0x7A, 0xAF, 0x82, 0x7C, 0xF7, - 0xDE, 0x57, 0xDF, 0xA4, 0x6F, 0xE2, 0xB7, 0xEF, 0x3B, 0x11, 0xE4, 0x6D, 0x9B, 0xF1, 0xD6, 0x2C, 0xBE, 0x3F, 0xD3, 0xBC, 0x71, 0x43, 0xEE, 0x2E, - 0xF0, 0x77, 0x34, 0xCF, 0x7D, 0xA8, 0xE6, 0x0E, 0x83, 0x75, 0x0F, 0x8B, 0xBA, 0x3B, 0xC1, 0xDD, 0xD7, 0xEE, 0x79, 0x77, 0xB7, 0xB3, 0x77, 0xB3, - 0x08, 0x72, 0xC6, 0x5A, 0x43, 0x3D, 0xA3, 0x5E, 0xFF, 0xB0, 0xFC, 0xDF, 0xB2, 0xFA, 0x61, 0xB3, 0x7D, 0x9A, 0x98, 0x53, 0xBF, 0x2F, 0xDE, 0x38, - 0x98, 0x2B, 0x3A, 0x6C, 0x0D, 0x8E, 0x0D, 0x0D, 0x12, 0x77, 0x0A, 0x28, 0x5E, 0x0A, 0xD6, 0xF1, 0xAE, 0x0E, 0x22, 0x5C, 0xA8, 0x51, 0x5B, 0x2A, - 0x7A, 0xE8, 0xBC, 0x36, 0x74, 0xD5, 0x2C, 0x3A, 0x5B, 0x8A, 0x5E, 0x1C, 0x47, 0xAF, 0x91, 0xD3, 0xA7, 0xF0, 0x6E, 0xE4, 0x7E, 0xDB, 0xE0, 0x05, - 0x4C, 0xE4, 0xDE, 0x79, 0xEF, 0x8B, 0x29, 0x19, 0x75, 0xCC, 0x8F, 0x7F, 0x41, 0xAF, 0xBC, 0x17, 0x0D, 0x91, 0x27, 0xE4, 0xAD, 0xFF, 0x5F, 0xDF, - 0xA8, 0x5F, 0x9E, 0x6E, 0xB5, 0x86, 0x25, 0xB8, 0xB3, 0x7A, 0x71, 0xB3, 0x40, 0xAE, 0xB0, 0xA2, 0xEC, 0xEF, 0x42, 0x9D, 0xC7, 0xAA, 0x3B, 0xEE, - 0xA2, 0xBE, 0xB5, 0xCE, 0x84, 0x0F, 0x0F, 0x1A, 0xF1, 0x23, 0x50, 0x33, 0x0D, 0xBF, 0x32, 0xE0, 0x9E, 0xB3, 0x03, 0x27, 0x91, 0x57, 0x0C, 0x03, - 0x01, 0x0A, 0xFF, 0x6B, 0xF5, 0x87, 0xC2, 0x82, 0xE7, 0x9B, 0x65, 0xE5, 0xF4, 0x48, 0xD8, 0x33, 0xD6, 0x27, 0x6A, 0x2A, 0x35, 0xCB, 0x77, 0x33, - 0x6F, 0x20, 0xC8, 0x9A, 0xD3, 0xD2, 0xD5, 0xA4, 0xF6, 0x75, 0xCB, 0xF4, 0x3D, 0xC1, 0xF9, 0x07, 0x14, 0x7A, 0x9F, 0xC7, 0x3E, 0x45, 0xF3, 0xE7, - 0x1C, 0xDC, 0xA3, 0xAA, 0xFC, 0xDF, 0x18, 0xF3, 0x61, 0xA3, 0x3F, 0xDC, 0xB6, 0x0F, 0x11, 0x8B, 0x51, 0xDE, 0xFB, 0x2C, 0xF8, 0x58, 0x5F, 0xF3, - 0x38, 0xA2, 0x9C, 0xC1, 0xD1, 0xFC, 0xAE, 0x50, 0x7F, 0xC1, 0xC2, 0xDC, 0x1E, 0x29, 0x3F, 0xB4, 0xCF, 0x55, 0x08, 0x90, 0xE7, 0x89, 0xE7, 0xB7, - 0xCD, 0x7A, 0xE5, 0x35, 0xFA, 0xAA, 0x7A, 0x9E, 0xD1, 0x41, 0x3F, 0x4E, 0x8C, 0x97, 0x7C, 0x68, 0x91, 0xCE, 0x0B, 0x49, 0x36, 0x29, 0x88, 0x63, - 0x81, 0xD0, 0x03, 0x03, 0x47, 0x00, 0xC6, 0x71, 0xFC, 0x2D, 0x69, 0xF5, 0xAD, 0xDB, 0xBB, 0x48, 0x89, 0xEA, 0x25, 0xC4, 0xE2, 0x3D, 0x5A, 0xDB, - 0xE5, 0x84, 0xD3, 0x2D, 0x9B, 0xA0, 0xDF, 0xE0, 0xA0, 0x05, 0x62, 0x67, 0xEE, 0xA4, 0x2A, 0xAE, 0x9E, 0xC3, 0xED, 0xA5, 0x93, 0xED, 0x64, 0x51, - 0xED, 0x8B, 0x7C, 0x6D, 0x7B, 0x99, 0x36, 0xA6, 0x6D, 0x36, 0x88, 0x85, 0x6C, 0x0B, 0x33, 0xB4, 0x37, 0x9D, 0xF0, 0x5D, 0x95, 0xC1, 0xF9, 0x73, - 0xE4, 0xBE, 0x61, 0x10, 0x71, 0x01, 0xD8, 0x44, 0x81, 0xBC, 0xD9, 0xE5, 0x1E, 0x33, 0xC5, 0x53, 0x84, 0x06, 0x7B, 0x2D, 0x67, 0xF7, 0xE3, 0xDC, - 0x6E, 0xEE, 0x64, 0x4A, 0xCE, 0xDA, 0x69, 0x9C, 0x2F, 0xDB, 0x24, 0xDA, 0xD1, 0x5A, 0x56, 0x3C, 0xEF, 0xBC, 0x90, 0x01, 0x33, 0x25, 0x57, 0xCE, - 0x68, 0x87, 0x41, 0xCF, 0xE6, 0xB9, 0x25, 0xDB, 0xDE, 0xB1, 0xA3, 0x0E, 0x70, 0x5F, 0x69, 0xF1, 0xC2, 0xB3, 0x54, 0xDF, 0xB2, 0xD8, 0x6A, 0xC5, - 0x17, 0xEC, 0x35, 0x77, 0x76, 0x8D, 0x38, 0xF7, 0x14, 0x09, 0xFB, 0x0D, 0x06, 0xB7, 0xA5, 0xBD, 0xEA, 0xD0, 0x1D, 0x6B, 0xF7, 0x74, 0x63, 0xBA, - 0x31, 0xB4, 0x70, 0xCF, 0xBA, 0x4F, 0x44, 0xBB, 0x6B, 0x95, 0xDD, 0x9A, 0x7A, 0xFB, 0x33, 0x00, 0xF7, 0xAD, 0xB4, 0xDD, 0x65, 0xC8, 0x1D, 0xFD, - 0x72, 0x34, 0x84, 0x62, 0x04, 0xB3, 0x54, 0x14, 0x46, 0x44, 0xE4, 0x64, 0x36, 0x44, 0x07, 0x36, 0xC0, 0x81, 0xBD, 0x0E, 0xCD, 0x0E, 0xC4, 0xA4, - 0xDB, 0x0E, 0xC2, 0xBB, 0x97, 0xF5, 0xDD, 0xEA, 0xCE, 0xD0, 0x75, 0x83, 0x50, 0xDA, 0x5D, 0x40, 0xED, 0x3D, 0xAE, 0x76, 0xA6, 0x5D, 0xFB, 0xD6, - 0xB1, 0x3D, 0xED, 0xDB, 0x49, 0xEC, 0x77, 0x31, 0xF6, 0xBE, 0x1F, 0xFB, 0x60, 0x93, 0x7D, 0xCB, 0xAE, 0x89, 0x66, 0x47, 0xED, 0xA2, 0xD7, 0x42, - 0xEF, 0x49, 0xE9, 0xCD, 0xA5, 0xF3, 0x8E, 0x0F, 0x7F, 0xE5, 0xC3, 0x3E, 0x87, 0x8D, 0x7E, 0xE8, 0xDA, 0x36, 0x61, 0x42, 0xD2, 0x19, 0x45, 0x36, - 0x1C, 0xC0, 0x05, 0x58, 0x59, 0x0C, 0x0D, 0x65, 0x1A, 0x73, 0x64, 0x28, 0x8B, 0x55, 0x30, 0x6B, 0x6E, 0x2A, 0x9B, 0xA8, 0xA9, 0x22, 0x29, 0x29, - 0xAA, 0xB5, 0xA8, 0x31, 0x39, 0xDC, 0x6D, 0x02, 0x54, 0x1D, 0xDE, 0x53, 0x9E, 0xA0, 0x53, 0xE0, 0x60, 0x13, 0xE2, 0x25, 0xD3, 0x24, 0xA6, 0x7D, - 0x29, 0xD8, 0xF3, 0x2E, 0x42, 0x42, 0xFF, 0xF9, 0xA1, 0x77, 0x6D, 0xD1, 0x83, 0x7E, 0xD7, 0x3F, 0xF0, 0xF9, 0xBE, 0xE2, 0x0F, 0xFD, 0x8B, 0x74, - 0x51, 0x7A, 0x2F, 0x7D, 0x4D, 0x77, 0xD3, 0x9F, 0xE8, 0x24, 0x20, 0xC2, 0x76, 0x3D, 0x57, 0xE8, 0xC0, 0xA1, 0xFF, 0xD9, 0xEA, 0x0C, 0xB6, 0xFA, - 0x84, 0xA3, 0xE3, 0xC0, 0x87, 0xC9, 0x1C, 0x82, 0x12, 0x41, 0xA5, 0x10, 0xD1, 0x3E, 0x90, 0x58, 0xC6, 0x0F, 0x5F, 0x14, 0x1E, 0xCA, 0xA3, 0x1E, - 0x1B, 0xA4, 0x1C, 0x17, 0x9C, 0x38, 0x70, 0x7C, 0x37, 0x90, 0xD8, 0x49, 0x1A, 0x57, 0x19, 0x3A, 0x19, 0x5D, 0xBE, 0xEC, 0x01, 0xBF, 0x6B, 0x05, - 0x19, 0x6A, 0x3C, 0x8D, 0xDF, 0x81, 0x66, 0x9A, 0xB0, 0x46, 0x5A, 0x05, 0x3C, 0x9A, 0x33, 0x0A, 0x5A, 0x55, 0xED, 0x39, 0x77, 0x6D, 0xD1, 0xD9, - 0x85, 0x54, 0x73, 0x8C, 0xA9, 0x66, 0x0D, 0x39, 0x33, 0x0A, 0xDB, 0xF2, 0x0D, 0x9E, 0xF2, 0x55, 0x72, 0x0C, 0x77, 0x64, 0x72, 0x01, 0x13, 0x18, - 0xF0, 0x3C, 0x72, 0x86, 0xF7, 0x71, 0x00, 0xC9, 0xFD, 0xA2, 0x97, 0xF1, 0x03, 0xD6, 0x62, 0x52, 0x04, 0xC4, 0x21, 0x8C, 0x87, 0x5B, 0x7C, 0xBD, - 0xB0, 0x14, 0x11, 0x9E, 0x4E, 0x10, 0x3C, 0xDB, 0x13, 0x2C, 0xB3, 0xE1, 0x97, 0x39, 0xEB, 0x17, 0x8A, 0xD1, 0x97, 0xE4, 0xC7, 0xC5, 0xDA, 0xE8, - 0x62, 0x6F, 0xD0, 0x16, 0xAF, 0x83, 0x14, 0xBB, 0x5F, 0x72, 0xBA, 0x20, 0x4A, 0x75, 0xF4, 0x15, 0xA0, 0x5B, 0x54, 0xC6, 0xC8, 0x35, 0xD1, 0x82, - 0x9B, 0x3A, 0x7B, 0x6B, 0x19, 0x6D, 0x4B, 0xAC, 0x5C, 0x4B, 0xEB, 0x52, 0x3B, 0x02, 0xA0, 0x59, 0x69, 0x16, 0x68, 0x48, 0xF6, 0x29, 0x2A, 0x96, - 0xC1, 0x12, 0xAC, 0xD4, 0x3D, 0xE9, 0xD5, 0x83, 0x99, 0xA5, 0xEB, 0x01, 0x59, 0x7A, 0xAB, 0x3D, 0xF7, 0x74, 0x6B, 0x81, 0x9D, 0xAD, 0x07, 0xD3, - 0x2E, 0xA1, 0x37, 0x06, 0xB9, 0xB6, 0x7A, 0x95, 0x04, 0xB5, 0x92, 0xDA, 0xA4, 0xED, 0xC3, 0x69, 0x94, 0x38, 0x48, 0x44, 0x6F, 0x25, 0x72, 0x1D, - 0x76, 0x28, 0xB3, 0xDD, 0xCA, 0xF4, 0xB4, 0x67, 0x3D, 0x53, 0x9D, 0xA7, 0x1A, 0xF9, 0xD2, 0xFF, 0x0E, 0x7B, 0x3E, 0x3A, 0xBE, 0x7A, 0xFD, 0x9B, - 0x77, 0x1B, 0x4F, 0x03, 0xD1, 0xA7, 0xB8, 0xD5, 0x67, 0x6E, 0xC4, 0x59, 0x90, 0xFE, 0xFF, 0xDF, 0x1D, 0xC7, 0x25, 0x41, 0x75, 0x8B, 0xE1, 0x81, - 0x2D, 0x26, 0x81, 0x5A, 0x63, 0xB9, 0xDA, 0x15, 0xD0, 0xB5, 0x27, 0x3E, 0xD0, 0xD6, 0xD2, 0x69, 0x67, 0xA0, 0x67, 0x75, 0xC7, 0x66, 0x35, 0x21, - 0x38, 0x13, 0xCA, 0x6E, 0x91, 0xC9, 0x7E, 0x38, 0xC6, 0xDE, 0x86, 0x88, 0x6D, 0xD1, 0x84, 0xAD, 0x73, 0x84, 0x75, 0x82, 0xBF, 0x42, 0x53, 0xBE, - 0x0A, 0x15, 0xBA, 0x2A, 0xC2, 0x5D, 0xE1, 0x44, 0xB8, 0xBE, 0xB8, 0xB6, 0x82, 0x6D, 0xB2, 0xE6, 0x47, 0xB0, 0x8E, 0xE8, 0x61, 0x6D, 0x3A, 0xCE, - 0x2F, 0xB0, 0x5D, 0x6D, 0x3E, 0x5E, 0xFD, 0xCC, 0x5B, 0x1D, 0x40, 0xA2, 0xFA, 0xD7, 0xAC, 0xEA, 0x93, 0x97, 0xFA, 0xE2, 0x36, 0x95, 0x01, 0x32, - 0x6A, 0xA4, 0x0A, 0x2A, 0x19, 0x2E, 0x6A, 0xCC, 0xDC, 0x69, 0x60, 0xDB, 0xB4, 0xD5, 0xC8, 0x34, 0xC3, 0xDC, 0xF4, 0x8A, 0xB4, 0x74, 0x12, 0x88, - 0x34, 0x98, 0x85, 0x14, 0x92, 0x94, 0x74, 0x81, 0x7B, 0xF4, 0x95, 0x6B, 0xD4, 0x03, 0x49, 0xD4, 0x76, 0x46, 0xF4, 0x50, 0x32, 0x34, 0xD9, 0x40, - 0xE8, 0x0E, 0x59, 0xA8, 0xC8, 0x24, 0x68, 0x6A, 0x08, 0x28, 0x88, 0x17, 0x8B, 0x2C, 0x06, 0x2C, 0x90, 0x42, 0x3E, 0xA7, 0x0B, 0x3F, 0x7B, 0x10, - 0x78, 0xCA, 0xFD, 0x79, 0xCA, 0xDF, 0x3C, 0x75, 0x96, 0xF1, 0x5B, 0x1A, 0x3A, 0xC3, 0xE2, 0x9C, 0x07, 0x16, 0x37, 0xF3, 0x78, 0x35, 0x37, 0x88, - 0x66, 0xAA, 0x60, 0xC2, 0x4C, 0xD1, 0x7B, 0x29, 0x1B, 0x68, 0xF9, 0x39, 0x6A, 0xF9, 0x87, 0x2B, 0x77, 0x5D, 0x54, 0xCE, 0x7C, 0x50, 0xB2, 0xD9, - 0x93, 0x48, 0xC5, 0x92, 0x35, 0x33, 0x91, 0x66, 0x21, 0x90, 0x53, 0x50, 0x77, 0x3B, 0x9E, 0x47, 0xB4, 0x1A, 0x15, 0x22, 0xB0, 0x1C, 0x23, 0x44, - 0x35, 0x5A, 0xC2, 0xA5, 0x20, 0xB1, 0x86, 0x62, 0x36, 0x8F, 0x11, 0x73, 0xC2, 0xA2, 0x71, 0x9C, 0x62, 0xAD, 0xA0, 0x22, 0x09, 0x86, 0x44, 0x36, - 0x8C, 0x13, 0x41, 0x87, 0x88, 0x3F, 0x5C, 0x87, 0x5F, 0x9E, 0x26, 0xD6, 0x5A, 0x7C, 0xC3, 0xB9, 0x16, 0x76, 0x3E, 0xA4, 0x42, 0x3D, 0x16, 0x84, - 0x99, 0xA6, 0x84, 0x12, 0x68, 0x08, 0x17, 0x28, 0x97, 0x48, 0xD4, 0x1D, 0x74, 0x51, 0x33, 0x88, 0x28, 0x61, 0x10, 0x10, 0x80, 0xA0, 0xE8, 0xB4, - 0xE0, 0x88, 0x04, 0x12, 0xB2, 0x23, 0x24, 0x22, 0x87, 0x7E, 0x61, 0x46, 0x44, 0x8D, 0x8C, 0xF8, 0x70, 0x22, 0x4A, 0x53, 0x44, 0x70, 0x30, 0x85, - 0x30, 0x10, 0x17, 0x62, 0xA8, 0x19, 0x44, 0x70, 0x11, 0x88, 0x9C, 0x33, 0x0F, 0x9D, 0x1F, 0xD2, 0xC2, 0x3E, 0x78, 0x84, 0x05, 0x3E, 0x35, 0x79, - 0x10, 0x0D, 0xF3, 0x80, 0x01, 0x85, 0x87, 0x9D, 0x39, 0xA0, 0x1A, 0x9A, 0x71, 0x8A, 0x3F, 0x4B, 0xA7, 0xBF, 0xAC, 0x0E, 0x75, 0x3C, 0xBB, 0x3A, - 0xCD, 0x93, 0x9F, 0x2E, 0x08, 0x3F, 0xF9, 0x82, 0x0E, 0x84, 0x20, 0x3A, 0x6C, 0x81, 0xE8, 0x00, 0x60, 0x87, 0x03, 0xDD, 0xAF, 0x8F, 0x73, 0xB2, - 0xAF, 0xCE, 0xB8, 0xCF, 0xA9, 0xC2, 0x06, 0xBB, 0xA3, 0x06, 0x58, 0x11, 0x1A, 0x14, 0x2D, 0x68, 0x80, 0xAB, 0xE5, 0xC3, 0x9F, 0xC6, 0xA8, 0xCC, - 0x90, 0xAF, 0xCD, 0x30, 0x22, 0xC1, 0x9E, 0x3E, 0x78, 0x0F, 0xE5, 0x55, 0xCF, 0x99, 0x48, 0xEF, 0x33, 0x54, 0x4F, 0xCD, 0x41, 0x37, 0x42, 0xC6, - 0xE0, 0x23, 0x9A, 0x37, 0x1C, 0x93, 0xA7, 0xF2, 0xE2, 0x42, 0x0C, 0xA4, 0x85, 0x24, 0x8F, 0x0A, 0x58, 0x1E, 0x74, 0xB3, 0x1C, 0x0A, 0x11, 0x06, - 0xF1, 0xEC, 0xAA, 0x26, 0x1C, 0xC6, 0xB8, 0x13, 0xD1, 0xF6, 0x25, 0xA4, 0x76, 0x45, 0x78, 0xB4, 0x82, 0x40, 0x7C, 0xC0, 0x6E, 0xD5, 0xCD, 0x4E, - 0x84, 0xCF, 0x81, 0xB1, 0x05, 0x07, 0x3F, 0x8A, 0x0D, 0x48, 0xEC, 0x75, 0x54, 0x1B, 0x18, 0x04, 0x71, 0xD2, 0xB9, 0x31, 0x2E, 0xF8, 0xBA, 0x9D, - 0xE7, 0x8D, 0xCE, 0xC1, 0xE1, 0x15, 0x20, 0xBA, 0x48, 0xA0, 0x97, 0x8B, 0x20, 0x94, 0x3D, 0x3F, 0x90, 0x08, 0x6D, 0xC0, 0xD6, 0x57, 0x6E, 0xB4, - 0xA5, 0x00, 0x74, 0x46, 0x5C, 0xB3, 0xE3, 0x8F, 0x7B, 0xA1, 0x81, 0xAB, 0xD1, 0xA0, 0xBF, 0x35, 0xC1, 0xDD, 0xB8, 0xD4, 0x7E, 0x9A, 0xDA, 0x1E, - 0xAA, 0x4F, 0xED, 0x4C, 0xEE, 0x21, 0x4C, 0x8E, 0xF7, 0x40, 0x2E, 0x49, 0x20, 0xEE, 0xDA, 0x41, 0x4E, 0xA9, 0xB7, 0x87, 0xD1, 0x28, 0x87, 0x45, - 0xDC, 0x9F, 0x98, 0xCA, 0x63, 0x7C, 0xEE, 0x77, 0xD2, 0xE4, 0x28, 0xAD, 0x63, 0x59, 0x08, 0xA8, 0xEC, 0x02, 0xFE, 0xF4, 0x46, 0x9F, 0x83, 0x8E, - 0x40, 0x83, 0xF6, 0x26, 0xE0, 0xB9, 0xF9, 0x08, 0x6D, 0xD4, 0x8A, 0xBD, 0xDA, 0x6F, 0x5A, 0x05, 0x0A, 0x1A, 0x7A, 0xBF, 0x8D, 0x7C, 0x61, 0x8D, - 0xFE, 0xD1, 0x26, 0xDF, 0x19, 0xA5, 0x5F, 0x95, 0xCA, 0xB7, 0x58, 0x33, 0x96, 0xE7, 0xA7, 0x27, 0x24, 0x6D, 0x50, 0xC5, 0x53, 0xD8, 0xB0, 0x42, - 0xF3, 0x12, 0x76, 0xF4, 0x6B, 0x8C, 0x7C, 0x6A, 0x46, 0x99, 0x3C, 0x9E, 0xFD, 0x62, 0x55, 0x1F, 0xEB, 0x9B, 0xFF, 0x50, 0x36, 0x68, 0xEF, 0x1A, - 0xF7, 0x00, 0x1A, 0x35, 0xC2, 0x99, 0x2C, 0x4A, 0xB7, 0x05, 0x48, 0x19, 0xF9, 0x88, 0x78, 0x0C, 0xEA, 0x34, 0xCC, 0x83, 0xBB, 0x17, 0x4E, 0x66, - 0xBD, 0x4B, 0x07, 0x05, 0x2D, 0xCE, 0xA2, 0x00, 0x66, 0x04, 0x9C, 0x04, 0x43, 0x7F, 0x24, 0x06, 0x9B, 0xA1, 0xA8, 0xA4, 0xE4, 0x22, 0xA7, 0x38, - 0x3C, 0x00, 0x00, 0x20, 0x82, 0x20, 0x00, 0x53, 0x89, 0x22, 0x8C, 0xC3, 0x18, 0x40, 0x8E, 0x31, 0xE8, 0xD4, 0x00, 0x04, 0x20, 0x05, 0x60, 0x4A, - 0x01, 0x1C, 0x07, 0x40, 0x20, 0x0A, 0x21, 0x0C, 0x03, 0x30, 0x0C, 0x44, 0x22, 0x00, 0x00, 0x42, 0x10, 0x00, 0x06, 0x00, 0x03, 0xC0, 0x10, 0x22, - 0x1A, 0x2A, 0x0B, 0x63, 0xAF, 0x8B, 0xC3, 0x1C, 0x0C, 0x16, 0x62, 0xFF, 0x0D, 0xDD, 0x72, 0xEC, 0x50, 0x3B, 0x2B, 0x4B, 0x76, 0xC9, 0xB4, 0xE9, - 0x58, 0x17, 0xCD, 0xD9, 0xF6, 0xF2, 0x35, 0xA5, 0x10, 0xC6, 0x4E, 0x83, 0xA8, 0x62, 0xB7, 0x53, 0x06, 0x31, 0x49, 0x35, 0xA8, 0xA8, 0x2E, 0x6C, - 0x3D, 0xB4, 0xA5, 0xE2, 0x9C, 0x1D, 0x67, 0xAE, 0x91, 0xDB, 0x20, 0xF5, 0x56, 0xD8, 0x27, 0x0A, 0x42, 0xE0, 0xAB, 0x7C, 0xA9, 0x0A, 0x5A, 0x67, - 0xD8, 0xF4, 0x94, 0x85, 0xEB, 0xA0, 0xBD, 0xC9, 0xBA, 0xC1, 0xF4, 0x58, 0x5B, 0x93, 0x13, 0x19, 0xA6, 0xE5, 0xF7, 0x4C, 0xEC, 0x83, 0xB7, 0xB8, - 0x7C, 0xC9, 0x59, 0x47, 0x9A, 0x8B, 0xFA, 0xFA, 0xD0, 0x28, 0xE7, 0x36, 0xE7, 0x88, 0xAF, 0xCD, 0x36, 0xC6, 0x1D, 0x85, 0x59, 0x55, 0xAD, 0x94, - 0xC7, 0xD9, 0x29, 0x0B, 0x0B, 0x08, 0xEC, 0x65, 0x44, 0xDB, 0x03, 0x1A, 0x7A, 0x09, 0x76, 0x22, 0xD0, 0xE1, 0x9F, 0x52, 0xAE, 0xE4, 0xC0, 0x21, - 0xB6, 0x28, 0xAB, 0xDF, 0x93, 0xDE, 0x82, 0xC4, 0x3E, 0x06, 0xB0, 0x33, 0x74, 0x42, 0x11, 0x73, 0x51, 0xB0, 0xCF, 0xF0, 0xD5, 0xC5, 0x11, 0xBD, - 0xBE, 0xD5, 0xE4, 0x7E, 0xA0, 0xF5, 0xC1, 0xDD, 0xB1, 0x4F, 0xAF, 0xE6, 0xEC, 0x92, 0xD3, 0x57, 0x73, 0x40, 0x66, 0x2D, 0x4E, 0x92, 0xCD, 0x24, - 0xA3, 0x23, 0x41, 0x77, 0x6F, 0x18, 0x00, 0x5B, 0x55, 0x2D, 0x1B, 0xA9, 0xFA, 0xDB, 0x4C, 0x85, 0xCB, 0xDF, 0xB1, 0x01, 0x06, 0x59, 0x84, 0xE3, - 0x8E, 0x99, 0xB4, 0x31, 0xF8, 0x9C, 0x75, 0xDD, 0x42, 0x41, 0x5F, 0xB3, 0x7B, 0x22, 0xB9, 0xDC, 0x49, 0x31, 0xCF, 0xBA, 0xCF, 0x39, 0x46, 0xDD, - 0xA1, 0x39, 0x4F, 0x70, 0x33, 0xD1, 0x78, 0xE8, 0x3C, 0x9C, 0xAD, 0xBF, 0xF3, 0x50, 0x3A, 0xA6, 0x8C, 0x3F, 0xB7, 0xB1, 0xEE, 0xDB, 0xC0, 0xC9, - 0xD1, 0xBC, 0x6E, 0x60, 0xE6, 0xF1, 0xBE, 0xE9, 0xDC, 0x19, 0xD7, 0xCC, 0xDC, 0x17, 0xE5, 0x7D, 0xC2, 0x0D, 0x15, 0x64, 0x7F, 0x64, 0x75, 0x5D, - 0x26, 0xD0, 0xFA, 0x1C, 0xCE, 0x5A, 0xF5, 0x97, 0x95, 0xBC, 0x30, 0x35, 0x9E, 0x95, 0xD0, 0x71, 0x13, 0x7F, 0xF4, 0xD0, 0x4A, 0xF5, 0x43, 0xCF, - 0x6B, 0x86, 0x2B, 0xB7, 0xBB, 0x50, 0xD1, 0x23, 0x7A, 0xB6, 0xD3, 0x3D, 0x2E, 0xFF, 0xEB, 0x70, 0x9F, 0xDC, 0x3F, 0xB6, 0xB0, 0x4C, 0xA7, 0x39, - 0xAB, 0xCE, 0x91, 0xDA, 0xB0, 0x0A, 0xB6, 0xE5, 0x73, 0xA6, 0x24, 0xC0, 0x35, 0x43, 0x7A, 0x22, 0xFB, 0xD4, 0xAE, 0x07, 0xD5, 0x33, 0xA0, 0x3D, - 0xFD, 0xBB, 0x28, 0xB1, 0x65, 0x0D, 0xC2, 0x63, 0xEC, 0xD3, 0xDC, 0x4C, 0xAF, 0x79, 0x8D, 0x80, 0x61, 0x36, 0x5A, 0xA9, 0x1F, 0x0E, 0xEB, 0x0C, - 0x98, 0xB9, 0xA7, 0xF6, 0x21, 0x28, 0xF3, 0xC7, 0xA0, 0xC2, 0xDC, 0x80, 0x04, 0x26, 0xAA, 0xFD, 0x1F, 0xF9, 0x6C, 0x91, 0xEA, 0x9A, 0x3F, 0xBD, - 0x83, 0xDC, 0x2D, 0xBA, 0x2D, 0xA9, 0xD0, 0x72, 0x7D, 0xF5, 0x4E, 0xB2, 0xC3, 0xAD, 0x1D, 0x13, 0x51, 0x5C, 0xB7, 0xF4, 0x95, 0x24, 0xAD, 0x96, - 0x99, 0x77, 0x8B, 0x6B, 0x55, 0x5B, 0xDB, 0x4A, 0x25, 0x7E, 0xC8, 0x5F, 0xFC, 0x8A, 0xC8, 0x4F, 0x36, 0x21, 0xDB, 0x14, 0x81, 0x99, 0x7E, 0xE8, - 0x93, 0x55, 0xC9, 0xE8, 0x42, 0x0F, 0xDC, 0xB9, 0x0D, 0xC3, 0xAD, 0xD0, 0x5A, 0x20, 0xD0, 0xB6, 0x53, 0xC3, 0xEF, 0x71, 0x6E, 0xD9, 0xFE, 0x74, - 0x56, 0xBB, 0x36, 0xC5, 0xF4, 0x07, 0xD0, 0x5F, 0xA4, 0x40, 0x46, 0xB2, 0x50, 0x60, 0x5D, 0x4F, 0x83, 0xC1, 0x91, 0x91, 0xF0, 0xF1, 0x8B, 0x45, - 0x99, 0x0E, 0xBB, 0x87, 0x58, 0x7A, 0x36, 0xD4, 0xC2, 0xB8, 0xB7, 0xCF, 0x67, 0xA2, 0xDE, 0xDB, 0x5F, 0x09, 0x01, 0x32, 0xE1, 0x9B, 0x96, 0xA3, - 0x45, 0x05, 0x9E, 0xD9, 0x42, 0xF0, 0x8D, 0x5D, 0xAF, 0xA7, 0x6D, 0x7A, 0x04, 0xC3, 0xA0, 0x05, 0x66, 0x52, 0x07, 0x92, 0x06, 0xA4, 0xB5, 0xDC, - 0xEF, 0x57, 0xA9, 0xBB, 0x34, 0x48, 0x4B, 0x57, 0xD4, 0x84, 0x62, 0xF7, 0xF3, 0x7A, 0xD8, 0x0D, 0x09, 0xF6, 0x5D, 0xA8, 0xE5, 0x85, 0x58, 0x6B, - 0x61, 0x62, 0x40, 0x98, 0x72, 0x73, 0x6B, 0x43, 0xD1, 0xFB, 0x2E, 0x40, 0x43, 0xEF, 0x64, 0xD4, 0x40, 0x3C, 0x39, 0x1B, 0xCA, 0x4E, 0x2D, 0x45, - 0x62, 0xF7, 0xDB, 0x05, 0x15, 0xDD, 0xE4, 0xCC, 0x6C, 0xA8, 0x25, 0x3E, 0x42, 0x61, 0xAC, 0x25, 0xB7, 0x7C, 0xF0, 0x80, 0x29, 0x77, 0x3F, 0xF9, - 0xF6, 0xA2, 0xDD, 0xFA, 0x5D, 0xF3, 0x78, 0xD2, 0x5B, 0x39, 0x27, 0xCC, 0x1A, 0x02, 0x7E, 0x95, 0xD3, 0x07, 0xCD, 0x71, 0xA5, 0x28, 0x38, 0x11, - 0x6A, 0xA1, 0x04, 0xC8, 0x21, 0x7E, 0x9E, 0x87, 0x8D, 0xA3, 0x3A, 0xED, 0x52, 0x5A, 0x08, 0x38, 0x1B, 0x29, 0x10, 0x24, 0xF5, 0x3B, 0x70, 0xC5, - 0x05, 0xF4, 0xAA, 0x96, 0x34, 0x30, 0xEC, 0xA2, 0x38, 0x74, 0xEA, 0xCC, 0x1E, 0xBD, 0xC9, 0xD6, 0x9F, 0x9B, 0x87, 0x59, 0x91, 0x96, 0xB3, 0x16, - 0x42, 0x5C, 0x9F, 0x5E, 0x6E, 0x76, 0x93, 0x6A, 0xAB, 0xB6, 0x5F, 0x6D, 0x4F, 0x6C, 0x1B, 0x9C, 0xFD, 0x64, 0x87, 0x6F, 0x67, 0x4D, 0x0E, 0x4D, - 0x8B, 0x3E, 0x1D, 0x7F, 0xAF, 0xA9, 0x25, 0xF0, 0xB2, 0xCD, 0x95, 0x82, 0x1B, 0xCC, 0x9A, 0x89, 0x27, 0x18, 0x5B, 0x7C, 0xD0, 0xA7, 0x89, 0x6D, - 0x21, 0x41, 0x38, 0x78, 0x35, 0x40, 0x37, 0xD7, 0xC4, 0x48, 0x6B, 0xF6, 0x21, 0x7E, 0xD0, 0x31, 0xD1, 0xCA, 0x6E, 0x1F, 0x18, 0x36, 0x45, 0xAF, - 0x09, 0xB2, 0xFB, 0x1D, 0xA2, 0x33, 0x4E, 0xAA, 0xDF, 0x1A, 0x3A, 0x10, 0xF4, 0xF0, 0x6E, 0x47, 0xD9, 0x8E, 0x20, 0x8D, 0x8F, 0xAE, 0x36, 0xD4, - 0x14, 0x3D, 0xAC, 0xAD, 0xD1, 0x7B, 0x24, 0xEC, 0xBF, 0xD3, 0x75, 0x26, 0x39, 0x80, 0xAD, 0x9E, 0xAA, 0x92, 0x3E, 0x86, 0xA7, 0xD1, 0x62, 0x4B, - 0x87, 0x03, 0x2C, 0xBD, 0x88, 0xEB, 0xF6, 0x5F, 0xE6, 0xD1, 0xFD, 0x3D, 0x9C, 0xC4, 0xAC, 0xC6, 0xE5, 0xDA, 0x14, 0x43, 0xC5, 0xE4, 0x50, 0x5A, - 0xD1, 0x5A, 0x45, 0x75, 0xF4, 0xD6, 0x20, 0xBB, 0x7F, 0x92, 0xA5, 0xB6, 0x87, 0xF9, 0x24, 0xAE, 0x8C, 0xB0, 0xA6, 0x01, 0xF8, 0x4B, 0x72, 0x5A, - 0x59, 0xDA, 0xA8, 0xBC, 0xF5, 0x40, 0xFD, 0x7F, 0x30, 0x27, 0xD7, 0x71, 0x96, 0x75, 0xF3, 0xCB, 0x35, 0x9C, 0x17, 0x95, 0x14, 0x9D, 0x05, 0x7A, - 0xA1, 0xEE, 0xDD, 0x2D, 0xB6, 0x82, 0xAE, 0x07, 0xA3, 0x8D, 0x4B, 0xB0, 0x8F, 0x30, 0xB9, 0xF8, 0x37, 0x68, 0x7A, 0xED, 0x05, 0x7B, 0x76, 0x20, - 0x04, 0xE6, 0xCD, 0x05, 0xA8, 0x25, 0x4F, 0xC8, 0xBF, 0x93, 0x66, 0x62, 0x17, 0x6D, 0x0F, 0xB0, 0x5B, 0x45, 0xAF, 0xAE, 0xE1, 0x9F, 0x39, 0x71, - 0x94, 0x72, 0x07, 0xEC, 0x16, 0x72, 0xAE, 0xD4, 0x07, 0xC1, 0xE6, 0xF7, 0xF8, 0x7F, 0xE7, 0x33, 0x07, 0x76, 0x6E, 0xEC, 0x34, 0x3B, 0xBC, 0xD3, - 0xE1, 0x6E, 0x2A, 0x77, 0x3F, 0xC0, 0x0E, 0x35, 0x64, 0xF0, 0xB5, 0x0F, 0x05, 0x3B, 0x2A, 0x3E, 0xE4, 0x08, 0xBD, 0x74, 0x06, 0xA1, 0x2D, 0xD1, - 0x5B, 0x24, 0xE7, 0x48, 0x5E, 0x63, 0x08, 0xAC, 0x06, 0x69, 0x7F, 0x25, 0x37, 0x0F, 0x18, 0xE0, 0xD0, 0xEB, 0x4C, 0x9C, 0x57, 0xB4, 0x41, 0xF7, - 0xDE, 0xAD, 0xA6, 0xF8, 0x2A, 0xBA, 0xE1, 0x14, 0x76, 0xAF, 0xDD, 0xBB, 0x9E, 0x46, 0x8E, 0x27, 0x74, 0xE8, 0xAF, 0xF2, 0xC4, 0xF3, 0x4D, 0x4D, - 0x76, 0xB5, 0xC5, 0xD2, 0xCD, 0x05, 0x6A, 0x1C, 0x7A, 0x4C, 0xA2, 0x72, 0x57, 0x0C, 0x0C, 0xD3, 0xA3, 0x7D, 0x7A, 0x7B, 0xB2, 0x39, 0x04, 0xB9, - 0x0E, 0xF6, 0x79, 0xB3, 0x5F, 0xA0, 0x81, 0xB6, 0x41, 0xC1, 0x11, 0xE6, 0xBB, 0x3F, 0x77, 0x86, 0x7F, 0x28, 0x0D, 0x10, 0xAF, 0x96, 0xC9, 0x22, - 0xFA, 0x61, 0x5B, 0x53, 0xBA, 0x75, 0x00, 0xC1, 0x9B, 0x31, 0x8E, 0xD9, 0xF8, 0xEE, 0x0A, 0x0E, 0xD1, 0x48, 0x70, 0x90, 0x75, 0x1E, 0xB0, 0x95, - 0xCF, 0x9B, 0x26, 0x0D, 0x2D, 0x24, 0x23, 0x3E, 0x9B, 0xC7, 0x76, 0x9D, 0x29, 0xD8, 0x36, 0x4C, 0x06, 0xAD, 0x6E, 0x55, 0x24, 0x96, 0xEA, 0x76, - 0x22, 0x8D, 0x0D, 0xDE, 0xEB, 0x3E, 0x07, 0x03, 0xC5, 0x06, 0xA2, 0x62, 0x35, 0xC2, 0x14, 0xDD, 0x6F, 0x64, 0xBA, 0x86, 0x49, 0xC2, 0x45, 0x47, - 0x01, 0xBA, 0xB7, 0x33, 0xB5, 0x2B, 0xE0, 0xF0, 0xD1, 0xED, 0xAA, 0xA7, 0xD7, 0x08, 0xDC, 0x4B, 0xC4, 0x2B, 0xF0, 0xA5, 0x79, 0x63, 0x82, 0x70, - 0x7A, 0x66, 0x69, 0x04, 0x6A, 0x84, 0x67, 0x9F, 0xCB, 0x95, 0x4A, 0x11, 0xAC, 0xB7, 0x07, 0x19, 0x66, 0x00, 0x32, 0x98, 0xD8, 0x7F, 0x17, 0x42, - 0xED, 0x85, 0x4B, 0x64, 0xFD, 0xFE, 0x3A, 0xDC, 0xB2, 0x95, 0x1E, 0x21, 0xC4, 0x2C, 0x0A, 0xDF, 0x9E, 0xFB, 0x8A, 0x15, 0xAF, 0xA5, 0xCB, 0xDF, - 0xC9, 0xB5, 0x2F, 0xA2, 0xDF, 0x76, 0xE0, 0xFB, 0x1C, 0xA6, 0x9F, 0x63, 0xCF, 0x5B, 0x23, 0x6D, 0x46, 0x43, 0x14, 0xF6, 0x09, 0x92, 0xB9, 0x9B, - 0xAD, 0xB6, 0x47, 0x28, 0xB2, 0x37, 0x5D, 0x91, 0x79, 0x09, 0xC2, 0xED, 0x0C, 0xCF, 0x5A, 0x98, 0xD3, 0xDF, 0xB4, 0x35, 0x5A, 0x89, 0xDA, 0xE2, - 0x69, 0xA4, 0xED, 0x37, 0xE6, 0xC8, 0xD1, 0xF3, 0x18, 0xDF, 0x6B, 0x34, 0xE4, 0x5D, 0xF9, 0xE8, 0x5A, 0x8B, 0x35, 0x11, 0xD7, 0x9D, 0xA5, 0x4A, - 0xF7, 0x83, 0x15, 0x6E, 0x95, 0xBA, 0x8E, 0x45, 0xEB, 0x1F, 0x40, 0x5C, 0x51, 0xB9, 0x11, 0x31, 0xE0, 0xC6, 0x1C, 0xC0, 0x59, 0xB6, 0x4D, 0x4E, - 0x46, 0x23, 0x27, 0x47, 0x47, 0x73, 0x5A, 0x96, 0x3D, 0x09, 0x7F, 0xB0, 0xFB, 0x70, 0x39, 0xA7, 0x60, 0xDF, 0xF8, 0x3E, 0xB8, 0xB8, 0x5B, 0xE5, - 0x4A, 0x46, 0x99, 0x15, 0x35, 0x19, 0x15, 0xBC, 0xF1, 0xF3, 0x1B, 0x26, 0xBE, 0xA1, 0x2C, 0xD2, 0x4B, 0xDF, 0xDF, 0xB8, 0xF1, 0xA8, 0xC8, 0xFD, - 0x89, 0x56, 0x45, 0x7F, 0x2E, 0x57, 0xEB, 0x88, 0x72, 0xDE, 0x56, 0xCC, 0x36, 0x06, 0x0B, 0xEE, 0x68, 0x13, 0x3C, 0x6D, 0xB3, 0x9B, 0xD4, 0x9F, - 0x50, 0x10, 0x3B, 0xE7, 0xA7, 0xDC, 0x2C, 0x38, 0xE7, 0x71, 0xF0, 0xBC, 0x7B, 0x0E, 0x05, 0x90, 0x07, 0x99, 0x15, 0xAA, 0xC1, 0x8D, 0x13, 0x03, - 0x7B, 0xFC, 0x49, 0xFD, 0xDE, 0x92, 0xEC, 0x14, 0xED, 0x76, 0x83, 0x24, 0x8B, 0x4B, 0x22, 0x34, 0x8A, 0xAA, 0xBE, 0xF1, 0xCD, 0x27, 0x6A, 0xF2, - 0x71, 0xF4, 0xD3, 0x17, 0x8A, 0x9D, 0x32, 0xCF, 0x9D, 0x72, 0x4E, 0x87, 0x5A, 0x3A, 0x81, 0x21, 0x8E, 0xD7, 0x6F, 0xD8, 0x05, 0x67, 0xA1, 0x65, - 0xB9, 0xFE, 0x09, 0x8F, 0x58, 0x7E, 0x69, 0x24, 0xFA, 0x41, 0xE8, 0xAD, 0x23, 0x28, 0x92, 0xDC, 0x7F, 0x87, 0xDE, 0xD9, 0x01, 0x76, 0xF0, 0xA8, - 0x29, 0x23, 0x73, 0xA1, 0x24, 0xB8, 0x8F, 0x49, 0x78, 0xC5, 0xB8, 0x9F, 0x43, 0xE8, 0x6F, 0x8F, 0xE8, 0x26, 0x1E, 0xED, 0x74, 0xE5, 0xFA, 0xDF, - 0xE9, 0x38, 0x63, 0x76, 0x9C, 0x5E, 0x9B, 0x3A, 0x3D, 0x33, 0x34, 0xFD, 0xFE, 0x92, 0x41, 0x8B, 0xB4, 0x60, 0x54, 0xAC, 0x26, 0x35, 0xEC, 0xCA, - 0xAB, 0x79, 0xDD, 0x81, 0x06, 0xF0, 0x27, 0xC2, 0xF8, 0x25, 0xAB, 0x2D, 0x66, 0xFD, 0x2F, 0x0B, 0xA4, 0xEF, 0xAA, 0xA9, 0x1B, 0x8A, 0x5E, 0x3F, - 0xE8, 0xB1, 0xD7, 0xB1, 0xAB, 0x68, 0xC6, 0x5F, 0xF3, 0xA1, 0xCE, 0xB6, 0xB3, 0xF3, 0x1A, 0x71, 0x60, 0xCC, 0x1C, 0x5B, 0x2C, 0x44, 0x69, 0xB5, - 0x46, 0xDE, 0xF0, 0x98, 0x48, 0x30, 0x46, 0x0F, 0xAD, 0x29, 0x9D, 0x47, 0x59, 0x27, 0x90, 0x73, 0xCF, 0x15, 0x2C, 0xEB, 0x94, 0xEC, 0xAD, 0x5E, - 0xB3, 0x9A, 0xFA, 0x15, 0x9F, 0xAF, 0xF4, 0x8E, 0x87, 0x1C, 0x47, 0xCD, 0xE0, 0x16, 0x83, 0xC1, 0x68, 0x70, 0x31, 0x0C, 0x77, 0xCC, 0x3A, 0xEC, - 0x5A, 0x2E, 0xD3, 0x93, 0xE9, 0x3F, 0x26, 0x6C, 0x0F, 0x29, 0x40, 0xFF, 0x8B, 0x2E, 0xCB, 0x72, 0x63, 0xD0, 0x60, 0xE3, 0xD0, 0xEE, 0xB4, 0x32, - 0x1E, 0x9E, 0x27, 0x33, 0xB3, 0xA5, 0x04, 0x72, 0xFC, 0x4C, 0xA2, 0x57, 0x0B, 0x56, 0xA1, 0x3D, 0x38, 0x3B, 0x73, 0x3D, 0xAD, 0x09, 0xE9, 0x7A, - 0x46, 0x4B, 0x6E, 0x6E, 0xB2, 0x2C, 0xF0, 0xB2, 0x85, 0x91, 0x58, 0x4A, 0xD1, 0x5F, 0x0B, 0x20, 0x19, 0x49, 0x87, 0xE0, 0x2C, 0xFF, 0x5E, 0x12, - 0xE9, 0x4A, 0xE6, 0x55, 0x98, 0xD8, 0x68, 0x07, 0x37, 0x3B, 0xB0, 0x72, 0xAB, 0x96, 0x3D, 0xB8, 0x0A, 0x3A, 0xCF, 0xE0, 0x81, 0x90, 0xA5, 0xB5, - 0x3D, 0x67, 0xB0, 0x09, 0x55, 0x49, 0x58, 0x75, 0x98, 0x5C, 0x3B, 0xD0, 0xD3, 0xBC, 0x15, 0xCF, 0xF2, 0x53, 0x28, 0x49, 0x22, 0xEC, 0x62, 0x79, - 0x3A, 0xA2, 0x16, 0xAE, 0x98, 0xF6, 0x0C, 0xC5, 0x1F, 0x8F, 0xA5, 0x59, 0xB1, 0x5C, 0x9E, 0x10, 0x5B, 0xBD, 0x73, 0xD9, 0xD3, 0x1C, 0x70, 0x40, - 0x1F, 0xF3, 0x13, 0x8E, 0x48, 0x7C, 0xDC, 0x23, 0xCB, 0x20, 0x30, 0xE7, 0xC5, 0x1E, 0x01, 0x6B, 0xB7, 0x29, 0x0E, 0x66, 0xB0, 0x66, 0x85, 0x8F, - 0x20, 0xAC, 0x7B, 0xCD, 0xDC, 0x61, 0x38, 0xFF, 0x23, 0xEF, 0xFE, 0x1F, 0xB6, 0xD6, 0x79, 0x9B, 0x60, 0x92, 0x9E, 0xF9, 0x4D, 0xDE, 0x32, 0x09, - 0xAB, 0xC9, 0x33, 0xB2, 0x9F, 0x38, 0x22, 0xBD, 0x39, 0x15, 0x05, 0xBD, 0xE3, 0x73, 0x65, 0xC1, 0x65, 0x0F, 0xF3, 0xF8, 0xBF, 0x33, 0x0D, 0xF7, - 0x19, 0xE6, 0xD6, 0xCD, 0xA1, 0xAC, 0xEB, 0x59, 0x64, 0x09, 0x0F, 0xA3, 0xB9, 0xCC, 0x9C, 0x64, 0x2B, 0x84, 0x38, 0x8D, 0x9F, 0xDA, 0x8D, 0x73, - 0x57, 0x2E, 0x10, 0x23, 0xEA, 0xD0, 0xD3, 0xCC, 0xB9, 0x76, 0x59, 0x5C, 0xF5, 0x49, 0xA6, 0xAB, 0x87, 0xE9, 0xB2, 0xAD, 0xE2, 0x96, 0x31, 0x11, - 0xBE, 0xCC, 0xFC, 0x10, 0x02, 0xAE, 0xBF, 0xCC, 0xC5, 0x77, 0x11, 0xC4, 0x87, 0x33, 0x8D, 0xDB, 0xE7, 0x58, 0x53, 0x6A, 0x97, 0x80, 0x1B, 0x64, - 0xCC, 0xAB, 0x62, 0x3A, 0xA5, 0x38, 0x5B, 0x73, 0x96, 0xE5, 0x72, 0x03, 0xC0, 0xD8, 0xFE, 0xE0, 0xA4, 0x79, 0xF8, 0xBE, 0x8E, 0x8A, 0xA1, 0x37, - 0x8E, 0xFB, 0x86, 0x6E, 0x1A, 0x65, 0x0D, 0xA7, 0x1B, 0xE1, 0x16, 0x8D, 0xC1, 0x71, 0x02, 0x42, 0x76, 0xBD, 0xB9, 0xD8, 0x6B, 0x3C, 0x42, 0x72, - 0x6F, 0xDF, 0x20, 0xBE, 0x31, 0xAA, 0x1D, 0x6B, 0xD3, 0xBF, 0xCA, 0xB3, 0x00, 0x8A, 0x30, 0x04, 0x45, 0x06, 0x92, 0x87, 0x9A, 0x75, 0x4E, 0x1C, - 0x63, 0xAC, 0xEA, 0x59, 0x6C, 0x81, 0x49, 0xE7, 0x5D, 0xE3, 0x9E, 0x8C, 0xD0, 0x95, 0x7B, 0x6F, 0x9A, 0xA0, 0xE5, 0xDE, 0x47, 0x33, 0xDD, 0x64, - 0xA6, 0xD5, 0xDC, 0xB4, 0xBF, 0xAC, 0x7B, 0x52, 0xDD, 0x5A, 0xCD, 0xD1, 0xD6, 0x12, 0xB5, 0x0C, 0xA3, 0x9C, 0x92, 0x6B, 0x44, 0xD6, 0x23, 0xB8, - 0x01, 0xF8, 0x0C, 0xBF, 0x0B, 0xF8, 0xD3, 0x49, 0x84, 0x9E, 0xA8, 0x23, 0x33, 0xD9, 0x75, 0x5C, 0x7F, 0x7A, 0x98, 0x91, 0xFE, 0x26, 0xF6, 0xE4, - 0x0B, 0x53, 0x8C, 0x07, 0x13, 0x76, 0xFA, 0x67, 0x5B, 0xFE, 0x88, 0x8C, 0x7B, 0xDE, 0xBE, 0x1F, 0x6D, 0x1D, 0x60, 0xE9, 0x09, 0xC0, 0x4C, 0x22, - 0xB7, 0x0D, 0x62, 0x8E, 0xE6, 0x8D, 0x56, 0xDB, 0x38, 0x8F, 0x9E, 0x13, 0x55, 0xB3, 0xAD, 0xB1, 0x7A, 0x41, 0x99, 0x41, 0xCB, 0x0E, 0xF8, 0x6D, - 0x23, 0xC2, 0x6B, 0x4E, 0x71, 0x2A, 0xBF, 0x18, 0xF1, 0x6F, 0x07, 0xD7, 0x00, 0x86, 0xB0, 0xAB, 0x07, 0x23, 0xEA, 0x7A, 0xFA, 0x14, 0xD0, 0x19, - 0x81, 0x1E, 0x7B, 0x26, 0xA0, 0x91, 0xAD, 0x9E, 0x98, 0xA7, 0x62, 0x8F, 0x1E, 0x78, 0x80, 0x3D, 0x79, 0xBC, 0xE6, 0x2E, 0xD5, 0x31, 0x2C, 0xD2, - 0x0D, 0x4A, 0x18, 0x82, 0x7B, 0x8C, 0x7C, 0x8D, 0x0D, 0xC8, 0xD1, 0xD0, 0x01, 0xC7, 0x65, 0xF7, 0x8C, 0xBA, 0xA4, 0xBA, 0xB2, 0x5A, 0x74, 0x61, - 0xF0, 0x01, 0x6D, 0x38, 0x08, 0x9F, 0x2C, 0x9C, 0x73, 0x66, 0x4C, 0x7C, 0x8E, 0xCF, 0xE0, 0x9E, 0x6B, 0x1A, 0x07, 0x64, 0x24, 0x1D, 0xE8, 0x58, - 0xF5, 0x10, 0x4C, 0x76, 0x1A, 0x5E, 0xE5, 0x7F, 0xAF, 0x9E, 0x3A, 0x82, 0x70, 0x37, 0x1E, 0x39, 0x00, 0x22, 0xA0, 0xE2, 0x78, 0xC2, 0xD7, 0x05, - 0x9E, 0x95, 0x9A, 0x18, 0x8E, 0x17, 0x73, 0x48, 0x1E, 0x21, 0x4C, 0x0D, 0xF5, 0x59, 0x54, 0x39, 0xA7, 0xE0, 0xDD, 0x0A, 0x4F, 0x37, 0x92, 0xF2, - 0x76, 0x85, 0xB0, 0xA3, 0xF1, 0x38, 0xE9, 0xF5, 0xD4, 0xE6, 0xFA, 0x76, 0xEB, 0x3F, 0xFC, 0xEC, 0xE6, 0x52, 0x36, 0x32, 0x00, 0xB8, 0xB7, 0xFF, - 0x88, 0x1F, 0x25, 0x36, 0xB1, 0x38, 0x28, 0x82, 0xE5, 0x90, 0x99, 0xFA, 0x2D, 0xEA, 0xB9, 0x50, 0xA6, 0x1F, 0xA3, 0x5A, 0xC4, 0x28, 0x22, 0xFC, - 0x51, 0x7D, 0x98, 0x93, 0xA3, 0x11, 0xC9, 0x80, 0xC6, 0xE7, 0xF4, 0x32, 0xB6, 0x60, 0x89, 0x39, 0x9B, 0xCE, 0xCD, 0xBA, 0x1D, 0xDF, 0x56, 0x70, - 0xF5, 0xE9, 0xB9, 0x0D, 0xCD, 0x86, 0x19, 0x6D, 0x8D, 0x5C, 0x43, 0x04, 0x4B, 0x38, 0xD9, 0xB7, 0x0A, 0x89, 0xE7, 0x66, 0x03, 0x08, 0xEA, 0x63, - 0xFC, 0x81, 0x2D, 0xC1, 0x96, 0x2D, 0xFB, 0x11, 0x46, 0xB3, 0x0D, 0xE1, 0x5A, 0x21, 0xCA, 0x63, 0xC6, 0x6F, 0x93, 0x70, 0x3C, 0xD2, 0x24, 0xCC, - 0x42, 0xFC, 0xC0, 0x01, 0x7B, 0xBC, 0xE6, 0xB1, 0xE2, 0x5D, 0x17, 0xC0, 0xAA, 0x95, 0x61, 0x45, 0xCD, 0x32, 0xC3, 0x75, 0x9B, 0x38, 0x99, 0x89, - 0x47, 0x58, 0x2F, 0x37, 0xB3, 0xED, 0xB6, 0x62, 0xD2, 0xF3, 0x8D, 0x1A, 0xC5, 0xBB, 0x4D, 0x51, 0xCE, 0xAB, 0xE1, 0x80, 0xBD, 0x9F, 0xEB, 0x21, - 0x83, 0xD1, 0xFD, 0x62, 0x71, 0x2C, 0x86, 0xF4, 0x9B, 0x81, 0x4D, 0x37, 0x99, 0x70, 0x26, 0xE2, 0xBE, 0xDA, 0x98, 0x3E, 0x38, 0x72, 0x54, 0x70, - 0x67, 0x28, 0x71, 0x32, 0xCC, 0xF3, 0xEA, 0x79, 0x1A, 0x8B, 0xE9, 0x56, 0x51, 0xFE, 0x98, 0x45, 0x86, 0x29, 0x04, 0x26, 0x5B, 0xBF, 0x83, 0xB7, - 0x69, 0xB2, 0xB0, 0x41, 0xDE, 0x5F, 0x53, 0x16, 0x26, 0x93, 0xB1, 0x0D, 0x83, 0x7E, 0x5D, 0x43, 0xCD, 0x63, 0x77, 0x96, 0xB8, 0xD7, 0x9E, 0x88, - 0xF7, 0x0D, 0x8B, 0x03, 0xBA, 0x76, 0x84, 0x4E, 0x3B, 0x33, 0xD1, 0x99, 0x35, 0x1E, 0xED, 0xFB, 0x4E, 0xB0, 0xE2, 0x1C, 0x5C, 0x87, 0x34, 0x0B, - 0x95, 0xD1, 0xE3, 0xBE, 0xB3, 0xBE, 0x2C, 0x8A, 0xAA, 0xE5, 0xE2, 0x59, 0x5E, 0x45, 0x33, 0xD3, 0x65, 0x86, 0x91, 0xDB, 0x52, 0x59, 0xAB, 0x84, - 0xC7, 0x69, 0x97, 0x85, 0xE1, 0x8E, 0x0D, 0xAA, 0xB1, 0x09, 0x23, 0xE7, 0xED, 0x8A, 0xB2, 0xE6, 0x5E, 0x19, 0x51, 0x46, 0x24, 0x2A, 0x4B, 0xF8, - 0x8B, 0x41, 0x7E, 0xD1, 0xC5, 0x72, 0x6C, 0xCD, 0x65, 0x0E, 0x07, 0x6C, 0x44, 0xCF, 0x5E, 0x75, 0x52, 0xF0, 0xD9, 0xEE, 0x3A, 0x36, 0x06, 0xD4, - 0xAB, 0xA8, 0x79, 0x9A, 0xB4, 0x11, 0xA1, 0x69, 0xA6, 0xD0, 0x6F, 0x2E, 0x4F, 0x0A, 0x02, 0x41, 0x37, 0x28, 0x56, 0x68, 0x17, 0xA0, 0x40, 0x8B, - 0x96, 0x25, 0x58, 0xD1, 0x96, 0xF4, 0xBA, 0xFC, 0xC4, 0x8F, 0xF8, 0x9E, 0xBC, 0xA0, 0xAF, 0x69, 0x75, 0x47, 0x85, 0xB9, 0xFB, 0x87, 0xBF, 0x16, - 0x28, 0x69, 0xB4, 0x57, 0x44, 0xAB, 0xB3, 0x63, 0x16, 0x75, 0x2F, 0x39, 0xB4, 0x26, 0x70, 0x03, 0xD7, 0xAE, 0xB5, 0x2E, 0x9B, 0x79, 0xC8, 0x48, - 0x9B, 0x8D, 0x03, 0x91, 0x6D, 0xE9, 0x42, 0x58, 0x36, 0x8A, 0x73, 0xEC, 0xF6, 0xB6, 0x4C, 0x72, 0x0C, 0x1C, 0x8C, 0x71, 0x54, 0xDA, 0xA5, 0x5A, - 0x53, 0xAE, 0x58, 0xF7, 0xE6, 0x6C, 0x36, 0x8B, 0x35, 0x49, 0x70, 0xB0, 0xA1, 0x9A, 0x2D, 0x12, 0x39, 0xD9, 0x7A, 0x0D, 0x49, 0x58, 0xA6, 0xD6, - 0xF7, 0x6A, 0x15, 0x13, 0x12, 0xB7, 0x39, 0x45, 0xAE, 0x39, 0xAE, 0xAF, 0x2F, 0x11, 0x31, 0x48, 0x23, 0x8E, 0x4E, 0x32, 0x4E, 0xA1, 0xAE, 0xB4, - 0x5D, 0xD1, 0xF9, 0xD7, 0x23, 0xEC, 0x36, 0x8C, 0x0E, 0x72, 0x0F, 0x8B, 0x2E, 0x5E, 0x64, 0x39, 0x46, 0xDE, 0xB1, 0x12, 0xEA, 0x91, 0x4E, 0xD1, - 0x63, 0xE8, 0xFB, 0x42, 0x01, 0x7A, 0xE5, 0xF8, 0xFE, 0xC0, 0xD8, 0x0C, 0xFA, 0xE6, 0x97, 0x85, 0x84, 0xD9, 0x0B, 0xB9, 0xFC, 0x8B, 0x1A, 0xDA, - 0x0C, 0xA0, 0x43, 0xD6, 0xF9, 0x5B, 0x6A, 0x06, 0xB7, 0x30, 0x07, 0xA5, 0x1C, 0x60, 0xB9, 0xA5, 0x83, 0x3E, 0xC7, 0x67, 0xFD, 0xAA, 0x27, 0xD0, - 0x5E, 0x8A, 0xFF, 0x8C, 0xB4, 0xCD, 0xE4, 0x6B, 0x5F, 0x70, 0x47, 0xA4, 0x40, 0xD7, 0x50, 0xEF, 0x05, 0x9D, 0x8B, 0xB5, 0x24, 0x58, 0x2D, 0xFE, - 0x8F, 0x02, 0x14, 0xAC, 0x62, 0xE8, 0x81, 0xF3, 0x35, 0xD5, 0x3D, 0x81, 0x91, 0x9D, 0x5D, 0x3C, 0xA1, 0xF1, 0x35, 0x81, 0x8E, 0xC6, 0xEA, 0xFB, - 0xD2, 0x74, 0x46, 0x13, 0x7B, 0x67, 0xD7, 0x8B, 0x0B, 0x70, 0x57, 0xBD, 0x19, 0xD4, 0xA9, 0x70, 0x45, 0xED, 0xE2, 0x3A, 0x8B, 0x8B, 0x75, 0x6E, - 0x37, 0x44, 0xC2, 0xD0, 0x9A, 0x27, 0xC4, 0x45, 0x34, 0x2D, 0x96, 0x3F, 0x0D, 0xC8, 0xF9, 0xE4, 0xF9, 0x7B, 0xDF, 0xD8, 0xAF, 0xD0, 0x89, 0xB3, - 0xE6, 0xAF, 0x31, 0xDB, 0x55, 0xFD, 0xB7, 0xF1, 0x1E, 0x2A, 0x06, 0xAD, 0x5F, 0x87, 0xEC, 0xA4, 0x52, 0x04, 0x33, 0x82, 0x73, 0xAB, 0xDD, 0xD5, - 0xD3, 0x81, 0x3B, 0x75, 0x20, 0xE0, 0x90, 0xAD, 0x57, 0x08, 0xBB, 0x26, 0x68, 0x37, 0xF9, 0xE1, 0xCF, 0xDD, 0x29, 0xF6, 0x9D, 0xE7, 0x67, 0x0E, - 0xBC, 0xC9, 0x61, 0x49, 0x31, 0xFF, 0x10, 0xAA, 0xDD, 0x92, 0x38, 0x14, 0xEF, 0x73, 0xB8, 0x8F, 0x73, 0xAC, 0x5E, 0x39, 0x4D, 0x41, 0xEC, 0x07, - 0x7C, 0xFF, 0xA6, 0x92, 0x45, 0xDB, 0xF4, 0xDA, 0xF2, 0xDF, 0x46, 0xB6, 0x4A, 0x06, 0x78, 0x4B, 0x0C, 0xFB, 0x22, 0x5D, 0x86, 0xC9, 0xDB, 0x00, - 0xF4, 0x9C, 0x38, 0x33, 0x0E, 0x8A, 0x10, 0x4A, 0x26, 0xBD, 0x0F, 0x49, 0xAA, 0x47, 0x6E, 0xC9, 0x4B, 0xE4, 0xA3, 0x35, 0x05, 0xCC, 0x58, 0xE6, - 0x79, 0xE7, 0xAD, 0x63, 0x58, 0xFB, 0x62, 0xF3, 0xFC, 0x5D, 0x61, 0x4E, 0xC9, 0x9E, 0x82, 0xD8, 0x20, 0x10, 0x72, 0x95, 0xE7, 0xD7, 0xA5, 0xE4, - 0xF6, 0x03, 0x67, 0x08, 0x8A, 0xEC, 0xD4, 0xB6, 0x30, 0xDF, 0xB8, 0x9D, 0xD9, 0xC2, 0x97, 0xCE, 0x28, 0x4B, 0xE2, 0xDC, 0xD2, 0x0A, 0xDE, 0xA4, - 0x2E, 0x7D, 0x9C, 0x8F, 0xFD, 0x36, 0xCD, 0xB6, 0x49, 0x3C, 0x76, 0x8B, 0xC8, 0xD0, 0x18, 0x9E, 0xE5, 0xD0, 0x7E, 0x89, 0xC7, 0x50, 0x66, 0x77, - 0x09, 0xAA, 0xAA, 0xCB, 0xFA, 0x11, 0x32, 0xD8, 0x36, 0x45, 0x64, 0xF2, 0xBB, 0x73, 0x16, 0x07, 0x4A, 0x91, 0x6F, 0xB2, 0xAF, 0x57, 0x48, 0xCF, - 0x36, 0xFD, 0x94, 0x4F, 0x06, 0xE2, 0x57, 0x0A, 0xB9, 0xEB, 0xC8, 0x5F, 0x1B, 0x80, 0x27, 0x6C, 0x19, 0x0A, 0xA5, 0x6A, 0xE5, 0xC2, 0xE1, 0xD1, - 0x0B, 0xBF, 0x29, 0xE2, 0x63, 0x4A, 0xD1, 0x7B, 0x86, 0xC1, 0x75, 0x57, 0xEF, 0x18, 0xB0, 0xF0, 0xB3, 0x59, 0x80, 0x1C, 0x62, 0xB3, 0xD0, 0x77, - 0x5E, 0xBB, 0x4B, 0xF2, 0x78, 0x98, 0x45, 0xE7, 0x5E, 0x87, 0xAE, 0xF6, 0xCC, 0x39, 0xEB, 0x17, 0x82, 0x11, 0x4F, 0xE9, 0x9E, 0xDB, 0xD7, 0x99, - 0x29, 0x43, 0x3E, 0xF1, 0xDA, 0x0C, 0xB8, 0xAD, 0xB7, 0x46, 0x36, 0xBA, 0xA5, 0x27, 0xDE, 0x3D, 0xAB, 0xB9, 0x6E, 0x42, 0x9B, 0xF5, 0x9B, 0x46, - 0x43, 0xD8, 0x6C, 0xF1, 0x1E, 0xC3, 0x01, 0x43, 0x1B, 0xAF, 0xDB, 0x47, 0x4C, 0x7E, 0x1F, 0x75, 0x4B, 0x1F, 0x7A, 0xE5, 0x86, 0x81, 0x6E, 0xB1, - 0x67, 0x15, 0xFA, 0x8A, 0x46, 0x63, 0x28, 0xA3, 0x71, 0x86, 0x6B, 0x1E, 0xAF, 0x08, 0x1B, 0xFA, 0xAA, 0xFF, 0xB0, 0x86, 0xC1, 0xBF, 0x1C, 0x58, - 0xDA, 0x80, 0x43, 0xFC, 0x0F, 0x6D, 0x6E, 0xDF, 0x18, 0xF8, 0x9E, 0xBC, 0xDB, 0xCE, 0x6D, 0x0D, 0x44, 0x8E, 0xCD, 0x39, 0xCE, 0xB1, 0x34, 0xCB, - 0x62, 0x42, 0x4C, 0xD3, 0x20, 0x0B, 0xB5, 0x90, 0x89, 0x89, 0xA1, 0xAC, 0x50, 0x96, 0x55, 0xD0, 0x0E, 0x0A, 0xE4, 0x9C, 0x86, 0x6F, 0x00, 0x48, - 0x29, 0x63, 0xC6, 0x0A, 0xDE, 0xD4, 0x0B, 0x5D, 0xCA, 0xEE, 0x02, 0x99, 0x55, 0xEC, 0x8D, 0xF9, 0x98, 0x5D, 0x48, 0x6E, 0xEB, 0x05, 0x68, 0x7E, - 0x11, 0xCC, 0x41, 0xFD, 0x08, 0x46, 0x87, 0x06, 0x17, 0xB2, 0x3A, 0x7C, 0xD1, 0x90, 0x07, 0x42, 0x53, 0x87, 0x0F, 0x1A, 0xD6, 0x40, 0xF8, 0xE8, - 0xB0, 0x8F, 0x43, 0x91, 0x0B, 0x51, 0x1C, 0xF6, 0xC1, 0xB0, 0x62, 0x21, 0xDE, 0xC1, 0x4E, 0xD6, 0xA7, 0xEE, 0xFC, 0x56, 0xD9, 0x1E, 0x34, 0xC3, - 0x7A, 0x0C, 0x28, 0x75, 0xC1, 0xC9, 0xF8, 0x01, 0x32, 0xE1, 0xE9, 0x71, 0xFB, 0xF6, 0x3F, 0xD5, 0xC1, 0xE5, 0xC7, 0x3F, 0x8D, 0xC7, 0xD8, 0x2F, - 0x14, 0x1E, 0xAD, 0x8C, 0x5C, 0xD4, 0x44, 0x72, 0xA2, 0x4D, 0xF5, 0x4D, 0x17, 0xEC, 0x82, 0x06, 0xDC, 0x62, 0xF2, 0xFC, 0x3D, 0xDC, 0x9E, 0x39, - 0x8F, 0x72, 0x4F, 0x70, 0xA1, 0x55, 0x3E, 0x4A, 0xAD, 0x9D, 0x7D, 0x6B, 0x64, 0xFD, 0x9C, 0x18, 0xA1, 0x34, 0x8B, 0x64, 0x8B, 0xD2, 0xFB, 0x4D, - 0xDA, 0xF0, 0x16, 0xE9, 0x8E, 0x4E, 0x82, 0x89, 0x7D, 0x9A, 0xD7, 0xC7, 0xB1, 0x90, 0x7B, 0xCD, 0xA9, 0x2B, 0x3D, 0xAB, 0xC1, 0x1C, 0xDD, 0xA3, - 0x39, 0x8F, 0x4C, 0x12, 0xE5, 0xE7, 0x72, 0x97, 0xD6, 0xFC, 0xD2, 0x53, 0xC4, 0x33, 0xB2, 0x92, 0x5A, 0xF4, 0x89, 0x2B, 0xCE, 0xB5, 0xC2, 0x9B, - 0x13, 0xE8, 0x66, 0xBD, 0xA6, 0x28, 0x31, 0x9C, 0xFE, 0x91, 0x07, 0x51, 0xA8, 0xA3, 0x42, 0xC5, 0xAE, 0x91, 0xD0, 0xCE, 0xDB, 0xF0, 0xE3, 0xB3, - 0x72, 0x18, 0x4D, 0xC7, 0x43, 0x4F, 0xE6, 0xA1, 0x4A, 0x63, 0x82, 0x6A, 0x36, 0x13, 0x09, 0x30, 0xFF, 0x60, 0x55, 0x3A, 0x93, 0xF7, 0x5B, 0xED, - 0x22, 0x6E, 0x93, 0x2F, 0x4A, 0xC2, 0xDA, 0xD9, 0xD6, 0xED, 0xC5, 0x87, 0x5C, 0x71, 0xAB, 0x97, 0x49, 0xC1, 0xE9, 0x94, 0x30, 0x84, 0x09, 0x67, - 0x87, 0x2F, 0x62, 0xF7, 0x65, 0xC6, 0x39, 0x4B, 0x3E, 0xF3, 0xD3, 0xB3, 0xD0, 0xA2, 0x7C, 0x9F, 0x72, 0x0D, 0x32, 0x4E, 0xCD, 0xCD, 0xB0, 0x67, - 0x13, 0x4A, 0xED, 0x84, 0x89, 0x6E, 0xEA, 0x90, 0x28, 0x3E, 0xC6, 0x06, 0x89, 0xCB, 0xAC, 0x5E, 0x1F, 0xC7, 0xC6, 0x15, 0xB5, 0xBB, 0x87, 0xA3, - 0x3C, 0xD5, 0x67, 0x87, 0x01, 0x99, 0xDD, 0x1B, 0xAC, 0xA9, 0xA2, 0xC1, 0xC2, 0xCE, 0xF4, 0xA6, 0x33, 0x02, 0x37, 0xDA, 0x1B, 0x0B, 0x43, 0x2E, - 0x5B, 0x35, 0x80, 0x21, 0x11, 0x38, 0xC4, 0xF5, 0x05, 0x64, 0xB9, 0xE9, 0x2B, 0xD2, 0xF1, 0x8D, 0x71, 0x2E, 0xEF, 0x6E, 0xA8, 0xE9, 0x10, 0x1B, - 0x75, 0x87, 0x26, 0x51, 0x40, 0xD1, 0x82, 0x93, 0x86, 0xFE, 0xD2, 0x50, 0x2F, 0xDA, 0xFE, 0x29, 0xA8, 0x37, 0x65, 0x92, 0xCC, 0x7D, 0xBD, 0x1B, - 0x35, 0xF9, 0xAC, 0xEB, 0xCE, 0x8D, 0xFF, 0xB8, 0xF3, 0xBD, 0x30, 0xFF, 0x92, 0xFA, 0x72, 0x85, 0x83, 0xDC, 0xF3, 0x34, 0x58, 0x09, 0x65, 0xC7, - 0x37, 0xDD, 0x80, 0xC9, 0xD3, 0x9B, 0x9B, 0x07, 0x41, 0xDB, 0xE8, 0xCE, 0xE5, 0xE7, 0xE7, 0x80, 0x77, 0x46, 0xB5, 0x43, 0xC0, 0x39, 0x0A, 0xFF, - 0xB4, 0x66, 0x28, 0xF9, 0xB7, 0xAC, 0xB9, 0xE5, 0x1F, 0x29, 0x1B, 0x84, 0x63, 0x06, 0xF7, 0x11, 0x7A, 0x99, 0x30, 0x57, 0x74, 0xDF, 0x3A, 0x1D, - 0xE8, 0x63, 0x63, 0x1D, 0xD8, 0x76, 0x1C, 0x3D, 0xCC, 0xB2, 0x64, 0xF9, 0x4C, 0xD0, 0x37, 0x18, 0x10, 0x4C, 0x28, 0x1C, 0x43, 0x07, 0xA4, 0x6D, - 0x31, 0x45, 0x46, 0xA6, 0xA4, 0x58, 0x25, 0x6F, 0x53, 0x09, 0xAE, 0xB1, 0x44, 0xE6, 0xFC, 0x2D, 0x81, 0x78, 0xAE, 0xD0, 0x5F, 0x9D, 0x55, 0x84, - 0x3E, 0xD1, 0x3D, 0xD0, 0xBA, 0xC6, 0xDD, 0xE5, 0x2A, 0x1B, 0x79, 0xED, 0x4F, 0x93, 0xDF, 0xDE, 0x8E, 0xF6, 0x25, 0xAF, 0x85, 0xC6, 0xC8, 0x04, - 0x72, 0x8F, 0x2F, 0xB7, 0x6A, 0x5B, 0x5B, 0xFD, 0x96, 0xB1, 0xED, 0x1C, 0x9A, 0xFE, 0x02, 0x3E, 0x8E, 0xEC, 0x06, 0x9E, 0x3E, 0x73, 0x20, 0x45, - 0xFB, 0x4D, 0x0D, 0xB4, 0x95, 0xF9, 0xC1, 0x14, 0xEF, 0xC6, 0x89, 0xE8, 0xB7, 0x8D, 0xD0, 0xED, 0x06, 0x88, 0x38, 0x6D, 0x48, 0xB6, 0x64, 0xD5, - 0x4F, 0x19, 0xC3, 0x65, 0xAF, 0x20, 0x79, 0xA6, 0x70, 0xD3, 0x2E, 0x98, 0xCE, 0x39, 0x45, 0x3F, 0xEF, 0x3C, 0xA9, 0x87, 0xF0, 0xB8, 0x8B, 0xD7, - 0x3D, 0x7A, 0x69, 0x0E, 0x43, 0xB5, 0x54, 0xDB, 0x8B, 0xDD, 0xCC, 0x59, 0xB8, 0x05, 0x9A, 0x38, 0xF5, 0xC2, 0x14, 0x10, 0xC8, 0xCE, 0xFE, 0xEF, - 0x9E, 0x6C, 0x6C, 0xE5, 0xD7, 0x7B, 0x8F, 0x7B, 0xEF, 0x21, 0xAE, 0xB7, 0x1B, 0x79, 0x76, 0x89, 0x50, 0xB9, 0x32, 0xB8, 0xBF, 0x97, 0x3C, 0x4F, - 0xEC, 0x9F, 0xEB, 0xB2, 0x3C, 0xD1, 0x13, 0x42, 0xDE, 0x9E, 0xD0, 0x22, 0xAD, 0x93, 0xBB, 0xE5, 0xE8, 0x14, 0xD5, 0x0B, 0xEF, 0xA9, 0xE5, 0xE7, - 0xDA, 0x81, 0xA2, 0xF3, 0xF1, 0xE7, 0x96, 0xC5, 0x83, 0x10, 0xFA, 0x4E, 0x23, 0xCA, 0x88, 0xEB, 0x78, 0x14, 0x6F, 0x78, 0xF7, 0x3E, 0x98, 0xE4, - 0xA6, 0x8E, 0xFE, 0x52, 0xFC, 0x52, 0xD3, 0x96, 0x4E, 0x49, 0x0E, 0x50, 0x22, 0x19, 0x47, 0xBD, 0x8F, 0x5D, 0x6E, 0x78, 0x31, 0x34, 0x69, 0xFC, - 0x0A, 0x86, 0xF1, 0x19, 0x38, 0x33, 0xE4, 0x10, 0x7A, 0x4C, 0x3D, 0x6B, 0xBC, 0x20, 0x72, 0x74, 0x72, 0x11, 0xD6, 0x8C, 0x00, 0x81, 0x9E, 0x03, - 0x5B, 0xFD, 0x1B, 0x63, 0x86, 0xDE, 0xCE, 0x38, 0x60, 0x1C, 0xE0, 0xD4, 0x2D, 0x0B, 0xBA, 0xCE, 0x12, 0xF4, 0x65, 0x35, 0x58, 0xBF, 0xCE, 0xA4, - 0xD7, 0x4C, 0x79, 0x83, 0xD1, 0xAC, 0x4F, 0xED, 0xE2, 0x57, 0xB7, 0xE5, 0x92, 0x8D, 0x49, 0x3C, 0x8D, 0x82, 0x8A, 0x93, 0xAF, 0xB8, 0x79, 0x24, - 0x74, 0xF5, 0x79, 0xEB, 0x72, 0x97, 0xAC, 0xB7, 0x51, 0x67, 0x55, 0xED, 0x9C, 0x22, 0x77, 0xCC, 0x02, 0x13, 0xBC, 0x3F, 0x09, 0xF4, 0xB4, 0xBE, - 0xA9, 0x16, 0xC1, 0xC6, 0xF3, 0x3A, 0x17, 0x3B, 0x13, 0x3E, 0xBA, 0xDF, 0x75, 0xA0, 0x81, 0xDE, 0x14, 0x4E, 0x8B, 0x2E, 0x6D, 0x76, 0x49, 0x1B, - 0x4C, 0xC1, 0xEE, 0xC0, 0xA3, 0x89, 0xAA, 0xAB, 0x36, 0xBF, 0x55, 0xD0, 0x7B, 0xEC, 0xA5, 0x0A, 0xA7, 0x16, 0x17, 0x5A, 0xB4, 0x53, 0x2C, 0x64, - 0x2D, 0x7E, 0xA3, 0x7C, 0xDE, 0x80, 0x4B, 0x81, 0xE9, 0xAE, 0x7A, 0x1C, 0x7D, 0xBD, 0x57, 0xB6, 0x60, 0xB6, 0x3E, 0xBB, 0xFD, 0x7F, 0xC9, 0xCE, - 0xB5, 0x80, 0xF2, 0x0E, 0x5E, 0x6F, 0x9C, 0x13, 0x78, 0x32, 0xB7, 0x70, 0x25, 0xE4, 0x43, 0xC8, 0x9C, 0xD9, 0x80, 0x9E, 0x6B, 0xB9, 0xDB, 0x80, - 0x92, 0x9D, 0x63, 0x51, 0xAE, 0xF2, 0x33, 0x27, 0xD3, 0xDB, 0xF7, 0x1D, 0x5E, 0x08, 0xFC, 0x25, 0x6B, 0xAC, 0x4B, 0x75, 0xC5, 0xB6, 0xDD, 0x63, - 0x4E, 0x4C, 0xE2, 0x60, 0xEC, 0xE2, 0xE6, 0xAC, 0xDD, 0xE3, 0xCB, 0x9C, 0x31, 0x77, 0x93, 0x10, 0xE2, 0xF9, 0x34, 0xA7, 0xA3, 0x65, 0x48, 0xAC, - 0xF1, 0x22, 0x80, 0xEA, 0x49, 0x83, 0x15, 0x86, 0xCB, 0x2A, 0x36, 0x40, 0xE8, 0x7F, 0x1D, 0x94, 0x00, 0x6C, 0x89, 0x7F, 0x4D, 0xB3, 0xC3, 0x09, - 0x6E, 0xD7, 0xC9, 0x4D, 0xB1, 0x73, 0xE8, 0x4F, 0x65, 0x4B, 0x1E, 0x01, 0x51, 0xB4, 0x36, 0x11, 0xA1, 0x42, 0xD6, 0xF4, 0x6F, 0xE1, 0x8D, 0x8B, - 0x3E, 0x28, 0xD7, 0xA5, 0x7C, 0x60, 0xC1, 0x41, 0x6F, 0x9A, 0xC8, 0xD0, 0xB1, 0xAA, 0x02, 0x49, 0x4A, 0xE9, 0xB6, 0x32, 0x75, 0xF2, 0xD0, 0x6A, - 0x63, 0x5A, 0xD2, 0xFD, 0xDA, 0x78, 0x63, 0x94, 0x15, 0x52, 0xB6, 0xE7, 0x2E, 0x6B, 0xDA, 0xE3, 0x45, 0x29, 0x9D, 0x7B, 0xF6, 0xBA, 0x01, 0x0B, - 0x0B, 0x97, 0xBC, 0x68, 0x73, 0x3F, 0x6F, 0x30, 0xC6, 0x04, 0x2E, 0x88, 0x43, 0xB7, 0x6D, 0xB2, 0x2E, 0x75, 0x1A, 0x69, 0x81, 0x5F, 0xBD, 0xA7, - 0xEA, 0x08, 0x05, 0x5F, 0xE2, 0xDD, 0x7B, 0xDF, 0x3A, 0x38, 0x53, 0xC4, 0xED, 0xB2, 0x87, 0x79, 0x4F, 0xF7, 0xED, 0xAA, 0xED, 0x41, 0x8A, 0x9D, - 0x20, 0x8A, 0x66, 0x18, 0x16, 0x28, 0xD5, 0x57, 0x40, 0xB7, 0x6B, 0xDD, 0xAE, 0x00, 0x70, 0x78, 0xB9, 0xCC, 0x14, 0x22, 0xFB, 0x62, 0xEA, 0x85, - 0xF6, 0x46, 0x12, 0xEB, 0x42, 0x53, 0x9F, 0x74, 0x6B, 0x60, 0x99, 0x4A, 0xF5, 0xD6, 0x6A, 0x85, 0xD6, 0x07, 0xAC, 0x8A, 0x50, 0xBF, 0xE7, 0xF9, - 0x8D, 0x09, 0x5C, 0x2F, 0x74, 0xBD, 0x35, 0xEB, 0x0C, 0xCC, 0xB6, 0xAD, 0x03, 0xE8, 0x8E, 0xE2, 0x62, 0xAD, 0x78, 0x34, 0xA9, 0x9A, 0x11, 0xCA, - 0xA4, 0x62, 0x18, 0x4C, 0xBC, 0x79, 0x56, 0x4B, 0xF3, 0x2E, 0x2F, 0xE3, 0x12, 0xF8, 0x47, 0x0C, 0x36, 0x3A, 0x68, 0x1D, 0xDB, 0x33, 0x90, 0xBC, - 0xAC, 0x66, 0x08, 0x8F, 0x39, 0x0E, 0x1D, 0x79, 0xF0, 0x5D, 0xCF, 0xA4, 0xF9, 0xEC, 0xC9, 0x9C, 0xBF, 0xEB, 0x59, 0xD1, 0x8A, 0xA7, 0xC6, 0xF5, - 0x74, 0xF0, 0xB6, 0x0F, 0x8F, 0x82, 0x64, 0xCD, 0x66, 0xA7, 0xD0, 0x4E, 0xBD, 0x76, 0x5E, 0x99, 0x24, 0x83, 0x8D, 0x2B, 0x69, 0x64, 0xD4, 0x56, - 0x6B, 0x81, 0x6E, 0x6B, 0xC1, 0xB9, 0xAE, 0x79, 0xFF, 0x71, 0xE6, 0xE8, 0x96, 0xA2, 0x1A, 0x48, 0xF7, 0x6C, 0xF9, 0x92, 0x17, 0x50, 0x43, 0x99, - 0x60, 0x47, 0x78, 0x6C, 0x62, 0x66, 0xCA, 0x98, 0xC0, 0xE2, 0x6E, 0x0F, 0xAD, 0x8C, 0x41, 0x80, 0x1A, 0x80, 0xD8, 0x2E, 0x99, 0x3D, 0x28, 0x19, - 0x00, 0xD3, 0xE3, 0x4A, 0xE9, 0x51, 0x87, 0x20, 0x54, 0xDE, 0xC8, 0xB6, 0xF9, 0x67, 0xBD, 0x86, 0x4F, 0x04, 0x0F, 0xBF, 0x6D, 0x71, 0xD5, 0x67, - 0xD4, 0xE7, 0xAE, 0xF7, 0xA8, 0x2C, 0xB1, 0x13, 0x4E, 0xEE, 0xF7, 0x09, 0xCF, 0xE6, 0xE9, 0x0C, 0xF4, 0x7A, 0x26, 0xB1, 0x21, 0x77, 0x91, 0xD1, - 0x45, 0xD7, 0x10, 0xC9, 0x0C, 0x8D, 0xF9, 0xB2, 0xAB, 0x85, 0x1D, 0x79, 0xD0, 0x95, 0x63, 0x36, 0x28, 0xE7, 0xD6, 0x9A, 0x23, 0x34, 0xAD, 0x63, - 0xF4, 0x2F, 0xCA, 0x29, 0x42, 0xEE, 0x37, 0x3B, 0x44, 0x00, 0xFD, 0x60, 0x66, 0x88, 0x4E, 0x43, 0x75, 0xBE, 0x65, 0x46, 0xB2, 0xA8, 0xA0, 0x9E, - 0x17, 0x24, 0xCB, 0x12, 0xA1, 0x01, 0x49, 0xF4, 0xE5, 0x1C, 0x9A, 0x2B, 0x2B, 0x5A, 0x53, 0x6F, 0x76, 0xE8, 0x6E, 0xC7, 0x5A, 0x1D, 0x4F, 0x69, - 0xE9, 0xE2, 0x76, 0x84, 0xCE, 0x1F, 0x2E, 0x90, 0x5E, 0xAA, 0x93, 0xCE, 0xA4, 0x3A, 0x8E, 0x01, 0xA5, 0x02, 0x0A, 0x0E, 0x55, 0x2A, 0x99, 0x19, - 0x0F, 0x5F, 0xE7, 0x2F, 0xB8, 0x20, 0x21, 0x9D, 0xD2, 0xAC, 0x6D, 0x21, 0x3F, 0x57, 0xB7, 0x16, 0x9D, 0xF4, 0x59, 0x2F, 0xDC, 0x33, 0xA6, 0x05, - 0x1C, 0xB6, 0xF7, 0xD3, 0x0F, 0x11, 0x0E, 0xD8, 0xFF, 0xBC, 0x44, 0x8B, 0xE9, 0xB6, 0xCE, 0xC1, 0x49, 0x12, 0x8A, 0xF3, 0x4E, 0xD2, 0x4B, 0x62, - 0x02, 0xA3, 0x61, 0xEA, 0x5C, 0x01, 0x52, 0x29, 0x03, 0xEB, 0x76, 0xF2, 0xCB, 0x3E, 0xB5, 0xCC, 0x56, 0xB9, 0xD1, 0x73, 0xF7, 0x41, 0x8C, 0x7C, - 0x97, 0xB5, 0x6F, 0x2F, 0x02, 0xD4, 0x7E, 0xF3, 0x61, 0xEA, 0x76, 0xCB, 0x09, 0xED, 0x58, 0xF4, 0xB0, 0x2D, 0xB1, 0x06, 0xFA, 0xAC, 0xA3, 0x7F, - 0x15, 0x86, 0xF6, 0x7A, 0xBD, 0xB4, 0x5B, 0xDA, 0xD7, 0xCD, 0x7E, 0x11, 0xBB, 0x49, 0x4B, 0x3A, 0xE8, 0x26, 0x08, 0x53, 0xEC, 0xE1, 0xB7, 0x2D, - 0xCB, 0xEB, 0x73, 0xBB, 0xBB, 0x00, 0xD2, 0x98, 0x87, 0xA0, 0x6C, 0x64, 0x46, 0xEF, 0x48, 0xB6, 0x45, 0x6B, 0xF4, 0x58, 0x31, 0xAF, 0x1A, 0x98, - 0x0C, 0xFB, 0xF9, 0x1C, 0x73, 0x0C, 0x8D, 0x4F, 0x71, 0x9D, 0x15, 0xD1, 0x61, 0x59, 0x4A, 0x50, 0x8F, 0x43, 0x48, 0xC6, 0x56, 0x3C, 0xEA, 0xA7, - 0x36, 0xF6, 0xBE, 0x5E, 0x80, 0xE8, 0xB6, 0x68, 0x11, 0x5D, 0x76, 0x36, 0xA4, 0x5B, 0x1D, 0x2B, 0x77, 0x8C, 0x66, 0x2A, 0x9A, 0x7C, 0xFD, 0xC5, - 0xC7, 0xFF, 0xB0, 0xCA, 0x58, 0xDC, 0x3C, 0x9D, 0x0F, 0x1B, 0x05, 0x37, 0xE3, 0x8B, 0xD7, 0xED, 0x3E, 0x7B, 0xF3, 0x8A, 0x9E, 0xBF, 0x9F, 0xF9, - 0x44, 0xC8, 0x81, 0x87, 0x7C, 0x54, 0xA4, 0x05, 0x0A, 0x6D, 0x0C, 0xFA, 0xCF, 0xC9, 0xCC, 0x70, 0x59, 0x5F, 0xDF, 0x6F, 0xC5, 0x20, 0xCA, 0x42, - 0xBA, 0xE1, 0xA9, 0xDE, 0x78, 0xD4, 0x54, 0xD0, 0xAE, 0x39, 0xD9, 0xBC, 0x69, 0x22, 0x5D, 0xBC, 0x86, 0x44, 0x36, 0xD6, 0xB8, 0xC4, 0x06, 0x20, - 0xFA, 0x6C, 0x17, 0xA8, 0x88, 0x07, 0x16, 0x00, 0xF1, 0xE6, 0xD9, 0xB4, 0xE3, 0x24, 0x5F, 0x3B, 0x17, 0x2E, 0xEF, 0x34, 0x5C, 0x12, 0xB4, 0x5E, - 0x53, 0xCD, 0xE7, 0xCC, 0xFD, 0x78, 0x66, 0x9D, 0xB6, 0x8C, 0x30, 0x0D, 0x3B, 0x73, 0xE5, 0x5A, 0x2D, 0xC9, 0x2F, 0xD8, 0xFA, 0xD3, 0x62, 0x81, - 0xD0, 0x9A, 0xC1, 0xF4, 0x64, 0xCC, 0x34, 0x19, 0x3A, 0xFD, 0x69, 0x2D, 0xA8, 0xC3, 0x27, 0x01, 0xF1, 0x19, 0x3D, 0x0E, 0x1C, 0x27, 0x38, 0x42, - 0xE4, 0xBD, 0x7A, 0xBD, 0x3B, 0xDD, 0x44, 0xF7, 0x16, 0x45, 0x6D, 0xA7, 0x6D, 0x50, 0xDD, 0xF4, 0x2D, 0x86, 0x8A, 0xE0, 0x33, 0xC5, 0x3C, 0x16, - 0x31, 0x45, 0xA2, 0x5F, 0x59, 0x57, 0x12, 0x2B, 0x52, 0x2D, 0xDE, 0x88, 0x29, 0xAF, 0xB6, 0x69, 0x10, 0x8F, 0xD6, 0xE6, 0x62, 0x0D, 0xBD, 0xDF, - 0xC7, 0xAC, 0x2E, 0xD7, 0x4A, 0xD6, 0xE3, 0xB5, 0xBD, 0x65, 0x66, 0x44, 0x98, 0x10, 0x5D, 0x4F, 0x70, 0x5E, 0xFA, 0x18, 0x3D, 0xBB, 0x01, 0x3A, - 0x9A, 0x9C, 0x73, 0xF8, 0xAF, 0x99, 0x76, 0xD8, 0xB3, 0x4A, 0x3F, 0x09, 0x16, 0x85, 0xD2, 0x0B, 0xD9, 0x24, 0x99, 0x79, 0x49, 0x30, 0x85, 0xC3, - 0xDD, 0xF7, 0xC4, 0x1A, 0xEF, 0x70, 0xE4, 0x37, 0x3C, 0x22, 0xEE, 0x2B, 0x5F, 0x79, 0x2A, 0x5B, 0x58, 0x03, 0x51, 0x5C, 0x2E, 0x0C, 0x72, 0x4C, - 0x2E, 0xB4, 0xCD, 0x16, 0xE6, 0x7E, 0x0F, 0x7D, 0x6E, 0x66, 0x98, 0x6D, 0x6D, 0x1D, 0x22, 0xE1, 0x20, 0x37, 0x6B, 0x7D, 0x0E, 0x01, 0xB3, 0xF5, - 0xB0, 0x05, 0x19, 0x9A, 0xD6, 0xF2, 0x28, 0x3D, 0x3B, 0xCC, 0xC0, 0xF9, 0x8D, 0x7E, 0xCF, 0x4A, 0xB1, 0xD7, 0xBF, 0x26, 0x46, 0x93, 0xC8, 0x9C, - 0xB7, 0x29, 0xD8, 0x38, 0x6F, 0x8F, 0x5F, 0x21, 0x8A, 0xC9, 0xC4, 0x20, 0xE6, 0x9F, 0xB0, 0x1F, 0x9D, 0x83, 0xE5, 0xC6, 0x26, 0xF8, 0xE0, 0xCD, - 0xA8, 0x20, 0xBB, 0x17, 0x32, 0xDD, 0xB1, 0x38, 0x27, 0x73, 0x45, 0xE7, 0x7A, 0xD9, 0xE1, 0x18, 0x2F, 0xE9, 0xA7, 0x9F, 0x6D, 0x69, 0xA8, 0x6E, - 0x83, 0xC6, 0x63, 0x74, 0xC4, 0x22, 0xD0, 0x70, 0x1C, 0x7E, 0x68, 0x9B, 0xE5, 0x25, 0x11, 0xA5, 0xF7, 0x2D, 0xB1, 0x59, 0x54, 0xD3, 0xD8, 0x57, - 0xF0, 0xC9, 0x33, 0x06, 0x9D, 0xBF, 0x78, 0x10, 0x15, 0x87, 0xDB, 0xE7, 0x33, 0x9F, 0xB7, 0xA1, 0x9A, 0x92, 0xEB, 0x7B, 0x8A, 0x2D, 0x1C, 0xCE, - 0x26, 0xC0, 0x04, 0xA1, 0x80, 0xE0, 0x2E, 0x81, 0x64, 0x0B, 0xCA, 0x97, 0xDD, 0x6B, 0x98, 0x0D, 0x68, 0xE9, 0xE5, 0x7D, 0x97, 0x00, 0x8D, 0xE5, - 0xB0, 0xAE, 0xD5, 0x99, 0xC5, 0x3A, 0xD3, 0x00, 0xA5, 0xD4, 0x6E, 0xB0, 0x60, 0xF9, 0xBE, 0x75, 0xB4, 0xB1, 0xDF, 0x88, 0xD6, 0x62, 0x37, 0x86, - 0xBC, 0x99, 0xC6, 0x9D, 0xD1, 0x14, 0x1F, 0x3B, 0x95, 0x5F, 0x71, 0x5C, 0xCD, 0x0E, 0xBC, 0xCB, 0x9B, 0x9E, 0x01, 0x74, 0xC0, 0x8A, 0x26, 0xA7, - 0x41, 0x93, 0xDF, 0x63, 0x4B, 0xD6, 0x4E, 0x25, 0x88, 0x1F, 0xA0, 0xD5, 0x1A, 0x81, 0x6A, 0x94, 0x77, 0x44, 0x9F, 0xA6, 0x2B, 0x54, 0x6B, 0x03, - 0x0D, 0xB2, 0x6D, 0x81, 0x59, 0xE8, 0xF8, 0x06, 0x13, 0x3D, 0xE0, 0xD1, 0xD6, 0x4D, 0x91, 0x18, 0x87, 0x3F, 0x18, 0x53, 0xE6, 0x00, 0xBA, 0xDA, - 0xEE, 0x00, 0x76, 0x79, 0x84, 0x7E, 0x2F, 0x35, 0xEF, 0xA2, 0xF6, 0x3C, 0xC4, 0xEB, 0xF3, 0xCD, 0x46, 0x33, 0x7E, 0xB7, 0xBD, 0x7D, 0x74, 0x87, - 0xE4, 0xBC, 0x5C, 0x8E, 0x0C, 0x18, 0x20, 0x5D, 0x19, 0x1D, 0x2C, 0x2D, 0x45, 0xF8, 0x62, 0x11, 0x90, 0x1D, 0x12, 0x4F, 0xA4, 0xCA, 0xD3, 0xCE, - 0x62, 0x8C, 0x56, 0x61, 0x0D, 0x9F, 0x31, 0x4A, 0x17, 0x39, 0x71, 0x2C, 0x96, 0xE7, 0x3F, 0x68, 0xF4, 0xAB, 0x57, 0x9A, 0x3A, 0xA2, 0x2B, 0x27, - 0xB3, 0xA5, 0xDB, 0x30, 0xB2, 0xBF, 0x89, 0xD0, 0x88, 0xCB, 0x0B, 0x86, 0x83, 0xD4, 0xE0, 0x73, 0x89, 0x98, 0x96, 0xC7, 0x3C, 0x54, 0x23, 0x7B, - 0xA5, 0x0F, 0x62, 0x36, 0x5D, 0xF0, 0x52, 0x6F, 0xE4, 0xF8, 0xC7, 0xA7, 0x31, 0xF1, 0xB1, 0xDE, 0xBA, 0xB6, 0x70, 0xB0, 0xC1, 0xAD, 0x46, 0xEE, - 0x1C, 0x57, 0xD8, 0x02, 0x14, 0x48, 0x49, 0x97, 0x3F, 0x8D, 0x81, 0x78, 0x43, 0x4C, 0x6E, 0xBB, 0x03, 0x50, 0xA9, 0x04, 0x46, 0xBD, 0x66, 0xAB, - 0x68, 0x3D, 0x19, 0x3F, 0x79, 0xC9, 0x0A, 0x6B, 0x7C, 0x67, 0x8D, 0xAC, 0x00, 0x4D, 0xA6, 0x9D, 0xEE, 0x50, 0x2D, 0x34, 0xD6, 0xA9, 0xA7, 0xF5, - 0x06, 0x80, 0x29, 0xEA, 0x97, 0xC9, 0x61, 0x28, 0xF7, 0x1B, 0x1C, 0x4A, 0xDE, 0xE6, 0x6E, 0x79, 0x89, 0x73, 0x8E, 0xE0, 0x96, 0x28, 0x8B, 0x1F, - 0x1F, 0x4C, 0x37, 0xDB, 0xF1, 0x9B, 0x51, 0xEB, 0x1F, 0xB3, 0x88, 0x7D, 0x9F, 0x8E, 0xFD, 0x5C, 0xE1, 0xDF, 0xDF, 0xE5, 0xBF, 0x59, 0x0B, 0x05, - 0x8F, 0x51, 0xE2, 0xA9, 0x79, 0x90, 0xBD, 0xEA, 0x27, 0x5B, 0x7D, 0xE0, 0x18, 0x4C, 0x6F, 0xDC, 0xB6, 0x6F, 0x9D, 0x35, 0x0B, 0xC6, 0x86, 0x52, - 0xC7, 0x36, 0x84, 0x20, 0x8A, 0xAE, 0x94, 0xB7, 0xFF, 0x49, 0xB6, 0x6B, 0xDA, 0xFD, 0xA0, 0x97, 0xD4, 0xB0, 0x68, 0x51, 0xF9, 0x71, 0x60, 0xEE, - 0x9F, 0xD3, 0x5C, 0xF6, 0x4E, 0xDC, 0x6A, 0x62, 0x50, 0x77, 0x26, 0xE9, 0x9A, 0xA1, 0x96, 0xF1, 0x1F, 0xA5, 0xCF, 0xB7, 0xBC, 0xAF, 0x07, 0x08, - 0xD8, 0x5C, 0xC6, 0x46, 0x9B, 0xA6, 0x2B, 0xE5, 0xF6, 0x49, 0x0A, 0x0C, 0xCA, 0x0D, 0xF3, 0xE1, 0xB5, 0xFC, 0x42, 0x07, 0x49, 0xAC, 0x70, 0x9F, - 0x09, 0x4B, 0x23, 0x3E, 0xEE, 0xBC, 0xB5, 0x92, 0x85, 0xCA, 0x53, 0x1F, 0xF0, 0x2C, 0x60, 0xCB, 0x23, 0xFC, 0x0C, 0x7F, 0xB9, 0x3B, 0x59, 0xDB, - 0x74, 0xA3, 0x51, 0x72, 0x85, 0xFC, 0xD5, 0xB4, 0x40, 0xD7, 0x70, 0xD8, 0x31, 0x44, 0xC5, 0x29, 0xA1, 0x58, 0x64, 0xF9, 0xE5, 0x9D, 0x1E, 0x4F, - 0xFA, 0xEE, 0x1E, 0xAB, 0x12, 0xCC, 0x0A, 0xE9, 0x62, 0x5D, 0x5F, 0x1D, 0xD7, 0x56, 0xB7, 0x68, 0x82, 0x33, 0x40, 0x26, 0xCE, 0x9C, 0xD3, 0xBC, - 0x86, 0x1C, 0x29, 0xA7, 0xD0, 0x0B, 0x29, 0xF9, 0x04, 0x9A, 0xF4, 0xE7, 0x67, 0x3E, 0x77, 0x7E, 0x28, 0xB8, 0xBF, 0x42, 0xC3, 0xBB, 0xA7, 0x52, - 0x8C, 0xEA, 0x98, 0xBC, 0x16, 0x91, 0xAB, 0x1E, 0x92, 0x8C, 0x2D, 0x75, 0xBB, 0x87, 0xB5, 0xB1, 0x0D, 0xA6, 0x3E, 0x5D, 0x33, 0x61, 0x93, 0x6E, - 0xFC, 0x62, 0x4D, 0x7F, 0x4F, 0xD3, 0xAD, 0xB5, 0xF7, 0xB9, 0xF7, 0x17, 0x73, 0xAB, 0xF2, 0x0A, 0xB1, 0xEF, 0xC2, 0x59, 0x31, 0xDF, 0x56, 0xD9, - 0xB4, 0x5E, 0x8E, 0xB0, 0x33, 0xE9, 0x5D, 0x8A, 0x43, 0x72, 0xE2, 0x54, 0x53, 0xDC, 0x37, 0xC7, 0x0E, 0xA4, 0xE5, 0x62, 0xF1, 0xC0, 0xA6, 0x25, - 0xB7, 0x6F, 0x8F, 0x9C, 0x37, 0x62, 0x9F, 0xC0, 0xB8, 0xA0, 0xD7, 0x28, 0x86, 0x1C, 0x0F, 0xDA, 0x35, 0x68, 0xC9, 0xF1, 0x53, 0xF9, 0x68, 0xA9, - 0x05, 0x0C, 0xFE, 0x14, 0x9E, 0x69, 0x50, 0x69, 0xD6, 0x31, 0xE0, 0xE7, 0x81, 0xC0, 0x33, 0x0E, 0xBA, 0x6C, 0x12, 0xDA, 0xE3, 0x24, 0xC8, 0xB3, - 0xD5, 0x01, 0x46, 0x51, 0x03, 0x0D, 0x19, 0x47, 0x9D, 0xC1, 0xB9, 0xDD, 0x64, 0x56, 0xC4, 0xE6, 0x8A, 0x05, 0x36, 0x57, 0x14, 0x26, 0x8B, 0x42, - 0x3E, 0xC1, 0x88, 0xB1, 0xC4, 0xB7, 0x99, 0x10, 0xAB, 0x99, 0x8F, 0xBD, 0x21, 0x5B, 0xE6, 0x1C, 0xEB, 0xE4, 0x6C, 0x3E, 0x13, 0x31, 0xA3, 0x04, - 0x9A, 0xA9, 0x6A, 0x91, 0x6A, 0x51, 0xF3, 0x14, 0xEF, 0xDC, 0x59, 0x3D, 0x96, 0x7F, 0x4E, 0x4E, 0xB3, 0x84, 0xE4, 0x8C, 0x33, 0x7A, 0x0C, 0x71, - 0x6B, 0x77, 0x16, 0x71, 0x50, 0xEC, 0xD8, 0xA7, 0x68, 0xAB, 0xED, 0x90, 0x27, 0x22, 0x98, 0x1B, 0x02, 0x5B, 0x72, 0x2B, 0x29, 0x6A, 0x7D, 0x92, - 0x30, 0x8F, 0x04, 0xE9, 0x99, 0xF9, 0xB3, 0xA0, 0x87, 0xE8, 0x6E, 0xB9, 0xD1, 0x04, 0x40, 0x1C, 0x55, 0x77, 0x81, 0x9D, 0xA3, 0x97, 0x8F, 0xE8, - 0x8E, 0xDB, 0xD5, 0x83, 0x44, 0x53, 0x41, 0xCA, 0xC8, 0x42, 0xDE, 0xA7, 0x71, 0x65, 0x8F, 0x31, 0x07, 0x0A, 0xD1, 0xF7, 0xEC, 0xB9, 0x83, 0xC7, - 0xD6, 0x82, 0xE8, 0x9B, 0x6E, 0x40, 0x79, 0x34, 0x96, 0x45, 0x6A, 0xEE, 0xDA, 0xBD, 0xBE, 0x6C, 0x9D, 0xE8, 0xD6, 0x29, 0x24, 0x7E, 0x95, 0x4F, - 0xBB, 0x60, 0x9C, 0x94, 0x41, 0xA3, 0x41, 0x4E, 0xD9, 0x2F, 0x19, 0xB8, 0xCA, 0xC0, 0x34, 0x83, 0xAE, 0x2E, 0x10, 0xE9, 0xAF, 0x8C, 0x2B, 0xCA, - 0x3A, 0x4A, 0xA5, 0xDA, 0x61, 0xAC, 0xD1, 0x15, 0x4D, 0x0A, 0x95, 0x3F, 0xA3, 0xBE, 0xFF, 0x3A, 0x2C, 0xAA, 0xCF, 0xE0, 0xBD, 0x95, 0xDF, 0xFA, - 0x84, 0x0F, 0x04, 0x43, 0x2F, 0x45, 0x07, 0x87, 0xB9, 0xB1, 0x0D, 0xDE, 0xE9, 0xEA, 0xE5, 0xDF, 0x7A, 0xC9, 0x30, 0xFA, 0xAF, 0xFE, 0x13, 0xB7, - 0xC5, 0x07, 0xE5, 0x22, 0xD0, 0xA0, 0x7B, 0xE4, 0xF8, 0x41, 0xA3, 0xB0, 0x80, 0x9B, 0x8F, 0x0E, 0x7B, 0x64, 0x3E, 0x02, 0x9D, 0x51, 0x91, 0x7F, - 0xAB, 0x5A, 0x3D, 0x39, 0xBF, 0x91, 0x03, 0xCD, 0x6A, 0x6E, 0xA0, 0xAF, 0x9D, 0xF9, 0x3E, 0x63, 0x04, 0xB6, 0xAF, 0xEE, 0x47, 0xB8, 0x18, 0xAC, - 0xA7, 0xDA, 0x42, 0x70, 0x1F, 0xA5, 0x42, 0x2D, 0x44, 0x44, 0xB5, 0xB4, 0x9B, 0xB3, 0x0B, 0x0F, 0x87, 0xC6, 0x95, 0x79, 0x60, 0x44, 0xCF, 0xD1, - 0xA6, 0xBA, 0x56, 0x0E, 0x74, 0xE0, 0x07, 0xA2, 0x0E, 0x8D, 0x16, 0x1E, 0x6B, 0xED, 0x52, 0x5F, 0x72, 0x40, 0xE4, 0x0C, 0xCF, 0x41, 0x8A, 0xDE, - 0xAD, 0x18, 0x1B, 0xBD, 0xC7, 0x1F, 0x90, 0x7F, 0x28, 0x8F, 0x73, 0xEB, 0x11, 0x59, 0x01, 0xD8, 0x42, 0x66, 0x06, 0xA5, 0xB1, 0xC8, 0x13, 0x22, - 0x2E, 0x88, 0x22, 0x9A, 0x57, 0x63, 0x2F, 0x3C, 0xE0, 0x39, 0x1C, 0x75, 0x97, 0x8D, 0xCB, 0x3A, 0x78, 0x2F, 0xFA, 0x7D, 0xAA, 0xEE, 0x69, 0x0A, - 0x4F, 0xA3, 0x58, 0x4E, 0xDB, 0x3A, 0x7F, 0xD4, 0xEB, 0xBD, 0x76, 0x8C, 0x9C, 0x95, 0xD3, 0xD4, 0xD9, 0x23, 0x55, 0x41, 0x16, 0xB8, 0x65, 0xE4, - 0x81, 0x0B, 0x73, 0x8A, 0xA3, 0x19, 0x8A, 0x58, 0xC9, 0x80, 0xBD, 0x69, 0x01, 0x6D, 0xEA, 0x55, 0x3B, 0x69, 0x95, 0xC5, 0x40, 0x4B, 0xA9, 0xE2, - 0xCF, 0x68, 0x81, 0xCA, 0x27, 0x8A, 0xA2, 0x81, 0x34, 0xBB, 0x9A, 0xE3, 0x43, 0xE9, 0x68, 0x2D, 0xE4, 0x9C, 0xFB, 0xB3, 0x1C, 0x44, 0x3D, 0x96, - 0x3C, 0x65, 0xEB, 0x11, 0x7C, 0xC1, 0x21, 0x60, 0xDF, 0xC0, 0x2C, 0x84, 0x6C, 0x7B, 0x09, 0x7A, 0x59, 0xD8, 0x47, 0x83, 0xFB, 0x6C, 0xC7, 0x5F, - 0xDA, 0x99, 0x76, 0xB3, 0x3F, 0x61, 0xD0, 0x45, 0x94, 0x25, 0x17, 0xAB, 0xB2, 0x38, 0x04, 0x0A, 0x05, 0xAB, 0x80, 0xB6, 0xF2, 0x9D, 0xCD, 0xE4, - 0x6D, 0x95, 0x22, 0x5E, 0x96, 0x3A, 0xCC, 0x2B, 0x84, 0xB1, 0x14, 0x4B, 0x2E, 0x2F, 0x78, 0x6E, 0xF6, 0xC9, 0xBD, 0x03, 0x18, 0x89, 0xF5, 0xB8, - 0x99, 0xF5, 0x18, 0xFA, 0x00, 0x5B, 0xAC, 0x87, 0x7F, 0xC7, 0x90, 0x90, 0x66, 0x42, 0x8C, 0x8D, 0x8F, 0xE1, 0x19, 0xDE, 0x74, 0x46, 0xC7, 0x4A, - 0x46, 0x5F, 0x1C, 0xB3, 0xFB, 0xCE, 0x03, 0xBF, 0xC7, 0x68, 0x96, 0xE8, 0x0A, 0xC0, 0xF0, 0x54, 0xE6, 0xE0, 0xD7, 0x95, 0x01, 0xA8, 0xDE, 0x3D, - 0x0C, 0x1A, 0xC6, 0x70, 0x7F, 0x1B, 0xF5, 0x44, 0x91, 0x04, 0x02, 0x24, 0x64, 0xCC, 0xC5, 0x26, 0x84, 0x4B, 0x67, 0x11, 0xDC, 0x87, 0xA1, 0xEA, - 0x8E, 0xC7, 0x31, 0x26, 0x4A, 0x1D, 0xE7, 0x41, 0x4B, 0x6B, 0x5C, 0x35, 0x10, 0xE8, 0xFA, 0x00, 0x2C, 0x89, 0xA4, 0xE0, 0x9C, 0xDE, 0x37, 0x15, - 0x7F, 0x12, 0xC2, 0x80, 0xD4, 0x73, 0xE2, 0xC8, 0xD0, 0xDD, 0x58, 0xD8, 0x14, 0xA2, 0x19, 0x4F, 0xDD, 0xDB, 0xF2, 0x7A, 0xCB, 0xF4, 0x99, 0xC3, - 0x7B, 0xF9, 0xF3, 0xBB, 0x63, 0x63, 0x88, 0xB9, 0x15, 0xE1, 0xD0, 0x30, 0x9D, 0xE2, 0xB5, 0x11, 0x70, 0xC9, 0xD2, 0x25, 0x06, 0xE0, 0x22, 0x19, - 0x30, 0x36, 0x30, 0x5A, 0x0B, 0xDE, 0x3A, 0x88, 0x09, 0x42, 0x5A, 0xCB, 0xF4, 0x30, 0x9A, 0x8C, 0x51, 0x0A, 0x30, 0x6A, 0xDA, 0x24, 0xC6, 0xE6, - 0x0C, 0x7D, 0x22, 0x1B, 0x1D, 0x93, 0x2B, 0x46, 0x32, 0xC8, 0xB2, 0x92, 0x4C, 0x72, 0x5E, 0x22, 0xCB, 0x83, 0x9F, 0xF6, 0xA3, 0x23, 0x5A, 0xC4, - 0x34, 0xBB, 0x48, 0xEC, 0x39, 0x4C, 0xD1, 0x4C, 0x93, 0xE6, 0xD9, 0xC0, 0x16, 0xE2, 0x76, 0x2C, 0x9E, 0xE4, 0xBC, 0x70, 0x19, 0x0F, 0x03, 0x41, - 0x83, 0x79, 0xDE, 0x8F, 0x7A, 0xEC, 0x40, 0x2D, 0x63, 0x19, 0x5B, 0x3D, 0xFB, 0xB2, 0x98, 0x64, 0x4B, 0xF5, 0x77, 0x3C, 0x3B, 0x30, 0xF8, 0x76, - 0x6E, 0xD8, 0xE5, 0xF2, 0x0E, 0x0B, 0x23, 0xFE, 0xCF, 0xC0, 0x49, 0x76, 0x1D, 0x0C, 0x68, 0x2D, 0xCD, 0xEF, 0x88, 0xEC, 0x61, 0xB7, 0xE5, 0x01, - 0x2F, 0x4E, 0x3A, 0x2C, 0x79, 0x54, 0x1A, 0x7D, 0x3D, 0x18, 0xAF, 0xEC, 0x91, 0xC3, 0xD9, 0xC1, 0x3C, 0xBD, 0x68, 0xF4, 0x51, 0x01, 0xD2, 0x02, - 0x5E, 0x41, 0x39, 0x00, 0x59, 0x28, 0x99, 0x1C, 0x3F, 0xAB, 0x97, 0x31, 0xD4, 0x16, 0xC5, 0x0F, 0x72, 0xCA, 0x04, 0x71, 0x0F, 0x77, 0xDC, 0xB2, - 0xE5, 0x12, 0xC3, 0xAA, 0xCE, 0x9C, 0x35, 0xC4, 0xD2, 0xC9, 0x1B, 0x30, 0x45, 0xDF, 0x15, 0xCC, 0xE1, 0xAB, 0xF6, 0x06, 0xCE, 0x44, 0x3E, 0xB0, - 0x22, 0x55, 0x64, 0xB4, 0xCF, 0x12, 0x55, 0xDA, 0x06, 0x8E, 0xE8, 0x4E, 0xEC, 0x4E, 0x10, 0xDD, 0xE7, 0x8C, 0x73, 0xA9, 0x60, 0xF6, 0x79, 0x22, - 0x73, 0x85, 0x2C, 0x97, 0x86, 0x8C, 0x57, 0xAE, 0x21, 0x23, 0xCD, 0x28, 0x9D, 0x15, 0xF3, 0xBA, 0x01, 0xBF, 0xB3, 0x98, 0xD8, 0xA1, 0x76, 0x2E, - 0xC7, 0xC9, 0x59, 0x6D, 0x52, 0x3F, 0x18, 0x76, 0x2A, 0xAF, 0x49, 0xFB, 0x3B, 0xD8, 0x7F, 0x9E, 0xEF, 0x0C, 0xCE, 0x64, 0xAF, 0xDB, 0xC3, 0xAA, - 0xD8, 0xF8, 0x90, 0xAB, 0x0A, 0x4D, 0x63, 0xA8, 0x64, 0xE5, 0xB4, 0x2A, 0xE1, 0xFD, 0x18, 0x67, 0xF7, 0xB9, 0x9B, 0x93, 0xF0, 0xF8, 0x6E, 0x98, - 0x0D, 0xFB, 0x5A, 0x81, 0x7C, 0x86, 0x95, 0x0A, 0xDF, 0x7D, 0x64, 0x5B, 0xDD, 0xD7, 0x50, 0xFE, 0xE2, 0x59, 0x4B, 0x9B, 0x05, 0x9A, 0x5E, 0x5A, - 0x3C, 0x7E, 0xB1, 0x88, 0xC2, 0xD7, 0x43, 0xB1, 0x9A, 0x19, 0x97, 0x09, 0x37, 0x1C, 0x81, 0x4E, 0x39, 0xE4, 0x45, 0xCD, 0x28, 0xE3, 0x50, 0xE7, - 0xE2, 0x6E, 0x68, 0x6D, 0x9D, 0xD4, 0x23, 0x13, 0x8D, 0x6F, 0x9A, 0x93, 0x72, 0xAC, 0xD5, 0xB7, 0x42, 0x04, 0xDC, 0xA3, 0x33, 0xBC, 0x55, 0x35, - 0x62, 0x5A, 0x06, 0x16, 0x35, 0x54, 0x0B, 0xFB, 0x3F, 0x47, 0xEB, 0x4B, 0xB6, 0x89, 0x6F, 0x8D, 0x11, 0x62, 0xC0, 0xAF, 0xB8, 0xAB, 0x6A, 0x55, - 0x39, 0xEF, 0xFC, 0x59, 0x8E, 0xC0, 0xC5, 0xC0, 0x71, 0x0D, 0x85, 0x29, 0x4E, 0x3E, 0x72, 0x37, 0x77, 0x3F, 0xE7, 0x84, 0x0C, 0xA0, 0xBE, 0x8C, - 0xF5, 0x52, 0x83, 0x51, 0xFC, 0x74, 0xD5, 0xFA, 0x19, 0xAB, 0xDE, 0xBC, 0x9D, 0x4B, 0xBE, 0xE7, 0xC3, 0x06, 0xCB, 0x81, 0x0B, 0x1D, 0xDA, 0x66, - 0x36, 0x86, 0x61, 0x08, 0x40, 0x53, 0xBF, 0x89, 0x27, 0xE2, 0x15, 0x35, 0x58, 0xB5, 0x0E, 0x71, 0xCE, 0x76, 0xDE, 0xB7, 0x94, 0x21, 0xAF, 0xAB, - 0x8F, 0xE4, 0x1A, 0x8E, 0x8C, 0x42, 0x2C, 0x18, 0xE2, 0x0C, 0x9A, 0xBD, 0xE1, 0x34, 0xE5, 0xB1, 0x4D, 0x9D, 0x2C, 0x46, 0x00, 0x4E, 0x2E, 0x36, - 0x9C, 0x1E, 0x23, 0x62, 0xE6, 0x9A, 0x83, 0x1F, 0x87, 0x2F, 0x59, 0xD6, 0x44, 0xE0, 0x96, 0xB2, 0xCC, 0x5A, 0x2A, 0x06, 0x63, 0x06, 0x65, 0x19, - 0x18, 0x1C, 0xF2, 0x39, 0x3D, 0xB8, 0x82, 0x36, 0x42, 0xCB, 0xC9, 0x37, 0x02, 0x79, 0x9F, 0x19, 0x0A, 0x87, 0x7B, 0x11, 0xE1, 0x6C, 0xC6, 0x61, - 0xF7, 0xBA, 0x22, 0x5A, 0x08, 0x51, 0x19, 0x7C, 0xE9, 0xE6, 0x8B, 0x9C, 0xE5, 0xA8, 0x3A, 0x99, 0x06, 0x44, 0xEB, 0x94, 0x34, 0x76, 0xEF, 0x4D, - 0xC2, 0xE6, 0xC4, 0xB8, 0x9E, 0x61, 0x18, 0x27, 0x22, 0x0C, 0xDE, 0x32, 0x0C, 0x47, 0x74, 0x55, 0x3D, 0xAB, 0x30, 0x71, 0x82, 0x90, 0xEC, 0x0B, - 0xBC, 0x0E, 0x2F, 0x9D, 0xC1, 0xE1, 0xC4, 0xAE, 0xD3, 0x0E, 0xDB, 0x1A, 0x82, 0xA3, 0x44, 0x74, 0xF5, 0xBF, 0x44, 0x5C, 0x3A, 0x95, 0x2E, 0x3D, - 0x93, 0x59, 0xC7, 0xF5, 0x3A, 0x44, 0x3E, 0x36, 0xAA, 0xBB, 0x38, 0x3B, 0x32, 0x42, 0xCA, 0xDC, 0x37, 0xF3, 0x93, 0x73, 0x6E, 0x7B, 0xBC, 0xE1, - 0x0C, 0x4F, 0x23, 0x9E, 0x9A, 0xC6, 0xF6, 0x44, 0x19, 0xA3, 0x3B, 0x02, 0x9A, 0x00, 0x03, 0xE0, 0x1D, 0x1A, 0x7D, 0x1C, 0xB9, 0x64, 0xE9, 0xDA, - 0xB2, 0xCC, 0x8B, 0xED, 0xEE, 0xDB, 0x9B, 0xAA, 0x97, 0x3D, 0xA3, 0x78, 0xF9, 0xA8, 0x04, 0x2C, 0x9F, 0x9E, 0xD8, 0x1F, 0x06, 0x81, 0xF3, 0x8D, - 0x1E, 0xAE, 0xD9, 0x7B, 0x57, 0xCF, 0xF0, 0x69, 0x24, 0xE1, 0x70, 0x92, 0xFB, 0x73, 0x76, 0x9E, 0x28, 0x3B, 0xB3, 0xDE, 0xD6, 0xD1, 0x94, 0xAF, - 0x9A, 0xE5, 0x92, 0x70, 0x0F, 0xE2, 0x9E, 0x47, 0x2B, 0x98, 0x1B, 0x16, 0xD6, 0x3B, 0x78, 0x47, 0xDD, 0xDE, 0x64, 0xE6, 0xC4, 0xEF, 0x51, 0xEA, - 0xCA, 0x1D, 0xD9, 0xA0, 0x7A, 0xD3, 0x36, 0xA0, 0xA3, 0x1B, 0xAD, 0x41, 0x24, 0x45, 0xFB, 0x84, 0x99, 0x8C, 0xF3, 0xD2, 0x30, 0x83, 0x91, 0x69, - 0x7A, 0x36, 0x07, 0xC7, 0x08, 0xDA, 0x87, 0xC8, 0x92, 0x19, 0x5C, 0xA3, 0xE9, 0xEB, 0x2C, 0xD3, 0x80, 0xF5, 0x99, 0x93, 0xC0, 0xBE, 0x41, 0xEE, - 0x42, 0x1E, 0x07, 0x9A, 0xCD, 0x0B, 0xB5, 0x2A, 0x65, 0x99, 0x23, 0x45, 0xD4, 0x94, 0xB5, 0xAD, 0x29, 0x93, 0xC3, 0x8D, 0x45, 0xAE, 0xF3, 0xFE, - 0x81, 0xBF, 0x09, 0x66, 0x23, 0xC2, 0xAE, 0x10, 0xAE, 0x26, 0xBF, 0xFB, 0xA2, 0x31, 0x7F, 0x9E, 0xAC, 0x93, 0xDC, 0x0D, 0xF7, 0x94, 0x33, 0x9D, - 0x65, 0x38, 0xF4, 0x97, 0x39, 0x69, 0x25, 0xDF, 0xBB, 0xA6, 0xD7, 0x68, 0x33, 0x92, 0xB5, 0xA4, 0xF5, 0xED, 0x1E, 0xB3, 0x16, 0x99, 0x73, 0xBC, - 0x18, 0xAA, 0xDC, 0xC1, 0xD7, 0xD3, 0x49, 0x16, 0xDE, 0x24, 0x38, 0x21, 0x1D, 0xB8, 0xA7, 0xB1, 0x4C, 0xDC, 0x0C, 0xCC, 0x1A, 0xF9, 0xC9, 0x46, - 0x8F, 0x90, 0xB3, 0x55, 0x6A, 0x22, 0x5F, 0xAA, 0x79, 0x21, 0xD8, 0xF0, 0xE4, 0xEF, 0xA9, 0x78, 0xDC, 0x0D, 0xD5, 0xDF, 0x22, 0x61, 0xD2, 0xC3, - 0x25, 0x68, 0x92, 0x89, 0x0A, 0x05, 0xA7, 0x57, 0xC2, 0x36, 0x50, 0x1C, 0x69, 0xFA, 0x6D, 0xAF, 0x83, 0xDD, 0x30, 0x7B, 0x9D, 0x25, 0x3A, 0x49, - 0x39, 0x38, 0x3C, 0x6E, 0xE3, 0xCC, 0xD6, 0xE4, 0x71, 0x5D, 0x70, 0x2D, 0xF0, 0x71, 0x70, 0x67, 0x8A, 0xBA, 0x6F, 0x00, 0x25, 0xBF, 0x8C, 0x6A, - 0xEB, 0xFC, 0x6B, 0x21, 0xCC, 0xAB, 0xEE, 0xC6, 0x9B, 0x94, 0xFF, 0x2D, 0xB9, 0x3F, 0x85, 0xEA, 0x6D, 0x63, 0x3E, 0x10, 0xBC, 0xC3, 0xCB, 0x7F, - 0x17, 0xB6, 0x55, 0xF8, 0x85, 0x0B, 0xBF, 0x68, 0x6B, 0x36, 0xCC, 0x2C, 0x37, 0x4F, 0x8A, 0x75, 0x2C, 0x62, 0xBA, 0x3F, 0x9A, 0xE4, 0x2F, 0x81, - 0x4E, 0x06, 0x68, 0x94, 0x0F, 0xE6, 0x51, 0xA1, 0xC5, 0xAD, 0xC2, 0x57, 0xE5, 0x39, 0xBF, 0x63, 0xB5, 0x01, 0x3D, 0xE6, 0xEA, 0x9B, 0xCC, 0x2D, - 0xC4, 0x96, 0x1B, 0xBC, 0x04, 0xEF, 0xC1, 0xAD, 0x67, 0xC5, 0xAB, 0xEA, 0xE7, 0x4A, 0x95, 0x63, 0x52, 0x06, 0x02, 0xBC, 0xE9, 0x02, 0xE7, 0xA4, - 0x69, 0x99, 0x64, 0x27, 0x62, 0xEF, 0x8B, 0xCA, 0x04, 0x31, 0x7E, 0x4D, 0x83, 0x5F, 0xE1, 0xF4, 0xEB, 0x45, 0x19, 0x65, 0x84, 0x17, 0xCF, 0x87, - 0x45, 0x79, 0x00, 0x62, 0x68, 0xE7, 0x83, 0xA8, 0x3E, 0x06, 0x1C, 0xCD, 0xE0, 0xD0, 0x63, 0xFB, 0xC6, 0x23, 0x55, 0xC0, 0x53, 0xFE, 0x45, 0x7D, - 0x3C, 0x9D, 0x34, 0xDE, 0xED, 0x0C, 0x5F, 0xBA, 0x06, 0xA6, 0x71, 0xBA, 0xD2, 0xE0, 0xB9, 0x41, 0x98, 0xAC, 0x53, 0x54, 0x29, 0x11, 0x71, 0x56, - 0x0A, 0x66, 0xDD, 0x76, 0x86, 0x50, 0xBA, 0x8F, 0x83, 0x77, 0xD6, 0x0F, 0xA8, 0x30, 0x17, 0xDB, 0x3B, 0x1B, 0x8E, 0x9D, 0x53, 0x3B, 0x54, 0xF2, - 0x7A, 0x83, 0xA6, 0x6F, 0x20, 0x27, 0x08, 0x46, 0x7A, 0x8C, 0x42, 0x90, 0x86, 0xB3, 0xE0, 0x12, 0x1C, 0xAD, 0x54, 0x68, 0xCF, 0x24, 0xD1, 0x6D, - 0xF3, 0x08, 0x93, 0x60, 0x4E, 0x60, 0xD1, 0x96, 0x69, 0x68, 0x2E, 0x17, 0x4E, 0xDD, 0xB6, 0xF8, 0xAD, 0x0A, 0x6B, 0x7A, 0x50, 0xE6, 0x93, 0x83, - 0xB3, 0x38, 0x8B, 0xB1, 0x24, 0xB5, 0x89, 0x1F, 0x98, 0xF9, 0xD8, 0xE4, 0x66, 0xC6, 0x25, 0x55, 0x9B, 0x1D, 0x59, 0x89, 0x74, 0x71, 0xCD, 0xB5, - 0x12, 0x0D, 0xBD, 0x26, 0x9A, 0x69, 0xDE, 0x92, 0xBB, 0x83, 0xDE, 0xB1, 0x26, 0xE6, 0x18, 0x7E, 0xA7, 0x6B, 0xCB, 0x1F, 0x83, 0x50, 0x3D, 0x39, - 0x94, 0x67, 0xED, 0xC5, 0x49, 0x3C, 0xF3, 0x90, 0xF9, 0x03, 0x1F, 0xD2, 0xBB, 0x81, 0x61, 0x24, 0x50, 0xE1, 0x35, 0x76, 0x17, 0xB9, 0x00, 0xA1, - 0xD7, 0x77, 0x9B, 0x00, 0x8F, 0x3E, 0xAB, 0x11, 0xBF, 0x33, 0xE7, 0x0A, 0xB1, 0xED, 0x9B, 0x57, 0xF2, 0xE0, 0x54, 0x13, 0x31, 0x45, 0x0F, 0xF4, - 0x68, 0x17, 0xD9, 0x80, 0xBA, 0xB1, 0x97, 0x72, 0x22, 0x2E, 0xB5, 0x57, 0x42, 0x8A, 0x1D, 0x1E, 0xA3, 0x70, 0x49, 0x0B, 0x39, 0x98, 0x9E, 0xA5, - 0x13, 0x2F, 0xB8, 0xAE, 0x6B, 0xBC, 0xDA, 0x2A, 0x3D, 0x36, 0xD5, 0x12, 0xB4, 0xC3, 0x29, 0x9F, 0x9E, 0x42, 0x2E, 0x33, 0x98, 0x82, 0xB1, 0x70, - 0x5C, 0xC2, 0xF0, 0x38, 0x43, 0xFA, 0x17, 0xB8, 0x88, 0xD0, 0xEE, 0x2D, 0x3A, 0x04, 0x85, 0xCE, 0x40, 0xD1, 0x53, 0x6B, 0xBB, 0xA3, 0x66, 0xB5, - 0x08, 0xF5, 0xDB, 0xAE, 0x53, 0xE5, 0xF2, 0x63, 0xB7, 0x0E, 0xC0, 0x78, 0x32, 0xF0, 0x51, 0xAF, 0x78, 0xB0, 0x00, 0xB5, 0x04, 0x01, 0x1C, 0xB9, - 0xCD, 0xF4, 0x55, 0xC3, 0x42, 0xF5, 0x80, 0xA9, 0x91, 0xC4, 0x20, 0xA4, 0x90, 0x59, 0xFB, 0xBE, 0x23, 0x67, 0x19, 0x87, 0x67, 0xBB, 0x1C, 0x1F, - 0x15, 0x12, 0x80, 0x96, 0xF6, 0xB9, 0x66, 0xC9, 0x95, 0x77, 0xC1, 0xC6, 0xBE, 0x90, 0xCF, 0x73, 0xB6, 0xA3, 0xED, 0x64, 0x13, 0x86, 0x19, 0x48, - 0xD6, 0xFD, 0xC6, 0x08, 0xFF, 0xF3, 0xDD, 0xAA, 0xC1, 0xF1, 0x0A, 0x1D, 0xB0, 0xDF, 0x32, 0x71, 0xDE, 0x85, 0x07, 0x36, 0x59, 0xF1, 0x16, 0x34, - 0x4D, 0x02, 0x65, 0xA6, 0x4B, 0x37, 0x72, 0xFE, 0x17, 0x85, 0x47, 0x92, 0x0F, 0x4E, 0x7F, 0x1E, 0xCD, 0xAB, 0x68, 0xE0, 0x06, 0x44, 0x93, 0x99, - 0x86, 0x13, 0xF5, 0x36, 0x76, 0x33, 0x46, 0xA6, 0x2F, 0xAB, 0x80, 0xF6, 0x08, 0xAD, 0x98, 0x61, 0xE1, 0xE5, 0xA6, 0xD3, 0x52, 0xFE, 0x03, 0x69, - 0x4D, 0x3F, 0xCF, 0x8F, 0x7A, 0x82, 0xF4, 0x81, 0x40, 0x17, 0x29, 0xF2, 0x90, 0x56, 0x0D, 0x9E, 0x92, 0x6B, 0x6D, 0x76, 0x13, 0x8A, 0x55, 0x60, - 0x4A, 0xBE, 0x3B, 0x6F, 0xCE, 0x24, 0x63, 0xD1, 0x94, 0x8E, 0x7E, 0x6D, 0xCB, 0x0C, 0xD6, 0xE0, 0x44, 0xBA, 0x79, 0xEC, 0xCD, 0x65, 0x10, 0xEC, - 0xD3, 0x8B, 0xC0, 0x89, 0xE3, 0x2D, 0xE6, 0x22, 0x42, 0xD7, 0x51, 0xC6, 0x70, 0xA6, 0x3F, 0xC7, 0xD4, 0x60, 0x26, 0xCF, 0xBC, 0x48, 0x2F, 0x93, - 0x73, 0x37, 0x4F, 0x48, 0xDE, 0xF2, 0xCF, 0x70, 0x4E, 0x07, 0xF8, 0xC0, 0x14, 0x4F, 0x75, 0xB6, 0x03, 0xB6, 0xFD, 0x2F, 0xFD, 0x9C, 0x3C, 0x85, - 0xB1, 0xCD, 0xE7, 0x6F, 0x5D, 0x6F, 0x40, 0xBA, 0x69, 0xD5, 0xEB, 0xDD, 0xE1, 0xD1, 0x00, 0xF6, 0x8D, 0x8C, 0x73, 0x14, 0xB7, 0x3A, 0x3D, 0x11, - 0xDB, 0x94, 0xE1, 0x4E, 0x24, 0xC3, 0xEB, 0xE5, 0xB1, 0xA1, 0x7A, 0x6C, 0x0D, 0xC9, 0x66, 0x77, 0xA9, 0x18, 0x60, 0xF4, 0x03, 0x2C, 0xAC, 0x00, - 0x8B, 0xC4, 0x68, 0x30, 0x05, 0x03, 0x0A, 0x03, 0x06, 0x03, 0x8A, 0x8D, 0xA3, 0x51, 0x29, 0x64, 0xE3, 0x28, 0x7E, 0xD7, 0xF6, 0xC5, 0x45, 0x73, - 0x1E, 0xB5, 0x62, 0x8E, 0x60, 0xE2, 0x8D, 0xD1, 0x09, 0xB5, 0x1A, 0xBC, 0xCC, 0xB9, 0x2A, 0xF3, 0xFB, 0x66, 0x2E, 0x82, 0x2A, 0x8B, 0x9E, 0x00, - 0x98, 0xF4, 0xC3, 0xB1, 0xD9, 0xEA, 0x17, 0xEA, 0x5C, 0xF5, 0xA8, 0x1A, 0xAF, 0x46, 0xFB, 0xFB, 0x90, 0x0C, 0x54, 0xB4, 0xC1, 0x76, 0xB4, 0x6B, - 0xCF, 0x59, 0x0F, 0x10, 0xB2, 0x3E, 0x2D, 0xB1, 0x3B, 0x93, 0xED, 0x45, 0x06, 0x3F, 0xEE, 0x17, 0x56, 0x89, 0xD5, 0xFD, 0xBA, 0x55, 0xE3, 0xDA, - 0xE6, 0x52, 0x37, 0xFC, 0x6A, 0x35, 0xE3, 0xA4, 0x57, 0x82, 0xF8, 0x74, 0x29, 0xA4, 0x1E, 0x0B, 0x0A, 0xF3, 0x42, 0x10, 0x5E, 0xD6, 0x4B, 0x20, - 0x52, 0x0E, 0xD2, 0xAA, 0x10, 0x84, 0xAD, 0xDD, 0x87, 0xA8, 0xC8, 0xE7, 0x4C, 0xB0, 0x31, 0x2F, 0xAB, 0x83, 0xD5, 0xBE, 0x6A, 0xBD, 0xFA, 0x55, - 0xDD, 0x79, 0x92, 0x04, 0xAF, 0x1B, 0xF6, 0x59, 0xB8, 0x69, 0x4F, 0xB5, 0x4D, 0xD7, 0x46, 0x7A, 0xB5, 0xA6, 0x3D, 0xD6, 0xCD, 0xA6, 0xFA, 0x2F, - 0xA5, 0xE9, 0x33, 0x7E, 0x62, 0x65, 0xC1, 0x24, 0x0C, 0x45, 0x89, 0x9B, 0x84, 0x7D, 0xDB, 0x00, 0x74, 0x9B, 0x24, 0x0F, 0x69, 0xA4, 0x6F, 0x80, - 0x08, 0x22, 0x19, 0x3D, 0x64, 0xB3, 0x30, 0x55, 0xC5, 0x07, 0x59, 0x49, 0xF6, 0x18, 0x56, 0x6B, 0xB1, 0xE2, 0xA3, 0xC5, 0x09, 0xA1, 0x7C, 0xD5, - 0x83, 0xDC, 0x5C, 0xD5, 0xC4, 0x8A, 0x1E, 0x05, 0xD7, 0xDE, 0xB4, 0xBD, 0x18, 0x2F, 0x45, 0x6E, 0xBB, 0x14, 0x7D, 0xBC, 0xBC, 0x0B, 0x16, 0xA4, - 0xCF, 0xD0, 0x5F, 0xDC, 0x48, 0x6C, 0x35, 0xFB, 0x27, 0xA4, 0x6C, 0x19, 0xC0, 0x18, 0x17, 0xCC, 0x1C, 0x17, 0xEA, 0xE1, 0x96, 0x0A, 0x0E, 0x5A, - 0xBC, 0x7A, 0xAA, 0x29, 0xB2, 0xD8, 0x88, 0xC5, 0xA5, 0x57, 0x35, 0x9F, 0x56, 0x1A, 0x8E, 0x55, 0x53, 0x7A, 0xAA, 0x9B, 0xD3, 0xA9, 0x36, 0x69, - 0x38, 0x0E, 0x28, 0xC1, 0xFF, 0xA4, 0x77, 0xE3, 0x94, 0x19, 0xD3, 0x94, 0x38, 0xC5, 0x64, 0xDB, 0xB4, 0xB4, 0x89, 0xA3, 0xF4, 0x8C, 0x96, 0x84, - 0x4B, 0x95, 0xE4, 0x62, 0x37, 0x8F, 0x26, 0x70, 0x34, 0x24, 0xC0, 0x08, 0x86, 0x5E, 0x14, 0x06, 0x81, 0xC8, 0x89, 0x70, 0x88, 0x2E, 0x84, 0xD0, - 0x00, 0xCD, 0xFD, 0xF0, 0xCA, 0x3C, 0x67, 0xFE, 0xBC, 0x7F, 0xF9, 0xD8, 0xAF, 0x54, 0xD5, 0x21, 0x78, 0x8D, 0xB2, 0xFD, 0x92, 0x81, 0x2D, 0x6B, - 0xBC, 0x75, 0x84, 0x35, 0x84, 0xF5, 0x01, 0xF5, 0xA5, 0x7A, 0x85, 0xBA, 0x52, 0x4D, 0xD9, 0x81, 0x57, 0x9F, 0xD3, 0x09, 0xCC, 0xC7, 0xE4, 0x56, - 0xF1, 0x24, 0x38, 0xCF, 0xFB, 0xC5, 0x0D, 0xAA, 0xAF, 0xCC, 0x2F, 0xE2, 0x49, 0xDC, 0xFB, 0xEC, 0x15, 0xE6, 0x7E, 0xF4, 0x12, 0xF5, 0x14, 0xF6, - 0xCB, 0xFB, 0x28, 0x1E, 0x36, 0xCF, 0xAB, 0x0F, 0x00, 0x7F, 0x8B, 0x33, 0x90, 0x7F, 0xF5, 0xB4, 0x5A, 0x5A, 0x1D, 0xAD, 0x9E, 0x54, 0x4B, 0xAA, - 0x11, 0xD5, 0x21, 0xD4, 0x20, 0x3E, 0xD4, 0x74, 0xEA, 0x04, 0x6A, 0x37, 0xB5, 0xFC, 0xAB, 0x39, 0x80, 0x9A, 0x75, 0xA0, 0xAB, 0x84, 0xF0, 0x51, - 0x68, 0xD2, 0x68, 0xA0, 0x9E, 0x43, 0x30, 0xB8, 0xA0, 0xF3, 0xD1, 0xD4, 0xBD, 0x73, 0x93, 0xA6, 0x48, 0xA1, 0x45, 0x4D, 0xC0, 0x5E, 0xB9, 0x62, - 0x7F, 0xB6, 0xB7, 0xD9, 0xE9, 0xEC, 0x15, 0xEC, 0xAB, 0xEE, 0x2D, 0x77, 0xAE, 0xBD, 0x2E, 0x31, 0xA5, 0xF7, 0xA4, 0x4E, 0x8D, 0x60, 0x0F, 0x18, - 0x50, 0x2C, 0x72, 0xC1, 0x83, 0xC0, 0x0F, 0x61, 0x70, 0xB4, 0xC2, 0x6F, 0x21, 0x9D, 0x41, 0x0A, 0x86, 0x95, 0x31, 0xF5, 0x01, 0xB5, 0x1C, 0x47, - 0x87, 0x87, 0xC5, 0x0F, 0x36, 0x1B, 0x98, 0x3D, 0x5C, 0xD5, 0x9C, 0x3D, 0xB0, 0x03, 0xFA, 0x30, 0xFF, 0x20, 0x69, 0x07, 0x62, 0xB2, 0x95, 0x59, - 0x71, 0xD7, 0x6E, 0x84, 0x19, 0xB9, 0x0D, 0x04, 0xC8, 0x65, 0x67, 0x46, 0x9F, 0x47, 0x1A, 0xB0, 0xB3, 0x23, 0x9C, 0xB7, 0x66, 0xB0, 0x13, 0xA1, - 0x39, 0x0F, 0x3E, 0xB0, 0xF3, 0x58, 0xB8, 0xE3, 0xC1, 0xC7, 0xBC, 0xBA, 0xB9, 0x57, 0x64, 0x36, 0xB6, 0xDD, 0x87, 0x32, 0x2B, 0xD8, 0xF3, 0x32, - 0xF7, 0xED, 0xE9, 0xA3, 0x76, 0xF3, 0x39, 0x0A, 0x66, 0x08, 0x1D, 0xE6, 0x6C, 0xBB, 0x77, 0x81, 0x19, 0x3B, 0xAF, 0x02, 0x6A, 0x28, 0xBB, 0x51, - 0x04, 0x05, 0x06, 0xD8, 0xFD, 0x6A, 0x28, 0x00, 0x67, 0x86, 0x0B, 0xF9, 0x1E, 0x16, 0x95, 0x36, 0x34, 0x36, 0xD2, 0xFD, 0xE8, 0xA6, 0x74, 0x06, - 0xDF, 0xC4, 0x2B, 0xCA, 0xFF, 0x0C, 0xD4, 0x05, 0xD4, 0x6F, 0x1A, 0x5E, 0xEC, 0xF2, 0xA9, 0x42, 0x4C, 0x1C, 0x42, 0x3A, 0x5B, 0x89, 0x5A, 0x2A, - 0x7A, 0x1D, 0xD0, 0xEF, 0xED, 0x93, 0x4B, 0x08, 0xF9, 0x76, 0x79, 0x55, 0x01, 0x59, 0xEC, 0xB1, 0x62, 0x08, 0x57, 0x35, 0x74, 0x56, 0x1A, 0x69, - 0x55, 0x0B, 0x26, 0x1F, 0x3B, 0x03, 0x77, 0x6E, 0xC2, 0x14, 0x1B, 0xB4, 0xA8, 0xCD, 0x00, 0x8C, 0x00, 0x38, 0x06, 0x70, 0x06, 0xA0, 0x00, 0x80, - 0x07, 0x00, 0x40, 0x03, 0xE1, 0x81, 0xAF, 0x00, 0xEA, 0x12, 0x3F, 0xEE, 0x27, 0x0A, 0xD4, 0x70, 0xFF, 0x47, 0x58, 0x04, 0x34, 0xFB, 0xC8, 0x50, - 0x3B, 0x50, 0xB7, 0xE5, 0x0D, 0x9A, 0x7D, 0xB0, 0x93, 0x7C, 0xA4, 0xBC, 0x31, 0x3E, 0x56, 0x09, 0xA9, 0x3B, 0xC8, 0x38, 0xA1, 0xCF, 0xE0, 0x56, - 0xA6, 0x9E, 0xAB, 0x09, 0xF8, 0xD9, 0x3D, 0xAA, 0xD8, 0xF1, 0xF8, 0xFB, 0xAB, 0xA8, 0x3F, 0xA5, 0x5A, 0x31, 0x4A, 0xD5, 0x27, 0xA4, 0x15, 0xA0, - 0x1A, 0x59, 0x08, 0xA5, 0x68, 0xE6, 0x43, 0xA1, 0x1B, 0x8D, 0x42, 0x47, 0x47, 0xCE, 0x99, 0xAF, 0x6F, 0x88, 0x21, 0x62, 0x96, 0xC1, 0xA7, 0x55, - 0x9F, 0xAA, 0xBC, 0xA1, 0xE2, 0x5D, 0x9C, 0xAA, 0x82, 0xC9, 0x11, 0x19, 0xCC, 0xB9, 0xBC, 0xB8, 0xA1, 0xA5, 0xD9, 0xF6, 0x16, 0xFA, 0xB6, 0x54, - 0xB4, 0x6B, 0xDB, 0x4E, 0xAB, 0x9C, 0xB4, 0xFB, 0x79, 0xA8, 0xBE, 0xAB, 0x2A, 0x37, 0x6B, 0xA7, 0x42, 0x7E, 0xD4, 0x07, 0x4C, 0xA7, 0xAC, 0x31, - 0x21, 0xCE, 0x4C, 0x53, 0x70, 0xEA, 0x1A, 0x6E, 0x1C, 0x47, 0x7B, 0x00, 0xD6, 0x8F, 0x8C, 0xBA, 0x0C, 0x52, 0xF5, 0xF4, 0xB4, 0x33, 0x09, 0x5F, - 0x08, 0x46, 0xCA, 0x52, 0xD7, 0xE0, 0xE3, 0x9D, 0x0F, 0x12, 0x9E, 0x1F, 0xAD, 0xAD, 0x3A, 0x5B, 0x50, 0x85, 0x2E, 0xC3, 0x03, 0x9E, 0x7C, 0xBA, - 0x8A, 0xCC, 0x1A, 0x56, 0x56, 0x16, 0x93, 0x44, 0xCD, 0x90, 0x4F, 0x84, 0x4C, 0x98, 0x40, 0x68, 0x97, 0x80, 0xE1, 0xDB, 0x23, 0x80, 0x48, 0x16, - 0xE4, 0x8E, 0xDC, 0x4D, 0x44, 0xFE, 0xA0, 0x43, 0xF2, 0x6F, 0x90, 0xC8, 0x16, 0xFB, 0xC7, 0xDE, 0x8B, 0x54, 0xDA, 0xA3, 0x8D, 0x20, 0xF8, 0x85, - 0xE3, 0xAD, 0x61, 0xC3, 0x63, 0x49, 0x23, 0xBE, 0x98, 0xB1, 0x63, 0xC6, 0x9E, 0x47, 0x8F, 0x66, 0xCE, 0xA1, 0x25, 0xA4, 0x78, 0x06, 0x66, 0x3B, - 0xE3, 0x25, 0x9B, 0xA5, 0x7F, 0x99, 0xF5, 0xAC, 0xCC, 0x32, 0x1A, 0xCB, 0xDF, 0x58, 0x19, 0xAA, 0x26, 0xC6, 0x8C, 0x48, 0xF2, 0x5A, 0x14, 0x0C, - 0x2D, 0x38, 0x64, 0x0A, 0x6B, 0xC7, 0x6C, 0x59, 0xFB, 0xC2, 0x09, 0xC6, 0x15, 0xE2, 0x8A, 0x49, 0x40, 0x12, 0x4B, 0x3A, 0x0F, 0x63, 0xAE, 0xBE, - 0xC0, 0x15, 0x13, 0xAE, 0x25, 0x0E, 0x8E, 0x5E, 0xF0, 0x0C, 0x02, 0x0C, 0x60, 0xEC, 0xD7, 0x65, 0xC7, 0xD7, 0xC9, 0xD1, 0xC5, 0x50, 0x48, 0xEF, - 0x58, 0x9D, 0x37, 0x8C, 0x67, 0xF7, 0x40, 0x9D, 0x2E, 0x1D, 0x56, 0x20, 0xAA, 0x5D, 0x45, 0xCA, 0xA4, 0xB0, 0x1D, 0xB4, 0xF9, 0xF6, 0x54, 0xD5, - 0xD6, 0x85, 0xCA, 0xC8, 0x7C, 0xB6, 0xF9, 0xC3, 0x2C, 0x50, 0x07, 0x59, 0x1F, 0x9D, 0x58, 0xAF, 0x46, 0xD8, 0x98, 0x99, 0xD7, 0x2C, 0x3D, 0x18, - 0x62, 0x84, 0x68, 0x48, 0x69, 0xDB, 0x00, 0xC1, 0xFF, 0xD2, 0xC4, 0x0C, 0x30, 0x7F, 0xDF, 0x7B, 0x3F, 0xDA, 0x21, 0xA8, 0x50, 0xF4, 0x72, 0x2C, - 0x6D, 0x6D, 0x1C, 0x45, 0x90, 0x22, 0x78, 0x8F, 0x02, 0x16, 0x05, 0xC5, 0x77, 0x7D, 0xC1, 0xBC, 0xC8, 0xE3, 0xA3, 0x98, 0x23, 0x9A, 0x78, 0x23, - 0x3F, 0x01, 0xF5, 0x8C, 0xE8, 0x65, 0x79, 0x28, 0x81, 0xD4, 0xC4, 0xDB, 0xA0, 0xA1, 0x03, 0x68, 0x3B, 0x06, 0x4C, 0x77, 0x61, 0x88, 0x16, 0xC2, - 0xC1, 0x12, 0x25, 0x10, 0x59, 0x0C, 0xAE, 0xBE, 0xED, 0xB1, 0x20, 0x25, 0x82, 0x38, 0x92, 0x7F, 0x1D, 0x1C, 0xEA, 0x62, 0xB5, 0x68, 0x4B, 0xB2, - 0x4B, 0xC7, 0xAD, 0x7C, 0x6D, 0x74, 0x2D, 0x10, 0xAF, 0x46, 0xC1, 0xC5, 0x80, 0xC9, 0xDC, 0x34, 0x3B, 0x5B, 0xC0, 0x2B, 0x34, 0x5A, 0xA5, 0xEF, - 0x59, 0x8C, 0x16, 0x33, 0xD9, 0x0C, 0x33, 0x94, 0xA4, 0xBF, 0x4C, 0x43, 0x77, 0xA1, 0x42, 0xC7, 0xA1, 0x4F, 0x71, 0xE9, 0x91, 0xF6, 0x56, 0x7B, - 0xB2, 0xBD, 0xDB, 0x9E, 0xC1, 0xDE, 0xC2, 0xBE, 0xF1, 0x6F, 0xAF, 0x69, 0xDF, 0x0B, 0x8F, 0xE4, 0x3B, 0x6C, 0xE3, 0x2B, 0xB7, 0xF0, 0x1C, 0xC5, - 0xBC, 0x57, 0x5D, 0xFE, 0x60, 0x42, 0x9C, 0x54, 0xD3, 0xC3, 0x81, 0xC2, 0x90, 0xB2, 0x4A, 0x52, 0xE6, 0xDF, 0xB9, 0x92, 0xDE, 0xBC, 0xB9, 0x87, - 0xB9, 0x89, 0x39, 0xE4, 0x1C, 0x3F, 0x5F, 0x9D, 0xE7, 0xCE, 0x73, 0x80, 0x8F, 0x3F, 0xEB, 0x63, 0xFA, 0x76, 0x89, 0xBE, 0x5E, 0x27, 0xDD, 0x16, - 0x92, 0xAE, 0x5B, 0x50, 0x6C, 0x83, 0x21, 0x9B, 0x58, 0xDC, 0xB3, 0x9C, 0x60, 0xD1, 0x46, 0xA1, 0xC7, 0x13, 0x35, 0x94, 0xCE, 0x47, 0xD8, 0xE9, - 0x4B, 0x61, 0x50, 0x1E, 0x76, 0x81, 0x30, 0x31, 0x6F, 0x31, 0x74, 0x83, 0x60, 0x27, 0x01, 0xDA, 0x3E, 0xA0, 0xF2, 0x37, 0x58, 0xF5, 0x57, 0xEC, - 0x24, 0x18, 0xD1, 0x3F, 0x3E, 0xCB, 0xD7, 0xF9, 0x48, 0xDF, 0xEA, 0x93, 0x7D, 0xB7, 0xCF, 0xE0, 0x77, 0xD2, 0x55, 0xE9, 0xB8, 0xF4, 0xBC, 0x1C, - 0x24, 0xEF, 0xC8, 0x3A, 0xBA, 0x92, 0x21, 0xAA, 0x73, 0x12, 0x9A, 0x44, 0x03, 0x8A, 0x25, 0xC4, 0xC2, 0x0C, 0xFE, 0x59, 0xE0, 0xCB, 0xD3, 0x4E, - 0x0D, 0x9F, 0x21, 0x41, 0xA7, 0x88, 0x3B, 0xCE, 0xC5, 0x0D, 0x9B, 0x96, 0x24, 0x34, 0x49, 0x19, 0xF5, 0x99, 0xAB, 0x78, 0x98, 0x2D, 0x38, 0x18, - 0x0F, 0x5E, 0x3E, 0xC1, 0x90, 0xDF, 0x5B, 0x3B, 0x54, 0x91, 0x58, 0xD4, 0xB1, 0xEA, 0x4F, 0x35, 0xA6, 0x1A, 0xEF, 0x67, 0xB4, 0x98, 0x8C, 0xAD, - 0x94, 0xB8, 0xE5, 0xB4, 0xEB, 0x8E, 0x48, 0xF2, 0xAA, 0xEA, 0x23, 0x1B, 0x5A, 0x44, 0x10, 0xDB, 0xEA, 0x7F, 0x0A, 0xD4, 0xB4, 0x58, 0x62, 0x45, - 0x97, 0x3C, 0x43, 0x93, 0x04, 0x80, 0x42, 0x05, 0xB1, 0x30, 0x83, 0xF0, 0x59, 0x20, 0x83, 0xA7, 0x5D, 0x08, 0xBC, 0xA0, 0x4B, 0xA7, 0x08, 0x4A, - 0xCE, 0x42, 0xBE, 0x4D, 0x4B, 0x57, 0x4D, 0xD2, 0xDD, 0xCC, 0xD9, 0x63, 0xCC, 0xD8, 0x0D, 0x97, 0xC6, 0xAF, 0xD3, 0xBC, 0x96, 0x24, 0xC8, 0x2B, - 0x86, 0x1C, 0x54, 0xBE, 0xDB, 0x94, 0x59, 0x68, 0xEE, 0xC9, 0x38, 0x90, 0x24, 0x5D, 0xA4, 0x9D, 0xCB, 0x7E, 0xE0, 0xBE, 0xA7, 0x51, 0xE3, 0x58, - 0x1A, 0xB1, 0xF2, 0x20, 0xDF, 0x79, 0xD0, 0xDE, 0x0C, 0x67, 0xFE, 0xB6, 0x56, 0x6F, 0x70, 0x74, 0x68, 0x64, 0xDC, 0xA9, 0x6F, 0x7F, 0x12, 0xBC, - 0xE6, 0x41, 0x8D, 0x92, 0xF3, 0xDC, 0xAE, 0x53, 0x31, 0xA6, 0x2A, 0xEE, 0xC4, 0x3E, 0x81, 0x52, 0xC0, 0x69, 0xE8, 0x8E, 0xD8, 0x4E, 0x60, 0xD8, - 0x94, 0x08, 0xB7, 0xCF, 0x22, 0x08, 0x2E, 0xCC, 0x0B, 0xD0, 0xBC, 0xAC, 0x24, 0xC7, 0x53, 0xDC, 0xFC, 0x84, 0x0C, 0x41, 0x70, 0x2D, 0x66, 0xF4, - 0x63, 0x23, 0x83, 0x4D, 0xCA, 0x32, 0xBB, 0x32, 0xFF, 0x58, 0xAB, 0xCD, 0x51, 0x24, 0x99, 0xEA, 0x50, 0x7D, 0x91, 0x41, 0x9E, 0xC8, 0x5F, 0x25, - 0x20, 0xEA, 0x43, 0x89, 0x83, 0xC1, 0x3A, 0x9B, 0x24, 0x1D, 0x04, 0x66, 0xBD, 0x02, 0x2B, 0xBD, 0x72, 0xB6, 0x6E, 0x68, 0x4C, 0x8F, 0x55, 0xAE, - 0x7F, 0x8A, 0xD0, 0x3D, 0x96, 0x01, 0xD4, 0x6B, 0x8B, 0xE6, 0x2A, 0x29, 0xF3, 0x0F, 0x9B, 0x16, 0xA2, 0x39, 0x06, 0x07, 0x7B, 0xB6, 0xD4, 0x83, - 0xF5, 0x20, 0x9A, 0x9A, 0xC0, 0x0F, 0x8D, 0x9C, 0xB6, 0x20, 0x29, 0xED, 0x22, 0x1F, 0x3D, 0x02, 0x04, 0x34, 0xF4, 0xE4, 0xFC, 0x72, 0xF2, 0xF9, - 0xA5, 0x75, 0x4E, 0x0B, 0xAA, 0x6F, 0x26, 0xA2, 0xDC, 0xC7, 0xBE, 0xA0, 0xD7, 0x43, 0xEC, 0x61, 0x96, 0xE7, 0x4F, 0x42, 0x5C, 0xAD, 0x7B, 0x52, - 0x04, 0x46, 0x5C, 0x2D, 0xF2, 0x34, 0xA4, 0xB9, 0xA3, 0xDC, 0xFE, 0xA2, 0xE7, 0x93, 0x9E, 0xAF, 0xF8, 0xF2, 0xD0, 0xD3, 0x3D, 0xAA, 0x3E, 0x89, - 0x79, 0x3E, 0xDF, 0x74, 0x75, 0x0B, 0xC0, 0x86, 0xEE, 0xD3, 0x10, 0x9D, 0xC2, 0x65, 0x9F, 0xF9, 0xF2, 0xF1, 0x5A, 0x97, 0x0C, 0x38, 0x17, 0x49, - 0xA5, 0x0D, 0x16, 0x40, 0x1B, 0x63, 0xF5, 0x0A, 0x97, 0xE0, 0x4A, 0xE0, 0xB8, 0x55, 0x3E, 0x82, 0xF5, 0x02, 0x49, 0x9E, 0xBE, 0x62, 0xF5, 0xF0, - 0x47, 0x6E, 0x87, 0x9D, 0xA3, 0x7E, 0x58, 0x70, 0x1A, 0x23, 0x57, 0x1E, 0xA3, 0xC3, 0x7E, 0x46, 0x40, 0xA8, 0x52, 0x9D, 0x3C, 0x81, 0x8B, 0x1E, - 0x0B, 0x6A, 0x5F, 0x3A, 0xBC, 0xCF, 0x30, 0x37, 0xAC, 0x80, 0x80, 0x6E, 0xAF, 0xBB, 0xEC, 0xED, 0x4A, 0x1F, 0x33, 0x74, 0xBF, 0xA1, 0x86, 0x56, - 0x3F, 0xAB, 0x61, 0xD5, 0xAA, 0x6A, 0x54, 0xB5, 0xA9, 0x9A, 0x73, 0x9A, 0xB2, 0x65, 0x80, 0xC7, 0x29, 0x87, 0x7A, 0xBD, 0x9E, 0xB0, 0x36, 0x53, - 0xBB, 0x2E, 0xB7, 0x85, 0x88, 0x08, 0xBA, 0xA4, 0xE0, 0xF9, 0xBC, 0x48, 0x30, 0xAC, 0xD8, 0x64, 0xF6, 0x13, 0xB7, 0x1A, 0x06, 0x76, 0x22, 0x0B, - 0x53, 0x7F, 0x76, 0x31, 0xBB, 0xBD, 0xED, 0xD1, 0x6E, 0x20, 0x6F, 0x1F, 0xC1, 0x83, 0xB1, 0x06, 0x13, 0x28, 0xF0, 0xA6, 0xB9, 0xC2, 0xD0, 0x20, - 0x2D, 0x33, 0xD1, 0x52, 0x2E, 0x04, 0x94, 0x2C, 0x04, 0x00, 0x84, 0xB3, 0x9B, 0x68, 0x10, 0x99, 0x77, 0x79, 0x56, 0x5A, 0xC0, 0x4D, 0xFB, 0x80, - 0x36, 0x58, 0xCF, 0x03, 0x51, 0x96, 0x45, 0x32, 0x76, 0xE7, 0x33, 0x8B, 0xD2, 0xF5, 0x0C, 0xB4, 0x15, 0xC3, 0x85, 0xD6, 0x21, 0x38, 0xD6, 0xBE, - 0x2C, 0xD6, 0x31, 0xE6, 0xFC, 0x09, 0xC3, 0x7C, 0x58, 0x5E, 0x63, 0xDC, 0x6A, 0x83, 0x94, 0x7D, 0x68, 0x27, 0x9D, 0x09, 0x3D, 0x8B, 0x2D, 0x79, - 0xEA, 0x87, 0xA2, 0x5B, 0x54, 0xFA, 0xD6, 0xF0, 0xA1, 0xFE, 0x94, 0x32, 0xCC, 0x74, 0x97, 0xC0, 0xFE, 0xD8, 0x5D, 0xCA, 0x6E, 0xA5, 0x6D, 0xB1, - 0x04, 0x22, 0x34, 0xE9, 0x0D, 0x0A, 0xA5, 0xC1, 0xC2, 0xCC, 0xEB, 0xB3, 0xC0, 0x00, 0x4F, 0x3B, 0x04, 0x78, 0x12, 0xFB, 0x4E, 0x11, 0x1A, 0x38, - 0x0B, 0xD7, 0x36, 0x2D, 0x17, 0x35, 0x49, 0x57, 0x5C, 0x1A, 0xA3, 0x98, 0xBE, 0xB4, 0x24, 0x21, 0x5D, 0x31, 0xC4, 0x35, 0xCF, 0x98, 0x67, 0x98, - 0xD3, 0xCC, 0x4F, 0x7C, 0x99, 0x40, 0xAC, 0x71, 0xF9, 0x87, 0x0A, 0xE6, 0x4C, 0x44, 0xFD, 0x1A, 0x6E, 0x10, 0xB6, 0xAF, 0x11, 0x28, 0x44, 0x51, - 0x49, 0x88, 0x17, 0xF4, 0x4B, 0x94, 0x5E, 0x18, 0x1C, 0x7C, 0xA6, 0x4B, 0x8F, 0xD2, 0x05, 0xB7, 0x12, 0xCC, 0x01, 0x7D, 0x3B, 0x74, 0xD0, 0x60, - 0xAB, 0x99, 0xD5, 0x7B, 0x75, 0xAB, 0x3A, 0xFF, 0x32, 0xC8, 0xC1, 0xAD, 0x9A, 0xBA, 0x38, 0x4F, 0x05, 0xA2, 0x44, 0x64, 0x41, 0xC1, 0xA2, 0xE8, - 0x96, 0xA1, 0xF3, 0x81, 0x44, 0x18, 0x7E, 0x25, 0x28, 0xB6, 0x06, 0x7B, 0x8C, 0xAB, 0x67, 0x9E, 0xF8, 0x4F, 0x7F, 0x21, 0x5D, 0x05, 0x7D, 0x93, - 0x8E, 0x4A, 0xB7, 0xA5, 0x0B, 0xD3, 0x9B, 0xE9, 0xB0, 0x1D, 0x67, 0x95, 0xFA, 0x0F, 0x79, 0xF2, 0xBB, 0x07, 0x7A, 0x01, 0x58, 0xF1, 0xFF, 0x33, - 0x34, 0xD4, 0x6B, 0x03, 0xEA, 0x54, 0x75, 0x8A, 0x4B, 0x81, 0xEF, 0xA2, 0xB3, 0x0A, 0x14, 0x7F, 0x22, 0x4C, 0xE2, 0x6C, 0xFB, 0xE1, 0xD6, 0x37, - 0x5C, 0xD8, 0x0B, 0x0A, 0xCD, 0x45, 0x8D, 0x5D, 0x7C, 0xF3, 0xFB, 0xDB, 0xBB, 0x9E, 0xEF, 0x3E, 0x67, 0x2E, 0x89, 0x27, 0x3A, 0xD2, 0xC2, 0x41, - 0x20, 0xA5, 0xE9, 0x1F, 0xCD, 0x6A, 0x1E, 0xF9, 0x53, 0x0F, 0x96, 0x3B, 0x8E, 0xE7, 0x06, 0x4A, 0x24, 0xE6, 0x0A, 0x3C, 0xCC, 0x95, 0x65, 0x92, - 0x62, 0x14, 0xD8, 0x48, 0x26, 0x60, 0x7C, 0x9C, 0x7C, 0x89, 0x1B, 0xF9, 0x74, 0xFB, 0x9A, 0xB7, 0x6D, 0x4D, 0xAB, 0x7D, 0x21, 0x49, 0x1B, 0x0C, - 0x45, 0xBB, 0x0E, 0x31, 0xEB, 0x31, 0x40, 0xB6, 0xC7, 0x38, 0x76, 0x47, 0x02, 0x2C, 0x97, 0xC8, 0xEB, 0xD4, 0xDA, 0xD5, 0x84, 0x52, 0xEB, 0x01, - 0x8F, 0xD3, 0x53, 0x15, 0xA6, 0xAA, 0xF4, 0x39, 0x22, 0xBC, 0x38, 0x6B, 0xA9, 0x1B, 0x20, 0xB5, 0x0D, 0xC9, 0x8B, 0x1A, 0x39, 0x55, 0x9A, 0xB7, - 0xC7, 0x0C, 0x3D, 0xD2, 0x6D, 0x45, 0x2C, 0x63, 0xCF, 0xC7, 0xC4, 0x81, 0xC0, 0xE0, 0x8B, 0x5F, 0xF6, 0x76, 0x5C, 0x74, 0x43, 0x14, 0xAF, 0x5A, - 0xD4, 0x3C, 0xA3, 0x6F, 0x2B, 0x33, 0x58, 0xBF, 0x29, 0x49, 0x3D, 0xD2, 0x70, 0x00, 0xCC, 0xB2, 0x4E, 0x62, 0xF2, 0x4C, 0xEC, 0xE2, 0x4A, 0x9E, - 0x4C, 0xB4, 0x45, 0x60, 0x20, 0x51, 0xC3, 0x8F, 0x58, 0x1E, 0x8A, 0xE0, 0xE5, 0x86, 0xCC, 0x7A, 0x82, 0x10, 0x42, 0x7F, 0x18, 0x9F, 0x90, 0x37, - 0x9E, 0xF0, 0x58, 0x89, 0x6E, 0xAD, 0x25, 0x01, 0x5F, 0x9E, 0x40, 0xEA, 0x33, 0x37, 0x3A, 0x22, 0x17, 0xE5, 0xE2, 0x20, 0x0F, 0x05, 0xC2, 0x03, - 0x6D, 0x9B, 0xB3, 0xF0, 0x1A, 0xFC, 0xBC, 0xD0, 0xC1, 0x53, 0x01, 0x26, 0xFE, 0xB0, 0xB1, 0xB3, 0xC3, 0x2C, 0x27, 0x0B, 0xD3, 0x4D, 0x15, 0xCA, - 0x9A, 0xBC, 0xC0, 0x99, 0xB3, 0x5F, 0x98, 0xA8, 0x8A, 0x97, 0xCC, 0x09, 0x2C, 0x87, 0x43, 0xF5, 0x96, 0x2B, 0x1B, 0x56, 0xB0, 0x19, 0x2B, 0x93, - 0x18, 0x29, 0x6B, 0x46, 0x27, 0xCD, 0x46, 0x25, 0xA7, 0x5C, 0xC8, 0x23, 0xED, 0x5C, 0x14, 0x80, 0x04, 0xDB, 0x33, 0xBB, 0x4F, 0x46, 0x46, 0xAD, - 0xE0, 0x5A, 0xFC, 0x8B, 0xF8, 0x4F, 0x60, 0xDD, 0xB3, 0x6E, 0x59, 0x53, 0xC3, 0xFA, 0x77, 0xBA, 0xBC, 0x40, 0xDD, 0xDA, 0x5C, 0x96, 0x5A, 0x06, - 0xC0, 0x01, 0x7E, 0x71, 0x69, 0x8B, 0x77, 0x01, 0x8F, 0x18, 0xD0, 0x3A, 0x03, 0xCF, 0x44, 0x0B, 0x98, 0xB5, 0x08, 0xE0, 0xAB, 0x57, 0x36, 0x9D, - 0x2F, 0xDB, 0x40, 0x24, 0x93, 0x19, 0xC3, 0xF9, 0x14, 0x83, 0x87, 0x59, 0xE9, 0xC1, 0xE4, 0x71, 0x38, 0xE9, 0xAF, 0x07, 0x22, 0xFA, 0xE8, 0x0D, - 0x76, 0xAF, 0x09, 0xBB, 0x21, 0x7A, 0xB8, 0x0A, 0x73, 0x6A, 0x09, 0x64, 0x24, 0xFD, 0x69, 0x40, 0x2B, 0x70, 0x2A, 0xFD, 0x2D, 0xC0, 0x20, 0xF4, - 0xB6, 0x74, 0x1A, 0xC4, 0x70, 0x3E, 0x0A, 0x1A, 0x1A, 0x23, 0xEB, 0x10, 0x2A, 0xE0, 0x20, 0x16, 0x22, 0xA6, 0xDE, 0xBE, 0xB8, 0x77, 0x3E, 0xBC, - 0xE5, 0xFF, 0x7F, 0xB3, 0xFA, 0x58, 0x1D, 0xBA, 0xE1, 0xFC, 0x3B, 0x3E, 0xEA, 0xA7, 0xD8, 0x5F, 0xE6, 0x32, 0x55, 0x31, 0xF0, 0x17, 0xBC, 0x6E, - 0xE8, 0xD9, 0xEC, 0x85, 0xE9, 0x38, 0x01, 0xD4, 0xCA, 0xF7, 0x61, 0xFA, 0xD1, 0xFF, 0xA0, 0xB3, 0xD0, 0x75, 0xE8, 0x2D, 0x30, 0x7F, 0xC2, 0x12, - 0x7D, 0x89, 0x09, 0x46, 0x60, 0xCC, 0x64, 0xD3, 0x3E, 0xC2, 0x03, 0xE3, 0x57, 0xB4, 0x62, 0x12, 0x1F, 0x88, 0x51, 0x20, 0x62, 0x4A, 0x0E, 0x03, - 0x00, 0xF1, 0x85, 0x59, 0x41, 0x04, 0xEB, 0x9E, 0xA0, 0x4F, 0xD2, 0x5B, 0xBF, 0x9A, 0x23, 0x81, 0xE9, 0x56, 0x0D, 0x99, 0xF2, 0x0F, 0x80, 0xF3, - 0x3C, 0xCC, 0xEF, 0x20, 0x37, 0x71, 0xC2, 0x9D, 0xE1, 0xDB, 0xA6, 0x9D, 0x44, 0xE5, 0x1F, 0xB1, 0xC8, 0x93, 0xFF, 0xEA, 0x1D, 0xC4, 0xB5, 0xDF, - 0x48, 0x01, 0xAF, 0xC4, 0xFB, 0x18, 0x56, 0x1C, 0x6A, 0x0D, 0x75, 0x4A, 0x81, 0x7F, 0x72, 0xD7, 0x7C, 0x3B, 0x9D, 0xF1, 0xE4, 0x1B, 0x57, 0xE7, - 0x70, 0x76, 0xF2, 0xE3, 0x37, 0x06, 0x2D, 0x11, 0x5F, 0x32, 0x71, 0x54, 0xAA, 0xD7, 0xEF, 0x41, 0x02, 0x96, 0x97, 0xB3, 0x68, 0xB3, 0x52, 0xA8, - 0x3A, 0xA4, 0x12, 0xB0, 0x16, 0xA4, 0xF4, 0x35, 0x38, 0x4C, 0x44, 0xFC, 0xC0, 0x39, 0xB4, 0xAA, 0x5E, 0x08, 0xF6, 0x24, 0x52, 0x8E, 0x75, 0x39, - 0x67, 0xBA, 0x94, 0xCF, 0xF1, 0x62, 0xC5, 0xF2, 0x7A, 0x6E, 0x88, 0xFC, 0x0E, 0x3D, 0x0F, 0xE4, 0x91, 0xB7, 0x1E, 0xD8, 0x4F, 0x62, 0xC9, 0x83, - 0xBF, 0xE6, 0xF9, 0x05, 0x7A, 0xE3, 0x27, 0x1D, 0xA5, 0xBD, 0x65, 0x70, 0x3D, 0xC1, 0x1E, 0x08, 0x14, 0x45, 0x05, 0x34, 0xD8, 0x5F, 0xA5, 0x28, - 0x5F, 0x77, 0xAA, 0x17, 0x0D, 0x71, 0xA7, 0xD4, 0x73, 0x19, 0xFE, 0x9E, 0x39, 0xE1, 0xD9, 0x0F, 0xAA, 0xEB, 0xE7, 0xC8, 0x60, 0xA3, 0xDC, 0x86, - 0xAC, 0xE6, 0xF1, 0x73, 0x1F, 0xE2, 0xBC, 0xD1, 0x8C, 0x9E, 0x0C, 0x4A, 0x5F, 0xD2, 0x66, 0x4C, 0x67, 0xE3, 0xA6, 0x63, 0xC1, 0xBB, 0xA2, 0x6A, - 0x03, 0xB4, 0xD1, 0x91, 0xC1, 0xD6, 0x90, 0xD1, 0xCB, 0x30, 0xAB, 0xD1, 0xED, 0xF9, 0x4F, 0xD1, 0x3C, 0x0E, 0x07, 0xA0, 0xFD, 0x6A, 0x61, 0x92, - 0xFE, 0x34, 0x83, 0x03, 0xA2, 0xBB, 0xAC, 0x12, 0xD4, 0x63, 0x8B, 0xAD, 0x5E, 0xF7, 0x0C, 0x99, 0x4D, 0x79, 0xCD, 0xE1, 0x40, 0xC9, 0xC3, 0xF2, - 0x3F, 0xFA, 0x37, 0x90, 0xD5, 0x2E, 0xD4, 0xBC, 0x20, 0x93, 0x62, 0xD0, 0x73, 0xC7, 0x16, 0xF3, 0x96, 0x79, 0x6A, 0xF4, 0xBC, 0x57, 0xBF, 0x0F, - 0x19, 0x51, 0xFA, 0x38, 0x55, 0xFA, 0x00, 0x0A, 0x30, 0x7F, 0x11, 0x60, 0x5F, 0xB5, 0xB4, 0x07, 0x69, 0xB0, 0x57, 0xE0, 0x41, 0xB3, 0xC2, 0xFC, - 0xFF, 0xAF, 0xFE, 0xEC, 0xCF, 0x36, 0xD1, 0xA5, 0x99, 0xAF, 0xF3, 0xCD, 0x09, 0xBC, 0x3D, 0xBA, 0xC9, 0x1D, 0x7F, 0x8F, 0x73, 0xED, 0xA7, 0x16, - 0xEC, 0x19, 0xAC, 0xF0, 0x3A, 0x48, 0xEF, 0x49, 0x7F, 0x8E, 0x56, 0x23, 0xB5, 0xAE, 0xDA, 0x53, 0x24, 0x83, 0x7A, 0xCE, 0x95, 0x04, 0xBB, 0xA6, - 0xF3, 0x30, 0xE9, 0xA6, 0xBF, 0x10, 0xE0, 0x68, 0x23, 0x58, 0x15, 0x6E, 0xA1, 0xB6, 0x55, 0xD7, 0xD7, 0x42, 0x4A, 0x9F, 0xEF, 0x38, 0xFF, 0xA5, - 0x8B, 0x20, 0x47, 0x2F, 0x8A, 0x19, 0x85, 0x86, 0xA8, 0x03, 0x03, 0x11, 0x12, 0x63, 0x49, 0x41, 0x92, 0x61, 0x0C, 0x03, 0xE8, 0x21, 0x8E, 0xA4, - 0x20, 0x04, 0x42, 0x51, 0x96, 0xA6, 0xD4, 0xD9, 0x01, 0x23, 0xF0, 0x60, 0xF7, 0x21, 0x84, 0xA2, 0x10, 0x06, 0x23, 0x11, 0x84, 0x81, 0x10, 0x83, - 0x14, 0x23, 0x44, 0x40, 0x04, 0xC4, 0x09, 0x09, 0x21, 0x86, 0x10, 0x66, 0x66, 0x68, 0x64, 0x1E, 0x08, 0xCF, 0x0B, 0x97, 0xFD, 0xF5, 0x94, 0x09, - 0xD2, 0xA8, 0xDA, 0xCD, 0x90, 0x5D, 0x79, 0x8D, 0xA8, 0xB1, 0x15, 0x48, 0x9A, 0x6A, 0xDA, 0x00, 0xD6, 0xFE, 0xDA, 0xF0, 0x63, 0x21, 0x88, 0xB5, - 0x0D, 0x86, 0x80, 0x18, 0x9D, 0x2D, 0x5F, 0x34, 0x66, 0x07, 0xEA, 0x69, 0x6F, 0x64, 0xE9, 0xD5, 0xB7, 0x85, 0xDC, 0x12, 0x75, 0xD8, 0x56, 0xEC, - 0xEA, 0x77, 0xD7, 0x2E, 0xBF, 0x3F, 0xA6, 0xFE, 0x0C, 0x07, 0x9A, 0x0F, 0xA1, 0xB8, 0xB1, 0x4D, 0x5A, 0xA2, 0x31, 0xBF, 0xFF, 0xF1, 0x0E, 0xC4, - 0x14, 0xDD, 0xE8, 0x9D, 0x8C, 0xE1, 0x48, 0x33, 0x20, 0x14, 0x7E, 0x13, 0x6A, 0x2A, 0x38, 0x91, 0x7D, 0xC3, 0x2D, 0x5A, 0xE3, 0x6A, 0x66, 0xE2, - 0x3E, 0x90, 0x8E, 0x89, 0xA1, 0x05, 0xE7, 0x47, 0x05, 0x2F, 0x06, 0x46, 0x9C, 0x7D, 0xFD, 0x23, 0x72, 0x06, 0xE3, 0x7E, 0x2B, 0x30, 0x64, 0xE2, - 0x5C, 0xF8, 0xA2, 0x29, 0x3F, 0xCC, 0xAF, 0x60, 0x88, 0x3C, 0x9E, 0x02, 0x32, 0xCB, 0x62, 0x46, 0xA6, 0x1D, 0xA8, 0xC7, 0xA8, 0x9C, 0xBB, 0xFD, - 0x46, 0xEC, 0xCB, 0x19, 0x8B, 0x23, 0xA8, 0xD9, 0xF4, 0x4F, 0x34, 0xC3, 0x03, 0xE6, 0x1F, 0x82, 0x63, 0x66, 0x1A, 0x72, 0xC0, 0xBE, 0xA1, 0x1D, - 0x2F, 0x70, 0x5B, 0xE0, 0xF8, 0x48, 0xAF, 0xCB, 0xFA, 0x4C, 0x68, 0x27, 0x6E, 0x4F, 0x98, 0x30, 0x79, 0x45, 0xB7, 0xF9, 0xED, 0xBF, 0x63, 0x61, - 0x4E, 0xB4, 0x73, 0x26, 0xB3, 0xEF, 0x1A, 0x6B, 0x44, 0x66, 0x05, 0x79, 0x15, 0xC0, 0xBC, 0xAC, 0x8D, 0x2A, 0x9E, 0xD5, 0x5D, 0xCC, 0x62, 0x7B, - 0xD0, 0xA9, 0x90, 0x3B, 0x6A, 0x47, 0xBC, 0x5D, 0x5A, 0x18, 0x1A, 0xE0, 0x60, 0x77, 0x69, 0x96, 0x41, 0x64, 0xF6, 0x05, 0xE0, 0x85, 0x16, 0xFF, - 0x79, 0xEC, 0xCA, 0xEF, 0xC5, 0xD9, 0x72, 0xF2, 0xB3, 0x42, 0x2F, 0x3A, 0x68, 0x12, 0xF1, 0x2A, 0xA7, 0xC4, 0xA0, 0xCC, 0x3E, 0x44, 0x6C, 0x8C, - 0x65, 0x3E, 0xF0, 0x90, 0x3B, 0xC4, 0x96, 0x42, 0x94, 0x3D, 0x5F, 0xC8, 0x7C, 0xC4, 0x56, 0x12, 0x72, 0xE1, 0x42, 0x5A, 0x1B, 0x8E, 0xA7, 0x6D, - 0x3A, 0xB9, 0x42, 0xBB, 0x79, 0x1D, 0xBB, 0xDC, 0x71, 0x75, 0x4B, 0xC3, 0x43, 0x6C, 0x2B, 0x80, 0x5A, 0x64, 0x03, 0x23, 0xA3, 0xA3, 0x2C, 0x46, - 0x14, 0x36, 0x8B, 0x28, 0x21, 0xB7, 0xB4, 0x50, 0x43, 0xC3, 0xB8, 0x30, 0x9E, 0xB7, 0xA3, 0x36, 0x45, 0x6B, 0xBB, 0xCE, 0x5D, 0x25, 0x68, 0x28, - 0x46, 0x2B, 0x65, 0x7B, 0x08, 0x73, 0x40, 0x77, 0xDC, 0xE3, 0x32, 0x83, 0xCB, 0x05, 0x0F, 0x8E, 0x9C, 0x9B, 0x65, 0xA1, 0x9F, 0x68, 0xC4, 0xB3, - 0x68, 0x56, 0x8D, 0x5A, 0xBC, 0xE2, 0x71, 0xC9, 0x13, 0x7A, 0x20, 0x4C, 0x55, 0xE4, 0x7E, 0xAC, 0xDF, 0x6D, 0x3F, 0xDB, 0x7F, 0x3D, 0x8B, 0x70, - 0x74, 0x1F, 0xA6, 0xDA, 0x8E, 0x35, 0xDA, 0x38, 0x16, 0x38, 0x26, 0x42, 0xDD, 0xD0, 0x8D, 0x8F, 0x5C, 0xED, 0x64, 0xB8, 0x20, 0x49, 0xBC, 0x3B, - 0x0D, 0xF1, 0x7D, 0x18, 0xC0, 0x8D, 0xEA, 0xB4, 0x8C, 0x35, 0xFA, 0x02, 0xB6, 0xF6, 0x1E, 0x28, 0x58, 0xD4, 0xD2, 0x3E, 0x80, 0xC3, 0xF1, 0x91, - 0x66, 0xFD, 0x67, 0x3D, 0x66, 0x1E, 0x6A, 0x5E, 0x65, 0x1E, 0xE5, 0x9D, 0xF4, 0x3E, 0x7D, 0xFC, 0x23, 0x92, 0x58, 0x70, 0x7F, 0x9C, 0x07, 0x1A, - 0x31, 0xBE, 0x52, 0x5C, 0x58, 0x7C, 0xE2, 0x7A, 0x4E, 0x3E, 0x86, 0xAD, 0x15, 0xC2, 0x85, 0xE0, 0xEB, 0xD4, 0x42, 0xFE, 0x04, 0x26, 0x4D, 0x33, - 0x28, 0x62, 0x09, 0xF8, 0x6E, 0xE2, 0x10, 0xF6, 0xED, 0x7E, 0x0C, 0x74, 0x14, 0xAE, 0xAC, 0x31, 0x78, 0x9C, 0x85, 0xFF, 0x89, 0x51, 0x38, 0xD4, - 0x7D, 0x3F, 0x98, 0xB5, 0xF2, 0x4A, 0x66, 0x84, 0xCB, 0x21, 0xE8, 0xBB, 0x46, 0x8B, 0x30, 0x3D, 0x09, 0x45, 0x62, 0x20, 0x23, 0xAE, 0x4D, 0xA8, - 0xE7, 0x62, 0x8C, 0xD9, 0xF5, 0xEC, 0x23, 0x0A, 0x66, 0x41, 0xE1, 0x22, 0x91, 0x04, 0x9B, 0xAD, 0x8F, 0x14, 0xF0, 0xF1, 0x01, 0xE2, 0xA5, 0xCB, - 0x0D, 0xBB, 0x3D, 0xF8, 0x49, 0xAB, 0xE0, 0xE9, 0x7C, 0x40, 0x74, 0xBF, 0x91, 0x95, 0x63, 0x6C, 0xA5, 0x5D, 0xB4, 0x70, 0xF0, 0xE0, 0x02, 0xDB, - 0x8F, 0x4A, 0x66, 0xD4, 0xD0, 0x37, 0xF3, 0x96, 0x3A, 0x4A, 0xE4, 0xF9, 0xA2, 0xEE, 0xD3, 0x9D, 0x35, 0x81, 0x41, 0x31, 0x85, 0x3D, 0x93, 0x3B, - 0x04, 0x63, 0x1C, 0x80, 0xBF, 0x3B, 0x5D, 0xB7, 0x1A, 0xC4, 0x71, 0xF5, 0xCE, 0xB2, 0xF5, 0x5D, 0xB2, 0xB7, 0xFF, 0xE5, 0x16, 0x87, 0xB7, 0x7C, - 0x40, 0x7B, 0x77, 0xCC, 0x45, 0x0D, 0x97, 0xCC, 0x9C, 0x4F, 0xFA, 0x7D, 0x52, 0x0B, 0x2E, 0x17, 0x7E, 0x77, 0x92, 0xF0, 0x8B, 0xA2, 0x47, 0xBB, - 0x21, 0x9D, 0xD9, 0xB4, 0xEF, 0x5E, 0x9D, 0xE1, 0xFC, 0xCB, 0x2B, 0x34, 0x31, 0x04, 0x56, 0x01, 0xE9, 0x19, 0x45, 0x21, 0x74, 0x8C, 0xBA, 0x3E, - 0xE0, 0x77, 0x6D, 0x06, 0x7B, 0x5B, 0x63, 0xC1, 0x06, 0xAD, 0x53, 0xAC, 0x09, 0xFD, 0xAD, 0x06, 0x1B, 0xC7, 0x73, 0x92, 0x6E, 0x7C, 0xD9, 0x37, - 0x5C, 0x11, 0x76, 0x6C, 0x81, 0xF3, 0xB4, 0xC4, 0x3D, 0x8A, 0x5E, 0xE7, 0xB8, 0x4C, 0x6D, 0xE3, 0xFC, 0x91, 0xB8, 0x44, 0x91, 0xA7, 0x2F, 0x55, - 0xD1, 0x01, 0x0F, 0x1F, 0x96, 0x51, 0xB6, 0xD9, 0x4B, 0xE5, 0x3B, 0xB3, 0xB4, 0xE5, 0x89, 0x7C, 0x76, 0x8B, 0xE6, 0xAD, 0x24, 0xAF, 0x1F, 0xBC, - 0x91, 0x3E, 0x48, 0x1F, 0xD4, 0x15, 0xC5, 0xB4, 0x12, 0xF6, 0x3F, 0xD9, 0x61, 0xED, 0x30, 0x48, 0x5D, 0x60, 0xD9, 0xB1, 0x63, 0x58, 0xD8, 0xDD, - 0x3F, 0x9C, 0x96, 0x7C, 0x00, 0x98, 0xE7, 0x45, 0xF0, 0xCE, 0x40, 0x22, 0x93, 0xB8, 0xEF, 0x38, 0x8F, 0x05, 0xDF, 0x64, 0xCA, 0xB4, 0xCB, 0x46, - 0x04, 0x99, 0x7D, 0xDE, 0xC4, 0xDA, 0xE7, 0x30, 0x02, 0x06, 0x9C, 0xCD, 0xEB, 0x31, 0x81, 0xD2, 0xBC, 0x9E, 0x10, 0x7D, 0x20, 0x3C, 0xAB, 0xBC, - 0x61, 0xFB, 0x87, 0x25, 0x8E, 0xDB, 0xD8, 0x78, 0x84, 0x59, 0x6C, 0xCD, 0x58, 0x85, 0x6A, 0x43, 0x9B, 0xF8, 0x26, 0xB9, 0xA2, 0x2E, 0x31, 0x31, - 0x6F, 0x6C, 0xBA, 0x36, 0xD5, 0xBA, 0xB5, 0xB0, 0xD3, 0x8E, 0xCA, 0x3E, 0xC3, 0x2C, 0x57, 0x00, 0xAC, 0x9A, 0x1A, 0xD5, 0x14, 0xFF, 0x40, 0x75, - 0x60, 0x64, 0x47, 0x6C, 0xDB, 0x5D, 0x39, 0x1F, 0x03, 0x4D, 0x23, 0xD9, 0x26, 0x27, 0x4D, 0x80, 0x06, 0xFB, 0x3A, 0x15, 0x7B, 0x1F, 0x70, 0x8D, - 0x5D, 0x49, 0x97, 0x08, 0x0D, 0x0C, 0xFF, 0x32, 0x88, 0x4C, 0xFC, 0x1C, 0x91, 0x0C, 0xFB, 0x33, 0xFE, 0x1E, 0x3B, 0xC3, 0x86, 0x49, 0x8A, 0xF0, - 0xC8, 0x5B, 0x75, 0x75, 0x7F, 0xBB, 0xCC, 0x9A, 0x53, 0x63, 0xBE, 0xD0, 0x9E, 0xCD, 0x5F, 0xEF, 0xD8, 0x1C, 0x5B, 0x0D, 0x69, 0xE3, 0xB4, 0x81, - 0xF9, 0x0C, 0xA2, 0xE3, 0x1C, 0x94, 0xB7, 0xE9, 0x15, 0x33, 0xB2, 0xDD, 0xEB, 0x71, 0xAD, 0x59, 0x66, 0xB6, 0xF6, 0x7A, 0x2C, 0x19, 0x09, 0xC1, - 0xF1, 0xCD, 0xC4, 0x8E, 0x11, 0xAD, 0x37, 0x65, 0xA5, 0xDE, 0x74, 0xE8, 0xEB, 0xFD, 0x56, 0xC9, 0x41, 0xC8, 0x5B, 0x1E, 0x8F, 0x0D, 0xB1, 0xC9, - 0x2C, 0x4B, 0x57, 0x52, 0x6D, 0x9B, 0xEB, 0x82, 0xA9, 0xAA, 0xDE, 0x8B, 0xC9, 0xA4, 0x28, 0xCE, 0xD1, 0xD5, 0x8A, 0x4B, 0xC4, 0x13, 0x91, 0x90, - 0xFF, 0x79, 0x4B, 0xC8, 0x9B, 0x45, 0xD7, 0x1E, 0x16, 0x6C, 0xFE, 0x6D, 0x94, 0x59, 0x6D, 0x3C, 0x07, 0x56, 0x30, 0x8A, 0x5E, 0x3A, 0x54, 0x83, - 0xB4, 0x5A, 0x97, 0x9D, 0xFD, 0x94, 0x87, 0x6E, 0x7D, 0x2A, 0x5E, 0x1D, 0x0E, 0xB3, 0x48, 0xAF, 0xE2, 0x43, 0x0D, 0xF2, 0x5B, 0x8B, 0xD1, 0x0A, - 0xA7, 0xCD, 0xB3, 0xF8, 0x20, 0x08, 0x6E, 0xDC, 0xE5, 0xBE, 0x80, 0xDB, 0xC8, 0x58, 0xFB, 0x61, 0xEC, 0x89, 0x6B, 0x7F, 0x8B, 0x00, 0xC8, 0x0B, - 0x7F, 0xDA, 0xC7, 0x38, 0x6B, 0xC2, 0x76, 0x3D, 0x1A, 0x4B, 0x84, 0xD9, 0xE0, 0x64, 0x99, 0xD5, 0x2D, 0xFE, 0x39, 0xD9, 0x1C, 0xA9, 0xAB, 0x43, - 0x96, 0xBF, 0xB4, 0x43, 0xEF, 0xD9, 0xF3, 0xF8, 0xA8, 0xDF, 0xF8, 0x88, 0xDF, 0xB2, 0x56, 0x17, 0xA9, 0xC0, 0x34, 0xA1, 0xC6, 0xD1, 0xDD, 0x0D, - 0xAD, 0x50, 0x1F, 0xB7, 0x8F, 0x08, 0x90, 0x7E, 0x63, 0xDB, 0x42, 0x92, 0x2D, 0x1A, 0xC5, 0xDB, 0xB7, 0x53, 0xB6, 0xE8, 0x9A, 0x71, 0x5C, 0xF4, - 0xD6, 0xF1, 0x99, 0x44, 0xC7, 0xDF, 0x71, 0xA1, 0x6F, 0xB3, 0x64, 0xA2, 0x98, 0x42, 0xF5, 0x8B, 0xDF, 0x42, 0x66, 0xB4, 0xB1, 0x62, 0xF1, 0x2C, - 0x78, 0x9D, 0x1C, 0x98, 0x8B, 0xB7, 0x76, 0xDB, 0xD4, 0xD0, 0xDA, 0x76, 0x20, 0xB0, 0xE6, 0xD4, 0xFB, 0x3C, 0x8A, 0xB9, 0xEB, 0x53, 0xA0, 0xCF, - 0xCD, 0xF9, 0xF6, 0x45, 0x24, 0x5A, 0xC2, 0xE8, 0x20, 0x62, 0xA2, 0x9D, 0x1D, 0x83, 0x5F, 0xAF, 0x79, 0x47, 0x3F, 0x8C, 0x67, 0x33, 0xB8, 0x90, - 0x2C, 0xA6, 0xA3, 0xA8, 0xE1, 0x43, 0xC1, 0xFF, 0xC5, 0x4F, 0x06, 0xF7, 0xCC, 0x1E, 0x0A, 0x6D, 0xFD, 0x6E, 0xCF, 0x5A, 0xC8, 0x15, 0x61, 0x50, - 0x1F, 0xA1, 0xA0, 0xCC, 0x88, 0x00, 0x13, 0xBA, 0x00, 0x1B, 0x5F, 0x58, 0xCE, 0x02, 0x5D, 0x7A, 0x80, 0xBC, 0x1F, 0x7A, 0xF1, 0x65, 0x4B, 0x4F, - 0x65, 0x2D, 0x8A, 0xA1, 0xB0, 0xAC, 0x56, 0xE2, 0x74, 0xC9, 0x31, 0x8E, 0x06, 0xFB, 0xA7, 0x38, 0xA3, 0xE5, 0x90, 0xA3, 0xFB, 0x34, 0x4D, 0x0C, - 0xE1, 0xB2, 0x77, 0xBC, 0x39, 0xCE, 0x2D, 0x85, 0xC2, 0x45, 0x6D, 0x0E, 0x1E, 0x26, 0x2C, 0xFC, 0x3E, 0xDC, 0x37, 0x55, 0x83, 0x4C, 0x6E, 0x3A, - 0xFA, 0x6E, 0x97, 0xF2, 0x90, 0xB8, 0x97, 0x9C, 0x4B, 0x7B, 0x79, 0x9D, 0xF9, 0x5E, 0x3E, 0x58, 0x8F, 0x20, 0xF1, 0x02, 0xEA, 0xAA, 0x25, 0x10, - 0x36, 0xC3, 0x78, 0x69, 0x8C, 0x13, 0xEE, 0xF1, 0xE0, 0xED, 0x61, 0xC1, 0xBD, 0x01, 0x18, 0xC7, 0x76, 0xFA, 0xE7, 0x05, 0x2E, 0xB7, 0x9F, 0x23, - 0xFC, 0xEC, 0x81, 0x29, 0xE1, 0x30, 0xE0, 0x69, 0xDE, 0x85, 0x75, 0xB0, 0xBD, 0xB5, 0x4C, 0xC0, 0x3C, 0x4D, 0xD1, 0x93, 0x5F, 0xA2, 0x71, 0x9E, - 0x5B, 0x99, 0x3B, 0xBF, 0x3B, 0x92, 0xAE, 0x62, 0x4A, 0x28, 0x03, 0x63, 0x45, 0x2D, 0x62, 0xC4, 0xBB, 0xBE, 0xB9, 0xF6, 0x81, 0x42, 0xC9, 0x10, - 0x13, 0x11, 0x11, 0x10, 0xE1, 0xA3, 0xF2, 0x92, 0x5F, 0xD6, 0x43, 0xD9, 0x36, 0xCE, 0x0F, 0x5B, 0x0F, 0x4C, 0xE1, 0xD8, 0xE8, 0xF8, 0x17, 0x49, - 0x18, 0x08, 0xEE, 0x9E, 0xB4, 0xAF, 0xB1, 0x4A, 0x69, 0xCB, 0xCE, 0x59, 0x8E, 0x1D, 0x53, 0x98, 0x33, 0x35, 0xF0, 0x39, 0x9F, 0x1A, 0x32, 0x8A, - 0x66, 0x3D, 0xCD, 0xFB, 0xD0, 0xA3, 0x41, 0x72, 0xCE, 0x68, 0xE0, 0xFE, 0x8A, 0x8A, 0x66, 0xAC, 0x6E, 0x9B, 0xF9, 0x59, 0x87, 0x19, 0x98, 0x23, - 0x31, 0x06, 0xE8, 0x2A, 0x0C, 0xE2, 0x1D, 0x0D, 0x01, 0x9D, 0x55, 0x35, 0x59, 0x2C, 0xEF, 0x1B, 0xB0, 0xAA, 0xCB, 0xDF, 0x69, 0x81, 0x02, 0x22, - 0x15, 0x84, 0xE1, 0x54, 0x9D, 0x1E, 0xFF, 0xAB, 0xA3, 0xCC, 0x87, 0x24, 0x0D, 0x8C, 0x03, 0x1C, 0xB5, 0xEE, 0xDE, 0xD4, 0xE0, 0xCD, 0xBF, 0xB0, - 0x39, 0x97, 0xE0, 0xBE, 0xD9, 0x1D, 0x51, 0x11, 0x7B, 0xCC, 0x73, 0xEC, 0xD7, 0xCC, 0x92, 0x70, 0x82, 0xC4, 0x2D, 0xDB, 0xBD, 0x2A, 0xCC, 0xA3, - 0xCB, 0x6E, 0x88, 0xF0, 0x1F, 0xAA, 0x80, 0xF2, 0x7B, 0xCB, 0x92, 0x7D, 0x80, 0x1E, 0x73, 0x88, 0x28, 0x7C, 0x89, 0xD2, 0x0A, 0x3B, 0xBD, 0x09, - 0xC4, 0x19, 0xA6, 0x31, 0x18, 0x74, 0x78, 0x90, 0x8B, 0xC5, 0xB6, 0x47, 0x8E, 0x03, 0xFE, 0x37, 0x15, 0x1D, 0x0A, 0x7A, 0x26, 0x1C, 0xEC, 0x74, - 0x9F, 0x76, 0x39, 0x6E, 0x8B, 0x32, 0xE1, 0x51, 0x54, 0x26, 0x0D, 0x06, 0x6E, 0xF4, 0x3D, 0x6C, 0x50, 0x32, 0x07, 0xB5, 0x44, 0x8C, 0x83, 0x48, - 0x46, 0x35, 0x09, 0x72, 0x93, 0xA5, 0x3C, 0x86, 0xF8, 0x3F, 0x73, 0x08, 0x04, 0xE3, 0x1F, 0x8F, 0xD0, 0xE3, 0xEA, 0x8A, 0xA4, 0xB0, 0x64, 0x19, - 0x85, 0x7A, 0xF0, 0x79, 0x0E, 0x2D, 0x49, 0x88, 0x3D, 0x54, 0x10, 0xAA, 0xA1, 0x7D, 0xED, 0xE9, 0xE1, 0xDD, 0xCB, 0x4D, 0x33, 0x7D, 0x14, 0x31, - 0x6E, 0x3B, 0x6E, 0xB1, 0xDE, 0xB3, 0x28, 0x23, 0xC9, 0xE9, 0xC9, 0x35, 0xC5, 0x4C, 0xDB, 0xC2, 0x9E, 0xF1, 0x3A, 0xDB, 0x6D, 0xDC, 0x0A, 0xDD, - 0x76, 0xBB, 0xAA, 0xC8, 0x9B, 0xA9, 0x83, 0x18, 0xB2, 0x1B, 0xD9, 0x8B, 0xC1, 0x12, 0x34, 0x40, 0xC3, 0xEE, 0x64, 0x3A, 0xC5, 0xC5, 0x76, 0xAB, - 0xA2, 0xCB, 0x69, 0x6C, 0xE6, 0xB4, 0xCD, 0xBE, 0xCB, 0xE9, 0x57, 0xDB, 0xE3, 0x93, 0xFF, 0x5E, 0x08, 0xCD, 0x8A, 0x16, 0x48, 0x16, 0xD4, 0x42, - 0x6D, 0xC6, 0x4D, 0xEC, 0xB3, 0x19, 0x3D, 0x5A, 0x8C, 0x9A, 0x90, 0xB2, 0x20, 0x2F, 0xD7, 0xB3, 0x17, 0xDE, 0x3F, 0x33, 0xFB, 0x7A, 0x77, 0x45, - 0xF2, 0x99, 0x0D, 0x17, 0x4E, 0x5B, 0x03, 0xD1, 0xE7, 0xDE, 0x63, 0x9F, 0xA1, 0xF7, 0xE6, 0xE8, 0x79, 0xC5, 0x4D, 0x98, 0x5D, 0x58, 0x67, 0x79, - 0xC9, 0x8F, 0xFE, 0xDF, 0xAB, 0xA6, 0xDC, 0xFD, 0x16, 0xE6, 0x9B, 0xFC, 0xA5, 0x56, 0x8B, 0x9F, 0xAD, 0x3D, 0xB8, 0x88, 0x50, 0xBB, 0x8C, 0xB0, - 0xD9, 0xE1, 0xE3, 0x67, 0x9B, 0x00, 0x9F, 0xAE, 0xE5, 0x54, 0x3F, 0x29, 0x26, 0xBF, 0x0C, 0xB5, 0x62, 0x94, 0xAD, 0x4C, 0x4E, 0xDE, 0x5D, 0xBD, - 0x64, 0xC9, 0x6D, 0xCB, 0x07, 0x74, 0x62, 0x6C, 0x1F, 0x58, 0x81, 0xAA, 0xF1, 0xB6, 0xE8, 0x4B, 0x13, 0x84, 0x47, 0x6A, 0xBB, 0xD6, 0xF9, 0x51, - 0x9C, 0xF8, 0x66, 0xCF, 0x3D, 0x7E, 0x91, 0x84, 0x3D, 0xB0, 0x9F, 0x52, 0x0B, 0x4B, 0xA8, 0x39, 0x5A, 0xA7, 0x37, 0x69, 0x8E, 0x20, 0xCF, 0x89, - 0xC7, 0x4E, 0x9C, 0xCA, 0xF9, 0x23, 0x76, 0xB7, 0xC0, 0x0E, 0x3F, 0xFF, 0x52, 0x83, 0x68, 0x84, 0xD5, 0xEB, 0x04, 0xF3, 0x20, 0x14, 0xD3, 0x89, - 0x13, 0xB9, 0x1D, 0x3E, 0x50, 0xD3, 0xAD, 0x12, 0x59, 0x90, 0x7C, 0xBF, 0xFD, 0xB5, 0x57, 0x16, 0xF0, 0x14, 0xDB, 0xCC, 0xD4, 0xD1, 0x46, 0x64, - 0x99, 0x48, 0x62, 0x1E, 0x3B, 0x01, 0x24, 0x4B, 0x9C, 0xDF, 0x7E, 0x44, 0x1B, 0xE4, 0xA0, 0xFF, 0x8B, 0x18, 0x90, 0xA9, 0x68, 0x69, 0x9B, 0xDE, - 0xD1, 0x7A, 0x43, 0x60, 0x3C, 0x80, 0x6E, 0x13, 0xC2, 0xBF, 0xDC, 0x1B, 0x1D, 0xFD, 0xBF, 0x41, 0x69, 0xA8, 0x41, 0xFB, 0xA5, 0x19, 0x27, 0xB6, - 0xC6, 0x30, 0x55, 0xD9, 0x7B, 0xE7, 0x5C, 0xDE, 0xA4, 0x8B, 0x71, 0xB2, 0x80, 0x80, 0x22, 0xC2, 0xC1, 0x02, 0x02, 0x0A, 0x20, 0x3E, 0x83, 0x70, - 0x67, 0x6B, 0x88, 0xA9, 0xA2, 0x1C, 0x2D, 0x21, 0xA2, 0x8A, 0x0A, 0xCE, 0x0E, 0xE0, 0xB2, 0x0A, 0x8F, 0x1C, 0xF1, 0xBB, 0x2D, 0x30, 0x1F, 0xBB, - 0x3E, 0x1E, 0x66, 0x82, 0xA7, 0xFB, 0x0E, 0xF5, 0xE1, 0xA3, 0x28, 0xCF, 0xB1, 0xB6, 0x45, 0x69, 0x74, 0x0A, 0x6D, 0xF6, 0x3D, 0x91, 0x29, 0x20, - 0xD9, 0x30, 0x07, 0x35, 0x1D, 0xF1, 0x02, 0xA9, 0xEC, 0x91, 0x52, 0xBB, 0xD2, 0xE4, 0x81, 0xEB, 0xF2, 0x1D, 0x0C, 0xB5, 0x2C, 0x83, 0xAF, 0x3B, - 0xED, 0xF3, 0x26, 0x05, 0x9E, 0x30, 0xF8, 0xC9, 0x07, 0x5B, 0x89, 0x73, 0xDE, 0xC3, 0x31, 0xBE, 0x91, 0x01, 0x55, 0x1F, 0xA7, 0x1D, 0x98, 0x32, - 0xF8, 0xB6, 0x04, 0x05, 0xB7, 0xB2, 0xBB, 0x72, 0x7C, 0x5D, 0x6F, 0x65, 0x99, 0x53, 0x0B, 0xC2, 0xF2, 0xF1, 0xDA, 0xA6, 0x15, 0xFC, 0xD6, 0x68, - 0xF1, 0xC2, 0x09, 0xD9, 0xEC, 0x5A, 0x58, 0x31, 0x18, 0x23, 0xDA, 0x2A, 0x1F, 0x3F, 0xD8, 0xDA, 0x19, 0xC0, 0xD6, 0xC7, 0xE9, 0x52, 0x98, 0x5A, - 0x0B, 0x67, 0xE6, 0x9C, 0xE7, 0x21, 0x5A, 0x55, 0x41, 0x76, 0xE6, 0x87, 0x45, 0x72, 0xC6, 0xDC, 0x5B, 0x34, 0xB2, 0xF9, 0x3F, 0x85, 0x41, 0xE2, - 0x1E, 0x60, 0x46, 0xC8, 0x96, 0xE6, 0x41, 0x0A, 0x85, 0x9C, 0xC9, 0xC6, 0xB1, 0x38, 0xB5, 0x26, 0x8B, 0x2F, 0xE7, 0xD9, 0x3E, 0xE1, 0xA9, 0xA8, - 0x72, 0x33, 0xF5, 0xE1, 0x1D, 0x4A, 0x60, 0xC9, 0x24, 0x43, 0xCB, 0xC4, 0x60, 0x26, 0xD6, 0xD9, 0xC3, 0x68, 0xDE, 0xFA, 0x90, 0xCF, 0xF2, 0x26, - 0x60, 0x1F, 0x96, 0x69, 0xCD, 0x66, 0x5D, 0xDA, 0x6D, 0x8C, 0xA1, 0x75, 0x04, 0x57, 0x6C, 0xC2, 0xAF, 0x31, 0x6D, 0x99, 0x77, 0x93, 0x95, 0xDF, - 0x0F, 0x43, 0x89, 0x67, 0x88, 0x46, 0x99, 0xE0, 0x90, 0x44, 0xEB, 0xA3, 0xD4, 0xD3, 0xA4, 0x7D, 0x82, 0x61, 0x9B, 0xCD, 0xFB, 0x2C, 0x04, 0x19, - 0x3F, 0x71, 0x63, 0xB1, 0x99, 0x26, 0xA6, 0x6D, 0x41, 0x43, 0x58, 0x4A, 0x73, 0xBE, 0xB6, 0x63, 0xBF, 0xD9, 0x56, 0xD5, 0x98, 0x2C, 0x21, 0x09, - 0x89, 0x6B, 0xE2, 0xCD, 0x53, 0xAA, 0xA5, 0xAA, 0x29, 0x23, 0x80, 0x81, 0x3F, 0x3D, 0x7F, 0xCB, 0x37, 0xB0, 0xF4, 0xD5, 0x09, 0xC6, 0x19, 0x96, - 0xE9, 0x38, 0x3E, 0x28, 0xB1, 0x2B, 0x0A, 0x01, 0x7E, 0xF1, 0x30, 0x43, 0x13, 0x64, 0x2D, 0x00, 0x57, 0xB4, 0xCF, 0xCF, 0x00, 0xD1, 0x00, 0xCD, - 0x00, 0x12, 0x66, 0xE3, 0x16, 0x08, 0xF1, 0x82, 0xCA, 0x71, 0x13, 0x9A, 0xF8, 0x48, 0xDA, 0xFC, 0x67, 0x6D, 0xEB, 0x72, 0xDE, 0x19, 0x15, 0xC2, - 0x08, 0xC0, 0x18, 0x9F, 0x93, 0x2A, 0xFF, 0xBF, 0xD5, 0x1C, 0x46, 0xD8, 0x5D, 0x8E, 0xC2, 0x33, 0xA4, 0xB0, 0x7F, 0x05, 0x40, 0xEB, 0x1A, 0x49, - 0xAE, 0xDF, 0x48, 0xF5, 0x53, 0x40, 0x83, 0xD0, 0xA4, 0xCA, 0x93, 0xE4, 0xFA, 0x57, 0x6A, 0xF6, 0xBA, 0xCF, 0xFE, 0xF9, 0xF6, 0x7F, 0xB3, 0x84, - 0xB2, 0xF4, 0xD6, 0x1E, 0x04, 0xA8, 0x53, 0x47, 0x72, 0x3A, 0x62, 0xC4, 0x7A, 0x98, 0x8E, 0xCF, 0x9A, 0x66, 0x3D, 0xF3, 0x87, 0x7F, 0x30, 0x47, - 0x87, 0xA1, 0xE5, 0x3F, 0x9C, 0xC5, 0xCA, 0x6D, 0xBA, 0x5A, 0xB6, 0x92, 0x46, 0x7B, 0x4E, 0xAE, 0x8A, 0xB1, 0xA3, 0x7A, 0x31, 0x99, 0x7A, 0x02, - 0x21, 0xD5, 0xF4, 0x8E, 0x52, 0x9B, 0x84, 0xA7, 0x79, 0x41, 0xE1, 0xB5, 0x3E, 0x31, 0x10, 0x72, 0x22, 0xDC, 0x37, 0x79, 0xF8, 0x62, 0xEA, 0x1C, - 0x59, 0x92, 0x4C, 0xA0, 0x04, 0x7B, 0x9C, 0xE4, 0xBA, 0x01, 0x49, 0x99, 0x04, 0x06, 0xE3, 0x51, 0xCA, 0x8F, 0xD1, 0x07, 0x87, 0xA2, 0xA3, 0x2D, - 0x22, 0x9E, 0x14, 0x43, 0x65, 0x72, 0x42, 0x5A, 0xA5, 0xEF, 0x04, 0x5D, 0x41, 0x06, 0x7E, 0x81, 0x38, 0x1C, 0xF8, 0xD9, 0xA0, 0xE1, 0xE3, 0xC8, - 0xD7, 0x93, 0xA2, 0x86, 0x27, 0x55, 0x71, 0xE7, 0x73, 0x43, 0x87, 0x38, 0x34, 0x67, 0xD7, 0x26, 0x38, 0x01, 0xD6, 0x0F, 0x46, 0xD4, 0x56, 0x3F, - 0x84, 0xCF, 0xF4, 0x00, 0xB3, 0x69, 0x75, 0x8C, 0x34, 0x54, 0xCE, 0xB3, 0xE0, 0x37, 0x3E, 0x62, 0x1E, 0x46, 0xE2, 0xFC, 0x79, 0x20, 0x3E, 0xA4, - 0x0F, 0xFA, 0xA3, 0x1F, 0x2E, 0x00, 0xBA, 0xA1, 0xA8, 0x00, 0xD6, 0x02, 0xD6, 0x5B, 0x6B, 0xAD, 0x75, 0xD2, 0x87, 0xE4, 0x2F, 0xA2, 0xBE, 0xBB, - 0xC0, 0x38, 0x56, 0x46, 0xE3, 0x5F, 0x90, 0xAC, 0xF2, 0xA1, 0xAF, 0x44, 0xE4, 0xA2, 0x2B, 0xE2, 0xE5, 0xEB, 0xE3, 0xB5, 0x5C, 0x0E, 0x35, 0x96, - 0xD7, 0x01, 0xA2, 0xA2, 0x69, 0x4A, 0xC8, 0x02, 0x70, 0x19, 0xD1, 0xD0, 0xDA, 0x67, 0xD1, 0xA3, 0x11, 0x80, 0xCC, 0x60, 0x5C, 0x90, 0xE0, 0x2A, - 0x2B, 0x2A, 0x1D, 0xC3, 0x34, 0x30, 0x36, 0xF6, 0x2B, 0xAF, 0x8D, 0x90, 0x0F, 0x3B, 0x60, 0xEA, 0x9C, 0x18, 0xB7, 0xA0, 0xE2, 0xAB, 0x05, 0xD4, - 0xCB, 0x04, 0x6A, 0x17, 0x5D, 0x14, 0xD7, 0xA7, 0xB0, 0x0A, 0x92, 0xAD, 0x12, 0x1F, 0xFD, 0x8A, 0xDB, 0x24, 0x9B, 0x22, 0x59, 0x67, 0x26, 0x15, - 0x3D, 0x89, 0x13, 0x48, 0x3C, 0x4C, 0x65, 0xDE, 0xCE, 0x2B, 0x7A, 0x04, 0x1E, 0x12, 0x59, 0x86, 0x12, 0xA8, 0x3D, 0x6C, 0x44, 0x3C, 0xC1, 0x58, - 0xF9, 0x0A, 0x60, 0xF0, 0xDE, 0xBB, 0xFC, 0x8B, 0x29, 0xF8, 0xB3, 0x3C, 0xCE, 0x06, 0x77, 0xC1, 0x8B, 0xF7, 0x50, 0x80, 0x33, 0x0D, 0xC6, 0xB7, - 0x4A, 0xC0, 0x05, 0x60, 0xC6, 0x0F, 0x64, 0xC2, 0x03, 0x24, 0xBE, 0x94, 0xBF, 0x05, 0x3C, 0x48, 0x4C, 0x0B, 0xDC, 0x46, 0x31, 0xE3, 0x1D, 0xA9, - 0x64, 0xF8, 0x1C, 0x2E, 0x3A, 0xFE, 0x5A, 0x2D, 0x97, 0xC7, 0x48, 0xB4, 0x34, 0x34, 0xC0, 0x65, 0x68, 0x39, 0x78, 0x57, 0x32, 0xB3, 0x08, 0x3C, - 0x95, 0x53, 0x0F, 0x26, 0x3D, 0xFC, 0xED, 0xC9, 0x88, 0x50, 0x60, 0x42, 0x12, 0x17, 0x96, 0x86, 0x7A, 0x0D, 0xB5, 0x56, 0x19, 0xD4, 0xFB, 0x38, - 0x18, 0x59, 0xB5, 0xAA, 0x80, 0x77, 0xB4, 0xE2, 0xDE, 0xF8, 0x6C, 0x12, 0xF7, 0x2F, 0x02, 0xF5, 0xF7, 0xD9, 0xAF, 0xB8, 0x8E, 0x36, 0xC4, 0xC1, - 0xF5, 0x5C, 0xE2, 0xAD, 0x25, 0x23, 0xA5, 0xC2, 0x1F, 0x72, 0x4F, 0x62, 0x23, 0xBB, 0x52, 0xB3, 0x88, 0x92, 0x0F, 0xF9, 0x97, 0x22, 0x00, 0xBA, - 0x93, 0x1E, 0xEC, 0xB5, 0xFA, 0x83, 0xEA, 0x0D, 0x7C, 0x04, 0xF4, 0x1E, 0x3B, 0x19, 0xF2, 0xC7, 0x43, 0xC2, 0x6A, 0x5A, 0x0F, 0x05, 0x80, 0x07, - 0x69, 0x28, 0xDD, 0xCB, 0x32, 0xF0, 0x2C, 0x7C, 0x6C, 0xE9, 0x6C, 0xBA, 0x35, 0xD3, 0x7A, 0x69, 0xBD, 0x36, 0x43, 0xB0, 0x86, 0xE5, 0xC0, 0xA0, - 0x95, 0x2D, 0x2B, 0x89, 0xCF, 0x89, 0x74, 0x66, 0x81, 0x99, 0xC6, 0x14, 0x56, 0x9D, 0x7E, 0xCE, 0xB9, 0xB1, 0xF6, 0x5A, 0x2B, 0x4D, 0x4E, 0x4F, - 0x1F, 0x15, 0x8D, 0xBC, 0x89, 0x74, 0x06, 0xD2, 0xEF, 0xF6, 0x7C, 0x42, 0x3A, 0xFE, 0x38, 0x50, 0x59, 0xF7, 0x1C, 0xF3, 0x10, 0xEC, 0x74, 0x48, - 0x1E, 0xFD, 0xE7, 0xB8, 0x04, 0xA1, 0x9E, 0xFF, 0xEF, 0x68, 0x16, 0xC1, 0x6D, 0x06, 0x23, 0xDB, 0x14, 0x46, 0x82, 0x89, 0x57, 0x38, 0x4E, 0x67, - 0x09, 0x5F, 0xCA, 0xE8, 0x88, 0xBB, 0x4E, 0x78, 0xBE, 0xCA, 0x1B, 0x97, 0xE8, 0xAB, 0x06, 0xE1, 0x1F, 0xEA, 0x35, 0xD9, 0x7A, 0x6C, 0x0D, 0xB6, - 0x86, 0xAF, 0x8D, 0x4C, 0x14, 0x99, 0xA0, 0x6A, 0x90, 0x92, 0x59, 0x1A, 0x48, 0xFA, 0x99, 0x96, 0xF9, 0xCF, 0xBD, 0xBE, 0x2D, 0x2D, 0xF4, 0xB2, - 0x72, 0x35, 0x5D, 0x00, 0x26, 0x03, 0xD3, 0xE2, 0x19, 0xE9, 0x03, 0xE0, 0x0F, 0x22, 0xA6, 0x21, 0xAC, 0xC8, 0x84, 0x58, 0x81, 0xA2, 0x5C, 0x69, - 0x74, 0xD1, 0x69, 0x61, 0x28, 0xBF, 0xE3, 0xBA, 0x25, 0x7D, 0x29, 0x5B, 0x8B, 0xAD, 0xB9, 0xD6, 0x41, 0xDF, 0x97, 0x8F, 0x19, 0xAD, 0x43, 0x23, - 0x83, 0x9D, 0x5E, 0x88, 0x11, 0x95, 0x54, 0x07, 0x12, 0x50, 0x32, 0x1E, 0x00, 0x9F, 0xC0, 0xA3, 0xE1, 0x55, 0x04, 0x6B, 0xF5, 0xDA, 0x6E, 0xFD, - 0xB5, 0xBE, 0x5A, 0x4B, 0xAD, 0x31, 0x7F, 0x48, 0xBB, 0x3F, 0x8D, 0x67, 0x05, 0x4E, 0xA4, 0x1D, 0x19, 0x83, 0x21, 0x44, 0x2B, 0x54, 0xF3, 0x21, - 0xFB, 0xD6, 0xBE, 0x04, 0xC9, 0xB8, 0x2D, 0x4A, 0x52, 0x96, 0x89, 0x1F, 0xF1, 0xC5, 0x8C, 0x83, 0xD6, 0x71, 0x94, 0xA0, 0xDB, 0xAD, 0xD9, 0xFD, - 0xA9, 0x65, 0xB0, 0x0F, 0x10, 0xF1, 0xB8, 0x2F, 0x0B, 0x81, 0x61, 0xB8, 0xB1, 0x18, 0x27, 0x6B, 0x92, 0x74, 0x12, 0x40, 0x72, 0x83, 0x84, 0x28, - 0x23, 0x20, 0x06, 0x9A, 0x40, 0x24, 0x92, 0x29, 0x91, 0xA0, 0x49, 0x41, 0x0A, 0xD9, 0xDA, 0x0C, 0x33, 0x8E, 0x23, 0x6A, 0xBA, 0x9E, 0xD8, 0x2F, - 0xF6, 0x9C, 0xCE, 0xBB, 0x09, 0x0B, 0x0B, 0x4B, 0x24, 0xF1, 0xCC, 0xF1, 0x94, 0xDF, 0x6C, 0xEA, 0x3A, 0x38, 0x5E, 0xEB, 0x0C, 0x7A, 0x87, 0x5A, - 0x3F, 0x80, 0x4D, 0xFD, 0x3C, 0x9A, 0x84, 0x33, 0x36, 0x5A, 0x81, 0xD1, 0x29, 0xFD, 0xB0, 0xB8, 0x26, 0x10, 0xA8, 0x4C, 0xE1, 0x69, 0x35, 0x05, - 0xAB, 0xF6, 0x82, 0x87, 0x5F, 0xFC, 0x03, 0xB6, 0x8D, 0x85, 0x13, 0x1B, 0xA6, 0x40, 0xF5, 0x54, 0xC5, 0x23, 0x78, 0x51, 0x26, 0x12, 0x59, 0x29, - 0x50, 0xEE, 0x0B, 0xF4, 0xD1, 0xA5, 0x0F, 0x7B, 0x02, 0x23, 0xA1, 0x62, 0xC0, 0xB2, 0xE8, 0x1B, 0x4B, 0x50, 0x6E, 0x36, 0xB3, 0x87, 0x03, 0xA9, - 0x17, 0x42, 0x6B, 0xA4, 0x95, 0xB9, 0xF8, 0x4D, 0xA0, 0x7B, 0x17, 0xCC, 0x81, 0xBB, 0xE3, 0x3D, 0x98, 0xC5, 0x22, 0x46, 0x34, 0xD2, 0xB3, 0x58, - 0xCE, 0xBC, 0x38, 0x0C, 0xF8, 0x1B, 0xB6, 0x22, 0xCF, 0x98, 0xB0, 0xAF, 0x1E, 0x8B, 0xE4, 0x68, 0xB5, 0x1B, 0xAE, 0x2C, 0xFD, 0x40, 0x93, 0x03, - 0xF4, 0x18, 0xCD, 0x3A, 0xFC, 0x33, 0xA7, 0x13, 0x80, 0xBB, 0xBD, 0xE5, 0xF4, 0xCC, 0x06, 0xBA, 0xE6, 0xD6, 0x6F, 0x7D, 0x17, 0x66, 0xF3, 0x56, - 0x18, 0x87, 0x14, 0xAC, 0x23, 0xA3, 0x0F, 0xA5, 0xB6, 0x05, 0x79, 0x3C, 0xD6, 0x20, 0x49, 0x8E, 0x22, 0x69, 0xBA, 0xB8, 0x15, 0x7F, 0x1E, 0xEE, - 0x51, 0x9F, 0x18, 0x68, 0xFB, 0x91, 0xC4, 0x17, 0xA3, 0xAE, 0x78, 0x94, 0xBB, 0xDD, 0x42, 0x8E, 0x9A, 0x67, 0xF8, 0x52, 0x70, 0x54, 0x68, 0x2D, - 0xFB, 0x4D, 0xB0, 0xCB, 0x0C, 0x27, 0x9C, 0xC2, 0x5A, 0x41, 0x51, 0x03, 0xF2, 0x82, 0x43, 0x7A, 0x5F, 0xCD, 0x35, 0x45, 0x5B, 0xB1, 0x94, 0x91, - 0x96, 0x67, 0xEB, 0xD5, 0xE2, 0x72, 0xCF, 0x67, 0x82, 0xCC, 0x68, 0x11, 0xA6, 0xF1, 0x58, 0x8F, 0xB8, 0x93, 0x8F, 0x37, 0xC1, 0xF4, 0x63, 0xB0, - 0xAD, 0x33, 0xD6, 0x51, 0x2C, 0xF8, 0x9C, 0xBE, 0x51, 0x6B, 0xB1, 0xE5, 0xCD, 0x8B, 0x7D, 0x6F, 0xEF, 0xAA, 0x78, 0x70, 0x35, 0x84, 0x2C, 0xA5, - 0x64, 0x14, 0xC9, 0x07, 0xC1, 0xA5, 0xC9, 0x61, 0xB6, 0xF6, 0xDC, 0xBC, 0xB1, 0xC5, 0x0B, 0x6F, 0xC9, 0x68, 0x35, 0x20, 0xBE, 0x86, 0x89, 0xFB, - 0x69, 0xF9, 0x77, 0xFE, 0xBA, 0x29, 0x48, 0x8E, 0xDA, 0xCB, 0x26, 0x9F, 0xA9, 0x03, 0xB7, 0x73, 0x65, 0xB5, 0xAE, 0xC3, 0x16, 0x65, 0x3E, 0x52, - 0x65, 0x9D, 0x30, 0xD9, 0xF5, 0x80, 0x55, 0x64, 0x47, 0x85, 0x91, 0xDD, 0x0F, 0x27, 0x72, 0xBE, 0x4A, 0x10, 0x8C, 0x91, 0x07, 0x72, 0x1B, 0x2F, - 0xF5, 0xB3, 0xA8, 0x58, 0xD3, 0x65, 0xB7, 0x64, 0xA3, 0xD0, 0x1F, 0x08, 0xF6, 0x9E, 0xD6, 0xD3, 0xE4, 0xAD, 0x4D, 0xF5, 0xEA, 0x8D, 0xC9, 0x5F, - 0x97, 0x8D, 0x5F, 0x1A, 0x32, 0x3C, 0xD7, 0xA2, 0x9D, 0x5E, 0xA3, 0x21, 0xF1, 0xC6, 0x62, 0x26, 0x64, 0x68, 0x44, 0xA9, 0x5F, 0x0A, 0x88, 0x43, - 0xF0, 0xC4, 0x34, 0xD2, 0xD7, 0x55, 0x5D, 0x97, 0xFC, 0xE2, 0x9D, 0xA3, 0xD8, 0x6F, 0x3C, 0xF0, 0xE9, 0xDC, 0xB8, 0x03, 0x8A, 0x5D, 0xAB, 0x5B, - 0x72, 0xE2, 0x06, 0x4C, 0x12, 0x94, 0x53, 0xAA, 0x21, 0x07, 0x9C, 0x2D, 0x71, 0x64, 0xC3, 0x5D, 0xB8, 0x7B, 0x0A, 0x34, 0xE0, 0x21, 0x29, 0x28, - 0x16, 0x14, 0x37, 0xBD, 0xBA, 0xAB, 0x6C, 0xF0, 0xE9, 0xE5, 0xCD, 0x1B, 0x66, 0xA4, 0x14, 0xB1, 0x69, 0x5A, 0x1B, 0x95, 0x74, 0xF8, 0x97, 0x1E, - 0xDD, 0x83, 0xD3, 0xEE, 0x9B, 0xE8, 0xDA, 0x47, 0xEC, 0xFC, 0x6C, 0xBF, 0xCD, 0xD9, 0xAC, 0xA3, 0x9A, 0x8A, 0xC0, 0xF3, 0xC2, 0x89, 0x3B, 0xC7, - 0x8A, 0xB1, 0xDA, 0x38, 0xC8, 0x80, 0xE3, 0x0E, 0xCF, 0x70, 0x5D, 0x8D, 0x9D, 0x36, 0xE4, 0x5C, 0x32, 0xC7, 0xDE, 0x9A, 0x35, 0xD8, 0xCB, 0xB4, - 0xE8, 0xFF, 0xDE, 0xC9, 0x9F, 0xF1, 0x56, 0xC3, 0x4D, 0xAB, 0x33, 0x79, 0x24, 0x89, 0x16, 0x2D, 0x96, 0xA9, 0xB3, 0xE8, 0x6F, 0x95, 0xD9, 0x7B, - 0x2E, 0x39, 0x9C, 0x7B, 0xCD, 0xDB, 0x40, 0xE5, 0x00, 0xD5, 0x4C, 0x0E, 0xFB, 0x84, 0xC3, 0x8D, 0xFE, 0xD6, 0x03, 0x9B, 0x8B, 0x4C, 0xAE, 0x70, - 0x71, 0xFD, 0x94, 0x0C, 0xBC, 0x21, 0x00, 0xA6, 0xEE, 0xB8, 0x1E, 0x40, 0xB8, 0x0E, 0xB7, 0xAE, 0x18, 0x17, 0xD3, 0x6B, 0x9A, 0xE7, 0x11, 0xED, - 0xB6, 0x3B, 0x15, 0x61, 0x7B, 0x05, 0xEE, 0xD1, 0x05, 0x75, 0xBC, 0xE9, 0xA0, 0x0E, 0x0C, 0x40, 0x06, 0xBA, 0x00, 0xAF, 0x00, 0xAD, 0x00, 0xA0, - 0xD0, 0xAF, 0xA0, 0x02, 0xC6, 0x9F, 0x10, 0xC7, 0x9E, 0x17, 0xB0, 0x9D, 0x23, 0x6E, 0x4E, 0x19, 0xE4, 0x4D, 0xA0, 0x64, 0x4D, 0xA7, 0x82, 0x4C, - 0x2C, 0x03, 0xCC, 0x31, 0x8F, 0x4B, 0xB9, 0x0F, 0xCB, 0xC0, 0x9C, 0xCA, 0x48, 0x1D, 0x4A, 0xCC, 0x8F, 0x49, 0xF7, 0x94, 0xE4, 0xAD, 0x4E, 0xA4, - 0xF0, 0x0E, 0xE4, 0xF3, 0x14, 0x64, 0x00, 0xD5, 0xE3, 0xC3, 0x77, 0xE4, 0x38, 0x6B, 0x54, 0x19, 0x64, 0xCC, 0x21, 0x5C, 0x44, 0x0A, 0x55, 0xA4, - 0x12, 0x4D, 0xBC, 0x2A, 0x44, 0x4C, 0xF3, 0x3D, 0x84, 0x1B, 0x35, 0xFC, 0x23, 0x2D, 0x7C, 0xFC, 0x7D, 0xB5, 0x16, 0xEC, 0xBD, 0x0E, 0x54, 0xA6, - 0x00, 0xBC, 0xAE, 0x00, 0x4C, 0x68, 0xF9, 0xBB, 0x70, 0xF1, 0xDB, 0xA8, 0xE8, 0x4B, 0xB1, 0xE0, 0xC3, 0x71, 0xD9, 0x3B, 0x7A, 0xD1, 0x9B, 0x52, - 0xCA, 0xEB, 0x5A, 0xC2, 0x43, 0xF3, 0xBA, 0xBB, 0xFB, 0xB2, 0x3B, 0xB4, 0xD3, 0x2F, 0xEF, 0xEA, 0x3C, 0xC1, 0xE8, 0x6C, 0x2B, 0xE7, 0x78, 0xF1, - 0xE4, 0x90, 0xF3, 0xE2, 0xAA, 0x2D, 0xE3, 0x0E, 0x2E, 0xE1, 0x2A, 0x66, 0xDF, 0x44, 0x68, 0xDD, 0x60, 0x98, 0xDB, 0x7C, 0x9A, 0xD9, 0x9A, 0x12, - 0xF2, 0xB5, 0x2B, 0x85, 0x22, 0x35, 0xDF, 0x9C, 0xF6, 0x9D, 0xD1, 0xEC, 0x14, 0xCE, 0x0C, 0x17, 0x02, 0x90, 0x01, 0x66, 0x8E, 0x1C, 0x82, 0x39, - 0xA0, 0x57, 0xA1, 0x70, 0xBD, 0x8F, 0xD4, 0xB0, 0x12, 0xDF, 0x77, 0xC2, 0xAF, 0x7C, 0x16, 0x7F, 0xF4, 0x91, 0x7C, 0x0B, 0xDE, 0xB2, 0x27, 0xE1, - 0x49, 0x7B, 0x17, 0xDE, 0xB5, 0xEB, 0xB8, 0xBE, 0x4F, 0xE2, 0x93, 0xBB, 0xDD, 0x77, 0xEF, 0x94, 0xBF, 0xD2, 0xC7, 0x7E, 0x59, 0xAF, 0xFC, 0x97, - 0x7D, 0xCC, 0xC1, 0xFF, 0x41, 0xF0, 0x20, 0x3F, 0xC4, 0x73, 0x25, 0xE0, 0x67, 0x09, 0xBB, 0x08, 0x2E, 0xB2, 0xF7, 0xE0, 0x90, 0x85, 0x92, 0x6C, - 0x6F, 0x96, 0x5F, 0x30, 0x97, 0xE0, 0x02, 0xC0, 0x94, 0x11, 0x56, 0x43, 0xB7, 0x31, 0x69, 0x23, 0x0B, 0xD5, 0x3C, 0x56, 0xD4, 0xCB, 0xF0, 0x57, - 0xD2, 0xB9, 0x03, 0x68, 0xE5, 0xB9, 0xA6, 0x5B, 0xAB, 0x07, 0x4D, 0xAB, 0x18, 0x3D, 0xBB, 0xE9, 0xE0, 0x96, 0x76, 0xFF, 0x4E, 0xC3, 0x32, 0x43, - 0xBC, 0x66, 0x47, 0xBC, 0x2E, 0xA4, 0xB8, 0x62, 0xA8, 0xB4, 0x92, 0x14, 0xB1, 0xD2, 0x18, 0xAD, 0x0A, 0x69, 0xA9, 0x3E, 0x6D, 0xA5, 0x56, 0x19, - 0xA1, 0x92, 0xCD, 0x9D, 0xAA, 0x6D, 0x99, 0xE6, 0xF9, 0xD2, 0xC4, 0x39, 0xD2, 0x4C, 0xBA, 0xD1, 0x54, 0x48, 0x51, 0xDC, 0xC8, 0xD0, 0x61, 0xD7, - 0x72, 0x2B, 0x91, 0x47, 0xB9, 0xDB, 0xE7, 0xC2, 0x48, 0x5C, 0x75, 0x39, 0x92, 0x6F, 0x2A, 0xD8, 0x37, 0x9C, 0xFB, 0x31, 0xD9, 0xC0, 0x1F, 0xE4, - 0x1F, 0x1E, 0x24, 0xD7, 0xF1, 0x3B, 0x39, 0xC8, 0x1E, 0xF2, 0xDE, 0xD9, 0x79, 0xDE, 0x54, 0x7B, 0xD5, 0xFB, 0x6C, 0x47, 0x7B, 0x13, 0xEE, 0x85, - 0xEF, 0x34, 0x3F, 0xFA, 0x36, 0xF4, 0x87, 0x39, 0xA9, 0x2F, 0xCD, 0x81, 0x7D, 0x70, 0x0E, 0x73, 0xED, 0x7D, 0xB0, 0xF3, 0x0A, 0x6F, 0x91, 0x7B, - 0xEC, 0xFD, 0x67, 0xBF, 0x2D, 0xF6, 0x8B, 0xF7, 0xCB, 0xEE, 0x59, 0xE9, 0x59, 0xC9, 0x12, 0x18, 0xD6, 0xB4, 0xD3, 0xD5, 0x4C, 0x3A, 0xC9, 0x8A, - 0x35, 0xF7, 0xF9, 0x5E, 0x86, 0x4D, 0x5F, 0x82, 0xBB, 0xC3, 0x69, 0x95, 0xBB, 0xF6, 0x5C, 0xBB, 0xD7, 0x40, 0xBB, 0xD8, 0x30, 0xBB, 0x69, 0x22, - 0xBB, 0x6A, 0x12, 0x1B, 0xEB, 0xE0, 0x06, 0x7E, 0xF0, 0xCC, 0x27, 0xD9, 0x28, 0xAE, 0x18, 0x44, 0x34, 0x59, 0xFE, 0x29, 0xCE, 0x93, 0x39, 0xFA, - 0x3C, 0xB9, 0x3D, 0xF1, 0x31, 0xF3, 0x11, 0xB7, 0x15, 0xBA, 0xF8, 0x33, 0x42, 0x60, 0xE4, 0x38, 0x88, 0x00, 0xAB, 0x43, 0x0E, 0x27, 0x32, 0xF7, - 0xEE, 0x32, 0x2F, 0x2C, 0x15, 0xD0, 0xED, 0x68, 0x7C, 0xC0, 0xA1, 0x1D, 0xF1, 0x80, 0x47, 0xEB, 0xD2, 0x7F, 0xE6, 0x41, 0x0F, 0x82, 0xF8, 0x28, - 0x7A, 0xCA, 0x27, 0xD2, 0x8B, 0x7E, 0x96, 0xAE, 0xF5, 0x8D, 0xDA, 0x72, 0x7F, 0xAB, 0xED, 0xF1, 0xB9, 0x36, 0x1D, 0x0E, 0xD9, 0x8E, 0xCC, 0x79, - 0x3D, 0x46, 0xFE, 0x90, 0x04, 0x1D, 0xBA, 0xC7, 0xC7, 0xD1, 0x73, 0x7E, 0xAE, 0x4B, 0x7D, 0x9D, 0xF6, 0x0E, 0x3E, 0xD5, 0xA6, 0xC2, 0x7F, 0xFB, - 0x0C, 0x1F, 0x6C, 0x13, 0xE2, 0xA1, 0x6D, 0x51, 0x9C, 0x50, 0xF7, 0xC5, 0x45, 0xF5, 0xD1, 0xEF, 0xAB, 0xFF, 0xFE, 0x6A, 0xDD, 0xFA, 0xC7, 0x4C, - 0xE8, 0x3F, 0x14, 0x9F, 0x45, 0x6F, 0xF9, 0x5C, 0x15, 0xED, 0x33, 0x0B, 0xDC, 0xA5, 0xFD, 0x82, 0x2B, 0xB5, 0x05, 0x75, 0x41, 0x9D, 0x85, 0x2E, - 0x2C, 0xE8, 0x64, 0x72, 0x48, 0x16, 0x0B, 0x8E, 0xA1, 0xB1, 0x64, 0xD5, 0xD1, 0x8A, 0x95, 0xF8, 0x0D, 0xB0, 0x07, 0xBC, 0x33, 0x76, 0x8D, 0xB7, - 0x80, 0x1F, 0xC8, 0x37, 0xB2, 0x39, 0x6E, 0x68, 0xA2, 0xC8, 0x00, 0xF3, 0xBC, 0xB2, 0xCC, 0x40, 0xDC, 0x4F, 0xE8, 0x5D, 0x08, 0xE9, 0xF7, 0x48, - 0x2F, 0x10, 0x35, 0x96, 0x44, 0x81, 0x62, 0xA8, 0x81, 0x0C, 0xD4, 0x0F, 0xC1, 0x2E, 0x49, 0x41, 0x51, 0x52, 0x69, 0x03, 0x12, 0x60, 0x40, 0x43, - 0x43, 0xA4, 0x04, 0x84, 0x79, 0x41, 0x52, 0x52, 0x50, 0xAF, 0xFA, 0x4C, 0x07, 0x0B, 0x06, 0xEF, 0xB5, 0x8C, 0x0A, 0x59, 0x35, 0x61, 0x4A, 0xB8, - 0x84, 0x9B, 0xCD, 0x60, 0x9E, 0xBF, 0x35, 0x03, 0xC8, 0x1C, 0xED, 0x05, 0x7E, 0xC7, 0x34, 0xDF, 0x6E, 0xFF, 0x6D, 0xDB, 0x6E, 0xFF, 0xDF, 0x0B, - 0xBD, 0xD7, 0xB7, 0x00, 0x99, 0x6D, 0xDA, 0x19, 0x0B, 0x1B, 0xEA, 0x90, 0x48, 0x47, 0x9B, 0x41, 0xF5, 0x8E, 0x9B, 0x76, 0x67, 0x6E, 0x58, 0x09, - 0x79, 0x60, 0x82, 0x5D, 0xBF, 0x61, 0xA1, 0x8C, 0xB3, 0xD5, 0x8E, 0xD5, 0x14, 0x9D, 0x7B, 0xC6, 0x93, 0x37, 0x30, 0xF2, 0x3B, 0xC0, 0x25, 0xDC, - 0x6C, 0x06, 0x9F, 0xBE, 0x8B, 0x36, 0x41, 0x6F, 0xBE, 0x7C, 0xE0, 0xC2, 0x39, 0x82, 0x30, 0x12, 0x03, 0x58, 0x50, 0xD7, 0xC8, 0xD8, 0x5B, 0x1B, - 0x34, 0x34, 0x8C, 0x16, 0xCD, 0xB7, 0xDB, 0x7F, 0xDB, 0xB6, 0xDB, 0x7F, 0x9B, 0x43, 0x19, 0x7A, 0x7A, 0x8E, 0xD9, 0x79, 0x36, 0xD9, 0xA4, 0xEC, - 0xCE, 0xFE, 0x84, 0x76, 0x67, 0x4C, 0x49, 0x4B, 0x49, 0xEA, 0xEF, 0x67, 0x6D, 0x5D, 0x19, 0x7A, 0x0D, 0x5A, 0x00, 0xFB, 0x76, 0xC2, 0xFA, 0x01, - 0x62, 0xF4, 0xA3, 0xB9, 0x4F, 0x2C, 0x51, 0xFA, 0xD5, 0x2D, 0xA5, 0xF3, 0x99, 0x76, 0x33, 0x93, 0xB9, 0x8B, 0x80, 0x11, 0x18, 0x78, 0x5F, 0xC2, - 0x88, 0x66, 0x94, 0x54, 0x1E, 0xA4, 0x56, 0xBC, 0xE7, 0x35, 0x11, 0xD3, 0xB2, 0x1C, 0xA7, 0x25, 0x28, 0x05, 0xA7, 0xE9, 0x52, 0xCE, 0x36, 0x0C, - 0xE1, 0xC9, 0x26, 0x61, 0x16, 0x1E, 0x14, 0x2D, 0x8E, 0x4E, 0x6D, 0xF6, 0x63, 0x8E, 0xDC, 0x1D, 0x67, 0x9D, 0x31, 0x8C, 0xA0, 0x62, 0x00, 0xCD, - 0x25, 0x7C, 0x43, 0xFA, 0xC5, 0xA3, 0xCF, 0x7B, 0x80, 0x0E, 0xE9, 0x2F, 0x99, 0x22, 0xEE, 0xB1, 0xB9, 0x99, 0xD0, 0xAA, 0x8C, 0x5F, 0xB0, 0x0F, - 0xA2, 0x19, 0x66, 0x33, 0xFB, 0xDC, 0x86, 0xB1, 0xC6, 0x3E, 0xB7, 0x19, 0xD6, 0x31, 0xAE, 0x63, 0x36, 0xF3, 0x1C, 0xD3, 0x30, 0xB6, 0x69, 0x6C, - 0x3F, 0x4B, 0x15, 0xCC, 0x14, 0x1C, 0x2C, 0xC5, 0x99, 0x03, 0x53, 0x7E, 0x96, 0x66, 0xFF, 0x28, 0xF3, 0xD8, 0x67, 0xF9, 0xAC, 0xA6, 0x97, 0xD1, - 0xF4, 0x2F, 0xC3, 0xEA, 0xF3, 0x01, 0xEC, 0x2E, 0x00, 0x4A, 0x5B, 0x70, 0x12, 0x32, 0x30, 0x2C, 0x27, 0x1D, 0x31, 0x87, 0x47, 0x36, 0x76, 0xF1, - 0x52, 0xB9, 0xDE, 0x78, 0xC5, 0xF6, 0x75, 0x10, 0x22, 0x2A, 0xC1, 0x19, 0x94, 0x72, 0x08, 0x37, 0x93, 0x08, 0xE1, 0x94, 0x0C, 0x0E, 0x5F, 0xC7, - 0xF3, 0xE7, 0x5C, 0x1D, 0xDE, 0xD3, 0xBB, 0x82, 0x70, 0x8A, 0x44, 0x43, 0xB3, 0xA3, 0x26, 0x53, 0x43, 0x01, 0x1F, 0x01, 0xF9, 0x00, 0xD4, 0x51, - 0x1F, 0xA9, 0xA9, 0x76, 0x74, 0x7D, 0xB5, 0xA9, 0x7B, 0xCA, 0xFA, 0xBA, 0x49, 0xCB, 0xE0, 0x36, 0xB0, 0x22, 0xEE, 0x08, 0x7B, 0xE3, 0xE2, 0xB0, - 0x24, 0x68, 0x89, 0xCE, 0x41, 0x75, 0xB4, 0x14, 0xEA, 0x25, 0xE8, 0x25, 0x38, 0xD7, 0x72, 0x03, 0xCE, 0xB8, 0xB8, 0xA3, 0xAA, 0xCE, 0x05, 0xAB, - 0xA4, 0x56, 0xF5, 0x1A, 0x26, 0xC1, 0xC4, 0x89, 0x1E, 0x3E, 0xE6, 0x95, 0x2B, 0x13, 0xCD, 0x8F, 0x41, 0xC2, 0x4E, 0x6F, 0x6C, 0x21, 0xAA, 0xA0, - 0x2A, 0x1A, 0xB2, 0xC2, 0x10, 0x95, 0x24, 0xD7, 0x9C, 0x1F, 0x1A, 0x6D, 0xD2, 0xE8, 0x1A, 0x13, 0xCD, 0xA6, 0xD5, 0x1A, 0x96, 0xAD, 0xBE, 0xD9, - 0x26, 0x75, 0x68, 0xC7, 0x54, 0x3E, 0xB6, 0x4F, 0x25, 0xD3, 0x95, 0x6A, 0xB1, 0xFD, 0x4C, 0x4B, 0x7D, 0x69, 0xBA, 0xEA, 0x57, 0xF3, 0x15, 0xAF, - 0x79, 0x89, 0xCD, 0xEE, 0x0A, 0x33, 0x82, 0x98, 0xF5, 0x00, 0xA0, 0x56, 0xB0, 0x16, 0xEA, 0x0A, 0xBB, 0x56, 0x85, 0xD8, 0x21, 0x55, 0x8B, 0x85, - 0xAB, 0x44, 0x5A, 0x4E, 0xDD, 0xD2, 0x5C, 0xE6, 0x9C, 0xA6, 0x33, 0x19, 0x75, 0xA3, 0x59, 0xAA, 0x8F, 0x93, 0x57, 0xF7, 0x9A, 0x47, 0x6B, 0x16, - 0x47, 0xA6, 0x17, 0x20, 0xB3, 0x10, 0x56, 0x44, 0x6D, 0xB3, 0x37, 0x2A, 0x14, 0x1B, 0xA5, 0xE2, 0xE8, 0x1C, 0x33, 0xD8, 0x52, 0x26, 0x9A, 0x4E, - 0x33, 0x03, 0xB5, 0xA0, 0x99, 0xA9, 0x35, 0x4D, 0x41, 0x56, 0xD6, 0xD4, 0x64, 0x37, 0x55, 0x59, 0x76, 0x56, 0x7D, 0x30, 0xC0, 0x72, 0x18, 0xAB, - 0x19, 0xAC, 0x86, 0xEA, 0xC2, 0xBE, 0xA8, 0x1B, 0xFA, 0x6C, 0xC2, 0xE8, 0x18, 0xF3, 0x48, 0xA7, 0x29, 0xD3, 0x94, 0x7F, 0xAE, 0x94, 0x6D, 0xAA, - 0x9B, 0xD2, 0x50, 0x3D, 0x54, 0xD6, 0xDD, 0xF9, 0x54, 0xCE, 0xDD, 0x2A, 0x71, 0xCD, 0x1A, 0x90, 0xE0, 0x43, 0x0F, 0x1A, 0xBF, 0xC2, 0xE4, 0x68, - 0x6A, 0x0C, 0x7A, 0xEB, 0x34, 0xE4, 0x53, 0x4E, 0xAA, 0x94, 0x4A, 0x34, 0x56, 0x25, 0x0C, 0x4B, 0x49, 0x5C, 0x85, 0xE1, 0x9D, 0xC2, 0xEC, 0xA7, - 0x98, 0x2A, 0xDE, 0xB5, 0x42, 0xA9, 0xA2, 0xAE, 0x28, 0x83, 0x54, 0x21, 0x65, 0x96, 0xAA, 0xA5, 0x24, 0xD6, 0x38, 0x25, 0xDC, 0x5C, 0x54, 0xCA, - 0x99, 0x73, 0x2E, 0x37, 0x19, 0x9D, 0xD4, 0x2C, 0xF5, 0xBF, 0x8E, 0xB6, 0xFF, 0xC6, 0xEF, 0x67, 0xBB, 0xFB, 0xD9, 0x88, 0x7F, 0x0D, 0xB5, 0xDF, - 0x57, 0xFF, 0x18, 0xC4, 0x9F, 0xC5, 0xF1, 0x44, 0xFD, 0x4B, 0x8C, 0x00, 0x41, 0xF7, 0x7B, 0x38, 0xFE, 0x67, 0x19, 0x88, 0xFF, 0x85, 0xFE, 0xBB, - 0xF8, 0x4F, 0x28, 0xFE, 0x10, 0x84, 0x7F, 0xCF, 0xF7, 0x37, 0xE8, 0xDF, 0xEC, 0xFE, 0x0B, 0xDA, 0xFE, 0x32, 0xE4, 0x5F, 0x66, 0xFF, 0xB2, 0xFE, - 0xC9, 0x8E, 0x3F, 0x59, 0xFD, 0xC9, 0xFA, 0x57, 0x50, 0xFC, 0x13, 0x20, 0x90, 0xFB, 0x09, 0xD4, 0x5F, 0xC0, 0xF1, 0xE7, 0xF5, 0x7E, 0xAE, 0x6B, - 0x23, 0x61, 0x89, 0x47, 0x53, 0xA1, 0x55, 0x5A, 0x0D, 0x5D, 0xD3, 0x55, 0xEE, 0xED, 0x35, 0x97, 0x8D, 0xBD, 0xB7, 0x90, 0xED, 0x74, 0x3D, 0x59, - 0x5A, 0xB7, 0x96, 0xBD, 0x05, 0x2E, 0x9D, 0x01, 0x6B, 0x8B, 0xDE, 0xEA, 0x58, 0x07, 0xA8, 0x2F, 0x04, 0xCD, 0x81, 0x76, 0x68, 0x1F, 0x95, 0xD1, - 0x4A, 0xE8, 0x92, 0x96, 0x71, 0xC1, 0xF4, 0x92, 0xEB, 0x66, 0xC1, 0xDC, 0x30, 0x36, 0xCF, 0xD5, 0x63, 0x23, 0x5D, 0x49, 0x56, 0xD5, 0xB5, 0xB3, - 0x93, 0xA8, 0x30, 0xBB, 0x8A, 0xB2, 0xEA, 0x61, 0x54, 0xC9, 0x5B, 0x02, 0x9D, 0xD0, 0x27, 0x28, 0x8A, 0xF6, 0x41, 0x7F, 0x34, 0x8A, 0x9B, 0xC2, - 0xFE, 0xB8, 0x40, 0xAC, 0xF0, 0x62, 0xB1, 0x6F, 0x2E, 0x1C, 0x8B, 0xE8, 0x26, 0xB2, 0x44, 0x1A, 0xCA, 0x2A, 0xA2, 0x8B, 0x5A, 0x14, 0x1D, 0xD5, - 0xB9, 0xA8, 0xAE, 0x9E, 0x94, 0xAC, 0xD1, 0x68, 0x5A, 0x93, 0xDD, 0x32, 0x9B, 0x76, 0xA9, 0x65, 0xBB, 0x36, 0x6C, 0x93, 0xEB, 0xC4, 0x8E, 0xB9, - 0x64, 0xEC, 0x13, 0x5A, 0xB4, 0x65, 0xA8, 0x99, 0xF6, 0x43, 0xFF, 0xF4, 0x25, 0x6A, 0xEC, 0x57, 0x14, 0x56, 0xEB, 0x10, 0xA3, 0x48, 0x00, 0x34, - 0xAC, 0x6B, 0x21, 0xAE, 0x0C, 0x80, 0x39, 0x01, 0xAC, 0x85, 0xB5, 0xCB, 0xC2, 0x0E, 0xB9, 0x44, 0x2C, 0xDC, 0xDD, 0x62, 0x81, 0xB4, 0x48, 0x73, - 0xA1, 0x5D, 0x9A, 0x0E, 0xAD, 0xD3, 0x8D, 0x02, 0x8C, 0xA3, 0x9E, 0x71, 0xF8, 0xCE, 0x36, 0x8E, 0x67, 0x1B, 0x6E, 0x67, 0x36, 0xE2, 0x79, 0x86, - 0xF0, 0x0C, 0xE3, 0x78, 0x6E, 0xE1, 0x3B, 0xA3, 0xA0, 0x67, 0x12, 0xC8, 0x33, 0x88, 0xB1, 0x73, 0x1A, 0xF1, 0x9C, 0x76, 0x76, 0x46, 0x3B, 0x3B, - 0x6F, 0xF0, 0x9D, 0x31, 0xF4, 0xCE, 0x6D, 0xCF, 0x12, 0xE8, 0x39, 0x82, 0xEF, 0xEC, 0x20, 0x78, 0x6E, 0x70, 0x76, 0x36, 0xAB, 0x3B, 0x97, 0xFD, - 0xAC, 0xE0, 0xEE, 0x9C, 0xE0, 0x77, 0x36, 0x30, 0x3C, 0x0F, 0xE8, 0x9D, 0x05, 0xD8, 0x73, 0x00, 0xB7, 0xB3, 0x58, 0x3D, 0xF3, 0x90, 0x67, 0xDE, - 0xF0, 0xCC, 0x53, 0xFB, 0x87, 0x19, 0x7F, 0x60, 0xBF, 0x3F, 0x89, 0xFC, 0x79, 0x0D, 0x7F, 0x5C, 0xC7, 0x1F, 0xB9, 0xF6, 0xD7, 0x9A, 0x3F, 0xAC, - 0xFB, 0xB7, 0xFA, 0xFD, 0x76, 0x77, 0x3F, 0xAA, 0xE1, 0x6F, 0x8A, 0xEE, 0x2F, 0xD5, 0xFB, 0x47, 0xAD, 0xFD, 0xA1, 0xFE, 0x7B, 0xB2, 0xFB, 0x39, - 0x09, 0xFF, 0x4D, 0xBD, 0x5F, 0x93, 0xF1, 0xCF, 0x24, 0xFC, 0x31, 0x15, 0x7F, 0xE3, 0xFF, 0x49, 0xC0, 0x5F, 0x12, 0xF1, 0x97, 0xD4, 0xF6, 0xCF, - 0xFD, 0x6F, 0x44, 0xFC, 0x17, 0xB9, 0xFD, 0x8A, 0x82, 0xFF, 0xA1, 0xFA, 0x5F, 0xB9, 0x7F, 0x90, 0xF1, 0x17, 0x34, 0xF6, 0x07, 0x9A, 0x7F, 0x51, - 0xED, 0xE7, 0x23, 0xFC, 0xE3, 0x90, 0x3F, 0x9E, 0xB6, 0xDF, 0xDA, 0x9F, 0x0E, 0xF1, 0x7F, 0xD3, 0xBF, 0x1B, 0xB5, 0x7F, 0xCD, 0xDA, 0x6F, 0xA6, - 0xFC, 0xC7, 0x0C, 0x7F, 0x31, 0xC9, 0xFF, 0x0B, 0xF0, 0x2F, 0x93, 0x3F, 0x9C, 0xEF, 0xC7, 0xA2, 0xF6, 0x53, 0x89, 0x42, 0xF7, 0xBF, 0x25, 0xFF, - 0x24, 0xC1, 0xDF, 0x48, 0xF2, 0x07, 0x12, 0xFF, 0x1F, 0x3E, 0xEE, 0x7E, 0x1F, 0xE5, 0xDF, 0x43, 0x2E, 0x74, 0xB6, 0x04, 0xAE, 0x99, 0xDD, 0x8E, - 0xCE, 0x96, 0xC0, 0xB5, 0xF3, 0x16, 0x8C, 0x9D, 0xA7, 0xE0, 0x78, 0x5E, 0x82, 0xE4, 0x79, 0x06, 0xEA, 0xCE, 0x23, 0x30, 0x3C, 0x6F, 0x8C, 0x78, - 0x5E, 0x80, 0x9F, 0x07, 0xA0, 0xCF, 0x13, 0x1B, 0x9E, 0x77, 0xB5, 0xF3, 0x30, 0x60, 0x67, 0xC2, 0xF3, 0xAF, 0x5D, 0xBF, 0x5C, 0xC4, 0x33, 0xAE, - 0xDE, 0xB9, 0xD6, 0xF0, 0x7C, 0x17, 0x3C, 0xBF, 0x4A, 0x9E, 0x5B, 0xB5, 0x9D, 0x59, 0x25, 0xCF, 0x76, 0xC0, 0x73, 0x2A, 0xE3, 0x19, 0x55, 0xEF, - 0x7C, 0xEA, 0x48, 0x6A, 0x4D, 0xEE, 0x3C, 0x2A, 0x78, 0x06, 0x75, 0xCF, 0x75, 0xC5, 0xB3, 0xA7, 0x7A, 0xE6, 0x64, 0x77, 0xD6, 0xE4, 0x3B, 0x67, - 0xBA, 0x67, 0x4C, 0x6E, 0x67, 0xE3, 0xD9, 0xF9, 0xD2, 0x0C, 0x9E, 0x29, 0xD1, 0xB3, 0xA4, 0x89, 0x2C, 0x9E, 0xE7, 0xDA, 0xCE, 0x90, 0xEA, 0xCE, - 0x8F, 0xEE, 0xB9, 0x51, 0xEF, 0xBC, 0x48, 0x78, 0x46, 0x94, 0x3C, 0x1B, 0x52, 0x3B, 0x17, 0xBA, 0x3B, 0x13, 0xF2, 0x9D, 0x03, 0x95, 0x67, 0x40, - 0xC4, 0xB3, 0x9F, 0x9F, 0x8B, 0xC2, 0xF3, 0x1E, 0xBA, 0xF3, 0x1E, 0xE1, 0x59, 0xCF, 0xF1, 0x1C, 0xF7, 0x3B, 0xC7, 0xCD, 0xB3, 0x1D, 0xB5, 0x73, - 0x9D, 0xBB, 0x73, 0x1D, 0xE0, 0x59, 0x8E, 0xF1, 0x4C, 0x34, 0x9E, 0xDF, 0xCC, 0xB3, 0x9B, 0xE1, 0x99, 0x8C, 0xDB, 0xB9, 0xCB, 0xEF, 0x0C, 0x37, - 0x76, 0xCE, 0x82, 0x3C, 0x67, 0xB9, 0xE7, 0x2C, 0xBF, 0x33, 0x16, 0xE3, 0xD9, 0x8A, 0xEF, 0x5C, 0xE5, 0x9E, 0xA7, 0xCC, 0x73, 0x94, 0xE4, 0xF9, - 0x89, 0xF0, 0xFC, 0x76, 0x3C, 0xBF, 0x11, 0xCF, 0x6E, 0x3F, 0x27, 0xB1, 0x3B, 0x1F, 0x31, 0x9E, 0x8D, 0xD8, 0x33, 0x70, 0x78, 0x1E, 0x22, 0x3C, - 0x03, 0xB9, 0x3B, 0xFF, 0xEC, 0x99, 0xC7, 0xF0, 0xCC, 0x83, 0x9E, 0x77, 0x20, 0xCF, 0x3B, 0xE4, 0x1E, 0x81, 0x61, 0xA8, 0x51, 0x18, 0xAF, 0x4D, - 0x46, 0x19, 0x05, 0x05, 0x05, 0x85, 0x0C, 0x63, 0xE1, 0x96, 0x88, 0x88, 0xA2, 0x24, 0x49, 0x1E, 0xB2, 0x30, 0x96, 0x74, 0x24, 0x14, 0xD5, 0x45, - 0x65, 0x14, 0x94, 0x51, 0xA9, 0x1F, 0x63, 0x90, 0x61, 0x3B, 0xD0, 0xB0, 0x9A, 0xB8, 0x61, 0xBB, 0xD0, 0xB0, 0xD8, 0x45, 0x25, 0xBE, 0x37, 0x44, - 0x69, 0x3F, 0x3C, 0x0E, 0x10, 0x60, 0x0F, 0x82, 0x1F, 0x24, 0xED, 0x47, 0x1F, 0x0C, 0xC4, 0xA4, 0xC3, 0xEF, 0x5A, 0x71, 0xD2, 0xEE, 0xD3, 0xDA, - 0x0E, 0xA5, 0xA7, 0x25, 0x38, 0x79, 0xDF, 0xF4, 0x9B, 0x74, 0xBE, 0xBB, 0xA9, 0x8B, 0x19, 0x94, 0xD9, 0x0F, 0x8A, 0x08, 0xDE, 0x9B, 0x48, 0x23, - 0x55, 0xB5, 0x23, 0x62, 0x77, 0xED, 0x5F, 0x98, 0xB3, 0x29, 0xC8, 0x46, 0x84, 0x94, 0x15, 0xFB, 0xF8, 0x33, 0x54, 0xFE, 0x93, 0xDB, 0xBB, 0x77, - 0x05, 0x03, 0x55, 0xCF, 0xE7, 0x38, 0x3B, 0x3C, 0xEC, 0x3E, 0xBE, 0x63, 0x2C, 0xCE, 0x1B, 0x69, 0x75, 0x63, 0x73, 0x0E, 0x92, 0xDE, 0x2C, 0x85, - 0x8F, 0x50, 0x00, 0xD3, 0x22, 0x37, 0xAB, 0xD9, 0x6D, 0x12, 0x23, 0xD5, 0x69, 0x4E, 0x77, 0x93, 0x92, 0x94, 0xA4, 0x24, 0xA5, 0xA9, 0x4D, 0xA5, - 0x67, 0x10, 0x14, 0xE8, 0x4F, 0xF6, 0xF0, 0x48, 0x72, 0xE6, 0x39, 0x8A, 0xD9, 0xEC, 0x76, 0x20, 0xA1, 0xA2, 0x11, 0x03, 0xDA, 0x46, 0xE7, 0x56, - 0x62, 0x53, 0x91, 0xB3, 0x60, 0x58, 0x03, 0x04, 0xD6, 0xA0, 0x58, 0xE5, 0x7B, 0xBE, 0x03, 0xFD, 0x32, 0x24, 0x4D, 0x1D, 0x78, 0xAA, 0x5A, 0x6F, - 0x8F, 0xEA, 0x91, 0xE4, 0xCC, 0x73, 0x14, 0x33, 0x45, 0x85, 0x7C, 0xBC, 0x99, 0x53, 0xCE, 0x62, 0x94, 0x21, 0xDE, 0x3D, 0x64, 0x3A, 0x9E, 0x2A, - 0x0D, 0xE4, 0x0D, 0x8B, 0xD4, 0xE7, 0x39, 0xDD, 0xB3, 0x8D, 0x9E, 0xA0, 0xAB, 0x5D, 0x27, 0x13, 0x34, 0x65, 0x20, 0xBD, 0x53, 0xA2, 0x62, 0x13, - 0xA1, 0x23, 0x7C, 0x99, 0xE5, 0xA1, 0xF2, 0x83, 0x42, 0x07, 0xAF, 0x82, 0xCD, 0xC1, 0x77, 0x68, 0x3E, 0x58, 0x2C, 0x0E, 0x3E, 0x06, 0xC4, 0x35, - 0x0E, 0xEA, 0x55, 0xDE, 0xBB, 0xA0, 0x02, 0xE1, 0x12, 0x14, 0x96, 0xEA, 0xC6, 0xA0, 0x12, 0xA5, 0x08, 0x46, 0x81, 0x86, 0x26, 0x06, 0x84, 0x11, - 0x00, 0xC6, 0x5D, 0x68, 0x39, 0xC0, 0x1E, 0xA5, 0x03, 0x58, 0x8B, 0x56, 0x2A, 0xBF, 0x0B, 0xE6, 0x71, 0xD2, 0xF4, 0xD5, 0xCE, 0x06, 0x85, 0x28, - 0xA1, 0x18, 0x46, 0xB6, 0x02, 0x81, 0x26, 0x7A, 0x33, 0x09, 0xAD, 0xA6, 0xEF, 0x34, 0x89, 0x56, 0xCC, 0x92, 0xE9, 0x73, 0x91, 0x05, 0x05, 0xE2, - 0x6E, 0x88, 0x9E, 0xA7, 0x26, 0x47, 0xA5, 0x22, 0x92, 0x59, 0x7D, 0x44, 0x72, 0xA7, 0x54, 0x00, 0x59, 0x00, 0x49, 0x00, 0xD8, 0xF7, 0x8E, 0xFB, - 0xCE, 0x81, 0xDF, 0x37, 0xD0, 0xB7, 0xCD, 0xF2, 0x5D, 0xE3, 0xF7, 0x9E, 0x69, 0xDF, 0x6E, 0xFC, 0x86, 0x31, 0xBE, 0x5B, 0xE2, 0x37, 0x4B, 0xDC, - 0x5B, 0x05, 0xFB, 0x36, 0x81, 0xBE, 0x4B, 0xE2, 0xDE, 0xC9, 0xE5, 0x9B, 0xE4, 0xF8, 0x46, 0xC2, 0x6F, 0x90, 0xF7, 0xDD, 0xF1, 0x37, 0xC7, 0xD7, - 0x3B, 0x63, 0xF9, 0xB6, 0xA8, 0x88, 0x7A, 0x1B, 0xAB, 0xEF, 0x88, 0x87, 0xEA, 0xBB, 0xA1, 0xF9, 0x5E, 0x20, 0x84, 0xAB, 0xCE, 0x37, 0xA9, 0xF0, - 0xF8, 0xED, 0xCB, 0xF9, 0x26, 0x13, 0x1E, 0x07, 0x7F, 0xAF, 0x3C, 0x1E, 0xE1, 0x05, 0x6B, 0xD4, 0x33, 0x06, 0x6A, 0x19, 0x93, 0xF0, 0x4D, 0xC5, - 0x82, 0xA5, 0x60, 0xB9, 0x8C, 0xF1, 0x7B, 0x8B, 0xCA, 0x7C, 0x6B, 0x31, 0xC0, 0xD0, 0x77, 0x16, 0x32, 0xEE, 0x8D, 0x85, 0xCC, 0x4E, 0xDD, 0xAB, - 0x23, 0xD6, 0xF9, 0xB6, 0xAA, 0x3A, 0x80, 0xA7, 0x6F, 0x2A, 0xE4, 0x5B, 0xFA, 0xF7, 0x94, 0x94, 0xDA, 0xFB, 0x29, 0x0A, 0x7E, 0x47, 0xDF, 0x77, - 0x13, 0x93, 0x4B, 0xF8, 0x7E, 0x3E, 0x9B, 0xEF, 0xA7, 0xFB, 0xEE, 0x24, 0xA4, 0xF6, 0x6D, 0xD4, 0x9C, 0xBE, 0x87, 0x84, 0xB2, 0x6F, 0xA0, 0x9F, - 0x9E, 0x07, 0x20, 0x0A, 0xEE, 0xC1, 0x57, 0x33, 0xB0, 0x2B, 0xFD, 0x2D, 0xF4, 0x37, 0xCE, 0xDF, 0x31, 0x7F, 0xAB, 0xFC, 0x2D, 0xF2, 0x77, 0xC6, - 0xDF, 0x0E, 0x7F, 0x1B, 0xFC, 0xD9, 0xF0, 0xCF, 0xD9, 0xF8, 0xCF, 0x75, 0x7F, 0xBE, 0xFE, 0xD9, 0xFA, 0xE7, 0xB1, 0x3F, 0x4B, 0xFF, 0xCC, 0xF4, - 0xE7, 0xA1, 0xFF, 0x19, 0x25, 0x53, 0xFC, 0x39, 0xE1, 0xCF, 0x03, 0xFF, 0x0B, 0xFB, 0xFE, 0xE3, 0xFD, 0x97, 0x4B, 0xFB, 0x2F, 0xF6, 0x7F, 0x1A, - 0x3D, 0x0A, 0x57, 0x2B, 0x57, 0x94, 0x48, 0x47, 0x06, 0x05, 0xE4, 0x27, 0x70, 0x38, 0xCC, 0xEE, 0xD5, 0x5D, 0xAD, 0x5D, 0x4D, 0x3D, 0x30, 0x23, - 0x13, 0x7F, 0xB1, 0x18, 0x78, 0x07, 0x87, 0xD6, 0x5A, 0x3D, 0x83, 0x6A, 0x58, 0x5A, 0x8D, 0x86, 0xBF, 0x6D, 0x07, 0xF9, 0x88, 0x6E, 0x64, 0x44, - 0x68, 0x51, 0x8E, 0xAB, 0xF4, 0x90, 0x30, 0xF8, 0x89, 0xCF, 0xEA, 0xCD, 0xB5, 0x85, 0x41, 0x21, 0xF9, 0xD0, 0xAC, 0x8C, 0x6C, 0x40, 0xFC, 0x03, - 0x2D, 0x60, 0x1E, 0xDD, 0x5B, 0x19, 0x56, 0xF4, 0x88, 0xE7, 0xE5, 0x24, 0x04, 0x43, 0xA0, 0xF8, 0x67, 0xC7, 0xE6, 0xE5, 0xC4, 0x5C, 0xE9, 0x08, - 0xC8, 0x31, 0x5C, 0x98, 0x74, 0x29, 0xE8, 0x75, 0x51, 0x7E, 0x5C, 0x2C, 0x3C, 0x80, 0xB1, 0xA8, 0x71, 0xA0, 0x29, 0x10, 0x53, 0x90, 0x14, 0x14, - 0x6A, 0x0D, 0x63, 0xF1, 0x9A, 0x88, 0xB4, 0x20, 0x05, 0x85, 0x74, 0xE0, 0x19, 0x03, 0xDD, 0x4E, 0x9B, 0xEF, 0x91, 0x2F, 0x84, 0x6D, 0xC0, 0x0E, - 0x04, 0x38, 0xDE, 0x19, 0xAD, 0x52, 0xC8, 0x5A, 0x0A, 0xA7, 0xFD, 0xA3, 0x57, 0x7E, 0xDF, 0xD4, 0x3D, 0x88, 0x0A, 0x70, 0x54, 0x64, 0x9C, 0x46, - 0x0D, 0x74, 0x3B, 0xF6, 0xCB, 0xAE, 0x7D, 0xD8, 0x7F, 0x75, 0x8A, 0x3A, 0x29, 0xE4, 0x8D, 0x5D, 0x4A, 0x3C, 0x55, 0x7C, 0x9D, 0xFF, 0x1A, 0xAA, - 0x78, 0x5F, 0xA9, 0xFC, 0x72, 0x51, 0xF2, 0x1D, 0xB6, 0x12, 0xD7, 0xB6, 0x5F, 0xB8, 0xE7, 0x0D, 0xA2, 0xEC, 0xBF, 0xCE, 0x51, 0x89, 0x77, 0x61, - 0xFD, 0x06, 0xBC, 0xBD, 0x1B, 0x6D, 0x4F, 0xB0, 0x94, 0xE9, 0x8F, 0xF0, 0xCB, 0xDA, 0xE9, 0xB8, 0xEE, 0xD7, 0x59, 0x5A, 0xAC, 0x1F, 0x55, 0xC5, - 0x26, 0x90, 0x22, 0xE3, 0xC5, 0x8A, 0x63, 0x81, 0xB7, 0xDC, 0x07, 0x00, 0xD4, 0x0D, 0xD2, 0xE1, 0xF1, 0x04, 0x0B, 0x00, 0x00, 0x16, 0x27, 0x37, - 0x49, 0x58, 0x6B, 0x7F, 0x90, 0xA0, 0xB2, 0xC5, 0xD6, 0xE9, 0xF8, 0x09, 0x0C, 0x00, 0x00, 0x19, 0x26, 0x36, 0x52, 0x6E, 0x8D, 0x9A, 0xAA, 0xB9, - 0xCD, 0xE0, 0xF0, 0x07, 0x0D, 0x00, 0x00, 0x1D, 0x30, 0x44, 0x58, 0x6D, 0x81, 0x96, 0xA5, 0xB4, 0xC5, 0xD8, 0xE8, 0xFD, 0x0E, 0x0E, 0x00, 0x00, - 0x1F, 0x35, 0x47, 0x5C, 0x6D, 0x7B, 0x91, 0xA2, 0xB3, 0xC4, 0xD6, 0xE9, 0xFF, 0x13, 0x0F, 0x00, 0x00, 0x21, 0x35, 0x45, 0x55, 0x65, 0x77, 0x86, - 0x99, 0xAA, 0xBA, 0xCE, 0xDF, 0xF0, 0x0A, 0x10, 0x31, 0x44, 0x56, 0x69, 0x7F, 0x90, 0xA1, 0x10, 0xC7, 0xD1, 0xDD, 0xE8, 0xF4, 0xFF, 0x0B, 0x11, - 0x00, 0x00, 0x19, 0x28, 0x34, 0x41, 0x4E, 0x58, 0x65, 0x72, 0x7E, 0x8B, 0x97, 0xA5, 0xB0, 0xC0, 0xCF, 0xDE, 0xEB, 0xF6, 0x04, 0x12, 0x00, 0x00, - 0x0F, 0x19, 0x24, 0x32, 0x41, 0x4B, 0x57, 0x63, 0x74, 0x83, 0x8D, 0x9A, 0xA8, 0xB5, 0xC3, 0xD2, 0xDD, 0xEC, 0xF9, 0x06, 0x13, 0x00, 0x00, 0x15, - 0x23, 0x31, 0x3E, 0x4F, 0x61, 0x6E, 0x7A, 0x85, 0x90, 0x9D, 0xAB, 0xB7, 0xC3, 0xD0, 0xE2, 0xF3, 0xFD, 0x07, 0x14, 0x00, 0x00, 0x17, 0x26, 0x35, - 0x40, 0x4E, 0x5D, 0x6A, 0x76, 0x82, 0x90, 0x9F, 0xAA, 0xB8, 0xC7, 0xDA, 0xE6, 0xF4, 0x01, 0x15, 0x00, 0x00, 0x0D, 0x1B, 0x27, 0x34, 0x3F, 0x4A, - 0x5D, 0x6E, 0x7E, 0x8A, 0x98, 0xA7, 0xB8, 0xC5, 0xD1, 0xE4, 0xF1, 0x01, 0x16, 0x00, 0x00, 0x12, 0x22, 0x36, 0x46, 0x80, 0xB1, 0xA4, 0x20, 0xBA, - 0x35, 0xF0, 0xD9, 0x0C, 0x00, 0xEC, 0x30, 0x7B, 0x1E, 0xFF, 0x79, 0x84, 0x00, 0xC8, 0x38, 0x60, 0x6E, 0xE4, 0xCD, 0x31, 0x14, 0x46, 0x1F, 0x5C, - 0x6B, 0x00, 0xFA, 0x7F, 0x5C, 0x1D, 0x38, 0x20, 0x1E, 0xD7, 0x1A, 0xAF, 0x65, 0x60, 0xB8, 0x1E, 0x92, 0x0F, 0x23, 0xD0, 0x7E, 0x9E, 0x1C, 0x6D, - 0x3F, 0x0F, 0x7C, 0x87, 0x4B, 0xCA, 0xD9, 0x16, 0x81, 0xD7, 0x09, 0x04, 0xD0, 0xCF, 0x63, 0x02, 0xBF, 0xF0, 0x1B, 0x20, 0xC3, 0x27, 0x2A, 0x6A, - 0x23, 0x49, 0x88, 0x18, 0x5E, 0xAA, 0x71, 0x32, 0x3F, 0x1E, 0xB7, 0x0A, 0x6E, 0x4D, 0xA6, 0xE0, 0x01, 0xD7, 0x01, 0xD4, 0x01, 0x89, 0x75, 0xD2, - 0x42, 0x37, 0xBA, 0x72, 0xDA, 0xAA, 0x37, 0xA2, 0x31, 0x34, 0xBA, 0x32, 0x3E, 0xD8, 0xDF, 0xEA, 0x22, 0xE0, 0xDA, 0x88, 0x5D, 0x6D, 0xD3, 0xB6, - 0x1B, 0xBD, 0xBB, 0x78, 0xEE, 0x4A, 0x32, 0xB7, 0x18, 0xEC, 0xD0, 0xA7, 0x74, 0xA3, 0xDC, 0x4F, 0xFA, 0xEE, 0xBD, 0x21, 0xF3, 0xED, 0x26, 0xED, - 0x62, 0xC2, 0xBC, 0x89, 0x9B, 0xC4, 0x97, 0x7D, 0xA7, 0x08, 0xB7, 0xBA, 0xC1, 0x77, 0xF7, 0xE6, 0x46, 0x91, 0xDC, 0x49, 0xB6, 0x59, 0xD3, 0xCE, - 0x6C, 0x63, 0x43, 0x52, 0xB5, 0x9E, 0x68, 0x23, 0x2E, 0x55, 0x39, 0xB4, 0xD1, 0x81, 0x36, 0xA0, 0x3D, 0xC4, 0x2A, 0x20, 0x88, 0xFD, 0xE3, 0x0D, - 0x7A, 0xC4, 0xD9, 0x66, 0xB4, 0xB0, 0x87, 0xD9, 0xE5, 0xA7, 0x88, 0x1F, 0xB0, 0x09, 0x60, 0x9F, 0x9E, 0xF6, 0xD3, 0x3E, 0x97, 0x3B, 0x09, 0xC8, - 0x49, 0x2A, 0x2B, 0xE7, 0x59, 0xB4, 0x79, 0x68, 0xF4, 0xF5, 0x05, 0xB8, 0x40, 0xFF, 0x01, 0x4D, 0x3E, 0x8B, 0xE4, 0xFC, 0x3F, 0xF8, 0xAA, 0x00, - 0x83, 0x3B, 0xEF, 0x26, 0x93, 0x46, 0x51, 0xA7, 0x54, 0xE9, 0x59, 0xFF, 0x2F, 0x82, 0xC3, 0x26, 0x4D, 0xA3, 0x62, 0x22, 0x7A, 0xF0, 0xCC, 0x87, - 0x83, 0x2D, 0x4D, 0x44, 0x99, 0xEB, 0x80, 0x98, 0x9B, 0x85, 0xFA, 0xB9, 0x45, 0x82, 0x2C, 0xE3, 0x98, 0x49, 0x9C, 0x72, 0xE4, 0x07, 0x8E, 0x19, - 0x68, 0x21, 0xC2, 0x2C, 0x80, 0x75, 0x6D, 0x11, 0x08, 0x4B, 0x4D, 0xFF, 0x00, 0xCE, 0xB4, 0x1C, 0x47, 0x2F, 0x86, 0x81, 0x78, 0x6F, 0x2B, 0xC6, - 0xCA, 0x5B, 0x63, 0xAA, 0xEA, 0xBF, 0x05, 0xA0, 0x39, 0x27, 0x4D, 0x62, 0x21, 0xA0, 0x1E, 0xDC, 0x8A, 0xB2, 0x0A, 0x5B, 0x55, 0xD7, 0x5F, 0x2B, - 0x25, 0x64, 0x19, 0x69, 0x86, 0x4B, 0x94, 0x3F, 0x3B, 0x33, 0x8C, 0x35, 0x15, 0x68, 0x26, 0xCA, 0x3E, 0x84, 0x95, 0x27, 0x78, 0x19, 0x00, 0x43, - 0x51, 0x93, 0x8A, 0xFE, 0xEC, 0x50, 0x21, 0xCD, 0xCB, 0x3A, 0x73, 0xDE, 0x40, 0x82, 0x41, 0x2B, 0xF1, 0xBB, 0x73, 0x53, 0x13, 0x61, 0xA1, 0x81, - 0x95, 0xAD, 0xC5, 0x5A, 0x95, 0x88, 0x7E, 0xAA, 0x3A, 0x90, 0x26, 0xA6, 0x1D, 0xCA, 0xC8, 0x46, 0x2D, 0x84, 0x46, 0xF4, 0xE4, 0x5E, 0x98, 0x71, - 0xF0, 0x22, 0xD0, 0x85, 0xFA, 0xA7, 0x8C, 0x36, 0x2D, 0x23, 0x19, 0xB3, 0x38, 0x11, 0xB2, 0x23, 0x8E, 0xED, 0x4C, 0x4C, 0x82, 0x02, 0x71, 0xB6, - 0xFA, 0x63, 0x87, 0xF8, 0xD4, 0x61, 0xB3, 0x88, 0x56, 0x12, 0x04, 0x2F, 0x8E, 0xAD, 0x2C, 0x03, 0x04, 0xB2, 0x56, 0xEA, 0x99, 0x92, 0x8D, 0x5B, - 0x08, 0xCF, 0x79, 0x35, 0x56, 0x90, 0x95, 0x1D, 0x90, 0xB7, 0xD4, 0xFF, 0x1A, 0x15, 0xA4, 0x87, 0x32, 0xB2, 0x71, 0x31, 0x4B, 0xE1, 0x92, 0x73, - 0x9F, 0x5D, 0x5C, 0x5B, 0x8A, 0x11, 0x62, 0x60, 0x0C, 0x06, 0x54, 0x6D, 0x9F, 0xA2, 0x00, 0x00, 0x4A, 0x53, 0xBE, 0x39, 0xA3, 0x88, 0x25, 0x8A, - 0xE0, 0x39, 0x48, 0x8F, 0xBB, 0xBA, 0x39, 0x38, 0x1A, 0x6D, 0x25, 0x30, 0x70, 0x91, 0xB7, 0x3F, 0x94, 0x94, 0xD0, 0xE5, 0xE3, 0x62, 0x95, 0x42, - 0x26, 0x82, 0x81, 0x67, 0x21, 0x79, 0x36, 0xD6, 0x4C, 0x94, 0x8D, 0x49, 0x38, 0xD0, 0xB5, 0xFE, 0x4F, 0xCF, 0x3D, 0x91, 0x65, 0xB4, 0x10, 0xFE, - 0xD5, 0xB1, 0x9D, 0x89, 0x45, 0x10, 0xC0, 0xFD, 0x9D, 0xA8, 0x81, 0x2A, 0xD5, 0x2C, 0x52, 0x09, 0xBC, 0x93, 0x71, 0x42, 0x43, 0x30, 0x00, 0x19, - 0xA1, 0x70, 0x81, 0x34, 0xC8, 0x82, 0x68, 0x4C, 0x6D, 0x8C, 0x16, 0x9D, 0x7B, 0x1B, 0x9F, 0x11, 0x25, 0x7D, 0x19, 0xDA, 0xF2, 0x0A, 0x36, 0x22, - 0x12, 0x19, 0xB0, 0xB1, 0xD7, 0x98, 0xEB, 0xDE, 0x13, 0x23, 0xAA, 0x50, 0xC5, 0x98, 0x7D, 0x13, 0x76, 0xC7, 0xF8, 0x79, 0x69, 0x9B, 0xAD, 0x8B, - 0x77, 0x23, 0x5E, 0x23, 0xC5, 0x46, 0x52, 0xCD, 0x35, 0xCF, 0xF1, 0x50, 0x8C, 0x2E, 0x22, 0x26, 0x82, 0x43, 0x3C, 0xA7, 0xE6, 0x5D, 0xAB, 0x60, - 0x97, 0xEF, 0x6E, 0x81, 0x2F, 0x20, 0xD5, 0xD2, 0x1E, 0x31, 0x92, 0xB8, 0xE8, 0x72, 0x69, 0xEB, 0x8F, 0xB6, 0xD9, 0x8A, 0x95, 0xE1, 0xF9, 0xEE, - 0x4A, 0xF5, 0x3E, 0x97, 0x2D, 0x93, 0xB3, 0x76, 0x47, 0xB3, 0x3A, 0x0B, 0xB3, 0x2A, 0x1F, 0xB0, 0xCD, 0x4B, 0x93, 0x97, 0x82, 0xB2, 0x6A, 0xB2, - 0x86, 0xB0, 0xFA, 0x51, 0xD3, 0x25, 0xED, 0x72, 0x5E, 0x1D, 0x34, 0x4C, 0x95, 0x62, 0xAD, 0xA1, 0xCB, 0xEB, 0xDC, 0x49, 0xD5, 0xA0, 0x5E, 0x15, - 0xDE, 0x8B, 0xBB, 0x16, 0x07, 0xA3, 0xA2, 0x2A, 0x2D, 0x2C, 0x2C, 0x46, 0xF0, 0x05, 0xDC, 0xDA, 0xE6, 0x25, 0x1E, 0x55, 0x48, 0xF6, 0x9D, 0xEA, - 0xCE, 0xC7, 0x46, 0x0C, 0x63, 0x3E, 0x86, 0xD1, 0x3C, 0xBB, 0x47, 0x0C, 0x1F, 0x2A, 0xB1, 0xCD, 0x78, 0x61, 0x3B, 0x18, 0x61, 0x17, 0x63, 0xE1, - 0x0F, 0x4C, 0xF5, 0xBD, 0xC2, 0x5C, 0xD4, 0x1F, 0x27, 0xDB, 0x88, 0x76, 0x59, 0x1C, 0x0E, 0x6B, 0x57, 0x84, 0xAD, 0x61, 0x2A, 0x52, 0xFA, 0x83, - 0xA6, 0x80, 0x6A, 0x26, 0x3F, 0xB5, 0x19, 0x9F, 0xA6, 0x40, 0x4C, 0x67, 0xA3, 0x9E, 0xAB, 0xC0, 0x73, 0xBE, 0x4A, 0x30, 0x9D, 0xFB, 0x4D, 0xD6, - 0x44, 0x71, 0xC0, 0x6F, 0xA0, 0x54, 0x01, 0xD8, 0xDC, 0xFA, 0x08, 0x46, 0x83, 0xE5, 0x06, 0x07, 0x82, 0x01, 0x73, 0x9C, 0xE9, 0xAE, 0x0E, 0x6C, - 0x80, 0xE1, 0xAE, 0x67, 0xB0, 0x8A, 0x0C, 0x69, 0x27, 0x9F, 0xB8, 0x66, 0x9A, 0x9D, 0x5A, 0x36, 0x80, 0x0C, 0x0C, 0xE2, 0x0B, 0xDC, 0xA5, 0x05, - 0x26, 0x63, 0xD9, 0xC4, 0x97, 0x0B, 0x4B, 0x69, 0xBD, 0x53, 0x46, 0x36, 0xD6, 0x72, 0x0B, 0xA6, 0x92, 0x62, 0x03, 0x27, 0xD9, 0xE6, 0xCC, 0xEF, - 0xE5, 0xDB, 0xDC, 0x8D, 0x77, 0x8D, 0x08, 0xFB, 0x43, 0xBB, 0xCC, 0x65, 0x07, 0x1D, 0xF8, 0x05, 0x9C, 0xBB, 0xF7, 0xCC, 0xBE, 0x65, 0x5F, 0xF6, - 0x9B, 0x2A, 0xBF, 0x63, 0x74, 0xD5, 0x0B, 0xBF, 0xF5, 0xF6, 0x76, 0xCA, 0x05, 0xB8, 0x55, 0x96, 0x4A, 0x0D, 0xFB, 0x8D, 0xFA, 0x95, 0xD3, 0x45, - 0x58, 0xBF, 0x54, 0xA5, 0x37, 0x67, 0xE0, 0x37, 0x6D, 0xC4, 0x49, 0x6F, 0x9C, 0xA8, 0xE1, 0x19, 0xBD, 0x61, 0xBC, 0x8A, 0xDD, 0x26, 0x52, 0xB2, - 0xE5, 0x1E, 0x47, 0x69, 0x67, 0xB3, 0xCB, 0xDE, 0xB5, 0xBB, 0x4B, 0xA4, 0xE6, 0x05, 0x01, 0x96, 0x8D, 0xEC, 0xE0, 0x15, 0xFB, 0x38, 0xCC, 0x5B, - 0x9E, 0x96, 0xD1, 0x62, 0x79, 0xC7, 0xD8, 0xC8, 0xAA, 0x29, 0xC2, 0xAF, 0xF7, 0x9E, 0x32, 0xE2, 0x85, 0x7A, 0x01, 0x78, 0xEB, 0x2B, 0x19, 0x21, - 0xAC, 0x58, 0xA0, 0xEE, 0x1F, 0xEC, 0x99, 0x66, 0x37, 0x53, 0xCD, 0xBD, 0x07, 0xFD, 0x0D, 0xCF, 0x52, 0xA8, 0x1A, 0x40, 0x61, 0x32, 0x37, 0x51, - 0x2A, 0xB2, 0x84, 0x6A, 0x3E, 0x9E, 0x8D, 0x08, 0x1D, 0xB4, 0x33, 0x0A, 0x50, 0x7F, 0x72, 0x62, 0x3B, 0xDB, 0xD2, 0xAB, 0xA7, 0x4E, 0xA5, 0x48, - 0xD0, 0x43, 0x5F, 0x14, 0x3D, 0xF4, 0x88, 0xE8, 0x46, 0x00, 0xFE, 0x34, 0xFA, 0x51, 0x52, 0xFD, 0xA4, 0xFF, 0xF9, 0xA6, 0xA7, 0x6F, 0xE7, 0xEE, - 0x4E, 0xE9, 0xFE, 0xC0, 0x36, 0x33, 0x59, 0xD1, 0xB2, 0x62, 0x70, 0x57, 0x6E, 0x0D, 0xC1, 0x5A, 0x5D, 0x6F, 0x79, 0x9A, 0xDE, 0xE2, 0x69, 0x21, - 0x69, 0x15, 0x55, 0x37, 0x1C, 0xB3, 0x4F, 0x0F, 0xF5, 0x08, 0x4F, 0x95, 0x5B, 0x79, 0x37, 0x3A, 0x59, 0x93, 0x62, 0xB4, 0x12, 0x95, 0x55, 0x0C, - 0x16, 0x9A, 0xD0, 0x49, 0xD6, 0xA0, 0x52, 0xA1, 0xE0, 0x37, 0x8F, 0x60, 0x15, 0x14, 0xB9, 0x52, 0x89, 0x48, 0xD5, 0x11, 0x82, 0xAD, 0xFA, 0x49, - 0x2D, 0xF6, 0x9D, 0xC3, 0x1E, 0x36, 0x2E, 0x4F, 0xEA, 0x77, 0x59, 0x39, 0xDE, 0x48, 0x37, 0xF5, 0xC2, 0x46, 0x16, 0xDC, 0xF5, 0x84, 0x8D, 0xF8, - 0x1C, 0x60, 0xE6, 0x94, 0x52, 0x56, 0xA7, 0xC9, 0x9E, 0x08, 0xC2, 0x29, 0xA1, 0x43, 0x3D, 0x48, 0xEC, 0x0F, 0xC2, 0xEA, 0xAE, 0xF2, 0xA9, 0x50, - 0x38, 0x8D, 0xAF, 0x5A, 0x52, 0xB3, 0x2B, 0x0B, 0x42, 0x9D, 0x3E, 0xD7, 0xBE, 0x53, 0x99, 0xAC, 0xA2, 0x29, 0xBD, 0x63, 0xDA, 0x66, 0x48, 0xAC, - 0x34, 0x44, 0x55, 0x3F, 0xC4, 0x42, 0x33, 0x85, 0xF8, 0x59, 0xAB, 0x59, 0xFD, 0xC3, 0x02, 0xB2, 0xB7, 0xDD, 0xDA, 0xDE, 0x6E, 0x3B, 0x56, 0x17, - 0xF5, 0xF4, 0xB8, 0xA6, 0x3B, 0x33, 0xD2, 0x0D, 0xF5, 0xE6, 0x6D, 0x84, 0x5E, 0x64, 0x2D, 0x47, 0x5C, 0x4D, 0x0A, 0x2D, 0xC0, 0xF4, 0x4C, 0x7B, - 0x2D, 0x31, 0x02, 0x6B, 0x2C, 0x8C, 0x79, 0x31, 0xAC, 0x0D, 0x94, 0xDC, 0xC4, 0xA8, 0x17, 0xA2, 0x34, 0x92, 0xE4, 0x15, 0xD8, 0x65, 0x2E, 0x96, - 0x36, 0x9A, 0x00, 0xCB, 0x49, 0x2E, 0x74, 0xC7, 0x36, 0x37, 0x92, 0xC9, 0x6C, 0xD3, 0x47, 0xDB, 0x66, 0xA6, 0x05, 0x64, 0x24, 0x59, 0xAA, 0x53, - 0x23, 0xDB, 0xF2, 0x99, 0xFC, 0x37, 0x4E, 0xD7, 0xDD, 0x7B, 0x2C, 0xEC, 0x77, 0x20, 0x8B, 0x35, 0x20, 0x6F, 0x81, 0xC9, 0xDD, 0x3A, 0x91, 0xBC, - 0x44, 0x56, 0xFA, 0x73, 0xA5, 0x59, 0x0B, 0xDE, 0x4D, 0x5B, 0x7D, 0x63, 0x8D, 0x13, 0x81, 0x9A, 0x9A, 0xCF, 0xD1, 0xE9, 0xC2, 0x4C, 0xED, 0xC8, - 0xE8, 0xDC, 0x10, 0xE6, 0x49, 0x14, 0x6F, 0xD6, 0xC5, 0xF9, 0xDD, 0x52, 0xB3, 0x65, 0x79, 0x98, 0x2B, 0x35, 0xDF, 0xD5, 0xB9, 0xF0, 0xEF, 0x4C, - 0x80, 0x5C, 0xF9, 0x18, 0xA7, 0xAF, 0xF8, 0xDC, 0x6C, 0xB3, 0xD9, 0x55, 0xD9, 0x13, 0x7A, 0xB0, 0x2B, 0xAF, 0xAC, 0xF9, 0x5A, 0xB6, 0xD9, 0x2A, - 0x77, 0x85, 0xBD, 0x8A, 0x2A, 0x04, 0x43, 0x10, 0x95, 0xC3, 0x26, 0x93, 0x5F, 0x1F, 0x2B, 0x74, 0x4F, 0x55, 0x49, 0x7A, 0x9C, 0x67, 0x1A, 0x87, - 0xCA, 0xE1, 0x90, 0x69, 0xA9, 0x97, 0x34, 0x53, 0x0D, 0x67, 0xA4, 0x8F, 0x65, 0x92, 0xA0, 0x63, 0x8C, 0x86, 0x80, 0x49, 0x82, 0xF0, 0xE5, 0xE8, - 0x31, 0xF1, 0x98, 0x88, 0x46, 0x72, 0x0E, 0x5F, 0x88, 0x96, 0x1A, 0xA1, 0x72, 0x1F, 0x85, 0x27, 0x23, 0x8C, 0x5A, 0x70, 0x22, 0xA5, 0x1A, 0x7C, - 0x9B, 0x20, 0x74, 0x7A, 0xE4, 0x40, 0x1C, 0xBB, 0x8A, 0x8C, 0x89, 0x48, 0xDD, 0x84, 0x3C, 0xCD, 0x6F, 0xA8, 0xA8, 0xEF, 0x6B, 0x7B, 0xE3, 0xBC, - 0x50, 0x4F, 0xB5, 0x53, 0x53, 0x9D, 0x55, 0x33, 0xD5, 0x56, 0xBB, 0xAE, 0xD6, 0xD4, 0x9A, 0x6A, 0x5A, 0x4B, 0xEB, 0xA5, 0xA4, 0x1A, 0xE9, 0xA8, - 0x36, 0xAA, 0x8B, 0xEA, 0x68, 0x0D, 0xAD, 0xEB, 0xFA, 0x2F, 0x74, 0x42, 0xC7, 0xFC, 0xA0, 0x0B, 0x7A, 0xA0, 0x03, 0xFA, 0xE6, 0xFF, 0xDC, 0xCF, - 0xFB, 0x5C, 0xF3, 0x7C, 0xBE, 0xE7, 0x99, 0xC7, 0x3C, 0x66, 0xED, 0xF4, 0xE7, 0x4F, 0x9C, 0x45, 0xAD, 0x54, 0x73, 0x9F, 0xF4, 0xAE, 0x3A, 0xC1, - 0x6B, 0x3C, 0x47, 0xDD, 0xE5, 0x70, 0x5C, 0x46, 0x84, 0x33, 0x5E, 0x5D, 0xAE, 0x5E, 0xFA, 0xD1, 0x41, 0xA0, 0x1D, 0xF9, 0xDB, 0x25, 0xE5, 0x65, - 0xFA, 0x7A, 0x2C, 0x9F, 0xE7, 0xCE, 0xED, 0x1C, 0x4F, 0xE5, 0xEB, 0x9C, 0x92, 0xCE, 0x3F, 0xA7, 0xAE, 0x4E, 0x5E, 0xCE, 0x25, 0x1F, 0xE7, 0x91, - 0x87, 0xF3, 0x37, 0x6D, 0xCE, 0x66, 0xCD, 0x21, 0x1F, 0x7F, 0x78, 0x34, 0x8E, 0x3F, 0xF3, 0xC6, 0x9B, 0x79, 0x19, 0xC6, 0x8F, 0xB9, 0x98, 0x87, - 0x39, 0x13, 0x37, 0x5F, 0xBC, 0xA2, 0x97, 0x77, 0x49, 0x3C, 0x97, 0x6F, 0x39, 0xE2, 0xB5, 0x64, 0xF9, 0xE1, 0xB1, 0x5C, 0x39, 0x18, 0x32, 0xB7, - 0x42, 0xC5, 0xF0, 0x90, 0x9F, 0xF2, 0xC2, 0x4B, 0x79, 0x94, 0x13, 0x1E, 0x4A, 0x1D, 0xF5, 0x27, 0x77, 0xF2, 0x26, 0x67, 0xF2, 0xC1, 0x25, 0x57, - 0x72, 0xC1, 0x27, 0x39, 0x92, 0xC0, 0x1F, 0xB9, 0x11, 0xC6, 0x3F, 0xBE, 0xC8, 0xAB, 0x1C, 0x7D, 0xC0, 0x9F, 0x4F, 0xE4, 0x43, 0xFE, 0xF7, 0x2F, - 0x17, 0xF2, 0x20, 0x40, 0xEE, 0xF7, 0x1F, 0xF7, 0xF1, 0xBE, 0xF7, 0xA8, 0x9E, 0xEF, 0x7B, 0x07, 0xA3, 0x77, 0x1E, 0xB5, 0x81, 0xE7, 0x1D, 0xAF, - 0xBE, 0xF0, 0x1D, 0xBF, 0x3B, 0x82, 0xDB, 0xE5, 0xA8, 0xA3, 0xBB, 0xF1, 0xB9, 0xDB, 0x90, 0x8B, 0x83, 0xFB, 0x1B, 0x8D, 0xD3, 0xFD, 0x69, 0xC6, - 0x65, 0x3C, 0xC6, 0xDB, 0xAE, 0xE3, 0x30, 0x5E, 0xDC, 0xCD, 0xC5, 0xD7, 0xDE, 0x82, 0xC5, 0x57, 0xA8, 0x3D, 0xC5, 0xD3, 0x8E, 0x76, 0x14, 0x27, - 0xD8, 0x8E, 0xE3, 0x67, 0x37, 0x71, 0xB3, 0x97, 0x38, 0x89, 0x97, 0x7D, 0xC4, 0x45, 0xFC, 0x7A, 0xB2, 0x8F, 0x3D, 0x04, 0x88, 0x7F, 0xB8, 0x87, - 0xB3, 0x75, 0x38, 0x87, 0x6F, 0xF8, 0xBA, 0xD8, 0x35, 0x3C, 0xC3, 0xA1, 0x1E, 0x76, 0x0C, 0xBF, 0x70, 0x09, 0x2F, 0xDF, 0xC2, 0x2B, 0x9C, 0xC2, - 0x27, 0x1C, 0xEC, 0x5F, 0x5E, 0xEF, 0x7A, 0x84, 0x73, 0x1D, 0xC2, 0x1F, 0x38, 0x78, 0x83, 0xAB, 0x38, 0x83, 0x2F, 0xB8, 0x84, 0x6F, 0x9D, 0xEE, - 0x0A, 0x9E, 0xE0, 0x08, 0x0E, 0xDC, 0xC0, 0x0B, 0x9C, 0xC0, 0x07, 0x08, 0xF8, 0xDA, 0x13, 0xD6, 0xC9, 0xBF, 0x1A, 0x8B, 0xC3, 0xE0, 0x7F, 0xEF, - 0xED, 0xFE, 0x66, 0xF1, 0xAD, 0xF6, 0xD9, 0x53, 0x7D, 0xEA, 0xFA, 0xA8, 0x07, 0x85, 0x86, 0xA8, 0xB3, 0xD3, 0x46, 0x76, 0x81, 0x05, 0x05, 0x05, - 0x05, 0x45, 0x29, 0xB4, 0x06, 0xA3, 0x48, 0x23, 0x8A, 0x84, 0x39, 0x84, 0x08, 0xA2, 0x9A, 0xA4, 0x03, 0xC3, 0x65, 0x80, 0xC6, 0x25, 0x10, 0x49, - 0x52, 0x92, 0x14, 0x94, 0x7F, 0xA4, 0xD2, 0x6E, 0x5F, 0xB6, 0xF8, 0x56, 0xE0, 0x8B, 0x06, 0x2B, 0x36, 0xA7, 0xBE, 0x8C, 0xD2, 0xB1, 0x3A, 0x9C, - 0xCD, 0xA9, 0x88, 0x2E, 0x21, 0x0B, 0x7A, 0xAA, 0xD3, 0xED, 0xC4, 0x4B, 0x83, 0x4A, 0xEA, 0x27, 0xD7, 0x95, 0x19, 0x8C, 0xB3, 0x31, 0x21, 0x93, - 0xD1, 0xAF, 0x76, 0x6A, 0xEB, 0x97, 0x33, 0x06, 0xE2, 0x3A, 0x73, 0x30, 0xF3, 0x71, 0xDC, 0xF9, 0x15, 0x2D, 0xBF, 0xFC, 0x74, 0x18, 0x98, 0xFE, - 0x55, 0x95, 0xEB, 0x7F, 0xB2, 0x1D, 0x3D, 0x5B, 0x68, 0x0A, 0x89, 0xDA, 0x51, 0xB1, 0x1A, 0x9D, 0xC4, 0xB6, 0x92, 0xA8, 0xA0, 0x62, 0x8F, 0xB8, - 0xB8, 0x34, 0xBA, 0x45, 0x9B, 0xBC, 0xE8, 0x6A, 0x71, 0x86, 0xA2, 0xE9, 0x16, 0xAC, 0x99, 0xEE, 0xB8, 0xEA, 0x17, 0x42, 0xBB, 0x3E, 0xAD, 0xD7, - 0x90, 0xE2, 0x1A, 0x47, 0xAE, 0xCB, 0xAD, 0x5E, 0xC0, 0x39, 0x3E, 0xE2, 0x5A, 0x2B, 0x76, 0x70, 0x0E, 0x79, 0xDD, 0x8B, 0x0D, 0x45, 0x0C, 0x8B, - 0xF5, 0xBA, 0x9F, 0xBE, 0x78, 0xA0, 0xA5, 0xBB, 0x09, 0x35, 0x95, 0x75, 0xA9, 0xEB, 0xFE, 0x33, 0x39, 0x6A, 0xB7, 0x75, 0x19, 0xB7, 0x76, 0x5C, - 0x8E, 0xA8, 0x7D, 0x9A, 0xC7, 0xD6, 0xBF, 0xF1, 0xE6, 0x02, 0xDC, 0xA2, 0x4C, 0x6C, 0x1D, 0xD3, 0xFF, 0x15, 0xEA, 0xBA, 0xD0, 0xEC, 0xDC, 0x5A, - 0x89, 0xE5, 0x19, 0xA6, 0x99, 0x79, 0x2B, 0xFE, 0x8D, 0x8A, 0x64, 0x76, 0x9B, 0xC4, 0xC9, 0x79, 0xB4, 0xF3, 0xD7, 0x66, 0x0F, 0x0D, 0x43, 0xDE, - 0x1B, 0x07, 0x22, 0x57, 0xE6, 0xB4, 0xC5, 0xDE, 0x1D, 0x98, 0x80, 0xD3, 0xDF, 0xD0, 0xFB, 0x46, 0xE4, 0xFE, 0xFE, 0x78, 0xFA, 0xBC, 0x0F, 0x67, - 0x6B, 0x4F, 0x4B, 0x1E, 0x78, 0xD6, 0xD7, 0x76, 0xE7, 0x55, 0x76, 0xAA, 0xC7, 0x0B, 0x66, 0x06, 0x3C, 0xED, 0xC4, 0xFD, 0xDE, 0x4A, 0x63, 0x2F, - 0xB0, 0xD0, 0xBF, 0x4F, 0x09, 0xBD, 0x65, 0x1B, 0xEF, 0x7D, 0x47, 0xDF, 0xF2, 0x53, 0xF1, 0x3E, 0x18, 0xDE, 0xFB, 0x65, 0x47, 0x07, 0x9A, 0x79, - 0x0D, 0xB6, 0xBB, 0x24, 0x49, 0x8A, 0xE8, 0x9C, 0x05, 0x19, 0x96, 0xFE, 0x88, 0x61, 0x13, 0x9F, 0xE9, 0x6C, 0x1E, 0xF2, 0xD9, 0x4C, 0x8F, 0xB9, - 0xAD, 0xB0, 0xDC, 0x65, 0xFC, 0x78, 0x68, 0x7C, 0x12, 0x8B, 0x17, 0x00, 0x8F, 0xDB, 0xC6, 0x43, 0x06, 0x5E, 0x10, 0x22, 0xE0, 0x6A, 0x8B, 0xE8, - 0xA2, 0xC4, 0xF7, 0xCE, 0x16, 0x45, 0x44, 0x64, 0x45, 0x4D, 0x04, 0xD6, 0xB4, 0xF9, 0xEB, 0x90, 0xA1, 0x39, 0x60, 0x37, 0xBC, 0x62, 0x12, 0xEA, - 0xD5, 0x12, 0x5B, 0x61, 0xF7, 0xE6, 0x83, 0x18, 0xAA, 0x2D, 0x0F, 0x02, 0x57, 0x2F, 0xE6, 0xE4, 0xE4, 0x11, 0xFC, 0x8A, 0x78, 0xAE, 0x47, 0xE6, - 0xFA, 0xCF, 0xF1, 0x74, 0x59, 0xBA, 0x9B, 0x1E, 0xE0, 0xBF, 0x96, 0x8D, 0x54, 0xEB, 0xC7, 0x59, 0xED, 0x3C, 0x9E, 0x0F, 0x2D, 0xFB, 0xDF, 0x65, - 0x85, 0xF0, 0xB8, 0xF5, 0x5F, 0xD5, 0xFB, 0xA0, 0x5C, 0x3E, 0xEF, 0x9C, 0x90, 0x49, 0x40, 0xFD, 0xD0, 0x8C, 0x9D, 0x47, 0x40, 0x51, 0x0F, 0x87, - 0xE8, 0x85, 0x4F, 0x13, 0xE5, 0xD2, 0xEC, 0xC6, 0xCF, 0xD1, 0x64, 0x18, 0xC2, 0xFB, 0xD5, 0x31, 0x1C, 0xA8, 0x7A, 0xCB, 0x35, 0xF5, 0xDC, 0x81, - 0x82, 0x67, 0xD9, 0xF4, 0x70, 0xB3, 0xA1, 0xD0, 0x37, 0xDD, 0x1F, 0xE2, 0xF3, 0xCE, 0xB9, 0x49, 0xC3, 0xBB, 0x9B, 0x39, 0x3B, 0x7E, 0x0E, 0xA9, - 0xB7, 0x7D, 0x27, 0x0F, 0xD6, 0x6B, 0x87, 0x7B, 0x5D, 0xCD, 0xFC, 0x56, 0xE8, 0x65, 0x29, 0x78, 0xA4, 0xFF, 0xA1, 0xA9, 0xE8, 0x51, 0x8A, 0x64, - 0x5E, 0xC7, 0xEF, 0x23, 0x9C, 0x9A, 0x15, 0x16, 0xD4, 0xE8, 0x27, 0xF1, 0x3F, 0x1F, 0x1A, 0xB9, 0x98, 0xEC, 0xF3, 0x2C, 0x1B, 0xC6, 0x7E, 0x8A, - 0x42, 0xEE, 0xA3, 0xCC, 0x00, 0xB2, 0x3F, 0xA6, 0x41, 0xB0, 0x28, 0xF5, 0xAE, 0x6A, 0x1C, 0x46, 0xAD, 0xE8, 0x7F, 0x33, 0xDB, 0xAA, 0x31, 0xBD, - 0x1A, 0x84, 0xAF, 0xE4, 0x10, 0xC6, 0x86, 0x30, 0xF6, 0x9D, 0x7B, 0xA0, 0x3A, 0x81, 0xFD, 0xC1, 0x0C, 0xCB, 0x9B, 0xA6, 0x5E, 0xCE, 0x78, 0x98, - 0xA6, 0x21, 0xCE, 0xF2, 0xBF, 0x92, 0xCA, 0x26, 0x8E, 0xEE, 0xA8, 0x2E, 0xED, 0x10, 0xD1, 0x05, 0xDD, 0xB4, 0xCF, 0x74, 0xFD, 0xB8, 0x60, 0xE1, - 0x80, 0x35, 0x12, 0xC2, 0xA7, 0x55, 0x24, 0xD0, 0x58, 0x52, 0xDB, 0x76, 0xF2, 0x5A, 0x2A, 0x75, 0x7E, 0x28, 0xC1, 0x76, 0x5F, 0xEA, 0x4C, 0x15, - 0xE6, 0xC6, 0x68, 0xBF, 0x6C, 0xE9, 0x7C, 0x95, 0x38, 0xA6, 0xF2, 0x3B, 0x3E, 0x9F, 0xED, 0x66, 0x29, 0x91, 0x95, 0x24, 0x3B, 0x03, 0xF6, 0x11, - 0x2A, 0x4C, 0x65, 0xFA, 0x95, 0xB1, 0x1C, 0xBB, 0x3A, 0x3D, 0x46, 0xC9, 0x32, 0x46, 0xCF, 0x8C, 0x71, 0xAC, 0x8D, 0x96, 0xF4, 0x6B, 0x4E, 0x07, - 0xA8, 0x5E, 0xFB, 0xCB, 0xFF, 0x1E, 0xB2, 0x67, 0x01, 0xB9, 0xD4, 0xE8, 0x56, 0x81, 0x54, 0x30, 0x3A, 0x8E, 0x30, 0x95, 0x1A, 0x9D, 0x2C, 0x80, - 0x0A, 0x62, 0xDA, 0xBE, 0x72, 0xCF, 0x6F, 0xFC, 0xDA, 0xB2, 0xAC, 0xC0, 0xD8, 0xDD, 0x05, 0xE6, 0x39, 0x68, 0x78, 0x27, 0x31, 0xC5, 0x23, 0x85, - 0x68, 0xDF, 0x59, 0x82, 0x16, 0x48, 0x1F, 0xF6, 0x2D, 0x9B, 0xDB, 0x27, 0xAC, 0xB3, 0x0D, 0x8E, 0x00, 0x8E, 0x14, 0x1C, 0x1E, 0xCE, 0x37, 0x72, - 0x68, 0xC6, 0x52, 0x9C, 0x1C, 0xC1, 0x3D, 0x23, 0xF8, 0xB6, 0x5B, 0x8C, 0x1F, 0x7E, 0x6C, 0x5C, 0x72, 0x6E, 0xF5, 0xDD, 0x34, 0x07, 0xBF, 0x05, - 0x2B, 0x1E, 0x71, 0x29, 0x69, 0xF2, 0x3E, 0x14, 0x52, 0xBB, 0x2F, 0x1A, 0x3B, 0xEF, 0x80, 0x03, 0x76, 0x13, 0x9A, 0x9B, 0xB2, 0xB2, 0x44, 0xE1, - 0xFD, 0xAA, 0xD2, 0xDA, 0x02, 0xC1, 0xFB, 0xB1, 0x67, 0xBC, 0xE2, 0x4A, 0x4A, 0xD4, 0x1E, 0xFE, 0x15, 0x1A, 0xCC, 0x53, 0xC3, 0xAD, 0x86, 0xF5, - 0x91, 0x64, 0x26, 0xC3, 0x6D, 0xE7, 0xF5, 0xE9, 0xC3, 0xEB, 0x15, 0xB6, 0x31, 0x08, 0x5D, 0xB2, 0xB7, 0x20, 0xB0, 0x8B, 0xC3, 0xE8, 0x87, 0xD8, - 0x14, 0x8B, 0x70, 0xF7, 0x6A, 0x85, 0x78, 0x4E, 0x0C, 0x5E, 0xB5, 0x30, 0xC7, 0x24, 0xA1, 0x8B, 0xBE, 0xAC, 0x48, 0xF3, 0xF3, 0x4F, 0x9D, 0x80, - 0x96, 0x9D, 0x91, 0xCE, 0xAE, 0x66, 0x6A, 0xD6, 0x65, 0xF3, 0x32, 0x38, 0xC0, 0xE1, 0x71, 0x5C, 0x29, 0x82, 0x81, 0xCB, 0x59, 0x10, 0x4E, 0x60, - 0x8C, 0x32, 0xC7, 0xE5, 0x17, 0xEB, 0xD7, 0xFC, 0x20, 0xEB, 0x8C, 0xF9, 0x97, 0x6C, 0x66, 0x13, 0x80, 0x43, 0xAD, 0xD1, 0xC1, 0x81, 0xAD, 0x4D, - 0x78, 0x5C, 0x02, 0x7E, 0xC2, 0x13, 0xA6, 0xEE, 0x3F, 0x80, 0xFA, 0x23, 0x08, 0x2C, 0xB7, 0xAA, 0xD7, 0x5A, 0x9F, 0x5C, 0xC8, 0xFD, 0xCE, 0xE3, - 0x4C, 0xAD, 0x13, 0x71, 0x41, 0x5B, 0xBB, 0xB1, 0x76, 0xAC, 0xA1, 0xFB, 0x26, 0xBD, 0xDF, 0xE7, 0x49, 0x8F, 0x25, 0x5D, 0xE8, 0xD8, 0xC7, 0x08, - 0x47, 0x02, 0x43, 0xCE, 0x39, 0x50, 0x19, 0x7C, 0xDC, 0xDF, 0x4E, 0x18, 0x26, 0xE2, 0x2B, 0x6A, 0x83, 0x4E, 0x58, 0x67, 0xFB, 0xB2, 0xBD, 0xBC, - 0xE5, 0x11, 0x82, 0x85, 0x00, 0x43, 0xC5, 0xE4, 0x77, 0x71, 0xB0, 0xF9, 0x38, 0x06, 0x7E, 0xDA, 0x1D, 0x38, 0x63, 0x78, 0xC3, 0x64, 0x2F, 0xE9, - 0x5F, 0xE5, 0x19, 0x3E, 0x8C, 0x52, 0x2A, 0xCA, 0xEA, 0xF9, 0x4E, 0x93, 0xFE, 0x93, 0x83, 0x9E, 0x62, 0x50, 0x20, 0x33, 0x5F, 0xFC, 0x88, 0x4A, - 0x2C, 0xDE, 0x23, 0xD6, 0x2C, 0x45, 0xEC, 0x32, 0x5B, 0xCC, 0x77, 0xFB, 0xDC, 0x78, 0xB7, 0x22, 0xF2, 0xBB, 0xBA, 0x13, 0xE2, 0xB9, 0x99, 0x63, - 0xDB, 0x4C, 0xE2, 0xB8, 0x71, 0x0E, 0x9C, 0xB1, 0xEF, 0xF3, 0x51, 0xC7, 0xA4, 0x43, 0xD0, 0x5E, 0x2E, 0x68, 0x96, 0x69, 0x4E, 0xA9, 0xF8, 0x35, - 0x8A, 0x89, 0x4C, 0xFF, 0xB8, 0x55, 0xFF, 0x58, 0xD0, 0x19, 0xCE, 0x10, 0x87, 0xBF, 0x27, 0xDC, 0xF5, 0x18, 0x73, 0x4D, 0x8F, 0xE6, 0x84, 0x9A, - 0x79, 0x71, 0xFE, 0xD3, 0x91, 0x9E, 0xE7, 0xE2, 0xB0, 0xB8, 0x20, 0xCC, 0x6D, 0xD3, 0xEA, 0x5A, 0x5E, 0x16, 0x4D, 0x02, 0x7D, 0x81, 0x19, 0x22, - 0x44, 0x7C, 0x91, 0xBD, 0x48, 0xEF, 0x31, 0x04, 0x24, 0x9E, 0x99, 0x39, 0x50, 0xB9, 0x83, 0x6B, 0xD6, 0xA6, 0x0C, 0x7F, 0x3D, 0x1E, 0xB3, 0xAA, - 0x5F, 0x00, 0xE8, 0x60, 0xA7, 0x45, 0x3E, 0xC4, 0x67, 0x23, 0x17, 0xEB, 0xFB, 0x92, 0xB4, 0xFF, 0x33, 0x9F, 0x74, 0x31, 0xF1, 0xE2, 0xDB, 0x96, - 0x7B, 0x7C, 0x58, 0x23, 0xEC, 0xC9, 0xEF, 0xD9, 0x3A, 0x85, 0x25, 0xEC, 0x3A, 0x9D, 0x11, 0xDF, 0xB2, 0xA6, 0x27, 0x60, 0x8F, 0x4B, 0x3B, 0xEE, - 0xB2, 0xA0, 0x71, 0xDA, 0x99, 0x1D, 0x40, 0xE7, 0xB1, 0xD5, 0x28, 0xAC, 0x1D, 0x02, 0xBB, 0xF5, 0xEF, 0x35, 0x31, 0xB9, 0x55, 0xF2, 0x95, 0x59, - 0x12, 0x4D, 0xB5, 0xD7, 0x1F, 0x13, 0x40, 0x99, 0x1D, 0x6C, 0x49, 0xE4, 0x8B, 0xCB, 0x55, 0x15, 0xCF, 0x59, 0x1D, 0x9E, 0x72, 0x1B, 0xA4, 0xD3, - 0x8A, 0x4D, 0xA5, 0xB4, 0x00, 0xD9, 0x11, 0x69, 0x49, 0x25, 0x6E, 0x02, 0x01, 0x51, 0x22, 0xFE, 0xD7, 0x72, 0x03, 0x78, 0xB6, 0x1D, 0x3B, 0x17, - 0x71, 0xF0, 0x02, 0x88, 0xF2, 0xBF, 0x39, 0xA9, 0x19, 0x65, 0x8D, 0x78, 0x73, 0xEA, 0xFA, 0xE3, 0x70, 0x51, 0x16, 0x7A, 0x71, 0xA2, 0x29, 0x7A, - 0x29, 0x34, 0x07, 0x95, 0xEF, 0xFB, 0xE8, 0xE4, 0x7C, 0x3A, 0x44, 0x47, 0x29, 0xAD, 0x77, 0xD3, 0x0C, 0xD1, 0x00, 0x5E, 0xC9, 0x23, 0xC8, 0x45, - 0x6E, 0x8E, 0x8B, 0x34, 0xEE, 0x5C, 0x74, 0x48, 0xFA, 0xA0, 0xEE, 0x0B, 0x0F, 0x86, 0x86, 0x64, 0x16, 0xCF, 0x88, 0xB2, 0xEB, 0x6B, 0x7A, 0xD0, - 0xE2, 0x6A, 0x06, 0xEB, 0x9A, 0xFE, 0xE5, 0x8A, 0xF1, 0xCF, 0xCB, 0x79, 0x8B, 0x42, 0xF0, 0xCB, 0x4B, 0xF0, 0x0C, 0x8C, 0x52, 0xD0, 0xD3, 0x1F, - 0xBC, 0xDF, 0xF5, 0xBC, 0x7B, 0x27, 0x4F, 0x7E, 0x93, 0x4B, 0xDB, 0x99, 0x3B, 0x17, 0xA6, 0xD6, 0x09, 0xF2, 0xC6, 0xE1, 0xF6, 0x0D, 0xF0, 0xC9, - 0x74, 0x43, 0x4C, 0xD0, 0x2F, 0x4D, 0x5C, 0x2E, 0x88, 0xDF, 0x08, 0x1B, 0xA7, 0xD6, 0xBC, 0x51, 0x23, 0xF3, 0x8A, 0x03, 0xFB, 0x35, 0xB6, 0x23, - 0xE0, 0xCC, 0x36, 0x23, 0x56, 0xC0, 0x6F, 0x6E, 0xC8, 0x3D, 0x49, 0xEE, 0x48, 0x19, 0x79, 0x45, 0xD8, 0x32, 0x44, 0xDB, 0x77, 0x62, 0xE7, 0x93, - 0x2D, 0x31, 0x41, 0x8F, 0xB6, 0x75, 0xBD, 0x90, 0x77, 0x53, 0x78, 0xE4, 0xAA, 0xF2, 0x2E, 0xA9, 0xC6, 0x3A, 0x40, 0xD7, 0x75, 0xD0, 0x5E, 0x54, - 0x14, 0x3F, 0x49, 0x35, 0x6E, 0xAD, 0xE8, 0x99, 0x66, 0xE6, 0x04, 0xB8, 0xCD, 0x74, 0x42, 0xD6, 0xF1, 0xC4, 0xBF, 0x24, 0x36, 0x2F, 0xC0, 0x6D, - 0xA6, 0x13, 0x72, 0xC0, 0xED, 0x7D, 0x29, 0x39, 0x45, 0xFC, 0x44, 0x9C, 0x58, 0x27, 0x85, 0x7C, 0x8B, 0x99, 0x17, 0xC0, 0xE8, 0xBC, 0xFD, 0x15, - 0x39, 0x66, 0x78, 0xA9, 0x02, 0x94, 0x4F, 0x00, 0x0A, 0x60, 0x98, 0x11, 0x44, 0x10, 0x53, 0x9B, 0x0E, 0x00, 0x00, 0xB0, 0x82, 0x62, 0x7E, 0x00, - 0x14, 0x64, 0x01, 0x8F, 0x02, 0x0A, 0x00, 0x00, 0x0A, 0x00, 0x40, 0x16, 0x3F, 0x49, 0x52, 0xF2, 0x93, 0x94, 0xB6, 0xEC, 0x96, 0xE4, 0x46, 0x69, - 0xEF, 0x93, 0x9A, 0x51, 0x54, 0xFB, 0xD8, 0x64, 0xB6, 0x91, 0xC8, 0xEC, 0xBF, 0x3D, 0xBE, 0x75, 0x70, 0x77, 0x22, 0xA2, 0xAA, 0xE8, 0xCC, 0x0E, - 0x33, 0x33, 0x27, 0xF8, 0xF4, 0x26, 0x80, 0x93, 0x32, 0x2F, 0x01, 0xF3, 0x00, 0xFE, 0x00, 0x1B, 0x0E, 0xF2, 0xBE, 0x94, 0x96, 0xFA, 0x8E, 0x9E, - 0x4E, 0x63, 0x43, 0xA5, 0xC6, 0x4B, 0x50, 0x99, 0xD3, 0x75, 0x06, 0x45, 0xB9, 0xBD, 0x9F, 0xBC, 0x08, 0xE9, 0xA8, 0xEA, 0x22, 0x7E, 0x33, 0xD2, - 0x9E, 0xC5, 0xF7, 0xC6, 0xEF, 0x67, 0x35, 0x54, 0xE6, 0x4B, 0x4C, 0x83, 0xDA, 0xDC, 0x73, 0xCA, 0x8A, 0xCA, 0xA7, 0xE4, 0x8E, 0xAF, 0xD0, 0x93, - 0xB0, 0x7D, 0x73, 0xF2, 0x0F, 0xF5, 0x9A, 0x7F, 0x6F, 0x39, 0xD9, 0xE9, 0xA4, 0xAB, 0x57, 0x91, 0xF3, 0x7D, 0x42, 0xB8, 0xEF, 0x35, 0xFB, 0x12, - 0xF7, 0x94, 0x54, 0x4A, 0x34, 0x29, 0x08, 0x5D, 0x57, 0x7A, 0x4F, 0x3E, 0x91, 0x06, 0x37, 0x8A, 0xD2, 0x21, 0x88, 0x53, 0x13, 0xED, 0x13, 0xC1, - 0x20, 0xA1, 0x75, 0x13, 0x98, 0x8E, 0x0B, 0x8B, 0x48, 0x84, 0x01, 0xF0, 0xC0, 0x9A, 0xC1, 0x12, 0x62, 0x89, 0xB0, 0x32, 0x58, 0xC5, 0x72, 0x0B, - 0x63, 0x65, 0xB0, 0x7C, 0x11, 0xB0, 0x0A, 0x60, 0x00, 0x30, 0x03, 0xD8, 0xC3, 0x92, 0xBD, 0xC0, 0x1A, 0x73, 0x81, 0xB5, 0xC0, 0x58, 0x60, 0x2B, - 0x30, 0x15, 0x58, 0x09, 0x96, 0x02, 0xFB, 0x60, 0x1E, 0x4B, 0x07, 0x26, 0x59, 0x38, 0xAC, 0x1D, 0x36, 0xC8, 0x70, 0x30, 0x12, 0x98, 0x09, 0xEB, - 0x90, 0x5C, 0xD8, 0x88, 0x0A, 0xDB, 0xB0, 0x30, 0x0C, 0x0A, 0xBB, 0xA8, 0x60, 0x13, 0x26, 0x61, 0x11, 0x86, 0x02, 0xCB, 0xB0, 0x13, 0x98, 0x09, - 0xCC, 0x82, 0x95, 0xC0, 0x48, 0x60, 0x1C, 0x22, 0x84, 0x50, 0x62, 0xFD, 0xCA, 0x61, 0xF9, 0xAA, 0x61, 0x85, 0x60, 0x23, 0xB0, 0x10, 0x3E, 0xB4, - 0x05, 0x83, 0xB3, 0x10, 0x04, 0x60, 0x14, 0xCC, 0xE2, 0x41, 0x86, 0x15, 0x00, 0x03, 0x41, 0x06, 0xF6, 0x41, 0x0F, 0x2B, 0x06, 0xE6, 0x81, 0x0D, - 0x34, 0xB0, 0x8A, 0xF5, 0xC3, 0x02, 0xAC, 0x03, 0x10, 0x6C, 0x03, 0xA6, 0x01, 0xCB, 0x80, 0x61, 0xC0, 0xC1, 0x05, 0x14, 0xCC, 0x82, 0x0A, 0x28, - 0x60, 0x13, 0x44, 0xC0, 0x24, 0x00, 0x31, 0xC0, 0xBA, 0x81, 0x3D, 0xC0, 0x20, 0x60, 0x0E, 0x34, 0xC0, 0x18, 0x60, 0x04, 0x80, 0x60, 0x0A, 0x20, - 0xC0, 0x12, 0x60, 0x07, 0x18, 0x10, 0x69, 0x82, 0xC2, 0x59, 0x81, 0x64, 0x45, 0x69, 0xD4, 0xCD, 0xF7, 0xD3, 0x28, 0xFF, 0x62, 0xF2, 0xCF, 0x34, - 0xD8, 0x4F, 0xBA, 0x18, 0xF5, 0x05, 0x94, 0xEF, 0x42, 0x5F, 0x56, 0xF9, 0xF1, 0xD4, 0xD2, 0x44, 0x44, 0x90, 0xBD, 0x9F, 0x6E, 0x94, 0xDF, 0xD7, - 0x82, 0x9B, 0x8A, 0x2C, 0x78, 0xA9, 0x8E, 0xDB, 0x1E, 0x5D, 0x39, 0xAC, 0x93, 0xB6, 0x86, 0x21, 0x8B, 0x39, 0x13, 0x67, 0x45, 0x7F, 0xEE, 0x73, - 0x47, 0x7D, 0x90, 0x4D, 0x57, 0x41, 0x11, 0xFA, 0x37, 0xA5, 0xBD, 0x8E, 0x7A, 0x94, 0xD1, 0x6F, 0x4B, 0x6E, 0xA2, 0x15, 0x94, 0xCE, 0x0F, 0xB1, - 0x6F, 0x2A, 0x95, 0xA2, 0xF5, 0x87, 0xCA, 0x09, 0xDC, 0x96, 0x56, 0x46, 0xB8, 0x1E, 0x2D, 0x9B, 0x1B, 0x43, 0xA1, 0x9D, 0xA5, 0xF4, 0xE9, 0xE3, - 0x0B, 0x4A, 0xDA, 0xBA, 0x94, 0x4C, 0x39, 0xF5, 0xB4, 0x91, 0x7B, 0x21, 0x7E, 0xF8, 0x0E, 0x92, 0xA0, 0x1E, 0xFA, 0xCC, 0xFE, 0x46, 0x46, 0xE3, - 0x8C, 0x79, 0xD1, 0x3A, 0x1D, 0xB1, 0x56, 0x34, 0xBD, 0x1D, 0x2D, 0x37, 0xAA, 0x8C, 0xA7, 0x23, 0x8F, 0x92, 0xB3, 0x1D, 0x51, 0x53, 0x9D, 0x90, - 0xC7, 0x9C, 0x40, 0xF5, 0x6D, 0xD6, 0xC8, 0x2A, 0xF1, 0xA6, 0xBF, 0xB4, 0x31, 0xDF, 0x53, 0x29, 0x9D, 0x33, 0xB2, 0x26, 0x6D, 0x17, 0xF1, 0x7E, - 0x2C, 0x7F, 0xA6, 0x37, 0xEB, 0x1F, 0xA7, 0xCD, 0x64, 0x5A, 0x27, 0x86, 0xD3, 0x16, 0x8A, 0xBE, 0xB4, 0xF4, 0x9D, 0x3F, 0x22, 0xC6, 0x76, 0xD0, - 0x54, 0x2D, 0x2B, 0xB5, 0x8F, 0x65, 0x39, 0xED, 0xFC, 0x2E, 0xA5, 0xAE, 0xBC, 0x2B, 0x8C, 0xBF, 0x79, 0x59, 0x99, 0x12, 0xAE, 0x83, 0xF9, 0x7C, - 0xC4, 0xF9, 0x54, 0x6F, 0xA8, 0x3F, 0x0B, 0x5B, 0xCA, 0x92, 0x83, 0xFA, 0xF4, 0x67, 0x04, 0x59, 0x5E, 0x51, 0x49, 0xBD, 0x85, 0x91, 0xA5, 0x95, - 0xC4, 0x91, 0x35, 0xB5, 0xC7, 0x7B, 0xED, 0x99, 0x90, 0xAE, 0x30, 0x7D, 0xF9, 0xC6, 0xA4, 0x77, 0xC7, 0xCB, 0xCB, 0x57, 0xA0, 0x07, 0x71, 0x12, - 0x15, 0x0F, 0x2B, 0x2A, 0x8D, 0x10, 0x4F, 0x21, 0x71, 0xCA, 0x12, 0xBA, 0x59, 0xD6, 0xB8, 0xEE, 0xC3, 0xD7, 0xE3, 0x3D, 0xBA, 0xA3, 0x66, 0x33, - 0xFA, 0xDE, 0xE5, 0x46, 0xD2, 0x8C, 0xB7, 0x68, 0x62, 0x43, 0x62, 0x52, 0xED, 0x32, 0x0B, 0xFD, 0x46, 0x8C, 0xAB, 0x01, 0xB9, 0x8A, 0x98, 0x9D, - 0xA0, 0xF6, 0xCD, 0xBA, 0xA8, 0xF2, 0x86, 0xDE, 0x77, 0xEB, 0xA5, 0xD4, 0x9F, 0x62, 0x24, 0x06, 0x76, 0xBB, 0x24, 0xFE, 0x6B, 0x28, 0xA9, 0x89, - 0x85, 0x34, 0xEA, 0x63, 0x8C, 0xC6, 0x3B, 0x71, 0xD5, 0x11, 0x61, 0x7D, 0xF7, 0xD4, 0x03, 0x8A, 0xB4, 0xE6, 0xCD, 0x0D, 0xA6, 0x99, 0xE8, 0x46, - 0xF1, 0x49, 0x71, 0x62, 0xB9, 0x9F, 0xF5, 0x25, 0xF1, 0x47, 0x5F, 0x96, 0xA8, 0xCB, 0x6A, 0x46, 0xFC, 0x5B, 0x12, 0xA3, 0x13, 0x97, 0xEF, 0x63, - 0x37, 0x17, 0xD3, 0xF1, 0x66, 0x2D, 0x5D, 0xA2, 0x85, 0x68, 0x5A, 0x62, 0xC2, 0x97, 0xEA, 0xAD, 0xD1, 0x72, 0x2A, 0xF5, 0x08, 0x55, 0x1A, 0xDA, - 0x13, 0x53, 0xA4, 0x2F, 0x66, 0xA7, 0xBD, 0x2B, 0xEB, 0xCF, 0xAB, 0xB7, 0xE2, 0x97, 0xE6, 0x1A, 0xF2, 0x54, 0xE2, 0xA4, 0xB6, 0x93, 0x17, 0x8D, - 0x5A, 0x30, 0x9A, 0x42, 0x1B, 0xAB, 0x09, 0x7A, 0x8D, 0x4F, 0xE5, 0x8C, 0x7F, 0x09, 0x32, 0x2D, 0xE7, 0x21, 0x08, 0xF1, 0x26, 0x47, 0x3D, 0xAA, - 0xB8, 0x93, 0xF6, 0x9E, 0x66, 0x5C, 0xA3, 0x5E, 0xA4, 0xAC, 0x9C, 0x68, 0xD6, 0x80, 0x1B, 0x31, 0x46, 0xC3, 0xA6, 0x5C, 0x39, 0x27, 0x02, 0xCB, - 0x51, 0xF5, 0x20, 0xAB, 0x3E, 0x87, 0x5E, 0x3E, 0x30, 0x96, 0xA7, 0x95, 0x90, 0xA6, 0xB4, 0xC5, 0xA0, 0x6C, 0x3C, 0x4D, 0x79, 0xD0, 0x5B, 0xF0, - 0x86, 0xAC, 0xFB, 0xA7, 0xFB, 0x84, 0xD2, 0x1A, 0xAE, 0x4B, 0xF2, 0x69, 0x94, 0x99, 0x44, 0xF8, 0x8F, 0x93, 0x29, 0x2D, 0x66, 0xEB, 0xC5, 0xA4, - 0x99, 0x2A, 0xED, 0x88, 0xB2, 0x52, 0xC9, 0x68, 0xD7, 0x14, 0xA1, 0x91, 0xEB, 0xA6, 0xF2, 0x49, 0x46, 0x2F, 0xE9, 0x44, 0x38, 0xEA, 0xAA, 0x0C, - 0x39, 0x6F, 0xA9, 0xAE, 0x87, 0x5A, 0x28, 0x22, 0x5C, 0x10, 0xEA, 0xBD, 0x23, 0x67, 0xBE, 0xCB, 0x6B, 0x48, 0x74, 0x35, 0xB5, 0xDB, 0x38, 0xCE, - 0x72, 0x22, 0x4D, 0xE1, 0xB3, 0xD9, 0xCC, 0x54, 0xAF, 0x27, 0xE5, 0x48, 0x7D, 0x6D, 0x12, 0xB3, 0xE9, 0x1C, 0xA6, 0x75, 0xED, 0x4B, 0x8C, 0x8B, - 0xB2, 0x5A, 0xEE, 0xEE, 0xC8, 0x57, 0x75, 0x2A, 0x8E, 0x6A, 0x25, 0x47, 0x56, 0x97, 0x29, 0xB9, 0x2F, 0x7A, 0x69, 0xEE, 0xF2, 0xD2, 0xA9, 0x11, - 0xFB, 0x28, 0x77, 0x7E, 0xB2, 0x40, 0xF0, 0xF3, 0x2D, 0xFB, 0x14, 0xA5, 0xF4, 0x9D, 0x9B, 0x21, 0x0E, 0xA2, 0xD6, 0x04, 0x3D, 0xAB, 0x66, 0xF8, - 0x3A, 0xA5, 0xCA, 0x7D, 0xE4, 0xA2, 0x43, 0xE9, 0xE9, 0x20, 0x2A, 0x35, 0xE0, 0xBB, 0x6E, 0xB2, 0xCA, 0x88, 0x70, 0x4D, 0xD0, 0x31, 0x22, 0x8E, - 0x46, 0x93, 0xD8, 0xF1, 0x56, 0x5A, 0xEB, 0xF6, 0x47, 0x79, 0x9F, 0x4E, 0x5E, 0xC0, 0x97, 0x44, 0x70, 0x3E, 0xBF, 0x6F, 0x1D, 0x7C, 0x08, 0xCA, - 0x0A, 0xAA, 0x5F, 0x3F, 0x88, 0xC4, 0x9C, 0xF0, 0xE5, 0xB3, 0xBD, 0x6E, 0x65, 0x8C, 0x0F, 0xBD, 0x9C, 0xAC, 0xEE, 0x8A, 0xCA, 0x2E, 0xF1, 0xE4, - 0x2E, 0x72, 0x52, 0x4A, 0xBC, 0x8A, 0x2B, 0x72, 0x53, 0x0C, 0x82, 0xC3, 0xA8, 0x62, 0xD2, 0xA2, 0x6B, 0x9D, 0x8C, 0x26, 0x85, 0xC2, 0xB4, 0x19, - 0x92, 0x38, 0x08, 0x47, 0x0A, 0x39, 0x10, 0xE5, 0x1C, 0x2F, 0x07, 0x82, 0x5A, 0x1E, 0x64, 0x18, 0x0A, 0x1A, 0x54, 0x23, 0x49, 0x92, 0x0E, 0xD4, - 0x06, 0xA4, 0xC4, 0xA6, 0x36, 0x50, 0xEB, 0xF3, 0x6C, 0xAD, 0x8E, 0xF7, 0xF9, 0xAA, 0x84, 0x2A, 0x98, 0x17, 0xAB, 0x56, 0x0A, 0x6B, 0xE2, 0xE0, - 0xC4, 0x1E, 0xB4, 0xAB, 0xDA, 0xF6, 0x49, 0x34, 0xC1, 0xA8, 0xAA, 0xB1, 0x90, 0x8C, 0x88, 0xE6, 0xD8, 0x32, 0xE4, 0x15, 0x32, 0x79, 0x2F, 0xC3, - 0xAE, 0xEE, 0xC4, 0x0D, 0x99, 0x3C, 0xAF, 0x53, 0xB8, 0xB0, 0x9C, 0x43, 0x23, 0x8C, 0x9D, 0x8F, 0xDC, 0xED, 0xF1, 0x93, 0x45, 0x44, 0x44, 0xA7, - 0xED, 0xCB, 0x9C, 0x5A, 0x57, 0x82, 0x61, 0x42, 0x01, 0x26, 0xE5, 0x81, 0x0C, 0x22, 0x89, 0x11, 0x53, 0xFC, 0xB4, 0x70, 0x55, 0xB2, 0x7F, 0x42, - 0x06, 0xDD, 0x0F, 0x70, 0x68, 0x93, 0x23, 0xB1, 0x9E, 0xF5, 0x6A, 0xEB, 0xD1, 0x68, 0x2C, 0xAD, 0x49, 0x44, 0x1E, 0xD4, 0xD4, 0xB8, 0xEF, 0xBA, - 0xDB, 0xA1, 0x88, 0x4C, 0x0B, 0xD1, 0xE7, 0x8E, 0x6D, 0xBA, 0xCA, 0x58, 0x6F, 0x68, 0x45, 0x4D, 0xF6, 0xC4, 0xA5, 0x9E, 0x70, 0x8C, 0x83, 0x9F, - 0x60, 0x83, 0xD0, 0xB2, 0x92, 0x09, 0x2A, 0x49, 0x14, 0x32, 0x34, 0x36, 0x46, 0xC2, 0x57, 0x9B, 0x80, 0x92, 0x1D, 0x41, 0x8E, 0x01, 0x31, 0xF6, - 0x36, 0xEB, 0x15, 0xF1, 0xBE, 0x96, 0xB6, 0xBF, 0xE7, 0xAF, 0xEA, 0xCB, 0x20, 0xF9, 0x07, 0xD7, 0x40, 0x42, 0x38, 0xB2, 0x26, 0x6F, 0xF5, 0x9E, - 0xE1, 0x3A, 0x77, 0x9A, 0xCE, 0x86, 0x7B, 0xFC, 0x36, 0x6B, 0x4F, 0xBC, 0x4B, 0xA9, 0x41, 0x25, 0x98, 0x04, 0x31, 0xD7, 0xA9, 0x7B, 0xF5, 0x3E, - 0xD8, 0xD1, 0xDE, 0x41, 0xA7, 0xE5, 0x80, 0x6E, 0x1E, 0x5C, 0xC1, 0x04, 0xBB, 0xD6, 0x83, 0xB7, 0x09, 0x1B, 0x96, 0xFF, 0xA7, 0xA1, 0xA7, 0x9E, - 0x54, 0xE4, 0x2E, 0xEB, 0x35, 0xE8, 0x52, 0xFF, 0xC5, 0xD6, 0x38, 0x07, 0x46, 0x49, 0x4F, 0x5D, 0x43, 0x88, 0x29, 0x41, 0xEC, 0x31, 0x35, 0x02, - 0x0D, 0x37, 0x61, 0x56, 0xF8, 0x4F, 0xF0, 0x45, 0xB6, 0xDC, 0xC8, 0xD2, 0x40, 0xAD, 0x41, 0x35, 0xBC, 0xD7, 0x83, 0x27, 0x79, 0x44, 0x2B, 0x80, - 0xF5, 0xD5, 0x31, 0x84, 0xED, 0x36, 0x18, 0x07, 0x6E, 0x4E, 0x3F, 0xD9, 0xBA, 0x6D, 0xCC, 0x7F, 0x07, 0x60, 0xD4, 0xA4, 0xA0, 0x28, 0x12, 0x55, - 0x9F, 0x24, 0x0D, 0x41, 0x2C, 0x97, 0x1E, 0xDC, 0x23, 0x81, 0x98, 0xD7, 0xCF, 0x33, 0xE2, 0x9E, 0x51, 0x42, 0xA2, 0xE8, 0x82, 0x01, 0x10, 0x93, - 0x57, 0x02, 0x07, 0x06, 0x83, 0xAE, 0x3C, 0x49, 0xC7, 0x2D, 0x9E, 0x26, 0x26, 0x05, 0x55, 0x48, 0x7E, 0x21, 0x9C, 0xEC, 0x91, 0x41, 0xDE, 0xEF, - 0x22, 0x53, 0xC6, 0x15, 0x39, 0xA2, 0xE0, 0x78, 0x18, 0x3A, 0x4E, 0x3E, 0x35, 0x23, 0x8C, 0x22, 0x5B, 0x1A, 0x42, 0x84, 0x19, 0x99, 0xCC, 0xD3, - 0x3E, 0x86, 0x53, 0xDD, 0x8B, 0x02, 0xD1, 0x1F, 0x5B, 0x05, 0x0C, 0xB0, 0x37, 0xC1, 0x6E, 0xB5, 0xD5, 0x13, 0xC9, 0xE7, 0x7D, 0x74, 0x97, 0x2C, - 0x73, 0xF6, 0x2E, 0xB0, 0x41, 0x34, 0x87, 0x06, 0x9B, 0xEF, 0x88, 0xE4, 0xDC, 0x73, 0xB6, 0x4C, 0x41, 0x5D, 0x4C, 0x31, 0xF3, 0x39, 0x89, 0x4F, - 0xB8, 0xA5, 0xB1, 0x54, 0xC4, 0xE7, 0xD4, 0x4E, 0x14, 0x8A, 0x78, 0x99, 0xD1, 0xBB, 0x18, 0xBA, 0x78, 0x74, 0xBC, 0x81, 0x86, 0x14, 0xA8, 0x61, - 0x79, 0xC5, 0x4A, 0x8D, 0xE4, 0x37, 0xBC, 0x18, 0x44, 0xEB, 0x96, 0x40, 0xEC, 0xDF, 0x72, 0x89, 0xC5, 0xE6, 0xC3, 0x4F, 0xE1, 0x1E, 0x46, 0x58, - 0xB7, 0xE8, 0x2C, 0xBA, 0x62, 0xBA, 0x49, 0xF0, 0x07, 0xD1, 0x18, 0x6A, 0xCB, 0xB8, 0x6D, 0x7C, 0xA2, 0x4D, 0x4C, 0x0D, 0x77, 0x5C, 0x26, 0x00, - 0x1F, 0x36, 0xB1, 0x5B, 0x28, 0x9A, 0x34, 0x43, 0xDB, 0xF0, 0x4B, 0x91, 0x32, 0x2E, 0x0E, 0xEF, 0xB8, 0x4E, 0x47, 0xBE, 0xAB, 0x4E, 0xAB, 0x85, - 0x0B, 0x7C, 0x37, 0xAC, 0xCF, 0x02, 0xF9, 0x09, 0x25, 0x57, 0xE9, 0x6E, 0x97, 0xE5, 0x5C, 0x2C, 0x34, 0x52, 0x46, 0x99, 0x6B, 0xB6, 0x76, 0x00, - 0xDC, 0xCB, 0x41, 0x70, 0x7E, 0xB3, 0x94, 0x15, 0xF2, 0xDE, 0x6B, 0x6D, 0xCB, 0x7C, 0xF0, 0x9E, 0xB9, 0xEA, 0x2F, 0x2A, 0x9F, 0x8F, 0x22, 0x73, - 0x51, 0xD3, 0x8D, 0xA2, 0x84, 0xDF, 0x34, 0x97, 0x03, 0x29, 0xD8, 0x17, 0x5C, 0xD3, 0x90, 0x1D, 0x42, 0x0E, 0x36, 0x7E, 0xD6, 0xA0, 0x42, 0x6B, - 0x7F, 0x1B, 0x4D, 0x3F, 0xF3, 0xC9, 0xE6, 0x14, 0x50, 0xD0, 0x6C, 0x06, 0x90, 0x90, 0xE8, 0x09, 0xB2, 0x28, 0xB1, 0xC5, 0x89, 0x56, 0xE9, 0x1C, - 0x97, 0x3A, 0x21, 0x6C, 0x4B, 0xDA, 0xB5, 0xFF, 0x9E, 0x90, 0x65, 0x89, 0x75, 0xB2, 0xB3, 0xD2, 0xC9, 0x24, 0xC6, 0x63, 0x44, 0xA1, 0xEF, 0x9D, - 0x34, 0xD6, 0x9F, 0xC1, 0x34, 0x72, 0xB0, 0x8F, 0xB2, 0x4A, 0xD5, 0x8C, 0x9C, 0x8A, 0x91, 0x10, 0x15, 0x84, 0xA0, 0x18, 0x38, 0xBA, 0x0E, 0x2D, - 0x5B, 0x23, 0x50, 0x54, 0x0B, 0xCD, 0x12, 0x91, 0x41, 0xAA, 0xB8, 0x00, 0x7D, 0x56, 0x10, 0x0C, 0x4E, 0x7F, 0x06, 0x32, 0xE8, 0xFC, 0x3F, 0xE7, - 0xAB, 0xF8, 0x58, 0x58, 0x14, 0x82, 0xB3, 0xEB, 0x99, 0x8C, 0x19, 0x50, 0xAA, 0xF0, 0x5B, 0x43, 0x40, 0x9F, 0xF6, 0xC1, 0x6D, 0x8B, 0x22, 0xA3, - 0xC1, 0xDD, 0x19, 0x7A, 0xFF, 0xDF, 0x42, 0x97, 0x7D, 0xE9, 0x79, 0x85, 0xB0, 0xB2, 0xAD, 0x73, 0x3A, 0x2B, 0x0A, 0x77, 0x48, 0xC4, 0x34, 0x7E, - 0x2B, 0xE0, 0xD5, 0x7B, 0x4C, 0xDC, 0x54, 0x0D, 0xFF, 0xD2, 0xF5, 0x0C, 0xD2, 0x16, 0xCB, 0xB6, 0xFC, 0x7B, 0x2E, 0x3E, 0xFB, 0x05, 0xC4, 0xBA, - 0xBC, 0x00, 0x0C, 0x50, 0x97, 0x45, 0x3E, 0x1D, 0x89, 0xFC, 0x0D, 0x95, 0x23, 0x2A, 0xD9, 0x2C, 0x52, 0x59, 0x9C, 0xF8, 0x88, 0x41, 0x5A, 0x69, - 0xBD, 0x1C, 0x1D, 0x77, 0xB7, 0xCC, 0xC8, 0x17, 0x24, 0x06, 0xF4, 0x86, 0x00, 0x93, 0x90, 0x8B, 0xC3, 0x27, 0xC9, 0xCC, 0xF8, 0x82, 0x6F, 0xD5, - 0x8E, 0x19, 0x44, 0x33, 0x2B, 0xE6, 0x02, 0x05, 0xDD, 0x1D, 0xB4, 0xC9, 0x44, 0x0F, 0x5F, 0x02, 0x01, 0x11, 0xEB, 0x06, 0x16, 0x56, 0x22, 0xBD, - 0x3E, 0x2B, 0xF4, 0x01, 0x31, 0x96, 0xAF, 0x3C, 0xFF, 0x07, 0xFF, 0x00, 0x95, 0x28, 0x0B, 0xFD, 0x4F, 0x22, 0x02, 0x48, 0xE8, 0x91, 0x27, 0x70, - 0x99, 0x2E, 0x54, 0x17, 0x6D, 0x7B, 0xE1, 0x2C, 0xD2, 0x44, 0x48, 0xBF, 0x66, 0x55, 0x24, 0x4F, 0xC2, 0x04, 0xD3, 0xA9, 0x34, 0xEE, 0x1C, 0x2E, - 0xFB, 0x1D, 0xEE, 0x21, 0xCC, 0x7D, 0xF5, 0xA6, 0xC8, 0xC8, 0x1A, 0xD1, 0x76, 0x01, 0xAD, 0xC0, 0xA5, 0x63, 0x23, 0x1B, 0x15, 0xFE, 0x5F, 0x95, - 0xDF, 0x42, 0x6E, 0x54, 0xAA, 0x2D, 0x96, 0x4C, 0xF3, 0x82, 0x51, 0xB2, 0x94, 0x16, 0x0B, 0xD5, 0x25, 0x62, 0x13, 0x45, 0x35, 0xC9, 0x18, 0x86, - 0xA6, 0x28, 0xA6, 0x91, 0x24, 0x15, 0x58, 0x38, 0x9A, 0x32, 0x07, 0x36, 0xB7, 0x9F, 0xDB, 0x14, 0x9D, 0x37, 0x1D, 0x52, 0xC8, 0x0E, 0x05, 0x1D, - 0x56, 0xB8, 0x71, 0x44, 0x37, 0x8A, 0xF8, 0x8A, 0x13, 0x00, 0x2D, 0x3B, 0xC6, 0x45, 0x1F, 0x57, 0xEF, 0xEE, 0x14, 0x65, 0x84, 0x50, 0x47, 0xE1, - 0x97, 0x21, 0x99, 0x9D, 0xB9, 0xA3, 0x0F, 0xD9, 0x00, 0x1C, 0x40, 0x2C, 0xA6, 0x36, 0x8E, 0x12, 0x73, 0x38, 0x9A, 0xD5, 0x4C, 0x23, 0x86, 0x90, - 0x45, 0x7F, 0xE9, 0x9B, 0xEC, 0xC2, 0xB2, 0x51, 0x0D, 0x31, 0x99, 0x63, 0x88, 0xC9, 0x81, 0x74, 0x67, 0xF4, 0x4B, 0xA1, 0xB4, 0x1F, 0xC7, 0x56, - 0xD4, 0xDB, 0x85, 0x02, 0x05, 0x89, 0x8B, 0x6F, 0x92, 0xCF, 0xF5, 0x97, 0x94, 0x25, 0x86, 0x3E, 0x0E, 0x28, 0x32, 0xB1, 0xF2, 0x40, 0x5A, 0x5D, - 0xD0, 0x64, 0x49, 0x14, 0xB5, 0x23, 0x45, 0x74, 0x1B, 0x1D, 0xB4, 0xE6, 0x9F, 0xB1, 0x50, 0xBB, 0x14, 0x51, 0x24, 0xF0, 0x22, 0x07, 0xC7, 0x85, - 0x7F, 0x48, 0x47, 0x8D, 0x86, 0x8A, 0xC4, 0x7A, 0x40, 0x24, 0x2D, 0x47, 0x5B, 0xB2, 0xC1, 0xED, 0xD8, 0x5E, 0x77, 0x81, 0x69, 0x34, 0x1D, 0x4F, - 0x42, 0x2D, 0xA2, 0xE8, 0xA3, 0x71, 0x36, 0x9A, 0xFB, 0x06, 0x56, 0x5D, 0x75, 0xD3, 0x10, 0x49, 0xF6, 0x7C, 0x86, 0x1F, 0x9B, 0x7D, 0x0A, 0x88, - 0x77, 0xC2, 0x23, 0x75, 0x69, 0x73, 0xD4, 0x22, 0xE6, 0x9C, 0x64, 0x72, 0x99, 0x8F, 0x66, 0x49, 0x44, 0x48, 0x83, 0xF7, 0x93, 0x18, 0x74, 0x67, - 0xE2, 0xA4, 0x8A, 0x67, 0xD1, 0x0C, 0x95, 0x27, 0x19, 0xEA, 0xAF, 0x92, 0xA5, 0xAB, 0x9A, 0xBD, 0x2B, 0xCB, 0x92, 0x1B, 0x50, 0x05, 0x18, 0xB3, - 0xD1, 0x7C, 0x61, 0x62, 0xF3, 0xC9, 0x91, 0xB4, 0x30, 0x27, 0xEC, 0x4E, 0x4A, 0xA3, 0x5F, 0x91, 0x0F, 0x80, 0x15, 0xC8, 0x95, 0xCC, 0x6C, 0x0B, - 0xDB, 0x2C, 0xE1, 0x06, 0x7C, 0x79, 0x1E, 0xC3, 0x3C, 0xD7, 0xE6, 0x66, 0x92, 0x44, 0x5E, 0x58, 0x3E, 0x47, 0x00, 0x36, 0x01, 0x46, 0x83, 0x37, - 0x46, 0xC0, 0xCD, 0xE7, 0xF4, 0xCE, 0xD8, 0xA0, 0x30, 0x03, 0x77, 0x68, 0x70, 0x00, 0x11, 0x5C, 0xCD, 0xB3, 0x50, 0x54, 0x1F, 0x24, 0x47, 0x12, - 0xCD, 0x79, 0x23, 0x65, 0xA8, 0xA9, 0xA4, 0x46, 0xBE, 0x91, 0x8B, 0x64, 0xC8, 0x2D, 0x18, 0xF6, 0xDF, 0xC5, 0xD9, 0xB3, 0x0F, 0xA4, 0x78, 0xFD, - 0x79, 0xFE, 0x70, 0x1F, 0xDE, 0xF8, 0x62, 0x4E, 0x03, 0x3D, 0xCE, 0x66, 0x01, 0x58, 0xC8, 0x06, 0x17, 0x3E, 0x26, 0xAD, 0x18, 0xFC, 0xCE, 0x4D, - 0x0D, 0x56, 0x89, 0x9C, 0x4B, 0x76, 0xC0, 0x1A, 0xD6, 0x66, 0x67, 0x60, 0x51, 0x83, 0xD9, 0x87, 0x9F, 0xB4, 0xE5, 0xAF, 0xD5, 0x89, 0x9E, 0xC9, - 0x75, 0x89, 0xD1, 0xAE, 0x27, 0xA5, 0x73, 0x17, 0xC4, 0xF4, 0x6D, 0xCE, 0xF3, 0x5C, 0x9D, 0xE6, 0xE6, 0xAC, 0xCD, 0x38, 0x94, 0x77, 0xD7, 0x35, - 0x5C, 0xC7, 0x93, 0xE2, 0x85, 0x05, 0xE0, 0x47, 0xEE, 0xD0, 0x6D, 0xF9, 0x8F, 0x4D, 0x45, 0x96, 0x6D, 0xBA, 0xFA, 0xA0, 0xD8, 0xF4, 0x69, 0x1D, - 0x30, 0x7B, 0xDF, 0x97, 0x74, 0xAC, 0xBF, 0xBE, 0x4F, 0x29, 0x34, 0x23, 0x00, 0xB7, 0x65, 0x6D, 0x7C, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x11, 0x53, - 0x19, 0xE9, 0xA6, 0xFD, 0x2D, 0xD6, 0xBF, 0x57, 0x81, 0xA7, 0x97, 0x90, 0x27, 0x99, 0xCC, 0x84, 0x84, 0x83, 0x36, 0xC4, 0x33, 0x08, 0x11, 0x02, - 0x08, 0x1F, 0x78, 0xD0, 0x01, 0x07, 0x1B, 0x68, 0x90, 0x01, 0x45, 0x88, 0x10, 0x40, 0xF8, 0xC0, 0x83, 0x0E, 0x38, 0xD8, 0x40, 0x83, 0x0C, 0x2A, - 0xC8, 0x54, 0x2E, 0x30, 0x80, 0xA2, 0xC5, 0x52, 0x5F, 0x8B, 0x15, 0x37, 0x95, 0x64, 0x61, 0xE1, 0x81, 0xC5, 0xC4, 0xC2, 0x02, 0x62, 0xF0, 0x46, - 0x7D, 0xEB, 0x7A, 0xFA, 0x12, 0x79, 0x89, 0x4C, 0x6C, 0x57, 0x5C, 0x39, 0x43, 0xD4, 0x41, 0x30, 0x31, 0x14, 0x18, 0x64, 0xA6, 0x62, 0xF2, 0x01, - 0xC6, 0x62, 0x31, 0x59, 0x99, 0xC8, 0x24, 0xC2, 0xB4, 0xD0, 0x0A, 0x0C, 0xDE, 0x76, 0xD2, 0x31, 0x12, 0xC9, 0x4A, 0x6E, 0x08, 0xEA, 0x07, 0xB4, - 0x1E, 0x01, 0xED, 0x3A, 0x24, 0x38, 0xFD, 0x48, 0x40, 0x5F, 0x7E, 0x99, 0x79, 0xED, 0xE2, 0x9A, 0x68, 0xCD, 0xA6, 0xA7, 0xD7, 0x6A, 0x82, 0x5A, - 0x4C, 0xE4, 0xA8, 0x26, 0xBD, 0x79, 0x3D, 0xA9, 0x96, 0xB6, 0xA3, 0xA5, 0xA8, 0xE1, 0xE5, 0xC1, 0x11, 0xB0, 0xA1, 0xE4, 0x9E, 0x20, 0x2F, 0x53, - 0xE9, 0x74, 0x3D, 0x5A, 0x97, 0x28, 0x3D, 0xF1, 0x11, 0xB7, 0x46, 0xC3, 0xBD, 0xB1, 0x55, 0x3B, 0x47, 0x97, 0x57, 0xA3, 0xA2, 0x3B, 0x3D, 0xA5, - 0x54, 0x0A, 0xDF, 0x33, 0x3E, 0x7B, 0x91, 0x8E, 0x3F, 0x15, 0x6E, 0x32, 0xFA, 0xA7, 0x10, 0x7E, 0x72, 0x36, 0xA6, 0xBB, 0x4B, 0x26, 0x9E, 0x4A, - 0x5C, 0x9C, 0x3A, 0xBB, 0x89, 0x60, 0x50, 0x71, 0x09, 0x01, 0x33, 0xE9, 0xB0, 0x5C, 0x56, 0x66, 0xE3, 0xB2, 0x5A, 0x93, 0x9C, 0x8C, 0x50, 0x26, - 0x14, 0x2A, 0x60, 0x2C, 0x16, 0x65, 0xBD, 0xF0, 0xC7, 0xA8, 0x04, 0x83, 0x8A, 0x0A, 0x08, 0x18, 0x8C, 0x4A, 0x65, 0x65, 0xB5, 0x78, 0x35, 0x19, - 0xA2, 0xB1, 0xC9, 0x48, 0x87, 0xE9, 0xAD, 0x1D, 0x31, 0x76, 0x15, 0xD7, 0x1F, 0x46, 0x4F, 0x5D, 0x56, 0x58, 0x9F, 0xAB, 0x86, 0x37, 0xD5, 0x50, - 0xC3, 0x75, 0x37, 0x71, 0x4E, 0x85, 0x30, 0x30, 0x30, 0xD6, 0x44, 0xA1, 0x90, 0x5C, 0xAC, 0x2A, 0x45, 0xF8, 0x6B, 0xE5, 0x3A, 0x9B, 0x47, 0x5D, - 0x4A, 0x15, 0xF2, 0xA3, 0xA5, 0xD7, 0xF0, 0x97, 0x5F, 0x32, 0xB4, 0xB1, 0xF3, 0x51, 0x7A, 0x04, 0x93, 0x4C, 0x45, 0xA4, 0x03, 0x0C, 0x3C, 0xA8, - 0x0A, 0x83, 0x59, 0x1A, 0x93, 0x11, 0x1D, 0xD2, 0xF7, 0x65, 0x6D, 0xB2, 0xC4, 0xBE, 0xA7, 0x53, 0x7E, 0xF8, 0x6F, 0x32, 0x66, 0x48, 0xBA, 0xCB, - 0x4C, 0x53, 0x9B, 0x18, 0xA9, 0x3D, 0x3B, 0x2A, 0x9B, 0xE4, 0xD5, 0x0D, 0x43, 0x71, 0x3F, 0x5F, 0xBB, 0x28, 0xF5, 0x26, 0xBC, 0xF5, 0xF7, 0x2D, - 0x19, 0x12, 0x2D, 0x4C, 0xE8, 0x9A, 0xAC, 0x34, 0xB5, 0x9C, 0x1A, 0xDC, 0xF1, 0xF5, 0xCB, 0x97, 0xFB, 0x50, 0x9B, 0x7C, 0x79, 0x11, 0xDF, 0x44, - 0xF2, 0xAF, 0x66, 0xDB, 0x44, 0xE7, 0x94, 0x22, 0x2A, 0xFF, 0x47, 0x63, 0x9A, 0x98, 0xFE, 0xA3, 0xF4, 0x2D, 0x99, 0xA0, 0xCF, 0x81, 0x62, 0xA8, - 0x51, 0xC1, 0xB4, 0x4C, 0x52, 0x6A, 0x33, 0x71, 0x10, 0x83, 0x4C, 0xA3, 0x4C, 0x99, 0x99, 0x07, 0x51, 0x1D, 0x43, 0x04, 0x59, 0x4B, 0x6D, 0x07, - 0xA4, 0x2C, 0xD4, 0x6F, 0x00, 0x52, 0x49, 0x6B, 0xAB, 0x37, 0xE1, 0x80, 0xA7, 0xB0, 0x46, 0x69, 0xA2, 0xD7, 0x4C, 0xFB, 0x80, 0x23, 0xB4, 0x6F, - 0x74, 0x2C, 0x57, 0xC2, 0x44, 0x29, 0x28, 0x39, 0x73, 0x02, 0xA5, 0x87, 0x6C, 0x2E, 0x3B, 0x19, 0x8E, 0xDB, 0x68, 0xAC, 0xC1, 0x09, 0x00, 0x44, - 0x17, 0x69, 0x2F, 0x74, 0x96, 0x2D, 0x4C, 0x34, 0x8C, 0x13, 0xD1, 0x28, 0x56, 0xD2, 0xB2, 0x86, 0xF3, 0x49, 0x5E, 0x90, 0x81, 0xF0, 0xE3, 0x82, - 0x6D, 0x15, 0x43, 0x5A, 0xC4, 0x5C, 0x5B, 0xE0, 0x01, 0x73, 0x6F, 0x04, 0x20, 0x87, 0x18, 0x8C, 0xA2, 0x84, 0xD0, 0x82, 0x45, 0xB3, 0x41, 0x89, - 0x1E, 0x11, 0xD7, 0x22, 0xEC, 0xB9, 0xE8, 0x1B, 0xBF, 0x4C, 0xB3, 0xE8, 0x83, 0x7D, 0x39, 0x8B, 0xA9, 0x50, 0x7A, 0x97, 0x44, 0xDC, 0xE4, 0x8C, - 0x32, 0xF3, 0x14, 0x0B, 0xE5, 0xF9, 0xBD, 0x2B, 0x55, 0x1E, 0x35, 0x66, 0x69, 0xFD, 0x65, 0xF2, 0xEB, 0x93, 0x0C, 0x74, 0x72, 0x8A, 0x8A, 0x2A, - 0x73, 0xFC, 0xA2, 0x20, 0x03, 0xE0, 0xBE, 0x8D, 0x07, 0x13, 0x02, 0xAE, 0xD3, 0x35, 0x11, 0xAC, 0x2A, 0x3C, 0x09, 0x7D, 0x84, 0xF6, 0x94, 0xDB, - 0x3A, 0x68, 0x88, 0x75, 0x24, 0x0D, 0x21, 0x59, 0x1C, 0x93, 0x29, 0xD5, 0xF9, 0x1D, 0xF8, 0x9C, 0x41, 0x43, 0xDD, 0xF0, 0xA4, 0x7B, 0xF2, 0xFF, - 0x05, 0xE9, 0x6D, 0xFD, 0x54, 0x22, 0xEC, 0x5F, 0xC0, 0x1F, 0x73, 0xDD, 0xD6, 0xBF, 0xA9, 0xBD, 0xD4, 0xE7, 0xC3, 0x72, 0x0D, 0x61, 0xC9, 0x8B, - 0xC2, 0xD2, 0x43, 0x29, 0x68, 0x1D, 0x06, 0x4B, 0xA6, 0x95, 0xB9, 0xA6, 0x12, 0x2B, 0xC2, 0x98, 0xC9, 0xB2, 0xBD, 0xDB, 0x27, 0x92, 0x0B, 0x04, - 0x77, 0x06, 0x41, 0x4A, 0x21, 0x21, 0x8A, 0x11, 0x95, 0xAA, 0x5E, 0xBB, 0x08, 0xC8, 0x20, 0xC9, 0x39, 0xEB, 0xEA, 0xA1, 0x58, 0x0A, 0xCF, 0xCD, - 0x8C, 0xC7, 0xD9, 0xB6, 0x3D, 0x3D, 0x39, 0xBC, 0x58, 0x4C, 0x0D, 0x81, 0xE4, 0x10, 0xCA, 0x99, 0x00, 0x37, 0x15, 0x13, 0x55, 0x74, 0x55, 0xC5, - 0xE4, 0xFC, 0xB0, 0xEE, 0x35, 0xC0, 0x94, 0x5A, 0xE3, 0x85, 0x0B, 0x75, 0x85, 0xD3, 0xB7, 0x21, 0x26, 0x8C, 0xDF, 0x0B, 0x3A, 0x4A, 0x08, 0x07, - 0x96, 0x19, 0x04, 0x82, 0xBB, 0xE9, 0xDC, 0xEB, 0x1D, 0xE5, 0x58, 0x4C, 0xC8, 0x0B, 0xDC, 0xE9, 0xF8, 0xFB, 0x72, 0x5A, 0x0E, 0x58, 0x9D, 0xAC, - 0xD3, 0xE7, 0x3C, 0x72, 0x68, 0x5B, 0xF1, 0xBF, 0xBE, 0xD8, 0x8F, 0x83, 0x30, 0x8F, 0x41, 0x5E, 0x3E, 0x1F, 0x5D, 0xC5, 0xB3, 0x40, 0xB2, 0x37, - 0xFA, 0x23, 0x9A, 0x6C, 0x02, 0x72, 0xD6, 0x69, 0x11, 0x7B, 0x51, 0x6B, 0x87, 0x03, 0xC6, 0x72, 0xB6, 0x83, 0xE1, 0x83, 0x8B, 0x83, 0xC3, 0x6B, - 0x06, 0x12, 0xD0, 0xCE, 0x27, 0x2D, 0xC0, 0xFF, 0x5C, 0x0B, 0x8F, 0x9C, 0x27, 0x05, 0x87, 0x96, 0x0E, 0x56, 0x10, 0x49, 0x4D, 0xEE, 0x93, 0x2E, - 0x2A, 0x6C, 0xB1, 0x6D, 0x06, 0x0A, 0xF3, 0x9D, 0x30, 0xAA, 0x14, 0xB2, 0x89, 0x7F, 0x13, 0xC2, 0xC8, 0x32, 0x48, 0x86, 0xF7, 0x35, 0xC2, 0x0A, - 0x86, 0x60, 0xF9, 0xB4, 0xEC, 0xED, 0x67, 0x54, 0x30, 0xA3, 0x1E, 0x39, 0x26, 0xBF, 0x9D, 0x85, 0x34, 0x48, 0xF6, 0xCE, 0x9C, 0x65, 0x07, 0xA5, - 0x13, 0xD4, 0xB0, 0x53, 0xDF, 0xB2, 0x3D, 0x3C, 0xFC, 0x59, 0x50, 0x4E, 0x2D, 0x91, 0x1B, 0x43, 0xEE, 0x49, 0xC1, 0xA5, 0xE0, 0x86, 0x39, 0x5C, - 0xF0, 0xDE, 0x81, 0xCD, 0xCF, 0x59, 0x36, 0x9C, 0xB6, 0x24, 0xCC, 0x64, 0x03, 0xDA, 0x89, 0x34, 0x58, 0xBC, 0x89, 0x98, 0x10, 0x9C, 0x10, 0x8C, - 0xB1, 0xB9, 0xC8, 0x11, 0xEA, 0x4F, 0x64, 0x99, 0xF4, 0x66, 0x5B, 0x7B, 0x1D, 0x72, 0x81, 0xCC, 0x22, 0x08, 0xDF, 0x11, 0x84, 0xAC, 0x9B, 0x57, - 0x83, 0xFB, 0x97, 0x2E, 0x1F, 0xEB, 0x31, 0xF8, 0xDA, 0x0A, 0x07, 0xA4, 0xB5, 0xC5, 0xEB, 0x6F, 0x03, 0xC6, 0x62, 0x09, 0xC6, 0x62, 0x11, 0x12, - 0xF6, 0x24, 0x89, 0xA5, 0x86, 0xF6, 0x75, 0x68, 0x54, 0x01, 0x26, 0xB8, 0xDD, 0xC7, 0x91, 0x5B, 0xA0, 0x11, 0x31, 0xB1, 0xA8, 0x6E, 0x47, 0x3D, - 0xBD, 0x49, 0x22, 0x9E, 0x4E, 0xE8, 0x03, 0x6E, 0xCF, 0xA2, 0x5A, 0x63, 0x8E, 0x03, 0xE8, 0xD8, 0x90, 0xD9, 0x4C, 0xA7, 0x92, 0x7E, 0xCF, 0x8D, - 0xA9, 0x8B, 0x4B, 0xF9, 0xCD, 0x7E, 0x42, 0x7C, 0xDD, 0x22, 0x89, 0x61, 0x69, 0xF6, 0xA8, 0x11, 0xF0, 0xF0, 0xBA, 0xE0, 0x23, 0x31, 0x60, 0x57, - 0x96, 0xCD, 0x5F, 0x26, 0xBB, 0x55, 0xD9, 0x74, 0x01, 0x1A, 0xC6, 0x50, 0x44, 0xB6, 0xD3, 0xE0, 0xA2, 0x75, 0xB3, 0x9F, 0x2E, 0xD4, 0x97, 0x81, - 0xC6, 0x88, 0x3C, 0x65, 0xA3, 0x4C, 0xAD, 0x97, 0xF1, 0xE8, 0x01, 0x4D, 0x2A, 0x00, 0x76, 0x30, 0x84, 0x24, 0x20, 0x6D, 0xB6, 0x1A, 0x17, 0x95, - 0xE5, 0xD6, 0x53, 0xD3, 0xDF, 0x5F, 0x06, 0x84, 0x87, 0xD1, 0xA4, 0xA2, 0x16, 0xD9, 0xDA, 0xC8, 0xD7, 0xE6, 0xA4, 0x91, 0xAB, 0xB2, 0x30, 0x09, - 0x14, 0x60, 0x00, 0x40, 0x97, 0x02, 0x80, 0x00, 0x75, 0x00, 0x79, 0x00, 0x33, 0x75, 0xEA, 0xCC, 0x69, 0x49, 0xA7, 0x9E, 0xDF, 0x22, 0xED, 0x96, - 0xBA, 0x7A, 0xCE, 0x98, 0x67, 0xA7, 0x71, 0x51, 0x2E, 0x41, 0x37, 0x9E, 0xC4, 0xB2, 0x43, 0xF5, 0x1A, 0xA7, 0x98, 0x33, 0x65, 0x60, 0xFA, 0x24, - 0x9A, 0x63, 0x62, 0x29, 0xC7, 0x31, 0xED, 0xB1, 0x2D, 0x37, 0x0D, 0x92, 0xC7, 0xD4, 0x77, 0x3A, 0x73, 0xE0, 0xB4, 0x8A, 0x81, 0x6B, 0xC6, 0x1F, - 0x33, 0x9D, 0xBA, 0x01, 0x39, 0xB2, 0x6C, 0x2A, 0x0D, 0x21, 0xF6, 0xB3, 0xBF, 0xC6, 0x97, 0xFC, 0x59, 0x12, 0xB4, 0x08, 0xF5, 0xD8, 0x56, 0x3B, - 0x0C, 0x0B, 0x8F, 0xB1, 0x58, 0xBC, 0x29, 0x0A, 0x11, 0x4D, 0x41, 0x51, 0x6C, 0xF5, 0xBE, 0xF0, 0xBA, 0xB2, 0x02, 0x97, 0x35, 0xC1, 0xC0, 0x51, - 0x01, 0x8E, 0x7B, 0x3A, 0x48, 0x05, 0x17, 0x99, 0x6C, 0xB6, 0x9A, 0x62, 0xC3, 0x0E, 0xAE, 0xC5, 0x26, 0xBA, 0x60, 0xC0, 0xF4, 0x07, 0x3A, 0x1C, - 0x90, 0x08, 0xF6, 0xB2, 0x3D, 0x14, 0x66, 0xEC, 0x90, 0xBA, 0xDA, 0x1E, 0x13, 0x90, 0x07, 0x22, 0xB7, 0x0E, 0x9B, 0x94, 0x26, 0x97, 0xA2, 0xE8, - 0x39, 0x55, 0x9D, 0x69, 0xF9, 0xE5, 0x24, 0x38, 0xED, 0x39, 0xDE, 0xAB, 0x7D, 0xDA, 0x1F, 0xFA, 0x9C, 0x5B, 0xE8, 0x2B, 0x5E, 0xE3, 0x4F, 0x1C, - 0x62, 0x76, 0x60, 0x9C, 0x8A, 0x63, 0x0B, 0x8C, 0xA6, 0xD0, 0x10, 0x3A, 0xC6, 0x25, 0x67, 0x1B, 0xFD, 0xAA, 0xAD, 0x39, 0xE4, 0x0C, 0x97, 0x11, - 0xE0, 0x84, 0x47, 0xBB, 0x3C, 0x1B, 0x0A, 0xBF, 0xD8, 0xB1, 0x3A, 0xBB, 0x4B, 0xF6, 0x48, 0xA7, 0x72, 0x28, 0xBF, 0xF0, 0xA8, 0x59, 0x80, 0x1D, - 0xF7, 0x68, 0xAE, 0x24, 0xBA, 0x7C, 0x1A, 0x24, 0xCA, 0x01, 0x00, 0x0A, 0x02, 0xBD, 0xB2, 0x5E, 0x6C, 0xCC, 0xD7, 0x32, 0xB4, 0x1C, 0xED, 0x0F, - 0xBD, 0x7E, 0x15, 0x88, 0xBD, 0xA6, 0x91, 0xC8, 0xC6, 0x4D, 0x8A, 0x44, 0xC7, 0x69, 0xF6, 0x6A, 0xFD, 0xDC, 0xDF, 0xFC, 0x91, 0x37, 0xD0, 0x08, - 0x0C, 0xB4, 0x8E, 0xD6, 0x8C, 0x35, 0xC2, 0xB4, 0xA5, 0x37, 0xE8, 0x0E, 0x9D, 0x99, 0x57, 0x39, 0x16, 0x9F, 0xE2, 0x4D, 0x5C, 0x6A, 0xA6, 0xCD, - 0xD7, 0xB2, 0xB4, 0x3C, 0x97, 0x97, 0xE5, 0xEB, 0x1D, 0xB7, 0x0B, 0x4E, 0xBF, 0x69, 0x4C, 0x4E, 0xA3, 0x25, 0x86, 0xB2, 0x3B, 0x71, 0xE9, 0x3C, - 0x5B, 0xC0, 0x58, 0x30, 0x20, 0x99, 0x64, 0xE2, 0x2C, 0x9B, 0xE1, 0xE2, 0xE8, 0xB4, 0xB3, 0x31, 0x0A, 0x39, 0x3D, 0x68, 0xD3, 0x7B, 0xDA, 0xD1, - 0xB6, 0x4C, 0x99, 0x98, 0x6A, 0xC4, 0x56, 0x7F, 0x09, 0x1C, 0x84, 0x56, 0x95, 0x01, 0x3A, 0x43, 0x41, 0x5F, 0x4F, 0xD1, 0x76, 0xDA, 0x92, 0x55, - 0xD3, 0x7B, 0x74, 0x77, 0xEE, 0x16, 0x95, 0x90, 0x6C, 0x10, 0xFA, 0xAC, 0xA9, 0x3D, 0xB2, 0x4B, 0xF5, 0x49, 0x67, 0xE6, 0x10, 0x34, 0xD4, 0xFC, - 0xDC, 0x5C, 0xEF, 0xCD, 0x3D, 0xD6, 0x61, 0xBD, 0x11, 0xCF, 0x98, 0x23, 0x73, 0xF4, 0x86, 0xD6, 0x63, 0x9B, 0x54, 0x58, 0xD7, 0xAB, 0xBA, 0x7D, - 0x33, 0x18, 0x07, 0x75, 0xDA, 0xC0, 0xC6, 0x09, 0x16, 0x02, 0xF2, 0x5E, 0xE0, 0x5C, 0xD3, 0x6A, 0xAB, 0xFE, 0xD0, 0x19, 0x8D, 0x79, 0x8A, 0x84, - 0x7A, 0x68, 0x0F, 0x92, 0xBB, 0xC4, 0xD0, 0x3D, 0xA7, 0x27, 0x89, 0xE6, 0x80, 0x5C, 0x77, 0xCC, 0x46, 0x28, 0xEC, 0xCD, 0xF2, 0xA1, 0xD3, 0xA6, - 0xC2, 0x45, 0xEC, 0x56, 0x61, 0x62, 0xBF, 0xB2, 0x5F, 0x76, 0x66, 0xBF, 0xE8, 0x17, 0xDD, 0xCE, 0x9B, 0x81, 0x62, 0xA8, 0x61, 0xA9, 0x95, 0x66, - 0x44, 0x92, 0xA4, 0xA0, 0x50, 0xEA, 0x41, 0x0C, 0x01, 0xA1, 0x98, 0x42, 0x8C, 0x39, 0xEF, 0x06, 0xD1, 0x98, 0x63, 0x84, 0x20, 0x43, 0x08, 0x11, - 0x4A, 0x34, 0x92, 0xD4, 0x30, 0x06, 0x03, 0x66, 0xFA, 0xAA, 0xB0, 0x5B, 0x9B, 0xF3, 0x94, 0x2A, 0x70, 0x0D, 0x33, 0xEA, 0x88, 0x6B, 0x0F, 0x23, - 0x57, 0x8B, 0x04, 0xFF, 0xA2, 0x48, 0x79, 0xD5, 0x9F, 0xFB, 0x96, 0xBF, 0x43, 0x8F, 0x66, 0x34, 0x2B, 0xD0, 0x49, 0x9D, 0x65, 0x89, 0x1D, 0x30, - 0xA9, 0xAB, 0x89, 0x22, 0x07, 0x1E, 0x3E, 0x32, 0x65, 0xC1, 0x1A, 0x4A, 0x0F, 0x9A, 0x52, 0x83, 0x65, 0x23, 0x8E, 0x0B, 0xAE, 0x38, 0x67, 0x77, - 0x30, 0x89, 0x31, 0xCB, 0x45, 0x4A, 0x63, 0x94, 0x4B, 0x67, 0x88, 0x82, 0xBA, 0x3F, 0x51, 0xC8, 0x5D, 0x1D, 0x0C, 0xA8, 0xD5, 0xA8, 0xCE, 0x72, - 0xF9, 0x0E, 0x80, 0xF7, 0xB0, 0xE7, 0x74, 0xCA, 0xFB, 0x85, 0x58, 0x60, 0x96, 0xAF, 0x5E, 0xBE, 0xEC, 0xD0, 0x48, 0x43, 0xC9, 0x99, 0x4E, 0x0D, - 0x93, 0x1F, 0x4D, 0xD7, 0x85, 0x12, 0xEA, 0xF6, 0x1C, 0xA3, 0xE2, 0x42, 0x17, 0x3D, 0x23, 0x28, 0x39, 0xC4, 0x64, 0x9C, 0x29, 0x53, 0xA5, 0x10, - 0xBD, 0x14, 0x13, 0x3B, 0x32, 0x73, 0x54, 0xDD, 0x84, 0x4F, 0x4E, 0x0D, 0xDD, 0xE0, 0xCA, 0xF8, 0xDB, 0x51, 0x3D, 0x9F, 0xDA, 0x51, 0x80, 0x12, - 0x0E, 0x66, 0x1D, 0x7E, 0x0A, 0x39, 0x76, 0x7A, 0x13, 0xAC, 0x85, 0x75, 0x3B, 0xD0, 0x79, 0x0E, 0x8B, 0x3E, 0x71, 0xE1, 0x95, 0x7E, 0x99, 0x25, - 0x46, 0x2A, 0x49, 0xA3, 0xA1, 0x03, 0xB5, 0x2A, 0xBD, 0x39, 0xEB, 0xDE, 0xCA, 0xBA, 0xF1, 0x65, 0xEE, 0xDF, 0x54, 0x13, 0xE3, 0x15, 0x80, 0xF0, - 0xAC, 0x9F, 0xAE, 0x71, 0x23, 0x93, 0x9E, 0xAC, 0xF6, 0xC7, 0x3C, 0x82, 0x58, 0xAA, 0xD3, 0x4D, 0xB8, 0x4C, 0x69, 0x2C, 0x29, 0x8A, 0xA1, 0x15, - 0x29, 0x21, 0xE0, 0x57, 0x53, 0xE3, 0x49, 0x5D, 0xD6, 0x14, 0x77, 0x18, 0x7C, 0x27, 0x08, 0x22, 0x16, 0xF3, 0x27, 0x23, 0xBD, 0x09, 0x35, 0x33, - 0x64, 0x47, 0xA9, 0x52, 0xB1, 0x0F, 0xAF, 0xCA, 0x7A, 0xB7, 0x50, 0x09, 0x14, 0x2E, 0xD1, 0xFA, 0x65, 0xF7, 0xA0, 0x57, 0x3D, 0x35, 0x5C, 0x68, - 0x16, 0x42, 0xE1, 0x94, 0x35, 0x0F, 0xB0, 0x5C, 0x7A, 0x54, 0x33, 0x6E, 0xBE, 0x38, 0x73, 0xBA, 0xB7, 0xA4, 0x7D, 0xB2, 0x1C, 0xE5, 0xA2, 0x99, - 0xB1, 0x51, 0x8D, 0xC2, 0x47, 0x26, 0x26, 0xCE, 0x50, 0x86, 0x89, 0x19, 0xB3, 0x7B, 0x9D, 0xEF, 0x2E, 0x75, 0x51, 0x2E, 0xA9, 0xB2, 0x01, 0xC8, - 0x36, 0x78, 0x15, 0x21, 0xB2, 0x89, 0x0F, 0x74, 0x8D, 0x3B, 0x6A, 0x83, 0x5A, 0xDF, 0xDC, 0x77, 0x0B, 0xAE, 0xA7, 0xE2, 0x10, 0x9D, 0x32, 0xE8, - 0x6E, 0x4C, 0x29, 0xA4, 0x3D, 0x4D, 0xB3, 0xC9, 0x5E, 0x0F, 0xB3, 0xDB, 0x8A, 0x34, 0xE8, 0x99, 0xC9, 0x28, 0x14, 0x87, 0xE2, 0x91, 0x3D, 0xBC, - 0xD0, 0x37, 0x86, 0x28, 0x81, 0xC0, 0x71, 0x28, 0x97, 0xC0, 0x6C, 0x38, 0x9F, 0x8C, 0x2D, 0x29, 0x1C, 0x5A, 0x46, 0xA7, 0x1B, 0x5A, 0x5C, 0x99, - 0xB1, 0xAD, 0xE6, 0xB3, 0xB2, 0x91, 0xEA, 0x7C, 0xE1, 0x84, 0x91, 0xD2, 0xAE, 0x1A, 0x85, 0x6D, 0xA7, 0x8A, 0xE7, 0x8E, 0x1C, 0xDC, 0xD1, 0xC2, - 0x43, 0x11, 0x74, 0x84, 0x74, 0x46, 0x1D, 0x3F, 0x9A, 0xE9, 0x73, 0x6B, 0x63, 0x57, 0xF6, 0x6E, 0x03, 0x3C, 0xC1, 0x34, 0xE9, 0x3D, 0x5B, 0x21, - 0x11, 0x7C, 0x39, 0xA6, 0xAD, 0x5D, 0x18, 0x01, 0xC0, 0x82, 0xEC, 0x41, 0x1A, 0xDC, 0x16, 0x4A, 0xF0, 0x56, 0xE9, 0x49, 0x4C, 0xE5, 0x4F, 0x84, - 0xCD, 0xF6, 0xE5, 0x20, 0x80, 0x4C, 0xEB, 0x80, 0xDF, 0x2D, 0x74, 0x79, 0xBE, 0xE7, 0xD2, 0xA3, 0x7E, 0x06, 0xF2, 0x34, 0x1F, 0xC1, 0x36, 0xA9, - 0xE2, 0xFD, 0x5D, 0x21, 0xD2, 0xFF, 0x49, 0x50, 0x22, 0x58, 0x17, 0x93, 0x6B, 0x2B, 0x80, 0x85, 0x5F, 0x9E, 0x08, 0xBD, 0x97, 0x60, 0x85, 0x76, - 0x30, 0xFA, 0x77, 0x5B, 0xBC, 0x2F, 0x2C, 0x41, 0x86, 0x18, 0x38, 0xD3, 0xD4, 0x4D, 0x2A, 0xF4, 0x79, 0x29, 0xCA, 0xDF, 0x3B, 0x73, 0x82, 0x88, - 0x34, 0x7B, 0x9E, 0x98, 0x67, 0x13, 0xEA, 0x92, 0xE1, 0x28, 0x89, 0xDA, 0x74, 0x36, 0x9F, 0x0E, 0xCA, 0x04, 0x6C, 0x8C, 0x1A, 0x0C, 0xEB, 0x69, - 0x27, 0xDB, 0x6F, 0x84, 0xD5, 0x6F, 0x71, 0x0F, 0xE3, 0xA3, 0x49, 0x3C, 0xC3, 0xCF, 0x04, 0x0B, 0x0E, 0x49, 0x1E, 0x90, 0x4B, 0x6D, 0x25, 0xDC, - 0xA7, 0x2C, 0x62, 0xC6, 0x26, 0x59, 0x87, 0xBC, 0xEA, 0x49, 0x64, 0xA6, 0x75, 0xA7, 0xFC, 0x63, 0x39, 0x5B, 0x12, 0x7A, 0xEC, 0x06, 0x6F, 0x90, - 0x69, 0x59, 0x3D, 0x56, 0xB8, 0x01, 0xC9, 0x39, 0xAD, 0xEB, 0xBC, 0x19, 0x4F, 0xD0, 0xB4, 0x4E, 0x05, 0x47, 0x08, 0x2C, 0x94, 0xDC, 0xF8, 0x99, - 0x83, 0x02, 0x0E, 0xED, 0x21, 0x60, 0x5E, 0x92, 0x26, 0xCA, 0x2E, 0x49, 0x43, 0xC0, 0xE0, 0xD1, 0x5C, 0x75, 0xC0, 0x56, 0x58, 0x42, 0x84, 0xD5, - 0x60, 0x11, 0xDB, 0xB2, 0xD6, 0xBE, 0x5C, 0x1E, 0x7E, 0x00, 0xFF, 0xE4, 0x84, 0xF4, 0x15, 0xE0, 0x0D, 0x77, 0x88, 0x2D, 0xE3, 0x53, 0xF4, 0x10, - 0x04, 0x51, 0x87, 0x2E, 0xA1, 0xD7, 0xEB, 0x30, 0xB7, 0xB3, 0x60, 0xFE, 0x2D, 0x81, 0x25, 0x97, 0x2E, 0x7E, 0xF1, 0xED, 0xC4, 0x1F, 0x52, 0xEE, - 0x80, 0x5C, 0x9D, 0x60, 0xB8, 0xD5, 0xBC, 0x76, 0xC4, 0x4D, 0x96, 0xB1, 0xD1, 0x7B, 0xCA, 0x30, 0xDB, 0x18, 0x6E, 0x87, 0x0E, 0x33, 0x09, 0x26, - 0x6F, 0x90, 0xF6, 0xC2, 0xBE, 0xFD, 0x5A, 0x31, 0xF9, 0x8F, 0x4B, 0x9F, 0x4F, 0xCF, 0x79, 0x1D, 0x46, 0x35, 0x6B, 0x41, 0xB1, 0x2F, 0xBD, 0xB3, - 0x0B, 0x97, 0x97, 0x1B, 0x00, 0x86, 0xF0, 0x41, 0x97, 0x9A, 0x2E, 0x21, 0xA0, 0x37, 0xEF, 0x29, 0xA1, 0xFA, 0x8A, 0x10, 0x1E, 0xB2, 0x73, 0xCC, - 0xF6, 0xE8, 0x06, + 0x28, 0xB5, 0x2F, 0xFD, 0xA4, 0xAD, 0x31, 0x03, 0x00, 0xDC, 0x22, 0x03, 0x8E, 0x4C, 0x44, 0xE9, 0x10, 0x2A, 0x10, 0x38, 0x7C, 0x31, 0xFF, 0xDA, + 0x6A, 0x32, 0xFE, 0x0B, 0x93, 0x28, 0x7D, 0x25, 0xFC, 0x14, 0xCA, 0xB1, 0x3E, 0x40, 0x88, 0xC5, 0x8B, 0x60, 0x1C, 0xBA, 0xD9, 0x07, 0x97, 0x17, + 0x22, 0x95, 0xDE, 0x9A, 0x34, 0x9F, 0xFA, 0xA8, 0xC7, 0x16, 0xB9, 0x53, 0xB0, 0x10, 0xF9, 0x10, 0xC9, 0x10, 0x90, 0x70, 0x66, 0x8F, 0x82, 0x6B, + 0xF7, 0x3B, 0x26, 0xC7, 0xC8, 0xA9, 0x15, 0x83, 0x67, 0x8D, 0xAC, 0x6C, 0x8C, 0x9A, 0x10, 0x54, 0xC8, 0xA8, 0x90, 0xE2, 0x16, 0x44, 0x8A, 0x13, + 0x13, 0x8A, 0xD0, 0x91, 0x8A, 0x44, 0x97, 0x89, 0x28, 0x22, 0x10, 0xC5, 0x64, 0x51, 0x14, 0x90, 0x3D, 0xAC, 0x5A, 0x35, 0xC4, 0x90, 0x7C, 0xA2, + 0x94, 0xEE, 0x97, 0xA0, 0x9D, 0xE7, 0x8D, 0xD0, 0x5B, 0x2C, 0xCF, 0x11, 0x7D, 0xE8, 0x6B, 0x68, 0xBB, 0xE3, 0x57, 0xA3, 0xEE, 0xFD, 0x8E, 0x7B, + 0x38, 0xA9, 0xA2, 0xF1, 0x95, 0xD1, 0xD1, 0x9C, 0xF0, 0x00, 0x37, 0x8B, 0x02, 0xFE, 0xE6, 0xC8, 0x23, 0x82, 0xB1, 0x3E, 0xC4, 0xF8, 0x34, 0xC5, + 0xE9, 0xB5, 0xC0, 0xFF, 0xFF, 0x1A, 0x6B, 0xF5, 0x0A, 0xC5, 0x53, 0xDB, 0x7F, 0xA5, 0xA5, 0x9B, 0x9C, 0x15, 0xEB, 0x96, 0xA5, 0x81, 0x72, 0xA5, + 0x8C, 0xE1, 0xCA, 0x86, 0xC8, 0x8A, 0xE4, 0xAD, 0x8A, 0x0A, 0x8C, 0x2A, 0x08, 0x6F, 0xAA, 0x4D, 0x4E, 0xEA, 0xEB, 0x44, 0x14, 0x5E, 0x07, 0xB8, + 0x1C, 0x1E, 0x2A, 0x70, 0xFE, 0xD4, 0x77, 0xEB, 0x74, 0xE9, 0xA1, 0xC9, 0xD1, 0x99, 0x89, 0xB2, 0x73, 0x3F, 0x43, 0x83, 0xEE, 0xBB, 0x67, 0xBF, + 0xFC, 0x21, 0xD3, 0xB9, 0xE7, 0x97, 0x1B, 0xE5, 0xF4, 0xEC, 0xC3, 0x80, 0xE7, 0x57, 0x66, 0xBF, 0x41, 0xC7, 0x1C, 0xEE, 0xC1, 0x5F, 0x81, 0x60, + 0x9A, 0xDF, 0xC0, 0xFB, 0x29, 0x67, 0xE5, 0x3D, 0xDF, 0xD4, 0xD4, 0x00, 0xEA, 0xFB, 0x76, 0x01, 0x9A, 0x86, 0xE0, 0xB3, 0x5C, 0x5B, 0xB3, 0xC5, + 0x0F, 0x33, 0x75, 0xF3, 0xA8, 0xCE, 0xBB, 0x86, 0x65, 0xEC, 0xD7, 0x6A, 0x6C, 0x0A, 0x49, 0xEC, 0xEF, 0x84, 0x15, 0x20, 0x03, 0x73, 0x5F, 0xC5, + 0x31, 0x34, 0xF8, 0xCA, 0xB2, 0x7B, 0x95, 0x28, 0x93, 0x63, 0xB8, 0xB7, 0xA0, 0xDB, 0xA2, 0x17, 0x8A, 0xC8, 0xC0, 0xC2, 0xF0, 0xAA, 0x04, 0xB0, + 0x4A, 0xDF, 0xDC, 0xC5, 0x86, 0x4F, 0x7E, 0xF1, 0x56, 0x79, 0x7E, 0xEB, 0x71, 0xC0, 0x81, 0xF4, 0x50, 0x7F, 0x21, 0x5E, 0xD0, 0x77, 0x4F, 0x42, + 0xB8, 0xDC, 0xCB, 0x7D, 0x54, 0x04, 0xDF, 0xB7, 0x74, 0x94, 0xFA, 0xE0, 0xC8, 0xFD, 0x93, 0x44, 0x80, 0x88, 0xA3, 0x0E, 0x46, 0xC0, 0x9B, 0xAE, + 0x17, 0x64, 0x25, 0x09, 0x64, 0x47, 0xF1, 0xF3, 0xB6, 0xEA, 0x83, 0x77, 0x01, 0x47, 0x00, 0xBF, 0x03, 0xBB, 0xEC, 0x00, 0x92, 0xC8, 0x2C, 0xCE, + 0x99, 0x81, 0xB9, 0x69, 0x75, 0xBD, 0x49, 0xFA, 0x35, 0xB9, 0x77, 0x35, 0x66, 0x31, 0x12, 0x8A, 0x04, 0xAC, 0x37, 0x34, 0x34, 0x7E, 0xE3, 0xCD, + 0xA4, 0x7B, 0x5E, 0xE8, 0xFF, 0xF1, 0x37, 0xEB, 0x1D, 0x6E, 0xDB, 0x42, 0x63, 0x0D, 0xAE, 0x3F, 0xD2, 0xEE, 0x8B, 0x8E, 0xFE, 0x40, 0xF2, 0x63, + 0x57, 0x25, 0xE3, 0x93, 0xF6, 0x72, 0x09, 0x74, 0xF8, 0xFD, 0xA1, 0x28, 0xE8, 0x0E, 0x0E, 0x28, 0x32, 0xEC, 0x67, 0x30, 0x83, 0x0F, 0xEB, 0xBC, + 0x47, 0xD3, 0x90, 0x07, 0x78, 0x6C, 0xE7, 0x96, 0x73, 0xE7, 0x63, 0x2E, 0x07, 0xFA, 0x45, 0x0E, 0x4F, 0x1D, 0x07, 0xC5, 0xC5, 0x8D, 0xD6, 0x0A, + 0x1B, 0x23, 0xDC, 0x9A, 0x03, 0xA6, 0x34, 0x64, 0xD1, 0x33, 0x16, 0x1C, 0xDD, 0x0F, 0x60, 0x64, 0x0A, 0x4F, 0x63, 0x1E, 0x81, 0x61, 0x38, 0x63, + 0xBC, 0xAC, 0x76, 0xB8, 0xE4, 0x7A, 0xB4, 0x18, 0xE3, 0xB4, 0xA8, 0x73, 0x58, 0x3C, 0x3E, 0x56, 0x68, 0xAA, 0x54, 0x76, 0x74, 0x52, 0x94, 0x76, + 0x50, 0xB2, 0xAC, 0x00, 0x9C, 0x5D, 0x9D, 0xC4, 0xB5, 0x99, 0x44, 0x70, 0x2B, 0xD9, 0xBB, 0xD0, 0x26, 0x81, 0x81, 0x64, 0xD1, 0x3E, 0x62, 0x59, + 0x28, 0x82, 0xC7, 0x10, 0x22, 0xBB, 0xF9, 0x41, 0xF4, 0x85, 0x1F, 0xFB, 0x13, 0x1E, 0x8D, 0x8F, 0x1E, 0x6D, 0x3C, 0x1B, 0x52, 0x86, 0xFD, 0xBE, + 0xE5, 0x80, 0x37, 0x6F, 0xC4, 0x9D, 0x35, 0xD8, 0x58, 0xEA, 0x6B, 0x06, 0x2D, 0x74, 0x35, 0x84, 0xB4, 0x1E, 0xF4, 0x1F, 0xE1, 0x12, 0xAD, 0xF8, + 0x02, 0x5D, 0xA9, 0xF4, 0x2C, 0xBA, 0xE4, 0x1C, 0x1B, 0xA0, 0xD9, 0xD7, 0x8C, 0x59, 0xD9, 0x41, 0x7B, 0x95, 0x6D, 0xE5, 0x97, 0xEE, 0x85, 0x28, + 0x5A, 0x71, 0xB9, 0x0B, 0x4B, 0x24, 0xDB, 0xF3, 0x78, 0x08, 0x2F, 0x51, 0xEA, 0x83, 0x88, 0x58, 0x76, 0x8D, 0x16, 0xBC, 0x89, 0xFA, 0x47, 0xB3, + 0xBC, 0x47, 0xB7, 0xA8, 0xF7, 0xD0, 0xED, 0xF1, 0xA8, 0x67, 0xF2, 0x23, 0xCC, 0xC8, 0xE6, 0xA1, 0xEE, 0x5F, 0x98, 0x17, 0xC5, 0xF0, 0xCA, 0x0F, + 0xEF, 0xD7, 0xFB, 0x87, 0x00, 0xFF, 0xB6, 0xF7, 0x3F, 0x85, 0xFF, 0x30, 0xEE, 0x5F, 0xD0, 0x99, 0x03, 0x87, 0xE6, 0x60, 0x00, 0xCC, 0x8B, 0x1C, + 0xCC, 0x1F, 0xFA, 0x25, 0xB8, 0x0F, 0x32, 0x7E, 0x6E, 0x84, 0x08, 0x7E, 0x2C, 0xEA, 0x6D, 0xAB, 0x08, 0x0F, 0x0C, 0x7E, 0x37, 0xD7, 0xC0, 0x2D, + 0xE1, 0xDE, 0x2C, 0xC4, 0xF8, 0xE0, 0x0E, 0x78, 0x12, 0x26, 0xFC, 0xF6, 0xC2, 0xBB, 0x58, 0x0A, 0xFE, 0xEC, 0x75, 0x27, 0x09, 0xB0, 0xAF, 0xA0, + 0x9F, 0xF9, 0xEC, 0x8E, 0xC6, 0x15, 0x15, 0x48, 0x2B, 0x6C, 0x0C, 0xE4, 0x6C, 0xCB, 0x3C, 0x9B, 0x00, 0xAD, 0xF3, 0xDC, 0x89, 0x66, 0x53, 0x3E, + 0xE6, 0x3F, 0xFC, 0xB2, 0xAE, 0x9C, 0x32, 0xE4, 0xAD, 0xF2, 0xBA, 0x03, 0xF2, 0xAA, 0x33, 0x72, 0x8D, 0x8A, 0xE3, 0xDF, 0x17, 0xC7, 0x53, 0xA3, + 0x32, 0x3C, 0x9E, 0x8D, 0x0B, 0xF4, 0x16, 0xF3, 0xB8, 0xEC, 0xF1, 0x36, 0x88, 0xB5, 0x94, 0x86, 0x4B, 0xFC, 0x0A, 0x1F, 0x08, 0x10, 0x7C, 0xC9, + 0x8E, 0xB1, 0xC1, 0x01, 0x30, 0xED, 0xCD, 0x6F, 0xE1, 0x99, 0x6F, 0xF3, 0x54, 0x2F, 0x27, 0x84, 0x5E, 0x17, 0x36, 0x18, 0xB8, 0x20, 0x60, 0x0C, + 0x51, 0xED, 0xA6, 0x23, 0x75, 0xC3, 0x08, 0xE4, 0xCE, 0xA8, 0xE2, 0xCE, 0xD1, 0xF5, 0x51, 0xC4, 0x2F, 0xFE, 0x06, 0x6F, 0xCD, 0x56, 0x6D, 0x21, + 0x31, 0x6B, 0xEB, 0xF6, 0xB4, 0xAB, 0xB3, 0xB3, 0x24, 0x46, 0x64, 0x7F, 0x35, 0x63, 0x2D, 0x7D, 0x62, 0x3D, 0x6A, 0x5F, 0x65, 0xB5, 0x5E, 0x77, + 0x98, 0x57, 0x41, 0x19, 0xC4, 0x4D, 0xE1, 0x34, 0xA5, 0x75, 0x4F, 0x52, 0xDC, 0x06, 0xA3, 0x89, 0x89, 0xA3, 0x69, 0xBF, 0xD0, 0xD0, 0xCF, 0xD0, + 0x19, 0xC7, 0xCF, 0x5E, 0xDD, 0xCF, 0xA4, 0x0F, 0x9E, 0x1D, 0x69, 0x17, 0x66, 0x8F, 0x9D, 0x3A, 0x32, 0x9C, 0x75, 0xA9, 0x78, 0xA8, 0xF5, 0xE6, + 0x08, 0x61, 0xCD, 0xB5, 0x99, 0x4C, 0x4B, 0x10, 0xCC, 0x0A, 0x50, 0x97, 0xB2, 0x3B, 0x2D, 0x08, 0x07, 0x58, 0xEE, 0x43, 0x2A, 0x37, 0x27, 0x54, + 0xB6, 0x79, 0x28, 0x5F, 0x90, 0xA0, 0x7C, 0x63, 0x49, 0x22, 0xDB, 0x49, 0xC6, 0xDF, 0x22, 0x53, 0x4A, 0x40, 0xCE, 0xF1, 0x1E, 0x8F, 0x2A, 0xEF, + 0x7A, 0x06, 0x1C, 0xCB, 0x5E, 0x57, 0x24, 0xE6, 0x35, 0x3E, 0x38, 0x66, 0x0C, 0x3D, 0x54, 0x21, 0xC2, 0x24, 0x45, 0x6F, 0xE7, 0x62, 0x23, 0xF2, + 0x22, 0x5B, 0x9F, 0x88, 0x0A, 0x20, 0x31, 0x07, 0x5A, 0x3E, 0x3C, 0x84, 0xE2, 0x09, 0xF7, 0x70, 0x24, 0x6E, 0xA8, 0x16, 0xAD, 0x07, 0x5A, 0x60, + 0x56, 0x58, 0x01, 0xC6, 0x5E, 0x05, 0x16, 0x4B, 0x48, 0xC8, 0xA4, 0xFF, 0xA0, 0x26, 0x7B, 0x67, 0xFB, 0xFF, 0xF3, 0xD1, 0xD1, 0xC1, 0xFC, 0x91, + 0xF6, 0x67, 0x77, 0x88, 0xBA, 0x00, 0x78, 0x3F, 0xC5, 0x4F, 0xD6, 0xA2, 0xE5, 0x26, 0x63, 0xF1, 0x92, 0x07, 0xB9, 0x6D, 0xBA, 0x05, 0x24, 0x22, + 0xBE, 0x1E, 0x90, 0x6F, 0xE4, 0x1B, 0xE7, 0xDD, 0x0E, 0xC8, 0x53, 0x03, 0x11, 0x51, 0xED, 0xBA, 0x4E, 0x5F, 0x69, 0x4C, 0x01, 0x2F, 0xE8, 0x75, + 0x4B, 0xF3, 0x7F, 0xF0, 0x45, 0x37, 0x92, 0xFF, 0xFF, 0x5A, 0x63, 0xAD, 0xC2, 0x1E, 0x1D, 0x6D, 0xA2, 0x80, 0x9A, 0x9B, 0x40, 0xD6, 0x18, 0xDB, + 0xDD, 0x93, 0x3C, 0x6E, 0x6E, 0x0D, 0x04, 0x8D, 0xDA, 0x5E, 0x7D, 0xC0, 0x24, 0x3C, 0x6D, 0x71, 0xC5, 0x17, 0xE0, 0xAA, 0x86, 0x86, 0xF7, 0x3B, + 0x9B, 0x61, 0x67, 0xA6, 0x77, 0x34, 0x43, 0x29, 0x31, 0x0F, 0xF0, 0x4F, 0xCB, 0x7C, 0x28, 0x90, 0xB9, 0x63, 0x8C, 0x71, 0x05, 0x8A, 0x45, 0x79, + 0x84, 0x25, 0xB0, 0x04, 0x63, 0xCB, 0x89, 0xF3, 0xC1, 0x7E, 0xD5, 0x81, 0x78, 0x31, 0xCE, 0xE8, 0x1A, 0xB1, 0xC3, 0x75, 0x7A, 0xB2, 0xDF, 0xAA, + 0x24, 0xD3, 0xDA, 0xDD, 0xC8, 0x8A, 0x6D, 0x90, 0xA5, 0x51, 0x73, 0xA5, 0xEC, 0xD7, 0xBE, 0xB2, 0x89, 0xB2, 0x22, 0xA1, 0xAB, 0xA2, 0x5A, 0xA3, + 0x0A, 0xFA, 0x9B, 0x6A, 0xA3, 0x20, 0xF5, 0x75, 0x8F, 0xC2, 0x0B, 0x84, 0xCB, 0xA1, 0x42, 0x05, 0x56, 0xF8, 0x7D, 0xC1, 0xF5, 0x4B, 0x13, 0xFF, + 0xFE, 0x51, 0xA7, 0x54, 0xFD, 0x33, 0x4C, 0xEA, 0xCD, 0xB2, 0x49, 0xBD, 0x21, 0x49, 0x2E, 0xC9, 0x1F, 0x89, 0xCD, 0x73, 0x34, 0x34, 0x6B, 0x94, + 0x83, 0xD5, 0x0E, 0x53, 0xA6, 0x5F, 0xBD, 0xB5, 0x1B, 0xA4, 0xD0, 0xE1, 0xF0, 0xDA, 0xA5, 0xC0, 0x0C, 0x2A, 0x9F, 0xF3, 0xF6, 0x95, 0x21, 0x47, + 0x2C, 0xA2, 0x9C, 0x28, 0xDF, 0xCA, 0xE4, 0x8E, 0xC5, 0x3D, 0x28, 0x28, 0x7D, 0xE7, 0x1B, 0xFF, 0xD3, 0xEE, 0x7E, 0x65, 0xFD, 0x79, 0x95, 0xC0, + 0xBA, 0x07, 0x59, 0x21, 0x02, 0xD9, 0x45, 0xFC, 0xBC, 0x79, 0xFA, 0xE0, 0x27, 0xDF, 0x08, 0x86, 0xEC, 0xC0, 0x22, 0x77, 0x40, 0x0E, 0x99, 0xBA, + 0x39, 0x33, 0x24, 0x08, 0x5E, 0x9C, 0xFE, 0x7A, 0x74, 0x0F, 0x27, 0x32, 0x0B, 0xA7, 0x06, 0x71, 0x8B, 0x16, 0xE1, 0xB6, 0x32, 0xDC, 0x26, 0x33, + 0x59, 0x40, 0x29, 0x84, 0x00, 0x14, 0x2B, 0xDB, 0x19, 0x8F, 0x7C, 0xAD, 0x78, 0x2D, 0x02, 0x96, 0xDA, 0x83, 0xD6, 0x01, 0x24, 0xDE, 0xD2, 0x42, + 0x18, 0x0B, 0xB0, 0xC4, 0x43, 0x63, 0xD1, 0x3E, 0xCB, 0x1B, 0x30, 0x83, 0x05, 0x0A, 0xB0, 0xCF, 0x2B, 0x4B, 0xE6, 0x2A, 0x6B, 0x1F, 0x92, 0x8D, + 0xBC, 0xC7, 0xDE, 0x9D, 0x62, 0x40, 0x5E, 0x61, 0x71, 0x3D, 0x98, 0x57, 0x82, 0xF8, 0x1C, 0xFA, 0x8B, 0x1E, 0xED, 0xA5, 0x87, 0xDB, 0x55, 0x08, + 0xC3, 0x95, 0x18, 0xBD, 0xC5, 0xC9, 0xF4, 0x9E, 0xFD, 0x63, 0xBE, 0xB7, 0xA0, 0x56, 0xC9, 0x98, 0x57, 0x09, 0x41, 0x52, 0x9D, 0x78, 0x98, 0x02, + 0xCB, 0x4B, 0x11, 0x31, 0x46, 0x31, 0x18, 0x86, 0xCB, 0x49, 0x80, 0x42, 0x6B, 0x7C, 0xEA, 0x1B, 0xE1, 0xC4, 0xA0, 0xDE, 0xE4, 0x48, 0xC9, 0xB4, + 0xC9, 0xBA, 0x54, 0xE8, 0xA8, 0xF4, 0x4A, 0x99, 0xC4, 0x79, 0x8A, 0x84, 0xDC, 0x7A, 0x84, 0x1B, 0xE3, 0x28, 0xC5, 0xB8, 0x48, 0x39, 0xB5, 0x08, + 0xA9, 0x4D, 0x44, 0x02, 0x39, 0x14, 0x00, 0x48, 0xE8, 0xC8, 0xC0, 0x7B, 0x81, 0x49, 0xD0, 0xD7, 0x30, 0x10, 0xDF, 0xED, 0xCF, 0x3C, 0xC4, 0x47, + 0x85, 0x0A, 0xB8, 0xA5, 0xC7, 0x3B, 0x35, 0x13, 0x3F, 0xBC, 0x21, 0x07, 0xF9, 0x44, 0x0E, 0xC7, 0x26, 0x0E, 0xCA, 0x82, 0x9B, 0x28, 0x26, 0x9B, + 0x22, 0xA6, 0x1A, 0x2A, 0x33, 0x1A, 0x31, 0xF6, 0x0C, 0x1B, 0xAB, 0x7B, 0x7E, 0x41, 0x86, 0x4E, 0x18, 0xD3, 0xF7, 0x05, 0x43, 0x98, 0xE0, 0x65, + 0x85, 0x8B, 0x8B, 0x66, 0x52, 0x8B, 0xA9, 0x2F, 0x0B, 0x6D, 0xE4, 0x0A, 0x70, 0x01, 0x15, 0x66, 0xBA, 0x8A, 0x47, 0x50, 0x0A, 0x0B, 0x17, 0x4A, + 0x8E, 0x33, 0x80, 0x24, 0x96, 0x13, 0x2B, 0x51, 0x13, 0x32, 0xC0, 0x92, 0xB6, 0xA9, 0x36, 0x9D, 0x9C, 0x04, 0x4D, 0x68, 0xE4, 0xC3, 0x0F, 0x5C, + 0xA4, 0x0E, 0xFA, 0x1D, 0xF2, 0xB8, 0x0C, 0x22, 0x82, 0xF4, 0x23, 0x95, 0x0E, 0xCF, 0x76, 0xDE, 0x6F, 0xF4, 0xCC, 0xC2, 0x2B, 0x55, 0x66, 0xD4, + 0xE1, 0x94, 0x2D, 0xBD, 0x34, 0x38, 0xFD, 0x5A, 0x78, 0xA9, 0xEA, 0x21, 0xD4, 0xFF, 0xA6, 0x5A, 0xAA, 0x66, 0x59, 0x91, 0x45, 0x58, 0xC5, 0x0F, + 0xE0, 0xAC, 0x61, 0xF7, 0x0F, 0xCE, 0x76, 0x9D, 0x2B, 0x97, 0x67, 0x14, 0x92, 0x9B, 0x9E, 0x51, 0xEB, 0x37, 0xBC, 0x05, 0xE1, 0xFD, 0x11, 0xF3, + 0x33, 0xB6, 0x32, 0xFD, 0xCD, 0x97, 0x36, 0xA7, 0xFF, 0x0D, 0xBF, 0xD5, 0xA6, 0x5D, 0x54, 0xD9, 0x13, 0xFC, 0x7E, 0x82, 0x0B, 0xBF, 0x63, 0xDD, + 0x99, 0xE1, 0xF0, 0xA7, 0x2E, 0x58, 0x8A, 0xE0, 0x90, 0x1A, 0x4E, 0x1A, 0x9C, 0xC5, 0x6F, 0x1C, 0x9C, 0x9C, 0xD3, 0xC9, 0xBB, 0xCF, 0xD3, 0xD7, + 0xD8, 0x58, 0xAB, 0xFD, 0x3E, 0x95, 0xA8, 0xCE, 0xF0, 0x86, 0x5C, 0xDA, 0x3B, 0x4F, 0x00, 0xFC, 0x8A, 0x4A, 0xF5, 0xFF, 0x4C, 0x5F, 0x9D, 0x16, + 0xFD, 0x6F, 0x7F, 0x2A, 0x1A, 0xDE, 0xA4, 0x5E, 0xFB, 0x52, 0x3F, 0xAA, 0x73, 0x0C, 0xEE, 0x0A, 0x82, 0x87, 0x5F, 0x16, 0xBF, 0xA3, 0xE1, 0x8E, + 0x3E, 0x6B, 0xB4, 0x0F, 0xFF, 0xEA, 0x91, 0x76, 0x28, 0xFE, 0xBB, 0x18, 0x2D, 0xCA, 0xC2, 0x64, 0xC3, 0x62, 0x3E, 0x71, 0x55, 0x5B, 0xE1, 0x0A, + 0x82, 0xC7, 0x7D, 0x93, 0xE7, 0xDE, 0x43, 0x22, 0x80, 0x9B, 0x47, 0xCF, 0xBA, 0x73, 0x5F, 0xDA, 0xF9, 0xC5, 0x39, 0x79, 0xB3, 0x9C, 0x19, 0x92, + 0xF7, 0xCD, 0xFE, 0xC1, 0x0D, 0x92, 0xB1, 0x4D, 0x1B, 0xB0, 0x06, 0x70, 0xF2, 0xDE, 0x61, 0x23, 0xC7, 0x36, 0xD4, 0x8A, 0xE6, 0x2B, 0x82, 0x16, + 0x34, 0x7A, 0x66, 0x0C, 0x73, 0xC6, 0x14, 0x6B, 0x76, 0x61, 0xC4, 0xCC, 0x7A, 0xB4, 0x7C, 0x0C, 0x41, 0x39, 0x94, 0x55, 0xF9, 0x64, 0x0A, 0x99, + 0x97, 0x10, 0x79, 0xA8, 0x3D, 0x63, 0x23, 0xC1, 0x31, 0x21, 0xF2, 0xB1, 0x53, 0x47, 0xEB, 0x54, 0x1B, 0xEB, 0x8E, 0x11, 0xEA, 0x5D, 0x18, 0xB5, + 0x2B, 0x9A, 0x74, 0x38, 0x8F, 0xB4, 0xAB, 0x50, 0xD4, 0x02, 0x60, 0xA8, 0xDE, 0x31, 0x34, 0x0A, 0xE9, 0x13, 0x9A, 0xE7, 0x53, 0xAE, 0xE1, 0xF9, + 0x82, 0xEC, 0xE2, 0x2E, 0xDF, 0xC9, 0xE4, 0x82, 0xD3, 0x84, 0x09, 0x3C, 0x5A, 0xDF, 0xE6, 0xE5, 0x8A, 0x66, 0xDD, 0x47, 0xA6, 0xEC, 0x2E, 0x66, + 0x08, 0xD8, 0x4B, 0xE5, 0xC7, 0x16, 0x93, 0x86, 0x2D, 0x54, 0x28, 0xE0, 0x2B, 0x5B, 0xE7, 0x95, 0x31, 0x7D, 0x2C, 0x5A, 0x46, 0xEF, 0x94, 0x13, + 0xC2, 0xE0, 0x27, 0xFE, 0xFA, 0xDE, 0x73, 0x82, 0x8A, 0x5C, 0x1C, 0xAE, 0xD1, 0xD1, 0xAB, 0x79, 0x30, 0xB7, 0x52, 0x1C, 0x83, 0xDB, 0x93, 0xD7, + 0xDE, 0xC9, 0xD3, 0xAF, 0x49, 0x6E, 0x84, 0x49, 0x34, 0x7A, 0xA9, 0xCF, 0x47, 0xE9, 0x85, 0x6E, 0x52, 0x65, 0x06, 0x24, 0x64, 0xD0, 0xA3, 0x54, + 0x03, 0x47, 0x6E, 0x99, 0x22, 0x65, 0xCE, 0xA2, 0xA4, 0x31, 0x22, 0x8E, 0x03, 0x43, 0x01, 0xDC, 0x42, 0x30, 0x5D, 0x6F, 0x7A, 0x84, 0x9B, 0xD6, + 0xD0, 0x1B, 0x24, 0xE3, 0x9A, 0xDC, 0xB9, 0xBB, 0xC6, 0xAC, 0x4D, 0x03, 0x22, 0x3A, 0x63, 0x21, 0xEE, 0xED, 0x26, 0x4A, 0x95, 0xB1, 0x1B, 0xDD, + 0x63, 0xEA, 0x60, 0x61, 0x46, 0x3D, 0x38, 0x73, 0xA0, 0xD0, 0x1C, 0xCC, 0xC1, 0xAC, 0xA8, 0xCC, 0xFC, 0xB1, 0xAA, 0x1C, 0xFA, 0xA9, 0x0C, 0xE6, + 0x93, 0x3C, 0x12, 0x83, 0x8C, 0x6F, 0x9B, 0xB1, 0xA1, 0x76, 0x2C, 0x22, 0x5A, 0x3F, 0x46, 0xF4, 0xC2, 0xB6, 0xC4, 0x6D, 0xE0, 0xAD, 0x6D, 0x33, + 0x4A, 0xAD, 0xE5, 0x59, 0x2D, 0x0B, 0xEE, 0x3D, 0x06, 0xF3, 0x6C, 0xD2, 0x8A, 0x16, 0xB7, 0x74, 0x6E, 0xCB, 0xE2, 0xA2, 0xCA, 0x67, 0xB8, 0xBD, + 0x92, 0x24, 0x4B, 0x1F, 0x22, 0x05, 0xDD, 0x9B, 0x48, 0x9D, 0xE0, 0x37, 0x7D, 0x8D, 0x3A, 0x4F, 0xE5, 0x3F, 0xC2, 0xFD, 0x71, 0xDF, 0x54, 0x13, + 0xEC, 0x41, 0x2B, 0xEE, 0x6D, 0x24, 0xEC, 0x5F, 0xA6, 0x77, 0x3C, 0x16, 0x76, 0x39, 0xE0, 0x7B, 0x60, 0xA0, 0xBB, 0xDE, 0x71, 0xBF, 0xB4, 0x74, + 0xDF, 0x71, 0xEE, 0xB4, 0xB0, 0xEE, 0xD0, 0x8F, 0x77, 0xF3, 0x0C, 0x77, 0xAF, 0xCE, 0xFB, 0xE5, 0xC4, 0xCD, 0xB6, 0x7A, 0x0F, 0x21, 0xDB, 0x7F, + 0xDB, 0xFB, 0x03, 0xB0, 0xFF, 0x0B, 0xEF, 0x3F, 0x64, 0xFF, 0xF6, 0xF7, 0x8F, 0xDB, 0x3F, 0x86, 0xFB, 0x5F, 0x60, 0xFF, 0x85, 0xF7, 0xCF, 0x67, + 0xFF, 0x9B, 0x77, 0xE0, 0xB9, 0xFB, 0xD6, 0xF6, 0xFE, 0xE1, 0xC1, 0x0D, 0xDD, 0x7C, 0xE7, 0x61, 0x74, 0xA3, 0xBC, 0x78, 0x6B, 0x91, 0xBA, 0x8D, + 0x9E, 0xDF, 0xDF, 0xD7, 0xFD, 0x5D, 0xDE, 0xBF, 0xD4, 0xFE, 0x95, 0xDE, 0xFF, 0xD7, 0xFE, 0x39, 0xEE, 0x9F, 0x6D, 0xFF, 0x36, 0xF7, 0x7F, 0x63, + 0xFF, 0x52, 0xF7, 0x0F, 0x76, 0xFF, 0x45, 0xF0, 0x2F, 0x77, 0xFF, 0x61, 0xF0, 0x2F, 0xF6, 0xFE, 0x73, 0xF8, 0x67, 0xF0, 0xFE, 0x1E, 0xE0, 0xBF, + 0xEF, 0xFD, 0x19, 0xE1, 0xBF, 0xF1, 0xFD, 0x49, 0xE1, 0xBF, 0xF4, 0xFD, 0x1B, 0xF1, 0xFF, 0xF7, 0xFD, 0x4B, 0xF1, 0xDF, 0xF4, 0xFE, 0x69, 0xE1, + 0x1F, 0xF8, 0xFE, 0xD7, 0xF0, 0xBF, 0xE3, 0xFE, 0x6F, 0xF0, 0x1F, 0xE7, 0xFE, 0xA7, 0xF0, 0x9F, 0xEA, 0xFE, 0x73, 0xE0, 0x5F, 0xE7, 0xFD, 0xAB, + 0xE0, 0x8A, 0x56, 0xEF, 0xCA, 0x02, 0x70, 0x36, 0xA9, 0xF7, 0xDE, 0x11, 0x5E, 0x2F, 0x0A, 0xCB, 0xC2, 0x7C, 0x43, 0x43, 0xAD, 0xE0, 0xC7, 0x3F, + 0xD3, 0xFF, 0x7F, 0xA4, 0xED, 0x16, 0x1D, 0x8D, 0x46, 0xE0, 0xAB, 0xC8, 0xBD, 0xFA, 0x41, 0xAC, 0x92, 0x41, 0x5C, 0x45, 0xB5, 0x47, 0x15, 0x84, + 0x39, 0xD5, 0x96, 0x28, 0xF5, 0x35, 0x1B, 0x85, 0xF7, 0x09, 0x97, 0x53, 0x86, 0x0A, 0x5C, 0x7C, 0xAA, 0xA7, 0x38, 0x5D, 0x86, 0x36, 0xDD, 0x8B, + 0x98, 0x68, 0x61, 0x2C, 0x85, 0xAE, 0x28, 0x39, 0xAF, 0x93, 0x7A, 0x8F, 0x92, 0x5E, 0x66, 0x90, 0xD8, 0x63, 0x47, 0x44, 0x1A, 0x46, 0x39, 0x73, + 0x45, 0x62, 0x34, 0x44, 0x57, 0xF5, 0xA1, 0x06, 0x70, 0x21, 0xB8, 0x15, 0xEF, 0x0F, 0x6A, 0x41, 0x77, 0x7E, 0x40, 0x91, 0x76, 0x3F, 0x83, 0x8E, + 0x3E, 0xAC, 0x25, 0x7A, 0x34, 0x4F, 0x79, 0x80, 0xEF, 0x76, 0x6E, 0x63, 0xEC, 0x7C, 0x08, 0xE6, 0x44, 0x7B, 0xE4, 0xF0, 0xB4, 0xC0, 0x41, 0x11, + 0xBE, 0xD1, 0x8A, 0xB5, 0x39, 0x02, 0xA9, 0x39, 0x80, 0xFC, 0xA6, 0x29, 0xDB, 0x99, 0xB1, 0x20, 0xEB, 0x7E, 0x70, 0x25, 0x53, 0x98, 0x1C, 0x03, + 0x09, 0x00, 0xA6, 0x13, 0xE5, 0x65, 0x75, 0xC8, 0x25, 0x97, 0xE8, 0x6E, 0x1C, 0x6F, 0x51, 0xAF, 0xB1, 0x78, 0x48, 0xAD, 0xD0, 0x50, 0x50, 0xD9, + 0x91, 0xA7, 0x28, 0xB1, 0xA1, 0x64, 0xDD, 0x01, 0x38, 0xAB, 0x70, 0x12, 0x27, 0x68, 0x12, 0xC1, 0x44, 0xC9, 0x5E, 0x8B, 0x36, 0x89, 0x4B, 0x92, + 0xC5, 0xD8, 0x11, 0x4B, 0x59, 0x11, 0xFC, 0x65, 0x88, 0x6C, 0x32, 0x88, 0x5E, 0xF6, 0x63, 0x3F, 0xEB, 0xD1, 0xF8, 0xEB, 0xD1, 0x56, 0x66, 0x77, + 0x50, 0xC0, 0x16, 0x4A, 0xE1, 0x88, 0x22, 0xDA, 0x00, 0x2B, 0xD2, 0x60, 0x03, 0xCB, 0xAF, 0x19, 0x84, 0xE1, 0xD5, 0x75, 0x46, 0xF1, 0xB4, 0x86, + 0x23, 0xF8, 0x1F, 0x21, 0x16, 0xAD, 0x38, 0x06, 0x5D, 0xC9, 0x20, 0xBE, 0xCA, 0x16, 0x87, 0xEF, 0x51, 0xE5, 0x29, 0xE8, 0xA1, 0xA9, 0x41, 0x75, + 0x3E, 0xAB, 0xFE, 0xFF, 0x4F, 0xFE, 0x67, 0xC7, 0x46, 0x47, 0x37, 0x90, 0xFF, 0xB0, 0xFF, 0xBF, 0xC6, 0xBA, 0xDD, 0x31, 0xFC, 0x26, 0x3F, 0x53, + 0x31, 0x66, 0xA6, 0x87, 0x0A, 0x50, 0x3A, 0x17, 0xE0, 0x0F, 0x20, 0x8B, 0x51, 0x27, 0x73, 0x4F, 0x18, 0x03, 0x59, 0x21, 0x06, 0x27, 0x11, 0x46, + 0xE3, 0x07, 0x26, 0x67, 0x11, 0x97, 0x72, 0xFC, 0x82, 0x50, 0xC2, 0x8B, 0xC0, 0xE9, 0x85, 0x18, 0x5B, 0x2C, 0x5E, 0xB5, 0x0C, 0x3D, 0xB2, 0x60, + 0x8F, 0xB1, 0x5C, 0xE4, 0x5C, 0x29, 0x9B, 0x58, 0xCD, 0x82, 0x58, 0x8D, 0x20, 0x53, 0x31, 0xEF, 0x50, 0x05, 0x01, 0x98, 0x6A, 0xB9, 0x92, 0xFA, + 0x1A, 0x8A, 0x5A, 0x72, 0x83, 0xCB, 0xC5, 0xA1, 0xD0, 0x30, 0x3C, 0xF5, 0x2D, 0x70, 0x62, 0xF0, 0xD6, 0xE4, 0xC8, 0xC7, 0xE4, 0x87, 0xB7, 0x04, + 0x2A, 0xA7, 0xF4, 0x78, 0x22, 0x89, 0xB7, 0x03, 0x92, 0x2A, 0x1E, 0x89, 0x43, 0x85, 0x51, 0xF1, 0xAD, 0x11, 0xCE, 0x68, 0x51, 0x89, 0x73, 0x9D, + 0xC8, 0xAA, 0x77, 0x48, 0x47, 0x2F, 0x04, 0xB7, 0x41, 0x7F, 0x63, 0x41, 0x07, 0x51, 0xF8, 0x05, 0x8A, 0x7B, 0xF9, 0xE1, 0x0B, 0x95, 0x6F, 0xD5, + 0x19, 0x7D, 0xBE, 0xAC, 0x35, 0xE7, 0xD5, 0x30, 0xEF, 0x55, 0xCD, 0x0B, 0xAB, 0x8D, 0xD1, 0xAA, 0xA9, 0xE7, 0x36, 0xD5, 0x4D, 0x6F, 0x7D, 0xAA, + 0x89, 0xFE, 0xA5, 0xE8, 0x44, 0x72, 0x36, 0x72, 0x5E, 0x3E, 0x6C, 0x7C, 0x58, 0x6A, 0x9A, 0x74, 0x68, 0x0C, 0x97, 0xDA, 0x74, 0x2D, 0x7B, 0x8C, + 0xA1, 0x2F, 0xF6, 0x5E, 0x29, 0xF2, 0x3D, 0x5D, 0x3D, 0xEA, 0x09, 0xA3, 0x6F, 0x7A, 0x6F, 0x77, 0xA6, 0xFC, 0xD3, 0x45, 0x95, 0xBA, 0x69, 0xEF, + 0x56, 0xBB, 0xB4, 0x31, 0x6E, 0x4F, 0x9A, 0x3B, 0x16, 0x4A, 0x4B, 0x13, 0x6A, 0x36, 0x28, 0x07, 0x5D, 0xD2, 0xA0, 0x3F, 0xB3, 0x3A, 0x39, 0xA6, + 0xF9, 0x2B, 0x3F, 0xE9, 0xBF, 0xB8, 0x43, 0xD2, 0xC2, 0xE2, 0x24, 0xC1, 0xC6, 0x64, 0xE3, 0x26, 0x48, 0xFC, 0x22, 0xA3, 0x03, 0x44, 0x54, 0x47, + 0x43, 0x5E, 0xC5, 0x72, 0x38, 0x8B, 0xFD, 0x0D, 0x92, 0xBC, 0x48, 0xBD, 0xFF, 0x6B, 0x9A, 0xB0, 0xD4, 0x3B, 0xFD, 0x5C, 0xEB, 0xC2, 0xB0, 0xFC, + 0x03, 0xC8, 0x9C, 0x50, 0x45, 0x2F, 0x29, 0x61, 0x9F, 0xB9, 0x2B, 0x37, 0x75, 0x5C, 0x93, 0xAF, 0x00, 0xF3, 0xA8, 0x30, 0xF7, 0xE8, 0x55, 0x3A, + 0x92, 0x53, 0xFE, 0xA4, 0x62, 0x78, 0x81, 0xEE, 0x17, 0x4D, 0x61, 0x04, 0x41, 0xCD, 0x7B, 0xDD, 0xF4, 0xB8, 0x75, 0xAB, 0xB7, 0x35, 0x8D, 0x72, + 0xDB, 0xCB, 0xC7, 0x42, 0x63, 0x4E, 0x1B, 0x75, 0x72, 0x81, 0xCF, 0x11, 0x4F, 0xE3, 0xB9, 0xAC, 0xA3, 0x65, 0x69, 0xF0, 0x40, 0x57, 0x6B, 0x7A, + 0x7E, 0xFF, 0xFF, 0x5F, 0x70, 0x6E, 0xDF, 0x18, 0xCC, 0xFF, 0x78, 0xE9, 0x6D, 0x6D, 0x35, 0x88, 0x9A, 0x9D, 0xEE, 0xFB, 0xEF, 0x0F, 0xF4, 0xDD, + 0x7F, 0xE5, 0xAB, 0xFC, 0x8F, 0xEF, 0xF1, 0xD9, 0x38, 0x8C, 0xBF, 0x46, 0xE7, 0xD3, 0xE0, 0x99, 0x26, 0x90, 0xD0, 0xCA, 0x29, 0xDC, 0x28, 0x19, + 0xAA, 0x7F, 0x1C, 0x9E, 0x35, 0xE3, 0x10, 0xAD, 0xEA, 0x1C, 0xF2, 0xFF, 0xC6, 0x8C, 0xBF, 0xE8, 0x19, 0xBB, 0xA4, 0x68, 0x0B, 0xEC, 0x6B, 0x09, + 0x04, 0xD3, 0x69, 0x0A, 0xBF, 0xE7, 0xEF, 0x7C, 0x9D, 0x4F, 0xF3, 0x61, 0xFE, 0xCB, 0x2F, 0xF9, 0x24, 0x1B, 0x3A, 0x48, 0xB9, 0x3E, 0xF8, 0x5F, + 0xAD, 0xFE, 0xE9, 0x6F, 0xF4, 0x87, 0x3E, 0xCF, 0xCF, 0xF9, 0x37, 0xDF, 0xE6, 0xD7, 0x7C, 0x96, 0xDF, 0xFE, 0x21, 0xEC, 0x8E, 0xBF, 0x0E, 0x2A, + 0x04, 0x23, 0xAE, 0x0B, 0x91, 0x62, 0x8A, 0x2F, 0x2E, 0xFF, 0x79, 0x2A, 0xE6, 0xAA, 0x1F, 0xFF, 0x6B, 0xC4, 0xD0, 0xCF, 0x94, 0x77, 0xFF, 0x4F, + 0xAF, 0x3F, 0xCF, 0xFB, 0x50, 0xAE, 0xD2, 0x92, 0x44, 0xAF, 0x72, 0x3F, 0xDE, 0xE5, 0x55, 0x15, 0xE8, 0xF3, 0x5B, 0xF1, 0x62, 0x0E, 0x7A, 0x61, + 0xD0, 0x78, 0x87, 0xDC, 0x4A, 0xC8, 0x5F, 0x5E, 0xA7, 0x83, 0xBC, 0x67, 0x2D, 0x8E, 0xA5, 0x42, 0xAE, 0xD5, 0x93, 0x37, 0x30, 0x2A, 0x87, 0x43, + 0xCC, 0x6B, 0xE8, 0x95, 0xE7, 0x35, 0x88, 0x2F, 0x6E, 0xC8, 0x51, 0x40, 0xE5, 0x37, 0x7D, 0xF5, 0x9E, 0x21, 0x71, 0x3D, 0x87, 0x1E, 0x57, 0x2F, + 0xFE, 0x6D, 0x3C, 0xBE, 0x58, 0xDE, 0x2D, 0xA5, 0x97, 0x71, 0xC7, 0xE1, 0x72, 0xBD, 0x53, 0x70, 0x5E, 0x7E, 0xA7, 0x17, 0x00, 0x97, 0xA7, 0xB0, + 0xAC, 0x97, 0x50, 0x14, 0x1F, 0x54, 0xD1, 0x53, 0x1A, 0xCE, 0xD6, 0xD6, 0xA4, 0xFF, 0xCF, 0xF7, 0xF9, 0x31, 0x28, 0x2B, 0xBF, 0x25, 0xF5, 0x0E, + 0x0C, 0xD5, 0xC3, 0x82, 0xD3, 0x41, 0x39, 0xD3, 0x15, 0x17, 0xAC, 0x52, 0x0D, 0x28, 0x98, 0x10, 0x05, 0x5F, 0xFF, 0xCF, 0xB1, 0x2E, 0xDE, 0x47, + 0xCB, 0xB0, 0x83, 0xA8, 0xDE, 0xEB, 0x98, 0x58, 0x7B, 0x7D, 0xD3, 0xFF, 0xFF, 0x6B, 0xAC, 0x9B, 0x35, 0x86, 0xE6, 0x24, 0x85, 0x06, 0xC8, 0xBE, + 0xDB, 0x1A, 0x83, 0xE8, 0x30, 0x81, 0xF0, 0x4A, 0x7F, 0x00, 0x67, 0x7D, 0x0E, 0x7F, 0x7B, 0x24, 0x95, 0x79, 0x3E, 0xD9, 0x3B, 0xAE, 0x29, 0x3A, + 0x30, 0x6E, 0x72, 0x66, 0x14, 0xE5, 0x6C, 0x4C, 0xD5, 0x71, 0x42, 0x56, 0x6E, 0x5E, 0x72, 0x6C, 0x7C, 0x8E, 0x6A, 0x9A, 0xAA, 0x68, 0xB8, 0xC6, + 0x66, 0xD2, 0x0A, 0xB8, 0x13, 0xCC, 0xC9, 0xD8, 0x59, 0x68, 0xF3, 0xD5, 0xDB, 0x90, 0xF3, 0x37, 0xFD, 0x71, 0x4F, 0xC2, 0x5D, 0x0F, 0x80, 0xA3, + 0xFD, 0x6B, 0x45, 0xE2, 0x50, 0xE3, 0x68, 0xE2, 0xBE, 0x77, 0xC1, 0x4F, 0xB1, 0x41, 0x4C, 0x58, 0xB8, 0x40, 0x3E, 0xF8, 0xEA, 0xE0, 0xEE, 0x68, + 0xF2, 0x7F, 0xF6, 0xA9, 0xCF, 0x5A, 0x79, 0xF7, 0x80, 0xE3, 0xBB, 0xBD, 0xD9, 0x15, 0xE7, 0xA7, 0x03, 0x57, 0xAC, 0x87, 0x6B, 0x61, 0xE1, 0xCD, + 0x25, 0xC9, 0x4D, 0x18, 0x40, 0x1B, 0x95, 0x5F, 0x5B, 0x4A, 0x02, 0x02, 0x10, 0x6C, 0x08, 0x40, 0x7D, 0xCA, 0xED, 0x76, 0xF2, 0x39, 0x33, 0x35, + 0x56, 0x12, 0xB5, 0xC0, 0x7B, 0x9A, 0xB3, 0x81, 0x34, 0xD4, 0x29, 0x01, 0x37, 0x78, 0xB4, 0x64, 0x41, 0x34, 0x16, 0x6A, 0xFB, 0x8C, 0x23, 0xB7, + 0x99, 0xD8, 0x99, 0xFB, 0xD8, 0x0C, 0xD6, 0x6D, 0x86, 0x32, 0x16, 0xC0, 0x02, 0x63, 0x00, 0x31, 0xBD, 0xB2, 0xE4, 0xA7, 0x32, 0x1F, 0x24, 0x32, + 0x15, 0x1A, 0x64, 0x76, 0x7A, 0x32, 0x95, 0xB4, 0x31, 0x2E, 0x32, 0xB1, 0x5A, 0x2B, 0xB1, 0x15, 0x33, 0x62, 0x48, 0x12, 0xC2, 0x12, 0x34, 0x08, + 0xDB, 0x18, 0x04, 0x8B, 0x2D, 0x05, 0xB3, 0xBB, 0x00, 0x97, 0x68, 0x17, 0x2A, 0xE1, 0x8E, 0x77, 0x5C, 0x7E, 0x09, 0xDA, 0xED, 0x5E, 0x45, 0x7C, + 0x5D, 0x22, 0x2A, 0xB9, 0x06, 0xC0, 0xD8, 0xAA, 0xC5, 0xD3, 0x3B, 0xB8, 0x6A, 0xD5, 0xB4, 0xFC, 0x4B, 0x1A, 0xAC, 0x28, 0xDE, 0x98, 0x15, 0xB9, + 0x16, 0x16, 0x88, 0xBF, 0x9D, 0x63, 0x48, 0xC2, 0x0A, 0x36, 0xE2, 0xC1, 0x78, 0x2E, 0x32, 0x0A, 0x45, 0x0F, 0x61, 0xBB, 0x02, 0xF1, 0x0D, 0xF9, + 0xA0, 0x0A, 0x3A, 0x10, 0xE0, 0x35, 0x77, 0x12, 0x37, 0xDF, 0xCC, 0xC1, 0x87, 0x73, 0x68, 0x8D, 0x0E, 0xFF, 0x6A, 0xE1, 0xD0, 0x5E, 0x56, 0x38, + 0xD4, 0x8C, 0x71, 0x0E, 0x1A, 0x0D, 0x80, 0x1E, 0x02, 0x6C, 0x59, 0xF0, 0x7F, 0x8D, 0xFF, 0xFF, 0xD5, 0x57, 0xA7, 0xD3, 0x80, 0xDF, 0xE4, 0xBF, + 0xB8, 0x3F, 0x0C, 0x99, 0xDB, 0x12, 0x6B, 0x9B, 0xD6, 0x7E, 0xCC, 0xE6, 0x82, 0xD8, 0x2C, 0xA6, 0x18, 0xE3, 0x9E, 0x98, 0x83, 0x24, 0xAE, 0x43, + 0x66, 0xAE, 0x3D, 0x33, 0x2E, 0xB6, 0xCC, 0xAD, 0xD9, 0xB4, 0x56, 0x07, 0xCB, 0xAC, 0xFD, 0x2E, 0x16, 0x8B, 0x12, 0xAC, 0x12, 0xB5, 0x95, 0xFE, + 0x80, 0x95, 0x90, 0xBB, 0xCA, 0xE4, 0x99, 0x0A, 0xEC, 0x69, 0xAA, 0x89, 0x4C, 0x8A, 0x41, 0x5A, 0x54, 0x5A, 0x03, 0xB8, 0x9F, 0x04, 0xA8, 0x06, + 0x01, 0x9E, 0x14, 0xD5, 0x9C, 0x3E, 0x38, 0x68, 0x12, 0xB5, 0x63, 0x8A, 0xFC, 0xB0, 0xE4, 0x5B, 0x42, 0x89, 0xF5, 0x51, 0xA9, 0xA3, 0x12, 0x49, + 0x46, 0x6A, 0x1C, 0x49, 0xE7, 0x55, 0x7E, 0xF4, 0x01, 0x69, 0x04, 0x65, 0x59, 0xC4, 0x93, 0x27, 0x5A, 0x83, 0x1D, 0xD2, 0x1A, 0x16, 0xAA, 0x30, + 0xE3, 0x8D, 0x20, 0x24, 0x1F, 0x64, 0x3F, 0xD1, 0x03, 0xF1, 0x21, 0xFE, 0x74, 0xE6, 0xFA, 0xA8, 0x68, 0xD0, 0x83, 0xEB, 0xC8, 0x43, 0x0A, 0xC5, + 0xF3, 0x27, 0xE8, 0xF4, 0xB6, 0xD0, 0x81, 0x41, 0xCE, 0xE1, 0xD0, 0xC3, 0x69, 0x72, 0x71, 0x73, 0x23, 0x66, 0x43, 0x20, 0xA7, 0x86, 0xCA, 0x4D, + 0x23, 0x21, 0x6D, 0x86, 0x2D, 0xD0, 0x2D, 0x02, 0x56, 0x86, 0x0E, 0x17, 0x43, 0x69, 0x08, 0x43, 0x58, 0xF4, 0xE2, 0x3A, 0x77, 0xD1, 0xFC, 0x2D, + 0xC7, 0x4D, 0x2C, 0xB4, 0x13, 0x58, 0xE6, 0x86, 0x2A, 0xCC, 0x58, 0x2A, 0xF6, 0x0F, 0x29, 0x2C, 0x00, 0x50, 0xBE, 0xE2, 0x00, 0x90, 0x70, 0x4F, + 0x16, 0xC0, 0x98, 0x90, 0xA5, 0x95, 0x70, 0x18, 0xD1, 0xA6, 0xD3, 0x21, 0x49, 0xD1, 0x36, 0xF2, 0x37, 0x43, 0x64, 0x54, 0x28, 0xE4, 0x91, 0x13, + 0xA4, 0xF7, 0xF9, 0x23, 0xB5, 0xE9, 0x63, 0xA3, 0xAE, 0x63, 0xD8, 0xA3, 0xC3, 0xA6, 0x8A, 0x1D, 0xE2, 0xCA, 0x31, 0x55, 0xB2, 0xDF, 0xE8, 0x39, + 0xA1, 0xC1, 0x76, 0xBB, 0xCE, 0x82, 0x51, 0x57, 0x38, 0x9B, 0xA7, 0xE1, 0x7E, 0xFF, 0xE0, 0x4D, 0x74, 0x1E, 0x25, 0x34, 0xA6, 0xF1, 0x33, 0x8A, + 0x0B, 0xCE, 0xB4, 0x9A, 0xCD, 0x9D, 0xCF, 0xCC, 0xCB, 0x4A, 0xCB, 0xB8, 0xA4, 0xCB, 0x2B, 0x1C, 0xC9, 0xD1, 0x55, 0xC9, 0x47, 0xAB, 0xC8, 0x31, + 0x25, 0x33, 0xC8, 0x08, 0x8F, 0x99, 0xF8, 0x64, 0x34, 0x68, 0x31, 0x46, 0x3B, 0x2B, 0xF6, 0xE3, 0xDD, 0x47, 0xB8, 0xA1, 0x13, 0xDF, 0x23, 0xE7, + 0xC3, 0x22, 0x8C, 0x85, 0x53, 0x2B, 0x04, 0x4F, 0x2A, 0xF8, 0x31, 0x82, 0x99, 0xF7, 0xAE, 0x72, 0x60, 0x10, 0x4B, 0xDF, 0xE3, 0x1F, 0xDF, 0xA3, + 0x02, 0xAB, 0x1B, 0x1A, 0xE3, 0xAA, 0x78, 0xF2, 0xFC, 0x62, 0x84, 0xD4, 0xBE, 0x37, 0x54, 0xD0, 0xE3, 0x53, 0x46, 0x5C, 0xD3, 0x17, 0x3B, 0xA5, + 0xA5, 0x2B, 0xE4, 0xA4, 0xA1, 0xBE, 0xA3, 0xCE, 0xC4, 0x7A, 0xE6, 0x09, 0x79, 0xD1, 0x0F, 0x92, 0x7A, 0x0A, 0x99, 0x5D, 0x2A, 0xFE, 0xFF, 0x1F, + 0xFF, 0xB3, 0x7D, 0xFF, 0x7F, 0x71, 0x7F, 0x0B, 0x5F, 0x9D, 0xDE, 0x47, 0x47, 0x17, 0xB7, 0x79, 0xC0, 0xB1, 0xB5, 0x79, 0x05, 0xEB, 0x6B, 0x8D, + 0xF4, 0x86, 0x86, 0x3A, 0xBD, 0x16, 0xFA, 0x7F, 0xA4, 0xFD, 0xD5, 0xB5, 0x28, 0x5F, 0x6B, 0x1F, 0xC0, 0x9A, 0xDD, 0xC9, 0x9B, 0x14, 0xDD, 0xE4, + 0xC1, 0xD4, 0xBC, 0x6D, 0xE0, 0xAC, 0x4D, 0x52, 0x87, 0x36, 0xD2, 0x48, 0x25, 0x92, 0x0A, 0xFB, 0xD7, 0x53, 0xA2, 0x7B, 0x75, 0x1D, 0xA7, 0x8C, + 0xB4, 0x3B, 0x0C, 0x54, 0xD6, 0xDF, 0xBA, 0xC5, 0x5E, 0xF5, 0xB2, 0x51, 0x9D, 0x4B, 0xC9, 0x6F, 0xF8, 0x3F, 0xF5, 0xAF, 0xA8, 0x3D, 0xEB, 0x61, + 0x0F, 0x35, 0x6B, 0x41, 0x07, 0x8D, 0xAE, 0xE4, 0x38, 0x34, 0xB2, 0x60, 0x28, 0x81, 0xEB, 0x04, 0x90, 0x49, 0x21, 0x3D, 0xC4, 0x2E, 0x47, 0x41, + 0x68, 0xE7, 0x19, 0xDC, 0x83, 0x36, 0x81, 0xC7, 0x12, 0xC4, 0xF4, 0x83, 0xF5, 0x99, 0x07, 0x5E, 0xD5, 0xED, 0xFD, 0xE4, 0xF1, 0x2F, 0x04, 0xA3, + 0x81, 0x36, 0x1C, 0xFF, 0x7F, 0x1A, 0x35, 0x47, 0x5A, 0x2D, 0x9D, 0xF6, 0x91, 0x7E, 0xD1, 0x27, 0xFA, 0x38, 0xDF, 0xE5, 0xA7, 0x7C, 0x94, 0x2F, + 0xF2, 0x41, 0x3E, 0xC7, 0xDF, 0xF8, 0xD1, 0xD1, 0xCE, 0x49, 0x7F, 0xBC, 0x7F, 0x58, 0xD1, 0x7F, 0xE4, 0xFF, 0xAF, 0xFE, 0xFF, 0xA7, 0xBF, 0xFA, + 0x74, 0xFE, 0x7F, 0x51, 0x80, 0xFF, 0xD3, 0xC7, 0xFF, 0xFF, 0x94, 0xFF, 0xD3, 0x70, 0xFF, 0xAB, 0x2B, 0x04, 0xB6, 0xAC, 0x0E, 0x76, 0x49, 0x63, + 0x95, 0x48, 0x45, 0xE0, 0xA2, 0xCA, 0x01, 0x44, 0x7F, 0xD4, 0x42, 0x49, 0x96, 0x40, 0xBB, 0xEC, 0x3E, 0x83, 0xCC, 0x3C, 0xDB, 0xD6, 0x5C, 0x7C, + 0x3D, 0xE8, 0xC4, 0xA3, 0xC0, 0x29, 0x07, 0x88, 0x3F, 0x0C, 0xDC, 0xEC, 0x83, 0xD4, 0xF4, 0xB4, 0xCC, 0x74, 0xCC, 0x63, 0xEE, 0xC2, 0x5E, 0x82, + 0x4A, 0x5E, 0x6A, 0xCC, 0xB0, 0xE4, 0x5D, 0xB5, 0x74, 0x91, 0xAD, 0xE4, 0xD8, 0xB3, 0x60, 0x4A, 0xA6, 0xCC, 0x19, 0x99, 0x4C, 0x43, 0x91, 0xBC, + 0xF2, 0x89, 0xB4, 0x23, 0x82, 0x84, 0xD3, 0x7A, 0x14, 0x04, 0xBB, 0xDF, 0xFD, 0x38, 0x46, 0x16, 0xAD, 0x18, 0xDC, 0x6A, 0x64, 0x0D, 0x63, 0xD4, + 0x8C, 0x53, 0x21, 0x63, 0x9E, 0xE2, 0x56, 0x2F, 0xC5, 0x89, 0x07, 0x45, 0x68, 0x14, 0x8A, 0x44, 0x8C, 0x89, 0x28, 0x7B, 0x88, 0x62, 0xA4, 0x7B, + 0x14, 0x46, 0x89, 0x87, 0x07, 0x56, 0x18, 0x62, 0xF8, 0xD5, 0xBB, 0xE5, 0xCE, 0x4B, 0x9C, 0xCA, 0xF3, 0xFE, 0x3C, 0x86, 0x1C, 0x31, 0x66, 0xBE, + 0xDE, 0xD7, 0x1D, 0xFF, 0xFF, 0x6C, 0x0E, 0x0D, 0x8E, 0xF4, 0xFF, 0x28, 0x2B, 0xEC, 0x0E, 0x54, 0xD1, 0xAE, 0xE6, 0x51, 0xF8, 0x3B, 0x1F, 0x77, + 0xE9, 0x85, 0xC7, 0x87, 0xE3, 0x4D, 0x1B, 0x70, 0x06, 0x21, 0xF1, 0xB4, 0x1A, 0xB8, 0x1E, 0x71, 0xDE, 0x2E, 0x0A, 0xAE, 0x28, 0x92, 0x17, 0x5C, + 0x83, 0x8B, 0xF6, 0xE4, 0x23, 0xA5, 0xB0, 0x7C, 0xB3, 0xF2, 0xAC, 0x72, 0x7C, 0x07, 0xDC, 0x1D, 0xFE, 0x44, 0x10, 0x8F, 0x65, 0x98, 0xB7, 0x0A, + 0xC2, 0x73, 0x21, 0xBF, 0xEB, 0x2F, 0x1F, 0x3D, 0xBD, 0x4D, 0x37, 0x5A, 0x70, 0x85, 0xBB, 0x34, 0x39, 0x75, 0x33, 0x2E, 0xC6, 0x4E, 0x84, 0x4E, + 0x94, 0xEC, 0xFD, 0x94, 0x40, 0x6D, 0xB5, 0x65, 0x5F, 0x49, 0xD6, 0xE2, 0x46, 0x7A, 0x2B, 0xBC, 0x2B, 0xE8, 0x89, 0xB4, 0x98, 0xBC, 0x69, 0x1B, + 0x78, 0xA0, 0x79, 0xBD, 0x41, 0x09, 0x75, 0x5E, 0xCC, 0x8E, 0x60, 0x87, 0x70, 0xD1, 0x00, 0x5D, 0xB2, 0x6B, 0x04, 0xD8, 0x70, 0xFF, 0xB1, 0x61, + 0x3F, 0x84, 0x83, 0x67, 0xE4, 0x12, 0x67, 0xE8, 0xA7, 0x64, 0x66, 0x97, 0xE4, 0x93, 0x39, 0xE1, 0x0C, 0xAF, 0x6E, 0xE1, 0x2A, 0xAD, 0x60, 0x63, + 0xA3, 0x60, 0x90, 0x0C, 0xA7, 0x20, 0xDE, 0x74, 0x4E, 0x63, 0x40, 0x49, 0x39, 0x10, 0x8E, 0xFA, 0xC6, 0x8C, 0xC2, 0xC4, 0x88, 0x76, 0x34, 0x85, + 0xAE, 0x84, 0x81, 0xCA, 0xC8, 0x7C, 0x0E, 0x40, 0xF3, 0x84, 0x72, 0xA2, 0x50, 0x97, 0xB4, 0x26, 0x80, 0x13, 0x50, 0x00, 0xBE, 0x42, 0x84, 0x4D, + 0xC9, 0x08, 0x9A, 0x84, 0x22, 0x32, 0x5B, 0x45, 0x60, 0x6E, 0x4E, 0x5E, 0x1E, 0x4F, 0x36, 0x46, 0x3E, 0x60, 0x74, 0xC1, 0x57, 0xA9, 0x62, 0x75, + 0x2A, 0x45, 0xEE, 0x59, 0xD2, 0x62, 0x31, 0x89, 0x62, 0x34, 0xAD, 0x5E, 0x24, 0xD9, 0xFF, 0x85, 0xC7, 0x4F, 0xFF, 0xAF, 0x5D, 0x50, 0xED, 0x09, + 0x13, 0x89, 0x1D, 0x3D, 0x87, 0x37, 0x3F, 0x85, 0x41, 0x13, 0x83, 0x5F, 0x15, 0x91, 0x41, 0x7F, 0x53, 0x76, 0x61, 0xE8, 0x38, 0xEF, 0xAA, 0xAD, + 0x69, 0xF1, 0x01, 0x66, 0xA1, 0x49, 0xBC, 0x96, 0xE2, 0x49, 0x53, 0xD4, 0x44, 0x85, 0x1D, 0x45, 0xB1, 0x8A, 0x43, 0x45, 0x4E, 0x41, 0xE7, 0xCA, + 0x9F, 0x27, 0x1D, 0x3C, 0x03, 0x4F, 0xB8, 0x20, 0x52, 0xD1, 0x79, 0x89, 0xE7, 0x14, 0x1B, 0xC5, 0xD3, 0xDE, 0x6E, 0x36, 0xE8, 0xD5, 0x6C, 0x76, + 0xCE, 0x04, 0xDC, 0xC8, 0x7C, 0x69, 0xC9, 0x4B, 0xD6, 0xC0, 0x2F, 0x9B, 0x92, 0x28, 0xE3, 0x6A, 0x31, 0xC2, 0x98, 0x66, 0x3F, 0x53, 0x39, 0x54, + 0x41, 0x68, 0x53, 0x6D, 0x55, 0x52, 0x5F, 0x75, 0x51, 0x78, 0x05, 0xE0, 0x72, 0x21, 0xA0, 0x02, 0xAD, 0xDA, 0x2E, 0xD8, 0x35, 0x91, 0x38, 0x8A, + 0x8F, 0x86, 0x4E, 0x18, 0xE5, 0x90, 0x14, 0x85, 0xE1, 0xE7, 0x6E, 0xFF, 0x9C, 0x23, 0x5B, 0x58, 0x93, 0x76, 0x3E, 0x94, 0x78, 0x02, 0x68, 0x39, + 0xB0, 0x31, 0x52, 0xAC, 0x39, 0xF0, 0x01, 0x4F, 0x06, 0x9A, 0x77, 0xB0, 0x7B, 0xB2, 0xA0, 0x00, 0xDE, 0xEF, 0x85, 0x8A, 0x8E, 0x6B, 0xFE, 0xFB, + 0xC8, 0xFC, 0x44, 0xC3, 0x10, 0xDA, 0x07, 0x18, 0xF2, 0xB3, 0x24, 0x50, 0x52, 0x59, 0x94, 0xA5, 0xAA, 0x41, 0x47, 0x81, 0x6D, 0x47, 0xC9, 0x8A, + 0xF5, 0x22, 0x8A, 0xE2, 0x9F, 0xB7, 0x77, 0x2A, 0x3C, 0xC4, 0x57, 0x9C, 0x01, 0x9A, 0x28, 0xD2, 0xF0, 0x86, 0xD3, 0xA8, 0xAC, 0x04, 0xDC, 0xBA, + 0x40, 0x43, 0x11, 0x72, 0x06, 0x8D, 0x6B, 0xF6, 0xC9, 0x63, 0x16, 0x13, 0xED, 0x86, 0x81, 0xF5, 0x2E, 0x33, 0xCA, 0x7D, 0xB7, 0xEC, 0xFA, 0xA8, + 0x70, 0xCE, 0x59, 0xFA, 0x36, 0xB3, 0x73, 0xDB, 0x17, 0x73, 0x36, 0x08, 0x59, 0x05, 0xC2, 0x62, 0xFE, 0x89, 0xA6, 0xC3, 0x11, 0xAF, 0x5E, 0x73, + 0x41, 0x11, 0x74, 0x5A, 0x50, 0x00, 0x45, 0x29, 0xF7, 0xAE, 0x05, 0x70, 0x3F, 0x43, 0x51, 0x2A, 0xBB, 0x3F, 0x88, 0x49, 0x25, 0xA3, 0x91, 0x5E, + 0x3B, 0xAE, 0xBC, 0xC8, 0x9C, 0x8D, 0x2D, 0xA0, 0x4F, 0x41, 0xC5, 0x49, 0x99, 0xE1, 0x87, 0x46, 0x89, 0x7B, 0xA6, 0x6C, 0x79, 0x38, 0xB7, 0x76, + 0xD8, 0xFC, 0xDC, 0x92, 0x60, 0x27, 0x42, 0xB3, 0x25, 0xAD, 0x72, 0x25, 0x60, 0xCA, 0x7A, 0x8F, 0xC3, 0xA7, 0x38, 0xC7, 0x14, 0x5D, 0xE6, 0x0F, + 0x96, 0x6F, 0x9C, 0x9E, 0x4F, 0x5B, 0xFB, 0x16, 0xCF, 0x80, 0xDD, 0x0E, 0x04, 0xF5, 0x03, 0xF5, 0xCE, 0x27, 0xE1, 0x87, 0x03, 0x08, 0x99, 0xAF, + 0x0F, 0xD7, 0x57, 0xF7, 0x23, 0x3E, 0x5A, 0xED, 0x9F, 0xAD, 0x38, 0x3D, 0x14, 0x75, 0x17, 0xB1, 0xF4, 0xC6, 0x57, 0x68, 0xBA, 0xB4, 0x3E, 0xFA, + 0xA7, 0xC0, 0x82, 0x31, 0x9A, 0x85, 0xE7, 0x4F, 0xA0, 0xE0, 0xCF, 0xCD, 0x3A, 0x8E, 0x83, 0x62, 0x77, 0x33, 0xA8, 0xEB, 0x9E, 0xD7, 0x65, 0x96, + 0x93, 0xF3, 0x7D, 0x31, 0x2B, 0x9E, 0xA1, 0xD1, 0x24, 0x24, 0x3E, 0x79, 0x99, 0x1F, 0x7C, 0x90, 0x56, 0xBE, 0x4A, 0x37, 0x55, 0x2B, 0xCE, 0x47, + 0x07, 0x8F, 0xD3, 0xAB, 0xC1, 0x6C, 0xFF, 0x68, 0xFC, 0xCB, 0xB0, 0x6B, 0x6B, 0x65, 0x4C, 0x88, 0xDD, 0x3B, 0x5D, 0x80, 0xFF, 0x4B, 0xFC, 0x0F, + 0x25, 0x62, 0xEA, 0xAC, 0x87, 0x1E, 0x73, 0x07, 0xB0, 0x2F, 0x28, 0x52, 0x4A, 0x0E, 0x1B, 0x24, 0x3B, 0x50, 0x37, 0xB3, 0x4E, 0x28, 0xE0, 0xDE, + 0x74, 0x4F, 0x0D, 0x7D, 0xA2, 0xFC, 0x3A, 0xCA, 0xFF, 0xEA, 0xF4, 0xB7, 0xFC, 0x7D, 0x1D, 0x6E, 0x4E, 0xD3, 0x04, 0x85, 0x5A, 0xFF, 0xAF, 0x35, + 0xF4, 0x1C, 0x5E, 0xF4, 0x05, 0x2B, 0x52, 0xD7, 0xF4, 0xEF, 0xC6, 0x62, 0x06, 0x83, 0x3C, 0x77, 0x38, 0x80, 0xBF, 0xF8, 0x6F, 0xFE, 0x8A, 0x1F, + 0x38, 0x27, 0xBD, 0xAC, 0x92, 0x08, 0xE0, 0x7E, 0x23, 0xAE, 0xD7, 0x90, 0x3F, 0xCF, 0xD7, 0x73, 0x68, 0x35, 0x04, 0xFD, 0xDE, 0x0F, 0xF3, 0x71, + 0xD6, 0xA4, 0x68, 0x67, 0x85, 0xE7, 0xAF, 0x1B, 0x7C, 0x10, 0x3F, 0x6F, 0x05, 0xE9, 0x83, 0xF9, 0xF1, 0x9A, 0x9E, 0xAA, 0xF2, 0x80, 0xB9, 0x5A, + 0xE3, 0x77, 0xF8, 0x19, 0x3E, 0x04, 0xC7, 0xA5, 0xB4, 0xDE, 0x17, 0x01, 0x1D, 0x9D, 0x18, 0xAD, 0x87, 0xAE, 0x7C, 0x01, 0x66, 0x7F, 0x5F, 0xE3, + 0x94, 0x00, 0x34, 0x74, 0x9C, 0xFF, 0xBF, 0x08, 0x65, 0x91, 0xB4, 0x87, 0x8F, 0x01, 0x52, 0x34, 0xCC, 0x41, 0x2C, 0x58, 0xD3, 0x09, 0x04, 0xBD, + 0xD7, 0xA6, 0x57, 0x57, 0x86, 0x3D, 0x2E, 0xD3, 0xE4, 0x2D, 0x41, 0x05, 0x5A, 0xBA, 0xB4, 0x59, 0x91, 0xF1, 0xAC, 0xF5, 0xF2, 0x55, 0xED, 0x62, + 0xDC, 0x46, 0x25, 0xFE, 0xF9, 0xDE, 0x04, 0x48, 0xAE, 0x4E, 0xB2, 0x1E, 0x3D, 0xB3, 0x80, 0x71, 0x8D, 0xC3, 0xCF, 0xE2, 0x57, 0x3F, 0xF9, 0x00, + 0x4D, 0x79, 0xB8, 0xAD, 0x3C, 0x04, 0xB4, 0xFC, 0x5D, 0x50, 0x5C, 0x44, 0x5D, 0x7E, 0xB0, 0x2B, 0xCE, 0x22, 0x44, 0x5E, 0x13, 0x41, 0x1C, 0x56, + 0x32, 0x7F, 0xBB, 0x17, 0x4F, 0x5E, 0xCD, 0x43, 0x27, 0xE6, 0xA8, 0xE4, 0xE2, 0xA0, 0x6C, 0xB8, 0x01, 0x02, 0xB5, 0xA9, 0x21, 0x9A, 0x02, 0x43, + 0x33, 0x92, 0x20, 0x16, 0xA7, 0xFD, 0x68, 0xD6, 0x61, 0x71, 0xB1, 0x52, 0x61, 0x6A, 0x13, 0x70, 0x41, 0xC8, 0x14, 0x0C, 0x38, 0xDF, 0xA6, 0x10, + 0x48, 0x02, 0x79, 0x62, 0xC4, 0xD2, 0x80, 0x08, 0x7E, 0x2B, 0x44, 0x36, 0x0F, 0x44, 0x1F, 0xF7, 0xB1, 0x3F, 0xF0, 0xF1, 0xF5, 0x3A, 0x92, 0x27, + 0x74, 0xB8, 0x51, 0xB0, 0x53, 0xB0, 0x38, 0xE0, 0x2E, 0x36, 0x8C, 0x00, 0x68, 0xC8, 0x71, 0xE3, 0xEB, 0x79, 0x2E, 0x5C, 0x0D, 0xC1, 0x33, 0xAD, + 0xF7, 0xF9, 0x45, 0xE4, 0x46, 0x27, 0xEA, 0x42, 0x57, 0xFE, 0x67, 0x3D, 0x03, 0xCE, 0x9F, 0x8B, 0xCD, 0x89, 0x79, 0xCC, 0xB4, 0x4C, 0xCB, 0xBA, + 0x62, 0xCB, 0x4E, 0x54, 0xC9, 0xD1, 0x14, 0x92, 0xE5, 0x1B, 0xAD, 0x2E, 0xB0, 0xAC, 0x86, 0xC2, 0xAB, 0x4C, 0x33, 0x54, 0x3D, 0x41, 0x4C, 0x05, + 0xBF, 0x4C, 0x6D, 0xDC, 0xE2, 0x98, 0x0A, 0xF0, 0xA4, 0x4C, 0x58, 0xA2, 0xAC, 0x60, 0xA2, 0x02, 0xDE, 0xF2, 0x74, 0x03, 0xE0, 0xAC, 0x80, 0x71, + 0x46, 0x02, 0x9D, 0x74, 0x3D, 0x9D, 0xCA, 0xCF, 0xBE, 0xFD, 0x18, 0xFE, 0x05, 0x4F, 0xB9, 0x4E, 0x5C, 0x72, 0x10, 0x17, 0x32, 0x54, 0xD7, 0x8C, + 0xAF, 0x03, 0xC7, 0x6B, 0x08, 0x64, 0xC8, 0x69, 0x30, 0xAE, 0xB0, 0x57, 0xDC, 0x87, 0x18, 0xFC, 0xA8, 0x19, 0x83, 0xF7, 0x13, 0x58, 0xB5, 0x16, + 0x98, 0x43, 0xD7, 0xB7, 0x98, 0xD9, 0x37, 0x27, 0xDD, 0x6B, 0xB2, 0xC2, 0x7B, 0x25, 0xA3, 0x9B, 0xD5, 0x92, 0x7B, 0x37, 0xF3, 0x62, 0xAF, 0xEC, + 0x56, 0x73, 0x80, 0xED, 0x22, 0x5D, 0xBC, 0xF6, 0x76, 0x82, 0xAC, 0xDE, 0x81, 0x2C, 0x8A, 0x5D, 0xEC, 0xFF, 0x00, 0x6B, 0x54, 0xE2, 0xD5, 0xFD, + 0xE8, 0x4A, 0x56, 0xD9, 0x0A, 0x4F, 0x65, 0x75, 0xF0, 0xAA, 0x27, 0x95, 0x95, 0x93, 0xA6, 0xC4, 0x45, 0x97, 0xEF, 0x44, 0x8F, 0x16, 0x84, 0xB6, + 0x09, 0x80, 0xCE, 0x35, 0x7D, 0xBE, 0xE9, 0x9E, 0x0A, 0xE6, 0x2E, 0xE2, 0x83, 0x9D, 0x1D, 0x3C, 0x70, 0xAA, 0x5D, 0xE1, 0x59, 0x7B, 0x37, 0xEB, + 0xB3, 0x9A, 0xC6, 0x92, 0x99, 0x26, 0x84, 0x32, 0xFF, 0x80, 0x4B, 0xD5, 0x94, 0x4B, 0x8D, 0x52, 0xCB, 0xDE, 0x65, 0x4B, 0x9B, 0x5F, 0x7C, 0x65, + 0x87, 0x0A, 0x0B, 0x2F, 0x29, 0x4A, 0x14, 0xFC, 0xE4, 0x02, 0xB9, 0xA4, 0xCD, 0x65, 0xA4, 0x87, 0x3B, 0xC8, 0xAD, 0xF9, 0xE3, 0x0A, 0xC1, 0x7B, + 0x05, 0x32, 0x47, 0xCC, 0xAA, 0x15, 0x7C, 0xD0, 0x8D, 0xC3, 0xB1, 0x8C, 0x9B, 0x7E, 0x2A, 0x9C, 0x2D, 0xA4, 0x38, 0x5D, 0x4A, 0xF1, 0x42, 0xA8, + 0x58, 0x5B, 0xA4, 0xD8, 0x94, 0x89, 0xE8, 0x1C, 0x76, 0x47, 0x14, 0xB3, 0xA3, 0x70, 0x91, 0x39, 0x94, 0x50, 0x66, 0xF8, 0x7E, 0x3C, 0x61, 0x42, + 0x05, 0x1E, 0xF8, 0x7A, 0xF2, 0x2E, 0xB1, 0x7B, 0x8B, 0x2F, 0x56, 0x61, 0x57, 0xFF, 0x9F, 0x98, 0x2E, 0xA5, 0x8A, 0xB0, 0xE3, 0x0A, 0xC7, 0x7F, + 0x54, 0xD8, 0xC0, 0x1C, 0x21, 0x3B, 0x01, 0xFE, 0x07, 0x43, 0xA2, 0x47, 0x69, 0x20, 0x7A, 0x52, 0x87, 0x01, 0x2F, 0x3C, 0xC5, 0x39, 0x4F, 0x79, + 0x28, 0xB5, 0xA2, 0x87, 0x63, 0xA6, 0xC2, 0xA6, 0x4A, 0x66, 0x8B, 0x6A, 0x2C, 0x4C, 0x47, 0x34, 0x0D, 0x78, 0x58, 0xCF, 0x92, 0xBA, 0xCB, 0xE2, + 0x53, 0xC7, 0x3E, 0x0D, 0x91, 0x67, 0x93, 0x31, 0x12, 0x9A, 0x00, 0xAE, 0xD5, 0xA8, 0xCC, 0x8C, 0x0B, 0xB8, 0xDD, 0x80, 0x76, 0xC8, 0x3A, 0xD6, + 0x2C, 0x63, 0x8C, 0x4C, 0x54, 0xEC, 0xA5, 0x24, 0xCC, 0x01, 0x2F, 0x58, 0x53, 0x50, 0x3C, 0x84, 0xC6, 0x57, 0x5A, 0x97, 0x17, 0x25, 0x4D, 0x97, + 0x1D, 0x02, 0xAE, 0x57, 0xF8, 0x96, 0xE0, 0x9E, 0x96, 0x70, 0x4D, 0x56, 0x64, 0x82, 0x2C, 0x91, 0x28, 0x3D, 0xEB, 0x86, 0xFD, 0x07, 0x12, 0x49, + 0xE8, 0x38, 0xBD, 0x98, 0xB7, 0x6E, 0x17, 0x9B, 0x43, 0x63, 0x43, 0x43, 0x14, 0x15, 0x30, 0x2D, 0x0E, 0x02, 0xF9, 0x2B, 0x0D, 0x4A, 0xEE, 0x45, + 0x09, 0x20, 0xDE, 0x65, 0x17, 0xC5, 0xF5, 0x9A, 0xB2, 0x25, 0xB8, 0xA6, 0x15, 0xBC, 0x9C, 0x15, 0x29, 0x95, 0x25, 0xA2, 0x72, 0xC5, 0x2A, 0x77, + 0xFE, 0x31, 0x0A, 0x96, 0x71, 0xE7, 0x4C, 0xC5, 0x92, 0x20, 0x88, 0xCB, 0xAE, 0x0D, 0x29, 0xC1, 0xD7, 0x01, 0x3B, 0x3C, 0xB2, 0x04, 0x72, 0x1A, + 0xEC, 0x02, 0x93, 0x82, 0xFB, 0x10, 0xED, 0x2E, 0xCB, 0x82, 0x1D, 0x3D, 0xED, 0x68, 0xE9, 0x82, 0x41, 0x13, 0x9D, 0x9B, 0xFF, 0x82, 0x79, 0x3F, + 0x9D, 0x5D, 0xEE, 0xC1, 0x1C, 0xBA, 0xCE, 0x43, 0x80, 0x09, 0x72, 0xD2, 0xCE, 0x61, 0x90, 0x09, 0xAE, 0x64, 0x9C, 0xE7, 0xF2, 0x09, 0xE0, 0x9C, + 0x9C, 0xFF, 0x86, 0x13, 0xDC, 0xCD, 0xD8, 0x45, 0x86, 0x24, 0x18, 0x84, 0xB2, 0x63, 0xE5, 0x49, 0xA0, 0x39, 0xC0, 0x0E, 0x58, 0x24, 0xF8, 0x76, + 0x82, 0xDD, 0x47, 0x4F, 0x30, 0x34, 0x09, 0x3B, 0x9E, 0xAC, 0x60, 0x14, 0x3B, 0x67, 0x2D, 0xB8, 0x60, 0xA3, 0x12, 0xCE, 0x07, 0x20, 0xD4, 0x92, + 0x55, 0x3A, 0x5B, 0x88, 0x4B, 0xE0, 0xE0, 0xD5, 0x79, 0x3D, 0xDF, 0xC7, 0xD5, 0x10, 0x56, 0xF5, 0x69, 0x3D, 0xD6, 0x2F, 0x62, 0x1F, 0x9D, 0x58, + 0x0C, 0x5D, 0x39, 0xF2, 0x2C, 0x4A, 0xE2, 0x1C, 0xEB, 0xD3, 0xEC, 0xFB, 0xC3, 0xAC, 0xAC, 0xA5, 0x67, 0xEE, 0xD8, 0xCA, 0x2F, 0x93, 0x00, 0xC9, + 0x95, 0x67, 0x11, 0x28, 0xEB, 0x10, 0x48, 0x0E, 0xAA, 0x42, 0x86, 0xB2, 0x9A, 0xF1, 0x55, 0xE0, 0x78, 0xAD, 0x4D, 0x86, 0x9C, 0x05, 0xE3, 0x0A, + 0x17, 0x8A, 0xFB, 0x08, 0xF7, 0x84, 0x76, 0x62, 0xC7, 0xCC, 0xE1, 0x4D, 0x4D, 0x61, 0x50, 0x7B, 0xF0, 0x23, 0x8B, 0x18, 0xBC, 0x9A, 0xC0, 0xAA, + 0xAE, 0xC0, 0x1C, 0xB5, 0xBE, 0xC5, 0x32, 0x7C, 0x71, 0x98, 0x7B, 0x4D, 0x4A, 0x78, 0xAF, 0x56, 0x60, 0xE8, 0xCC, 0xD8, 0x1D, 0xE0, 0xAC, 0x9B, + 0x75, 0x92, 0x7B, 0xD7, 0x82, 0x1B, 0x27, 0xA4, 0x1F, 0x4C, 0x7A, 0xB1, 0xF7, 0x75, 0xAB, 0x59, 0x66, 0xBB, 0xA8, 0xA0, 0xF6, 0x96, 0x8E, 0x76, + 0xF5, 0x93, 0xB6, 0x84, 0x6D, 0x26, 0xFB, 0xBB, 0x28, 0x9B, 0x03, 0x1C, 0xEB, 0x11, 0x0A, 0x8B, 0xD5, 0xF1, 0xBA, 0x03, 0xC3, 0xD5, 0x00, 0x4E, + 0xAB, 0xD6, 0x1A, 0x8B, 0x55, 0x03, 0x55, 0xAC, 0x9C, 0x57, 0xD4, 0xF4, 0xB3, 0x20, 0xCD, 0x05, 0x24, 0x75, 0xBB, 0x8E, 0xAA, 0x21, 0x75, 0x44, + 0xE1, 0x32, 0x42, 0x59, 0x40, 0x80, 0xB2, 0x95, 0x54, 0x7E, 0x2A, 0x45, 0x7A, 0x42, 0x98, 0xE1, 0xE2, 0x4C, 0xB5, 0x73, 0xC4, 0x09, 0x67, 0x04, + 0x62, 0x45, 0x7C, 0xA5, 0x50, 0x92, 0xE6, 0x60, 0x57, 0x82, 0x16, 0xAF, 0x76, 0x95, 0x77, 0x7C, 0x6A, 0x4E, 0x4D, 0x36, 0xB6, 0x9F, 0xC4, 0x0F, + 0x35, 0xBD, 0xFA, 0x01, 0xAB, 0x92, 0x51, 0xA2, 0x8A, 0xCA, 0x88, 0x2A, 0xC8, 0xC0, 0x54, 0x9B, 0x98, 0xD4, 0x57, 0x5E, 0x14, 0x1E, 0x03, 0xB8, + 0xDC, 0x21, 0x54, 0xE0, 0xD8, 0x53, 0x5F, 0xA7, 0xD3, 0xE5, 0x5C, 0x93, 0xA3, 0x9E, 0x89, 0xB6, 0xBE, 0x04, 0xEA, 0x42, 0xA9, 0x79, 0x45, 0x12, + 0x2F, 0x6E, 0x92, 0x8B, 0x29, 0x12, 0x47, 0xF4, 0xD1, 0xD0, 0xDD, 0x28, 0x07, 0xA6, 0x28, 0x0C, 0x95, 0xE8, 0x8A, 0x69, 0x68, 0x2E, 0x58, 0x08, + 0xEE, 0xEC, 0xFD, 0xE1, 0x23, 0xE8, 0xCE, 0x09, 0x28, 0x52, 0xE7, 0x67, 0x50, 0x80, 0x0F, 0xAB, 0x55, 0x8F, 0x66, 0x04, 0x1E, 0xE0, 0x9D, 0x9D, + 0x5B, 0x11, 0x3B, 0x1F, 0x57, 0x39, 0xD0, 0x93, 0x39, 0x3C, 0x6E, 0x38, 0x28, 0x23, 0x6E, 0xB4, 0x30, 0xD8, 0x18, 0x51, 0xD6, 0x1C, 0x28, 0xA4, + 0x21, 0x6B, 0x75, 0x60, 0x2C, 0x53, 0x68, 0x18, 0xF3, 0x88, 0x87, 0xE1, 0xE4, 0x7C, 0x51, 0xBD, 0x75, 0xC1, 0x7D, 0xD1, 0x52, 0xEC, 0xDC, 0x92, + 0x7E, 0x66, 0xE9, 0x78, 0xB1, 0x42, 0xE3, 0xA2, 0xA2, 0xF3, 0x9C, 0x92, 0x04, 0x8D, 0x92, 0xE5, 0x02, 0xE0, 0xEC, 0xE5, 0x24, 0x4E, 0xC9, 0x24, + 0xC2, 0x52, 0xC9, 0x5E, 0x80, 0x36, 0x09, 0x33, 0x92, 0x45, 0x07, 0xFA, 0x11, 0xCB, 0x07, 0x22, 0xF8, 0xB3, 0x10, 0x59, 0xC0, 0x3C, 0x88, 0x1E, + 0xC2, 0xC7, 0xBE, 0xEE, 0xE3, 0x83, 0xF0, 0x68, 0x87, 0xE8, 0x70, 0x47, 0xB2, 0xDF, 0x92, 0x1C, 0x70, 0x55, 0xF9, 0x46, 0x7C, 0x35, 0xAE, 0x21, + 0x27, 0xC6, 0x8D, 0x4B, 0xD2, 0x0F, 0x42, 0xAD, 0xCA, 0x85, 0xF3, 0xA5, 0x1A, 0x72, 0x09, 0x5B, 0xD8, 0xC6, 0x07, 0x2B, 0x33, 0xC8, 0xE9, 0xC5, + 0x8A, 0x45, 0xA1, 0xF8, 0xFF, 0xF5, 0x7D, 0x95, 0x8C, 0xB5, 0x56, 0x72, 0xFE, 0x5F, 0xF3, 0x2D, 0x9B, 0x44, 0x68, 0x50, 0xB2, 0x57, 0x6F, 0x93, + 0xF0, 0x23, 0x59, 0x5C, 0x31, 0x62, 0xE9, 0x28, 0x82, 0xF7, 0x0B, 0x91, 0x3D, 0x05, 0xD1, 0x3B, 0x7E, 0xEC, 0xEF, 0x1F, 0xFF, 0xD4, 0xA3, 0x8D, + 0xDA, 0xE1, 0x8E, 0xC1, 0x11, 0xE5, 0x61, 0x07, 0xFB, 0x78, 0xA0, 0xE7, 0xE1, 0xFF, 0xCF, 0x28, 0xAF, 0x69, 0xA2, 0x20, 0x41, 0x53, 0x9F, 0x16, + 0x58, 0xA2, 0x56, 0x6F, 0xE8, 0x8A, 0xE8, 0xDE, 0xF8, 0x5F, 0x93, 0x1E, 0x56, 0x41, 0x03, 0x4B, 0x5E, 0xE1, 0xE7, 0x4D, 0x0F, 0xF7, 0xC1, 0xAB, + 0xD2, 0x80, 0xEC, 0xCE, 0x58, 0xC8, 0x10, 0x77, 0x13, 0xC5, 0x90, 0xB1, 0xC7, 0xD4, 0xC9, 0x80, 0x19, 0x4D, 0xE1, 0xCC, 0x81, 0x44, 0x73, 0x30, + 0x0D, 0xF3, 0x22, 0x00, 0xE6, 0x8F, 0x61, 0xE5, 0x50, 0x5C, 0x65, 0x30, 0xAC, 0xE4, 0x91, 0x25, 0x64, 0x3C, 0x7D, 0xC6, 0x86, 0x84, 0xE3, 0x11, + 0x2E, 0xFA, 0xB1, 0xAF, 0x17, 0xB6, 0x94, 0xB7, 0x81, 0xCC, 0xB6, 0xCD, 0x42, 0x71, 0x4B, 0x07, 0xB5, 0x2C, 0xCF, 0xF9, 0xE0, 0x94, 0xD9, 0x24, + 0xD2, 0x16, 0xB7, 0x75, 0xCB, 0xE2, 0x78, 0x25, 0xC9, 0xDB, 0x4F, 0xA1, 0x81, 0x3E, 0xA3, 0xF7, 0x75, 0xFF, 0x1C, 0x88, 0xB8, 0xC6, 0xA5, 0x38, + 0x36, 0x09, 0xDC, 0xA9, 0x19, 0x5C, 0xCE, 0x8F, 0x9B, 0xF0, 0x03, 0xB8, 0x38, 0x61, 0x78, 0x56, 0xE4, 0x5E, 0x96, 0x88, 0xDA, 0x67, 0x4D, 0x6C, + 0xBF, 0xBA, 0x6B, 0x5D, 0xC9, 0x74, 0xA1, 0x3B, 0x15, 0x89, 0x46, 0x13, 0x51, 0x50, 0x20, 0x8A, 0xF5, 0xB6, 0x51, 0x18, 0xB9, 0x38, 0x3C, 0x40, + 0xBA, 0xC1, 0xD7, 0xBE, 0x9A, 0xC1, 0x3E, 0xC2, 0xAF, 0xD2, 0xB1, 0xAE, 0xE1, 0x16, 0xF5, 0xEE, 0xFF, 0xFF, 0xE9, 0xFE, 0x1C, 0xF2, 0xE6, 0xEA, + 0x67, 0xAD, 0x4A, 0x86, 0x62, 0x15, 0xD5, 0x14, 0x55, 0xD0, 0x83, 0xA9, 0x36, 0x36, 0xA9, 0x2F, 0xC0, 0x28, 0xBC, 0x0A, 0x70, 0x39, 0x48, 0xA8, + 0x40, 0x02, 0x4F, 0x7D, 0x79, 0xA7, 0x4B, 0x7A, 0x93, 0xE3, 0x30, 0x13, 0xED, 0xE0, 0x12, 0xA8, 0xAA, 0x52, 0x33, 0x66, 0x12, 0x2F, 0x71, 0x92, + 0xCB, 0x2C, 0x12, 0x5B, 0xE4, 0x68, 0x48, 0xB3, 0x96, 0xE8, 0x2A, 0x6B, 0x68, 0x8E, 0x59, 0x08, 0x0E, 0xEE, 0xFD, 0x61, 0x25, 0xE8, 0x6E, 0x0B, + 0x28, 0xF2, 0xE8, 0x67, 0x30, 0xCE, 0x87, 0x75, 0xAC, 0x47, 0x53, 0x8F, 0x07, 0x18, 0x69, 0xE7, 0x16, 0xC5, 0xCE, 0x07, 0x59, 0x0E, 0xB4, 0x8B, + 0x1C, 0x9E, 0x06, 0x38, 0x28, 0x88, 0x37, 0x5A, 0x7E, 0x36, 0x46, 0x9E, 0x35, 0x07, 0x1C, 0x69, 0xC8, 0x72, 0x67, 0x2C, 0x7C, 0x70, 0x3F, 0xF8, + 0x32, 0x85, 0x8F, 0x31, 0x8F, 0xA8, 0x30, 0x9C, 0xA9, 0x2F, 0xAA, 0xC1, 0x2E, 0xB8, 0xC2, 0x2D, 0xC6, 0x1F, 0x2D, 0x6A, 0x10, 0x96, 0x0E, 0xE1, + 0x15, 0x9A, 0x1D, 0x95, 0x1D, 0x90, 0x14, 0xA5, 0x10, 0x94, 0xAC, 0x1D, 0x00, 0x67, 0x3C, 0x27, 0x71, 0x57, 0x26, 0x11, 0xB0, 0x4A, 0xF6, 0xDC, + 0xDA, 0x24, 0xDE, 0x48, 0x16, 0x31, 0xEC, 0x47, 0x2C, 0xF1, 0x44, 0xF0, 0x70, 0x21, 0xB2, 0x27, 0xF4, 0x20, 0xFA, 0x0C, 0x1F, 0xFB, 0xBC, 0x8F, + 0x6F, 0xE8, 0xD1, 0x3E, 0x64, 0x77, 0xF8, 0xEC, 0x37, 0x07, 0xFC, 0xC5, 0xB3, 0x28, 0x8C, 0x73, 0xEC, 0x52, 0xB3, 0x2F, 0x53, 0x33, 0x51, 0x9D, + 0x2F, 0xF6, 0x17, 0xC2, 0x1A, 0x29, 0xEE, 0xE5, 0xCD, 0x7A, 0x0D, 0xFB, 0x39, 0x89, 0x26, 0xC0, 0x9F, 0x21, 0x93, 0x46, 0x80, 0xE5, 0xFD, 0xC7, + 0x1D, 0xA8, 0x6D, 0x7E, 0xEA, 0x97, 0x03, 0xEC, 0x60, 0xC4, 0xDC, 0xF1, 0x60, 0x99, 0xC4, 0x0C, 0xF0, 0x1F, 0xF6, 0x21, 0x1E, 0x56, 0xE9, 0x0D, + 0xF1, 0x38, 0xFE, 0x09, 0x37, 0xE8, 0x7A, 0x89, 0x5F, 0x7A, 0xDE, 0x4B, 0xFD, 0x92, 0x4D, 0x47, 0x5C, 0xAA, 0x6B, 0x84, 0xDC, 0x35, 0xFA, 0xB0, + 0x36, 0xD2, 0x7B, 0x0D, 0xB6, 0x1C, 0xFB, 0x9A, 0x81, 0x8E, 0xBA, 0x0E, 0xC4, 0x9D, 0xD6, 0xF0, 0x47, 0xEC, 0x44, 0x2B, 0xF2, 0x40, 0x57, 0x5E, + 0x3D, 0x8B, 0x62, 0x39, 0xC7, 0xBA, 0x35, 0xFB, 0xBE, 0x31, 0x2B, 0x63, 0x60, 0xEE, 0xC0, 0x5B, 0x26, 0x79, 0xC3, 0x43, 0x86, 0xCA, 0x30, 0xE3, + 0xEB, 0xC4, 0xF1, 0x9A, 0xA1, 0x0C, 0x39, 0xBC, 0x71, 0x05, 0xCE, 0xE2, 0xBE, 0xDB, 0x3D, 0x83, 0x4B, 0x62, 0x47, 0xE7, 0x61, 0x3F, 0x59, 0x61, + 0x50, 0x7D, 0xF0, 0x63, 0x72, 0x0C, 0x5E, 0x68, 0xE0, 0x55, 0x14, 0x60, 0xF6, 0x8B, 0xAF, 0x31, 0x91, 0x6F, 0xCE, 0x52, 0xAF, 0x09, 0x18, 0xEF, + 0x95, 0x19, 0x8C, 0x9D, 0xA2, 0x5D, 0x35, 0x26, 0xDD, 0xAC, 0xB0, 0xDC, 0xBB, 0x33, 0xDC, 0xB8, 0xB9, 0x7E, 0x10, 0xC2, 0x8B, 0x3D, 0x0F, 0xB7, + 0x9A, 0x20, 0x6C, 0x17, 0x19, 0x6B, 0x6F, 0x23, 0x69, 0xF1, 0xF5, 0x59, 0x68, 0x55, 0x59, 0xFD, 0x0A, 0x59, 0x94, 0xC9, 0xD8, 0x6F, 0x0A, 0x6B, + 0xC4, 0xFA, 0xEA, 0x06, 0x76, 0x25, 0x2B, 0x5E, 0x65, 0xC3, 0x69, 0x97, 0xEE, 0xB5, 0x54, 0x66, 0xDA, 0xD5, 0x9C, 0xE8, 0x92, 0x94, 0xFE, 0x8B, + 0x9B, 0x02, 0xD7, 0xDA, 0x60, 0xDA, 0x5E, 0xAD, 0xAD, 0x73, 0x80, 0xA6, 0x88, 0x34, 0x3C, 0xBD, 0x80, 0xDB, 0x49, 0xB4, 0x43, 0xE8, 0x33, 0x68, + 0x56, 0xB3, 0xCF, 0x17, 0xB3, 0x98, 0xE2, 0x32, 0x18, 0x4B, 0x65, 0x46, 0xAD, 0x63, 0xCE, 0x30, 0x63, 0x64, 0xC6, 0x62, 0x2F, 0x4C, 0x61, 0x0F, + 0xDA, 0x60, 0x4D, 0x67, 0xF1, 0x10, 0x40, 0x5F, 0x69, 0x10, 0xBC, 0x28, 0xB9, 0xBA, 0xEC, 0x40, 0x70, 0xBD, 0x1E, 0xD8, 0x12, 0x8C, 0xD4, 0x12, + 0xF6, 0xCA, 0x8A, 0x14, 0x91, 0x25, 0x92, 0xE0, 0x8A, 0x75, 0xF2, 0xEA, 0x67, 0x43, 0x95, 0x0C, 0xD6, 0x2A, 0x2A, 0x05, 0x54, 0x41, 0xF6, 0xA9, + 0x36, 0x0E, 0x52, 0x5F, 0x9A, 0x51, 0x78, 0x8B, 0x70, 0xB9, 0x5A, 0xA8, 0xC0, 0x0E, 0x4F, 0x7D, 0xCC, 0x4E, 0x97, 0x2A, 0x9A, 0xEE, 0x2B, 0x4C, + 0xB4, 0xA3, 0x4B, 0xA0, 0xCE, 0x4A, 0xCD, 0xBD, 0x49, 0xBD, 0x2D, 0x49, 0x2F, 0x1B, 0x48, 0xEC, 0xA4, 0xA3, 0x21, 0x5F, 0xA3, 0x9C, 0xB2, 0x22, + 0x31, 0x0E, 0xA2, 0x2B, 0xBA, 0xA1, 0x06, 0x36, 0x42, 0x70, 0x7F, 0xEE, 0x0F, 0x52, 0x41, 0x77, 0x0E, 0x80, 0x22, 0xE5, 0x3F, 0x83, 0x1F, 0x7C, + 0x58, 0xEF, 0x7A, 0x34, 0x1F, 0x79, 0x80, 0x09, 0xEC, 0xDC, 0xA6, 0xEE, 0x7C, 0xD0, 0xDB, 0xD0, 0xC2, 0x76, 0x9E, 0x41, 0x1C, 0x14, 0xD5, 0x1B, + 0x2D, 0x4C, 0x1B, 0x23, 0xE2, 0x9A, 0x03, 0xB3, 0x65, 0x22, 0x6E, 0x0B, 0x99, 0xF5, 0x07, 0x3D, 0xEE, 0x42, 0xDA, 0x98, 0x47, 0x65, 0x18, 0xCE, + 0xE5, 0x97, 0xD5, 0x14, 0x97, 0x5C, 0x95, 0x16, 0xE3, 0x22, 0x7B, 0x8B, 0xDA, 0x88, 0xC5, 0x63, 0x65, 0x85, 0x46, 0x6C, 0xE7, 0xC8, 0xAD, 0x84, + 0xD4, 0xCE, 0x1A, 0x73, 0x9F, 0x91, 0xB5, 0xE3, 0xE6, 0xDC, 0xEC, 0x77, 0xB0, 0xB2, 0xCE, 0x89, 0x76, 0x72, 0xD0, 0x83, 0x22, 0x77, 0xE9, 0x9E, + 0x4E, 0xE1, 0x89, 0x55, 0xBA, 0x3D, 0x1F, 0x42, 0x78, 0x59, 0x63, 0x1F, 0xAC, 0x2C, 0xBD, 0x53, 0xC8, 0xF3, 0x20, 0x99, 0xF6, 0x87, 0xE9, 0xBD, + 0x5E, 0x6F, 0x41, 0xC2, 0x36, 0xE3, 0x8A, 0x36, 0x66, 0x66, 0xDB, 0x85, 0x1F, 0x0B, 0xAB, 0x7D, 0x45, 0xD7, 0x51, 0x45, 0x86, 0xA6, 0xCA, 0xFA, + 0xB4, 0x7E, 0x52, 0x5B, 0xAF, 0x89, 0x51, 0x27, 0x62, 0xAE, 0x77, 0xD9, 0xC5, 0x03, 0xE9, 0x59, 0xFF, 0xFF, 0x5F, 0x9A, 0x60, 0x02, 0xE0, 0xD9, + 0xFF, 0x9F, 0x43, 0x23, 0xAD, 0x91, 0x5E, 0x67, 0x5E, 0x62, 0xCE, 0xE1, 0x68, 0xF1, 0xDE, 0x6C, 0x67, 0xDE, 0x4C, 0x42, 0xDA, 0x8E, 0x35, 0xDA, + 0x74, 0x88, 0x0B, 0xC0, 0x0C, 0x20, 0x90, 0x25, 0xC2, 0x56, 0x04, 0x97, 0xC7, 0xF5, 0xAC, 0x8D, 0xA9, 0xA9, 0xED, 0x65, 0x0D, 0xA0, 0xB3, 0x4B, + 0x5B, 0x84, 0x13, 0x20, 0x77, 0x47, 0x4B, 0x4E, 0x71, 0xD6, 0x87, 0x7A, 0xA6, 0x22, 0x1A, 0xC0, 0x31, 0x38, 0x00, 0x12, 0xEF, 0x18, 0x48, 0xAC, + 0x58, 0xDA, 0x5C, 0x58, 0x0F, 0x32, 0x98, 0x5D, 0x5D, 0x4A, 0x16, 0x2F, 0xB8, 0xE2, 0x1E, 0xBF, 0x00, 0xCA, 0x7E, 0x3F, 0x2E, 0xC1, 0x2B, 0x3F, + 0xA6, 0x1C, 0xB1, 0x1A, 0x0B, 0x84, 0x81, 0x48, 0xB8, 0x18, 0x29, 0x94, 0x06, 0xD5, 0xA7, 0x03, 0x2B, 0x9C, 0x14, 0x89, 0x9B, 0x36, 0x98, 0xA6, + 0x00, 0x56, 0xFA, 0xED, 0x49, 0x2A, 0xED, 0x48, 0xFA, 0x24, 0x48, 0x1C, 0xAE, 0x47, 0x22, 0x95, 0x46, 0x20, 0x54, 0x45, 0xF0, 0x2D, 0x22, 0x27, + 0x58, 0x79, 0x1C, 0x5C, 0xAA, 0x8A, 0x40, 0x01, 0x20, 0x11, 0x07, 0x7E, 0x2E, 0x58, 0xF0, 0x61, 0xA1, 0xA1, 0xE7, 0x04, 0x21, 0x0F, 0x2C, 0xE2, + 0x4E, 0x67, 0xA6, 0x4E, 0xB2, 0x67, 0x8E, 0x6C, 0x21, 0x8E, 0xB1, 0xF2, 0xCD, 0xF2, 0xA6, 0x0D, 0x8B, 0x6D, 0x8D, 0xD7, 0x2E, 0x8D, 0x52, 0xF3, + 0x8C, 0x9C, 0xDA, 0x5D, 0x61, 0x2D, 0xD3, 0xE7, 0x8E, 0x99, 0x3B, 0xC3, 0x38, 0x3E, 0xBD, 0xF8, 0xB5, 0xB8, 0xA4, 0xA6, 0xB5, 0x3C, 0x26, 0xB1, + 0xF0, 0x42, 0xAD, 0xA8, 0x96, 0xAD, 0x70, 0x0C, 0x48, 0x29, 0xA6, 0x4B, 0xC1, 0x99, 0x80, 0x52, 0xF2, 0x07, 0xC0, 0x8A, 0xC4, 0x89, 0xCE, 0x03, + 0x93, 0x37, 0x16, 0x25, 0x58, 0x80, 0xED, 0x3C, 0x57, 0x12, 0x03, 0x90, 0x23, 0x26, 0x2C, 0x45, 0x34, 0xE4, 0x43, 0x32, 0x61, 0x41, 0x14, 0x87, + 0xDF, 0x1F, 0xB6, 0x33, 0x3C, 0x36, 0x55, 0x3B, 0xA0, 0x4F, 0xD8, 0x2F, 0x88, 0xD9, 0x20, 0x98, 0x1C, 0x5F, 0x64, 0xE3, 0xE9, 0x0B, 0xAE, 0xE1, + 0xEE, 0x59, 0x93, 0x0D, 0xA9, 0xE1, 0x59, 0xF7, 0xB4, 0x83, 0xF8, 0x9F, 0xAB, 0x8D, 0x36, 0x3D, 0x85, 0xFE, 0x63, 0xBE, 0x3F, 0xAB, 0x36, 0xB9, + 0x3E, 0xF8, 0x73, 0x25, 0x22, 0x6B, 0x55, 0xD1, 0x35, 0x4D, 0xD0, 0x6B, 0xFA, 0xB2, 0xC0, 0x32, 0xD4, 0x5D, 0xF9, 0x9C, 0xC6, 0x62, 0x37, 0x90, + 0x45, 0x0B, 0x2C, 0xE5, 0x1A, 0x6E, 0x52, 0xE9, 0x50, 0x92, 0xA6, 0x28, 0xD2, 0x6C, 0x0E, 0x19, 0xF5, 0xF3, 0x8F, 0x10, 0x9C, 0xE0, 0x77, 0x35, + 0x08, 0x85, 0x9F, 0x01, 0x9E, 0xD0, 0x2E, 0xF7, 0x33, 0x30, 0x0D, 0x46, 0xBC, 0xEF, 0x7D, 0x55, 0x15, 0xA7, 0x27, 0xD3, 0x66, 0xFF, 0xFF, 0x33, + 0x3C, 0x12, 0x75, 0xCA, 0xEE, 0x40, 0xE8, 0xD4, 0x59, 0x40, 0x99, 0xCF, 0x11, 0xA1, 0x97, 0x8B, 0x88, 0xC7, 0x53, 0x7A, 0xE4, 0x2C, 0x16, 0xC4, + 0x8F, 0xB2, 0xE4, 0x86, 0xBE, 0x29, 0x5D, 0x1E, 0x3E, 0x6E, 0x57, 0x5B, 0x6D, 0x22, 0x80, 0x05, 0xF2, 0x8A, 0xE5, 0x3F, 0x90, 0x75, 0x3D, 0x3D, + 0x7A, 0x57, 0xBE, 0x3E, 0x88, 0xE0, 0xB7, 0x49, 0x6A, 0xEE, 0x7D, 0xBC, 0xD5, 0xDB, 0xC4, 0x7F, 0xB8, 0x6F, 0x43, 0x7F, 0xFE, 0xCF, 0x91, 0x76, + 0x8C, 0xEE, 0x87, 0xE1, 0xD3, 0x36, 0x02, 0x1D, 0x73, 0x26, 0x19, 0x23, 0xDB, 0x15, 0x7B, 0xF9, 0x09, 0x7B, 0xA0, 0x06, 0x6B, 0xDA, 0x0A, 0xE1, + 0xA6, 0xA7, 0xC5, 0xD5, 0x29, 0x9F, 0xE8, 0x76, 0x7A, 0xF5, 0xD7, 0x34, 0xBA, 0x20, 0x8A, 0xBA, 0x2F, 0xD4, 0xFF, 0x5F, 0x90, 0xEF, 0x07, 0xFD, + 0x4F, 0xA0, 0xFD, 0xBB, 0xFE, 0xA7, 0xB7, 0xFF, 0x9B, 0xBE, 0x37, 0xD8, 0x9E, 0xF4, 0xA2, 0x2F, 0x62, 0xB6, 0x5D, 0x13, 0xD0, 0xF1, 0x84, 0xF5, + 0x19, 0x1B, 0xE8, 0xFA, 0xCC, 0x3A, 0x8A, 0x22, 0xFD, 0xD3, 0xD6, 0x7D, 0xF8, 0xBE, 0x7B, 0xB9, 0xCE, 0x95, 0xE2, 0x47, 0xA9, 0xD4, 0x13, 0x88, + 0x7E, 0x36, 0xA3, 0x3A, 0x1F, 0xEF, 0xAF, 0x63, 0x69, 0x37, 0x6A, 0xFC, 0x11, 0x48, 0xED, 0x53, 0x9A, 0xDF, 0xF4, 0xFF, 0x97, 0x4B, 0xD3, 0x3F, + 0x81, 0xC6, 0xD6, 0x1F, 0x05, 0x7B, 0x19, 0x2C, 0x3E, 0x2D, 0x23, 0xA8, 0xFE, 0xE7, 0x2C, 0xBD, 0x3F, 0xE0, 0x04, 0xDD, 0x9D, 0x01, 0x45, 0x52, + 0xFD, 0x0C, 0x42, 0xF0, 0x61, 0x25, 0xD0, 0xA3, 0x09, 0x82, 0x07, 0xB8, 0x6A, 0xE7, 0x36, 0x72, 0xE7, 0xA3, 0x40, 0x0E, 0xB4, 0x6A, 0x0E, 0x8F, + 0x05, 0x1C, 0x94, 0xC9, 0x1B, 0x2D, 0x42, 0x1B, 0x23, 0xD6, 0x9A, 0x03, 0x99, 0x34, 0x64, 0xC5, 0x33, 0x16, 0x0A, 0xDD, 0x0F, 0x48, 0x64, 0x0A, + 0x37, 0x63, 0x1E, 0x6B, 0x61, 0x38, 0x6D, 0x5F, 0x54, 0x99, 0x5D, 0x70, 0x9B, 0x5B, 0x8C, 0x57, 0x5A, 0xD4, 0x2C, 0x2C, 0x1D, 0xCE, 0x2B, 0x34, + 0x48, 0x2A, 0x3B, 0x2D, 0x29, 0x4A, 0x2D, 0x28, 0x59, 0x49, 0x00, 0xCE, 0x92, 0x4E, 0xE2, 0xCA, 0x4C, 0x22, 0x94, 0x95, 0xEC, 0xD1, 0xB5, 0x49, + 0xD0, 0x91, 0x2C, 0xFE, 0xFD, 0x11, 0xCB, 0x3F, 0x11, 0xBC, 0x83, 0x10, 0xD9, 0x3B, 0x88, 0xFE, 0xC3, 0xC7, 0x1E, 0xD0, 0xA3, 0xD1, 0xF0, 0x7B, + 0xB4, 0x21, 0xD9, 0x1D, 0x72, 0xD8, 0xEF, 0x3C, 0x07, 0x5C, 0x78, 0x23, 0x3E, 0xAC, 0xC1, 0x06, 0x42, 0x5F, 0x33, 0x08, 0x99, 0xAB, 0x21, 0x10, + 0xA7, 0xF5, 0x88, 0xFF, 0x08, 0x91, 0x68, 0x45, 0x11, 0xE8, 0xCA, 0x9E, 0x67, 0xD1, 0x1E, 0xE7, 0xD8, 0xAC, 0x66, 0xDF, 0x2C, 0x66, 0x65, 0x38, + 0xE6, 0x0E, 0xB8, 0x65, 0x12, 0x2D, 0x65, 0x9D, 0x0C, 0xC9, 0x41, 0x06, 0x90, 0xA1, 0xE2, 0x66, 0x7C, 0xE5, 0x1D, 0xAF, 0xE9, 0xC9, 0x90, 0x3B, + 0x34, 0xAE, 0x80, 0xA2, 0xB8, 0xAF, 0x73, 0x4F, 0xE8, 0x82, 0xD8, 0x51, 0x3F, 0xBC, 0x89, 0x2B, 0x0C, 0xEA, 0x19, 0xFC, 0xEA, 0x19, 0x83, 0x37, + 0x17, 0x18, 0x39, 0x17, 0x98, 0xFD, 0x7F, 0x55, 0xBE, 0x6F, 0x4E, 0x4C, 0x2F, 0x52, 0x0C, 0xEF, 0x55, 0x13, 0x8C, 0x00, 0x4D, 0xBB, 0x6A, 0x32, + 0xBA, 0x59, 0x47, 0xB9, 0x77, 0x4E, 0xB8, 0x71, 0x63, 0xFA, 0x41, 0x01, 0x2F, 0xF6, 0xE6, 0x6E, 0x35, 0x23, 0xD8, 0x2E, 0xD6, 0x6B, 0x6F, 0x45, + 0xD0, 0xE2, 0x1B, 0xCC, 0x42, 0x4F, 0xCA, 0xEA, 0xFD, 0x64, 0x51, 0x48, 0xC4, 0x7E, 0x47, 0x58, 0x23, 0x16, 0xAF, 0xEE, 0x53, 0x57, 0x32, 0xD7, + 0x56, 0x78, 0x0C, 0x56, 0x07, 0x32, 0x56, 0xD9, 0x3C, 0x4A, 0x35, 0x40, 0x93, 0xC6, 0x5E, 0x91, 0x8A, 0x78, 0x89, 0x2A, 0xBB, 0x89, 0xFE, 0x24, + 0x08, 0x25, 0xC1, 0x02, 0xED, 0xDA, 0xF0, 0x19, 0xF4, 0xE6, 0xD9, 0xB6, 0xC0, 0xC5, 0x17, 0x5E, 0x27, 0x1E, 0x1F, 0xE7, 0xBD, 0x09, 0x8F, 0xF6, + 0xBA, 0xD9, 0x87, 0xD7, 0xF4, 0x14, 0xCD, 0x74, 0xBC, 0xC5, 0xDC, 0xE5, 0xBD, 0x04, 0xED, 0xBC, 0xDC, 0xD0, 0xB0, 0xE4, 0xD5, 0x5B, 0xBA, 0xF4, + 0x56, 0x72, 0x40, 0xB3, 0x68, 0xDA, 0xA0, 0xCC, 0x79, 0x99, 0x4C, 0xAB, 0x91, 0xBC, 0x5A, 0x8A, 0xB4, 0x8B, 0x0A, 0x6B, 0xC3, 0x94, 0x93, 0x43, + 0x94, 0x1A, 0x4E, 0x00, 0x44, 0x9D, 0x27, 0x5D, 0x2C, 0x26, 0x62, 0xFA, 0x92, 0x02, 0xCF, 0x6D, 0x07, 0x5F, 0x24, 0x78, 0x2E, 0x23, 0x1B, 0x70, + 0x45, 0x0E, 0x95, 0x42, 0x34, 0x41, 0x98, 0xDB, 0xF4, 0x1F, 0xB6, 0x7F, 0x1E, 0xC2, 0x8E, 0x10, 0x62, 0x7C, 0x3E, 0x5B, 0xD7, 0x0C, 0x4E, 0x27, + 0xED, 0xC3, 0x40, 0x5F, 0x29, 0x51, 0x8B, 0xA4, 0x7B, 0xD2, 0x21, 0x44, 0xB1, 0x85, 0xC6, 0x24, 0x14, 0xEF, 0xEA, 0x0E, 0x30, 0x5D, 0x90, 0xF8, + 0xC0, 0xEF, 0x39, 0x89, 0xA1, 0xFD, 0x1F, 0x6F, 0xCC, 0xDF, 0x48, 0x6F, 0xA8, 0xD3, 0x75, 0xE9, 0x8F, 0x74, 0x47, 0x58, 0x7E, 0xCC, 0xB3, 0x29, + 0x96, 0xC9, 0xB3, 0x6D, 0xAB, 0xB8, 0x3A, 0x02, 0xC4, 0x90, 0xA2, 0xE9, 0x06, 0x83, 0x15, 0x52, 0xDA, 0xBC, 0x7B, 0x5C, 0x5E, 0x1E, 0x26, 0xFB, + 0xFF, 0x35, 0x4D, 0x47, 0x71, 0xBC, 0xE9, 0x97, 0xE4, 0x27, 0xDE, 0x06, 0xE2, 0x3A, 0x50, 0x76, 0x5C, 0xA0, 0x6C, 0x48, 0x03, 0x62, 0x3E, 0x6E, + 0x03, 0xD8, 0x58, 0x66, 0x7C, 0x4F, 0x11, 0x74, 0x37, 0x3E, 0xA9, 0x22, 0x07, 0x56, 0xC7, 0x41, 0x18, 0xE4, 0x67, 0x88, 0xC9, 0x79, 0x9E, 0x4C, + 0x9E, 0xE3, 0x3F, 0x88, 0x72, 0xA7, 0xC4, 0x78, 0x5A, 0x03, 0x38, 0x02, 0xA8, 0x08, 0xC3, 0x79, 0x0D, 0x2D, 0x46, 0x5C, 0xC6, 0x13, 0xF3, 0xF4, + 0x2C, 0xF4, 0xF2, 0xA0, 0x62, 0x4A, 0xAF, 0x63, 0x49, 0x30, 0x64, 0x64, 0xA4, 0xC6, 0xD5, 0x25, 0xF4, 0x26, 0x81, 0x46, 0x31, 0x9E, 0x42, 0x06, + 0xE2, 0x4F, 0xB9, 0x43, 0xF1, 0x22, 0xA1, 0xB5, 0xAF, 0xC0, 0x31, 0x6F, 0x37, 0x81, 0xCF, 0xCE, 0x70, 0x2D, 0xDF, 0x03, 0xD9, 0xC3, 0x43, 0x8A, + 0xB2, 0x93, 0xEB, 0xD2, 0x5B, 0x8F, 0x23, 0x0B, 0xD0, 0xA3, 0x50, 0xDD, 0xDC, 0x54, 0xD9, 0x0C, 0x6D, 0xD6, 0x20, 0x18, 0xA4, 0x69, 0xA2, 0x9B, + 0xD9, 0x63, 0x71, 0x5F, 0x49, 0x90, 0xD9, 0x00, 0x23, 0x86, 0xAC, 0xC6, 0x25, 0xD3, 0xB8, 0x05, 0x56, 0x8B, 0x85, 0x56, 0xC1, 0xCA, 0xF1, 0x67, + 0x9B, 0xAB, 0x03, 0x49, 0x8A, 0x06, 0x23, 0x08, 0xCE, 0x44, 0x46, 0xA1, 0x42, 0x1E, 0x23, 0x41, 0x7C, 0x43, 0x3E, 0x52, 0x81, 0x3E, 0x36, 0xF4, + 0x7E, 0x87, 0x30, 0x73, 0x87, 0x8D, 0x18, 0x3B, 0x24, 0x94, 0x63, 0xCA, 0xFD, 0x37, 0x7A, 0x3E, 0x68, 0xB0, 0x05, 0xAF, 0xB3, 0x46, 0xF6, 0xEA, + 0x0A, 0x70, 0x69, 0x38, 0xDA, 0x3F, 0x58, 0x14, 0x9D, 0x97, 0x08, 0x9D, 0xF9, 0x9F, 0x51, 0xD0, 0x39, 0xD3, 0x9E, 0x7E, 0xE6, 0x65, 0xAC, 0x65, + 0xDC, 0xCB, 0xE5, 0x91, 0xD9, 0xE4, 0xE8, 0xA3, 0xE4, 0x23, 0x5C, 0x64, 0x99, 0xB1, 0x19, 0x64, 0x8D, 0xC7, 0x4C, 0x77, 0x32, 0x1A, 0xE8, 0x18, + 0x0B, 0x10, 0x2C, 0xEE, 0x0B, 0xFB, 0x8B, 0x6C, 0x0A, 0x7B, 0x45, 0xB7, 0x6B, 0x62, 0x0C, 0x1B, 0x22, 0x5C, 0x06, 0x8A, 0xA7, 0x0A, 0x87, 0x6C, + 0x25, 0x86, 0x6A, 0x26, 0x4E, 0x58, 0x08, 0xA2, 0x1B, 0xAB, 0xA8, 0x8B, 0xA0, 0xDE, 0xE0, 0xF8, 0x02, 0x0C, 0xB0, 0x3B, 0xBA, 0xCC, 0xBE, 0xD6, + 0xEE, 0xD7, 0xAA, 0x85, 0x02, 0xD6, 0x19, 0x62, 0xF0, 0x85, 0x10, 0xFF, 0xAA, 0x03, 0x7A, 0x92, 0x29, 0x88, 0x1E, 0x7B, 0x29, 0xDA, 0x8B, 0x8E, + 0x9E, 0x89, 0xCC, 0x17, 0x12, 0x36, 0x1D, 0x7F, 0x9D, 0xDE, 0xB8, 0xAB, 0xCF, 0xE9, 0xFF, 0x80, 0x1C, 0xD5, 0xBD, 0x35, 0xFA, 0xBB, 0x3C, 0xB8, + 0x70, 0x99, 0x7E, 0x6D, 0xAD, 0x50, 0xD2, 0xD2, 0x1D, 0xCA, 0x42, 0x0D, 0x90, 0xB5, 0x8E, 0x5F, 0x0D, 0x3B, 0xB8, 0xAA, 0x59, 0x60, 0xB5, 0x71, + 0x56, 0x35, 0xC5, 0x47, 0x75, 0x03, 0x61, 0xAA, 0x40, 0x0A, 0xA9, 0x2A, 0x10, 0x6D, 0x0C, 0xA2, 0xF5, 0xC8, 0x36, 0x63, 0x3B, 0x83, 0x6A, 0xBB, + 0x05, 0x69, 0x1B, 0x05, 0x71, 0x7B, 0xD6, 0xB7, 0x8D, 0xB9, 0x5A, 0x6F, 0xE6, 0x68, 0xD7, 0xEE, 0xEB, 0x2E, 0x36, 0xED, 0xE7, 0x91, 0xFA, 0x10, + 0xBB, 0x0E, 0xE3, 0x53, 0x0F, 0xBB, 0xA9, 0x3B, 0x69, 0xD5, 0xA7, 0xEA, 0x06, 0xEA, 0x6D, 0x4E, 0x6D, 0x3A, 0xAE, 0x36, 0x9E, 0x80, 0x36, 0xE0, + 0x81, 0xF6, 0x61, 0x84, 0xB6, 0x86, 0xB6, 0xA7, 0x88, 0x36, 0x62, 0xBB, 0x0E, 0x81, 0x7B, 0xD7, 0x85, 0xDB, 0xB3, 0xAD, 0xC1, 0xDA, 0x06, 0x49, + 0xAC, 0xBB, 0x50, 0xD6, 0x7B, 0x3E, 0xEB, 0x4C, 0xAD, 0xF5, 0x2D, 0xDD, 0xBA, 0x00, 0xE3, 0x7A, 0xBA, 0x6E, 0xD7, 0xAE, 0xF3, 0xC9, 0xD4, 0x05, + 0x81, 0xEA, 0x4E, 0x75, 0x4C, 0xAE, 0xBA, 0x29, 0xD4, 0x7C, 0x76, 0x58, 0xDF, 0x62, 0x7E, 0x29, 0xEF, 0xC8, 0xDB, 0xAF, 0xE8, 0xE9, 0x73, 0xC4, + 0xE6, 0x86, 0x9F, 0xBF, 0x90, 0x76, 0xD9, 0x2E, 0x55, 0xB5, 0x6F, 0xFE, 0x73, 0x4B, 0x55, 0xB5, 0x46, 0x61, 0x58, 0x86, 0xBB, 0x19, 0x43, 0x95, + 0xB0, 0x7D, 0xCA, 0x6B, 0x3B, 0xB5, 0x68, 0x6E, 0x42, 0x04, 0x32, 0x63, 0xA2, 0x65, 0x59, 0xCA, 0x2C, 0x51, 0x6A, 0x46, 0xC2, 0xB2, 0x0D, 0x8A, + 0x75, 0x21, 0xC3, 0x7A, 0xEE, 0x8A, 0x1D, 0x4A, 0x12, 0x85, 0x41, 0x10, 0x1B, 0x56, 0x26, 0xEA, 0xB4, 0x17, 0xDB, 0x05, 0x67, 0x17, 0x7A, 0xDB, + 0x7C, 0xB7, 0x6D, 0xB9, 0xF3, 0x6C, 0xE3, 0xDC, 0x88, 0xCD, 0x7A, 0xEE, 0x50, 0x16, 0x14, 0xEE, 0x5E, 0xA4, 0xB7, 0xA6, 0x21, 0xFE, 0xAE, 0x8D, + 0xE5, 0x92, 0x16, 0x17, 0x21, 0xFB, 0x69, 0xD0, 0xE5, 0x77, 0x47, 0xE5, 0x41, 0xF5, 0xE0, 0xF9, 0x0A, 0x74, 0x9A, 0xCB, 0x74, 0x60, 0x7C, 0x73, + 0x5A, 0x6A, 0x70, 0x9A, 0x26, 0x6F, 0x92, 0x88, 0x6D, 0xE0, 0xD6, 0x6A, 0x02, 0x60, 0xD2, 0x18, 0xFA, 0xCC, 0x38, 0x40, 0x72, 0x8B, 0x18, 0x95, + 0x01, 0x5C, 0xC7, 0x50, 0x82, 0x80, 0x81, 0xCC, 0xBF, 0xB8, 0x12, 0x70, 0x51, 0x15, 0x6C, 0x39, 0x06, 0xD2, 0x3F, 0x8A, 0x88, 0x4F, 0xAD, 0xF5, + 0x3D, 0x10, 0xF2, 0x88, 0x6A, 0x72, 0x09, 0x5C, 0xF9, 0x3B, 0x0A, 0x39, 0x09, 0x96, 0x38, 0x03, 0x3D, 0x25, 0x60, 0x3C, 0x38, 0x58, 0xCF, 0x93, + 0x41, 0x1F, 0x03, 0x32, 0xBE, 0x23, 0x43, 0x9F, 0x53, 0x21, 0x7F, 0x93, 0xA3, 0x87, 0x92, 0xCC, 0x7B, 0xD1, 0xE5, 0x13, 0x2E, 0xC4, 0xDD, 0x0A, + 0xE8, 0xCB, 0x28, 0x3B, 0x2B, 0xFF, 0x67, 0xE7, 0xA3, 0xD6, 0x78, 0x65, 0xC8, 0xC0, 0x63, 0x5B, 0x32, 0xDE, 0x5D, 0x1E, 0xAA, 0xB8, 0x4C, 0x23, + 0x6C, 0xAD, 0x28, 0xA0, 0xA5, 0x9B, 0x96, 0x85, 0x6A, 0x21, 0x6B, 0x2D, 0xE1, 0x6A, 0x98, 0xF0, 0xAA, 0x66, 0x84, 0xD5, 0x06, 0x86, 0xAA, 0x29, + 0x4A, 0xAA, 0x9B, 0xC2, 0xA9, 0x02, 0xAD, 0x52, 0x55, 0x9B, 0xF0, 0x50, 0xAE, 0x20, 0x3A, 0x03, 0x40, 0x78, 0x10, 0x7E, 0x00, 0xF3, 0x7C, 0x0E, + 0x41, 0xF4, 0x48, 0x1E, 0xF2, 0x78, 0x46, 0xB6, 0x76, 0xBE, 0xEB, 0xF4, 0xE0, 0xBB, 0x2F, 0xE0, 0xC7, 0xFA, 0xB7, 0x06, 0xF1, 0x1B, 0xC4, 0xC5, + 0xDD, 0x65, 0xF5, 0xDE, 0x83, 0x7B, 0x67, 0xDA, 0xDF, 0xB7, 0xA2, 0xEF, 0x69, 0x23, 0x77, 0x98, 0xBB, 0x9D, 0xCF, 0x9D, 0x8F, 0xE9, 0x2E, 0xA8, + 0x75, 0x3F, 0xBB, 0x63, 0x1A, 0xB8, 0x9B, 0x0A, 0xA8, 0xD3, 0x82, 0xFC, 0xDF, 0xD7, 0xFA, 0x32, 0x2C, 0xBD, 0xC3, 0xB0, 0xBD, 0x72, 0xF8, 0x73, + 0xE4, 0xEA, 0x93, 0x86, 0xB8, 0xEE, 0x42, 0x57, 0x0A, 0xCE, 0x53, 0x1E, 0x69, 0xAF, 0xB4, 0xD0, 0x7F, 0x56, 0x6B, 0x3A, 0x00, 0xE7, 0xA9, 0x01, + 0x84, 0xE9, 0xE3, 0x42, 0x57, 0x81, 0xD3, 0xB9, 0x94, 0xE8, 0x48, 0x6A, 0xF4, 0x00, 0x74, 0x3B, 0x3A, 0x9F, 0x03, 0xBA, 0xFC, 0x7F, 0xA0, 0xDF, + 0x7D, 0xD3, 0x47, 0xBA, 0xE0, 0x07, 0xF1, 0x5B, 0xFC, 0x75, 0xE4, 0x1F, 0x8E, 0xFD, 0x35, 0xAA, 0x7F, 0xE3, 0x92, 0x3E, 0x45, 0xFC, 0x6F, 0x64, + 0xE9, 0x6D, 0x22, 0xBF, 0x2A, 0x99, 0x8E, 0xD7, 0xF3, 0xDF, 0x50, 0xE8, 0x81, 0x23, 0xF4, 0x3C, 0x22, 0xFA, 0xA5, 0x0F, 0x1D, 0x8C, 0x4E, 0xAB, + 0x45, 0xCF, 0x34, 0xFA, 0xCD, 0x06, 0xE8, 0xB6, 0x62, 0xDF, 0x25, 0x8F, 0xFE, 0xCC, 0xE0, 0x0F, 0x1D, 0xF8, 0x30, 0x7D, 0x3F, 0x4C, 0xC3, 0x6F, + 0xF4, 0x8C, 0x31, 0x6F, 0x65, 0x9E, 0xC3, 0xF0, 0x98, 0xCF, 0xF8, 0x90, 0x63, 0xD0, 0x63, 0xFE, 0xE9, 0x4D, 0x33, 0xE0, 0x69, 0x8D, 0xDE, 0xC0, + 0x1F, 0xCF, 0x9C, 0xBE, 0x77, 0x9C, 0xC2, 0x57, 0x50, 0xDF, 0x39, 0x24, 0xF0, 0xBD, 0xB3, 0x21, 0x71, 0x16, 0x10, 0x54, 0x52, 0xFF, 0xEF, 0xD8, + 0xFF, 0xCE, 0xE1, 0x97, 0xD9, 0xF8, 0x3F, 0x9D, 0x74, 0x27, 0x55, 0x3A, 0x57, 0xDF, 0x4F, 0x1B, 0xFC, 0x08, 0x04, 0xD0, 0x25, 0xB0, 0x7C, 0x0D, + 0xAF, 0xF4, 0x11, 0x30, 0xE8, 0x89, 0x86, 0x9F, 0x05, 0xE4, 0x07, 0x95, 0xA3, 0xBF, 0xDE, 0xD1, 0x61, 0x34, 0x7D, 0x19, 0xCB, 0x74, 0x35, 0x8B, + 0x6F, 0x02, 0xFA, 0x67, 0x30, 0xD0, 0x85, 0xFE, 0xE8, 0xF0, 0xF8, 0x8F, 0xAF, 0xFD, 0xB5, 0x17, 0xBA, 0x82, 0xD9, 0x6F, 0x27, 0x82, 0xCE, 0x87, + 0x48, 0x0F, 0x6C, 0xFB, 0x2A, 0x1A, 0xFC, 0x16, 0x6F, 0x3A, 0x29, 0x14, 0x3D, 0xF6, 0xF9, 0xF7, 0xB6, 0xA0, 0x23, 0xD7, 0xFD, 0x0D, 0x16, 0x39, + 0x88, 0xB0, 0xDE, 0xC5, 0x59, 0xEF, 0x03, 0xA2, 0x6F, 0x6A, 0xD1, 0x73, 0xED, 0xE8, 0xD3, 0x92, 0xF4, 0x09, 0xAE, 0xF4, 0x76, 0x65, 0x7A, 0x3E, + 0x37, 0xBD, 0x20, 0x9D, 0xBE, 0x31, 0x34, 0x9E, 0x29, 0x6A, 0xFA, 0x21, 0x4F, 0x3B, 0x05, 0xF7, 0xCD, 0x8C, 0x33, 0x93, 0x18, 0x18, 0x7C, 0x37, + 0xC5, 0xE5, 0x3D, 0xD6, 0x1E, 0x7D, 0x0D, 0x0E, 0x0D, 0x9E, 0xF7, 0x7F, 0xDF, 0x51, 0x0F, 0x41, 0xE2, 0x2C, 0x1F, 0xE2, 0x43, 0xFF, 0x7F, 0xE5, + 0x9F, 0x7C, 0x84, 0xB9, 0xF9, 0xEE, 0x40, 0xC5, 0xA2, 0x61, 0x34, 0x02, 0xEF, 0xE7, 0xDD, 0x62, 0xC4, 0x77, 0xE3, 0x79, 0x1E, 0xF1, 0x4B, 0x75, + 0x3C, 0x27, 0x4E, 0xEB, 0x8E, 0x67, 0x7E, 0xE4, 0x9B, 0x9F, 0xE2, 0xB6, 0x3A, 0x79, 0x97, 0xB4, 0xF8, 0xB3, 0x55, 0x7E, 0x08, 0x2A, 0x0F, 0xD3, + 0x96, 0x0F, 0x1B, 0x90, 0x77, 0xBA, 0x90, 0x9F, 0x9B, 0x90, 0xB7, 0xE7, 0xDB, 0x1C, 0xC4, 0xE9, 0xF0, 0xE2, 0x78, 0x94, 0x1C, 0x0E, 0x77, 0x0F, + 0x06, 0x88, 0xFE, 0x48, 0x3B, 0x09, 0xFE, 0x7F, 0x10, 0xDE, 0x88, 0xDE, 0x6D, 0x59, 0x6E, 0x2C, 0xCF, 0x53, 0x91, 0x5F, 0xB6, 0xE5, 0x46, 0x72, + 0x5A, 0x20, 0x79, 0xE6, 0x8A, 0xBE, 0x99, 0x4B, 0x6E, 0x7B, 0xA4, 0x77, 0x39, 0x20, 0x7F, 0x1E, 0xD3, 0x0F, 0x75, 0xE9, 0x61, 0xE6, 0xF4, 0x61, + 0x08, 0xF4, 0x4E, 0x75, 0xFD, 0xDC, 0x9E, 0x7E, 0xC0, 0x0A, 0x7D, 0x1B, 0x06, 0x39, 0xDD, 0x9F, 0x1C, 0xEF, 0x43, 0x1C, 0xF0, 0x44, 0xFC, 0xF0, + 0x31, 0x2E, 0x89, 0x8F, 0x7B, 0xA6, 0xC6, 0x5B, 0x6F, 0xE3, 0x75, 0x86, 0xF2, 0xDD, 0x66, 0xF9, 0xB1, 0x73, 0x7C, 0x03, 0x24, 0x0E, 0xF2, 0x22, + 0xEF, 0x32, 0x9C, 0xEF, 0x79, 0xCE, 0x37, 0x85, 0xE4, 0xB9, 0x5C, 0xF2, 0x69, 0x3C, 0xF9, 0x04, 0x4A, 0x79, 0x3B, 0xAC, 0x3C, 0x5F, 0x80, 0xBC, + 0xE0, 0x5B, 0x9E, 0xD1, 0x41, 0x1E, 0x13, 0x2F, 0x6F, 0x0A, 0xE1, 0x4E, 0x9B, 0xE3, 0xFE, 0x35, 0xBE, 0x2F, 0xCB, 0xB0, 0xA3, 0x3E, 0xC3, 0x59, + 0x00, 0xF5, 0x43, 0x1B, 0x1C, 0x1B, 0x94, 0xF9, 0xFF, 0x15, 0x11, 0xDB, 0x3A, 0x44, 0xCF, 0x4D, 0x87, 0xF6, 0x5B, 0x2B, 0x48, 0xB4, 0x74, 0x3B, + 0xB2, 0x50, 0x7F, 0xB2, 0xD6, 0x38, 0x57, 0xC3, 0x5B, 0x57, 0x35, 0x54, 0x56, 0x1B, 0x40, 0x55, 0x53, 0x04, 0xA8, 0x6E, 0xB8, 0xA6, 0x0A, 0xD0, + 0xA5, 0xAA, 0x0E, 0xE8, 0x07, 0xE5, 0x6E, 0x1A, 0xF4, 0x16, 0xF4, 0x88, 0x7A, 0x42, 0x3D, 0x0A, 0x4F, 0xFD, 0x6C, 0xA6, 0x1E, 0x53, 0x51, 0xCE, + 0x4C, 0xAB, 0xAF, 0x05, 0x95, 0xB7, 0x2C, 0xEB, 0x9D, 0x77, 0xE5, 0x42, 0xB6, 0x72, 0x18, 0xB5, 0x1C, 0xAC, 0x59, 0xEE, 0xE4, 0x96, 0xCF, 0xB1, + 0xC8, 0x07, 0x3C, 0xC9, 0xDB, 0x4C, 0xF4, 0x74, 0x33, 0x7A, 0xBC, 0xB7, 0x1E, 0x10, 0x4A, 0x7F, 0xE8, 0xA5, 0x97, 0x1C, 0xA0, 0xF7, 0x4C, 0xA0, + 0x6F, 0x9D, 0xA0, 0xAF, 0x83, 0xEF, 0x77, 0x47, 0xEC, 0x8F, 0x49, 0xE8, 0x35, 0x14, 0xF5, 0x20, 0x14, 0xE4, 0x2E, 0x7C, 0xF2, 0x9E, 0x40, 0x39, + 0x53, 0x0A, 0xF9, 0x96, 0xA5, 0x5C, 0x80, 0xA8, 0x1C, 0x01, 0xAC, 0x7C, 0x02, 0xAF, 0x9C, 0xC3, 0x0C, 0xB9, 0xA0, 0x86, 0x9C, 0xF1, 0x44, 0x8E, + 0x49, 0x23, 0x37, 0x45, 0x81, 0xCF, 0x7A, 0xDE, 0x7F, 0xEB, 0xF0, 0x65, 0xBF, 0x77, 0x87, 0xD7, 0x7D, 0xE5, 0xCB, 0x9E, 0xE3, 0xF2, 0x36, 0xE4, + 0xC3, 0xB3, 0xC0, 0x08, 0xC2, 0xFF, 0x7A, 0xE6, 0x5E, 0x00, 0x2D, 0x9A, 0x80, 0x4A, 0x34, 0xDB, 0x04, 0x18, 0xF9, 0x00, 0xF6, 0x5A, 0x20, 0x93, + 0x1A, 0x85, 0x9B, 0x01, 0x90, 0x31, 0x69, 0x26, 0xA6, 0x04, 0xAC, 0x36, 0xA1, 0x65, 0xB2, 0x9D, 0x19, 0xA3, 0x99, 0xD9, 0x56, 0x30, 0x33, 0xA9, + 0x2B, 0x7B, 0x36, 0x51, 0x36, 0x14, 0x82, 0x0C, 0x80, 0x85, 0xB1, 0x30, 0x49, 0xB1, 0x22, 0xC2, 0xB0, 0x48, 0xB5, 0xF8, 0x17, 0x1D, 0xAD, 0xD7, + 0x62, 0x6B, 0x17, 0xE0, 0x32, 0xD7, 0xA8, 0xF1, 0x96, 0x8A, 0x5A, 0x2D, 0xE0, 0x76, 0x56, 0x29, 0x73, 0xD6, 0x07, 0xD0, 0x55, 0xF0, 0xCA, 0xD5, + 0x4C, 0x89, 0x55, 0xC8, 0x51, 0x55, 0x54, 0x10, 0x95, 0xCF, 0xD8, 0x54, 0x53, 0x01, 0x29, 0xAE, 0xB9, 0xA8, 0x05, 0xC8, 0xF0, 0x02, 0x65, 0x50, + 0x23, 0xBE, 0x9E, 0x30, 0xD0, 0x39, 0x7D, 0xC0, 0xD0, 0x64, 0xF8, 0xC7, 0x14, 0x59, 0xB8, 0xD4, 0xA9, 0xA6, 0xC4, 0xBA, 0x99, 0x94, 0x6B, 0x87, + 0x04, 0x7C, 0x02, 0x49, 0xC2, 0x87, 0xA3, 0x74, 0x9E, 0x91, 0xCD, 0x47, 0xD1, 0xCC, 0x21, 0x11, 0x95, 0xCE, 0x50, 0x54, 0xA7, 0x50, 0x9B, 0xD5, + 0xDB, 0x0C, 0x45, 0x10, 0x5E, 0x1B, 0x50, 0xDD, 0xE4, 0x4F, 0xE0, 0x95, 0x8F, 0x0A, 0xAC, 0x9E, 0x4B, 0x37, 0x9E, 0xD2, 0xB7, 0x9D, 0x5D, 0x4D, + 0x9D, 0x5C, 0x2D, 0x1D, 0x90, 0x06, 0xFA, 0x1C, 0x90, 0x13, 0x38, 0x48, 0x72, 0x37, 0x3D, 0x78, 0x9B, 0x36, 0xCC, 0x9A, 0xAD, 0x5B, 0x9A, 0x30, + 0xCE, 0x19, 0x02, 0x9D, 0xEE, 0xB9, 0x17, 0x32, 0x17, 0xF4, 0x31, 0x7F, 0xCF, 0x30, 0x84, 0x1E, 0x2F, 0x8D, 0xAE, 0xED, 0x39, 0x46, 0x92, 0xC5, + 0x8D, 0x91, 0x3F, 0x52, 0x91, 0xD1, 0x9A, 0x90, 0x59, 0x07, 0x20, 0xBD, 0xC4, 0x1F, 0xA9, 0x26, 0x1F, 0x1B, 0x07, 0xF4, 0x1D, 0xC2, 0xB7, 0x1D, + 0x36, 0x48, 0xEC, 0x10, 0x15, 0x1C, 0x73, 0x11, 0xF4, 0x94, 0x86, 0xAF, 0xF9, 0x00, 0x58, 0x36, 0x7A, 0x50, 0x77, 0x14, 0x06, 0x63, 0xB8, 0x9B, + 0x2D, 0x54, 0x89, 0xD7, 0xA7, 0x0C, 0xCD, 0x4E, 0x2D, 0x8E, 0x9B, 0x10, 0x59, 0x98, 0x68, 0x4D, 0x96, 0x30, 0x9D, 0x95, 0x9A, 0xDF, 0x49, 0xB6, + 0x2D, 0x49, 0x2E, 0x5E, 0x47, 0xCF, 0x49, 0x47, 0x43, 0x42, 0x46, 0x30, 0x65, 0x45, 0x61, 0x5F, 0x44, 0x4E, 0x74, 0x43, 0x73, 0x0A, 0x84, 0x06, + 0xFC, 0xBD, 0xDB, 0xE0, 0x82, 0xE8, 0x1E, 0x00, 0xE1, 0x65, 0xF8, 0x01, 0x04, 0xF4, 0x39, 0x34, 0xEC, 0x91, 0x84, 0xE4, 0xF1, 0xE4, 0xDC, 0x69, + 0xCD, 0xEF, 0xD4, 0x81, 0xD0, 0xD9, 0x15, 0x8E, 0x1F, 0x0F, 0xE7, 0x68, 0x3C, 0xC3, 0x71, 0x40, 0x54, 0x6F, 0x5C, 0xF4, 0x36, 0x3D, 0xC4, 0x35, + 0x4C, 0xD0, 0x34, 0x5C, 0x22, 0x33, 0x69, 0x2F, 0xEE, 0x04, 0x3D, 0x32, 0x76, 0x4B, 0x31, 0x7C, 0x59, 0x30, 0x82, 0x66, 0x2F, 0x8C, 0x70, 0x2E, + 0x98, 0x0F, 0xF0, 0x2D, 0xA6, 0x71, 0x2C, 0xB4, 0x2C, 0x2B, 0xBF, 0xBB, 0xF6, 0x65, 0x18, 0xF5, 0x8E, 0x47, 0xF7, 0x0A, 0x64, 0x3B, 0x87, 0x82, + 0x7D, 0xD2, 0x90, 0x38, 0x05, 0xCB, 0x84, 0xDA, 0x22, 0xB7, 0x0A, 0x55, 0x6F, 0xA0, 0xC9, 0x0C, 0x3F, 0x5D, 0x4A, 0xED, 0x5F, 0xB3, 0x3D, 0x8D, + 0x17, 0xB7, 0x89, 0x88, 0xFA, 0x47, 0xE5, 0x8D, 0x39, 0xA2, 0xF1, 0x87, 0xFD, 0x31, 0x39, 0x0D, 0x3C, 0xD7, 0x3D, 0xE4, 0xA5, 0xA7, 0xD4, 0x25, + 0x02, 0x4B, 0x2B, 0xD4, 0x41, 0x16, 0x2C, 0x1E, 0x56, 0xEF, 0x87, 0xAB, 0xE4, 0x13, 0x57, 0xEC, 0x47, 0xAB, 0x8D, 0xAD, 0x5F, 0x15, 0x03, 0x48, + 0x05, 0x64, 0x38, 0xF5, 0x04, 0x29, 0x55, 0xA5, 0x17, 0xA5, 0x96, 0x87, 0xBB, 0xA1, 0x80, 0xBA, 0x1B, 0x7E, 0xCA, 0xE0, 0xC2, 0x89, 0x30, 0xA4, + 0x09, 0x05, 0x2E, 0xD3, 0x26, 0xCF, 0x12, 0xA6, 0xA7, 0x52, 0xE2, 0x6F, 0x52, 0x6D, 0x2E, 0x12, 0xB2, 0xCF, 0xD1, 0xF3, 0x3F, 0x4A, 0xD1, 0x32, + 0x82, 0x89, 0x29, 0x3A, 0x32, 0x40, 0xE4, 0xD4, 0x34, 0x54, 0x96, 0x27, 0x34, 0x00, 0xED, 0xAD, 0x20, 0x2E, 0x88, 0xEE, 0x09, 0xA8, 0x83, 0xDE, + 0x0F, 0x60, 0x9A, 0x4F, 0x23, 0x8A, 0x1E, 0x49, 0x09, 0x3C, 0xA7, 0x2E, 0x76, 0x5A, 0x47, 0xE8, 0x08, 0xE3, 0xE6, 0x1C, 0x53, 0xE6, 0xEC, 0x38, + 0xE2, 0xA8, 0xD7, 0x6E, 0xB2, 0x4E, 0x6D, 0x68, 0x28, 0xD4, 0xC4, 0xC5, 0xA0, 0x91, 0x0A, 0x9C, 0xA1, 0xA3, 0xBA, 0xCF, 0xEE, 0x64, 0x44, 0x40, + 0xC6, 0xC0, 0xE5, 0xC0, 0x70, 0x7E, 0xBC, 0xE8, 0x55, 0xB9, 0xE0, 0xEA, 0xB4, 0x24, 0x16, 0x68, 0x49, 0x5B, 0xAD, 0xE8, 0x0A, 0xAD, 0xCC, 0xB4, + 0xA9, 0xAC, 0xBF, 0x52, 0x92, 0xB0, 0x00, 0x40, 0x63, 0x00, 0x60, 0xF6, 0x76, 0x12, 0x53, 0x68, 0x52, 0x87, 0x57, 0xF2, 0xB4, 0xD9, 0x1E, 0x71, + 0x82, 0x44, 0xCD, 0x76, 0xA4, 0x12, 0x2F, 0x72, 0xD7, 0x1C, 0x12, 0x7B, 0x0B, 0x42, 0xC8, 0xF2, 0x3F, 0x88, 0x39, 0x3D, 0x26, 0x9D, 0x3D, 0x48, + 0x5E, 0xB0, 0x5F, 0x5B, 0xD8, 0x41, 0xCF, 0x1B, 0xC8, 0x49, 0x1B, 0x71, 0x17, 0x0D, 0x91, 0x97, 0xF5, 0x5C, 0x89, 0xAE, 0x86, 0x72, 0x4C, 0xEB, + 0xC1, 0xFC, 0xB2, 0xBF, 0xE8, 0x44, 0x26, 0xE8, 0x07, 0xF7, 0xE7, 0xD0, 0x33, 0x67, 0xC8, 0xBB, 0xE6, 0xCE, 0x0E, 0xB0, 0x21, 0x06, 0xBE, 0x9E, + 0xA4, 0x5C, 0x10, 0x33, 0xE8, 0x07, 0xBA, 0xD6, 0xD9, 0x6D, 0xA4, 0xFC, 0xCF, 0x67, 0xFF, 0x69, 0xFF, 0xAB, 0x3F, 0x81, 0xF9, 0xB7, 0x8A, 0x27, + 0xE3, 0x17, 0x53, 0xBC, 0x45, 0x30, 0xC3, 0x67, 0x01, 0xBC, 0xA1, 0xAF, 0x54, 0x20, 0x5F, 0xBD, 0x68, 0xF7, 0x0A, 0xC2, 0xFF, 0x2F, 0x71, 0xFF, + 0x73, 0x7A, 0x5B, 0xC7, 0xE3, 0x2F, 0x90, 0xD4, 0x46, 0xC0, 0x87, 0x04, 0x9B, 0xD9, 0x05, 0x39, 0x17, 0x8B, 0xF8, 0x5A, 0x9D, 0xBD, 0x49, 0xAD, + 0xC0, 0xE7, 0x1F, 0x10, 0xA2, 0xEA, 0x9D, 0xD6, 0x01, 0x46, 0x80, 0x25, 0x00, 0x38, 0xDA, 0x21, 0x49, 0xDB, 0xEC, 0x83, 0xE9, 0x6B, 0xEA, 0xB4, + 0xEE, 0xB5, 0x28, 0xB8, 0xD5, 0xA7, 0x35, 0xCB, 0x11, 0x63, 0x4A, 0x2F, 0x49, 0x53, 0x48, 0x7F, 0x54, 0x0B, 0x53, 0x76, 0x0F, 0x9C, 0x37, 0x0D, + 0x9B, 0x7D, 0x87, 0xEA, 0xAD, 0x54, 0xE5, 0xCE, 0x22, 0xF0, 0xA6, 0xBF, 0x2D, 0xB8, 0xF7, 0x06, 0xDF, 0x84, 0xEE, 0x45, 0xCC, 0xB7, 0x65, 0xA6, + 0x1B, 0x4F, 0x78, 0x97, 0xA5, 0x75, 0xEB, 0x33, 0xEF, 0x7B, 0x4D, 0x7B, 0xE3, 0xE9, 0xBB, 0x5D, 0x6B, 0x07, 0xBB, 0xBF, 0x99, 0xED, 0x51, 0x2A, + 0x77, 0xB0, 0x15, 0x3B, 0x9B, 0xD1, 0xFD, 0xC8, 0x5E, 0xC7, 0xF2, 0x6E, 0x71, 0x23, 0xBD, 0x15, 0x93, 0xDC, 0x95, 0x64, 0x6F, 0xA4, 0x4D, 0xBC, + 0x8F, 0xFB, 0x3B, 0x0F, 0x83, 0xCD, 0xFE, 0x83, 0x7F, 0x2C, 0x44, 0x40, 0x86, 0xDC, 0xE1, 0xAB, 0xA7, 0x68, 0x9A, 0x98, 0x9C, 0x55, 0x83, 0x01, + 0x3B, 0x53, 0x65, 0x21, 0xDD, 0x45, 0x8B, 0x74, 0xB3, 0xBE, 0x6D, 0xF7, 0x0E, 0x98, 0xE6, 0xF0, 0xF5, 0x16, 0xDA, 0x3E, 0xF1, 0x36, 0x08, 0xEE, + 0xFD, 0x5B, 0xC0, 0x46, 0xAC, 0x38, 0x36, 0x0C, 0xDC, 0xE9, 0x1B, 0x5C, 0x0E, 0x93, 0x9B, 0x30, 0x9E, 0xDB, 0xD5, 0x59, 0x9B, 0xC8, 0x89, 0x02, + 0x70, 0x10, 0x08, 0xFC, 0xE0, 0xD9, 0xF4, 0x40, 0xC8, 0xBB, 0x6E, 0xED, 0x83, 0x11, 0xDA, 0xAD, 0x51, 0x1D, 0xAC, 0x0F, 0x48, 0x82, 0x11, 0x7F, + 0x3A, 0xEF, 0xD7, 0xFE, 0xD9, 0x7F, 0xFF, 0x2B, 0x3E, 0xE3, 0x24, 0xA0, 0x09, 0xCE, 0xCE, 0x47, 0xED, 0x09, 0x9D, 0x7C, 0x96, 0xE8, 0x4F, 0x8E, + 0x29, 0x37, 0x07, 0x51, 0x22, 0xAF, 0xED, 0x30, 0x9F, 0x0C, 0x92, 0x3B, 0xAB, 0x98, 0xBB, 0x76, 0xC9, 0x5F, 0x46, 0xE7, 0xC1, 0x6F, 0x45, 0xAB, + 0x99, 0x10, 0x2F, 0xFD, 0x1B, 0x94, 0x4E, 0x5D, 0xDE, 0x80, 0x3D, 0xD9, 0x22, 0x1C, 0x90, 0x63, 0xFF, 0x08, 0xD7, 0x03, 0x12, 0xAD, 0xFC, 0x30, + 0x9F, 0x1B, 0xAE, 0x0B, 0xE6, 0xF8, 0x5F, 0xC5, 0x5A, 0x0D, 0xF3, 0x69, 0xFF, 0xE8, 0x77, 0xF0, 0xC7, 0xB5, 0x7B, 0x92, 0x15, 0x6B, 0x21, 0x4B, + 0x43, 0xE8, 0x4A, 0x99, 0xF0, 0xCA, 0xE6, 0xCB, 0x8A, 0xE4, 0x82, 0xBD, 0x01, 0xED, 0x67, 0xC7, 0xFA, 0x49, 0xC2, 0xBA, 0x9C, 0xAD, 0x9A, 0x58, + 0x51, 0x0A, 0xDC, 0x81, 0xFE, 0x61, 0xCC, 0xC2, 0xA5, 0x4D, 0xF9, 0xD6, 0xE6, 0x58, 0xAC, 0xB4, 0x18, 0xE1, 0x8B, 0x16, 0x6F, 0x13, 0xEF, 0x13, + 0x6A, 0xC7, 0x35, 0x4D, 0x07, 0xC6, 0x80, 0x9C, 0x19, 0x12, 0x02, 0xE9, 0x10, 0x9C, 0x6B, 0xFE, 0x8A, 0xA6, 0x57, 0xD1, 0x3C, 0xD5, 0x00, 0x3E, + 0xFD, 0x21, 0xD7, 0x16, 0xBB, 0x84, 0x6F, 0xE3, 0x2F, 0xFD, 0xBF, 0x2A, 0x24, 0x0F, 0xD2, 0x21, 0x56, 0x52, 0x34, 0xD6, 0xEA, 0x9F, 0x4E, 0x6B, + 0x48, 0x57, 0xF8, 0xAB, 0x71, 0x10, 0xC4, 0x5F, 0x69, 0x49, 0x66, 0x5E, 0x94, 0x22, 0x58, 0x5D, 0x76, 0x4B, 0x5C, 0xAF, 0x24, 0x5B, 0x82, 0x66, + 0x5A, 0xC1, 0xC6, 0x59, 0x91, 0x4C, 0x59, 0x22, 0xED, 0x2B, 0xD6, 0xB3, 0xAB, 0x1F, 0xA0, 0x2A, 0x19, 0x10, 0xAA, 0xA8, 0x4C, 0xA8, 0x82, 0xAA, + 0xA6, 0xDA, 0xDE, 0x52, 0x5F, 0x05, 0xA2, 0xF0, 0xBC, 0xE0, 0x72, 0x16, 0xA0, 0x02, 0x85, 0x9E, 0xFA, 0x08, 0x9D, 0x2E, 0xBF, 0x9A, 0x1C, 0x33, + 0x99, 0x68, 0x15, 0x2C, 0x81, 0xDA, 0x95, 0x9A, 0x39, 0x24, 0xF1, 0x6A, 0x26, 0xB9, 0x2C, 0x22, 0x71, 0xD4, 0x1E, 0x0D, 0x75, 0x30, 0xC2, 0x61, + 0x2E, 0x0A, 0x53, 0x41, 0x74, 0xB5, 0x32, 0x34, 0x37, 0x2A, 0x04, 0x77, 0xF4, 0xFE, 0xEB, 0x0D, 0xBA, 0x6B, 0x01, 0x8A, 0xDC, 0xF8, 0x19, 0x4C, + 0xF2, 0x61, 0xAD, 0xE9, 0xD1, 0x2C, 0xE3, 0x01, 0xE6, 0xD8, 0xB9, 0xA5, 0xDB, 0xF9, 0xB0, 0xC9, 0x81, 0xFE, 0xA3, 0xCB, 0xE1, 0x91, 0xC2, 0x41, + 0x71, 0x70, 0xA3, 0x25, 0xDF, 0xB5, 0x31, 0xFA, 0x50, 0x73, 0x60, 0xDE, 0x4A, 0x43, 0xF6, 0x38, 0x63, 0x81, 0x40, 0x9B, 0xDB, 0x41, 0xEA, 0xB1, + 0x4C, 0xA1, 0x60, 0xCC, 0xA3, 0x25, 0x0C, 0x67, 0x8B, 0x17, 0x55, 0x58, 0x17, 0xDC, 0xD8, 0x96, 0xE2, 0x19, 0x2D, 0x69, 0x64, 0x96, 0x8E, 0xD8, + 0x15, 0x1A, 0x00, 0x2A, 0x3A, 0xC8, 0x29, 0x49, 0xC9, 0x28, 0x59, 0x00, 0x00, 0x9C, 0xA1, 0x9C, 0xC4, 0x0D, 0x99, 0x44, 0x20, 0x2A, 0xD9, 0x8B, + 0xB7, 0x49, 0x80, 0x91, 0x2C, 0x2E, 0x18, 0xB1, 0x94, 0x13, 0xC1, 0x87, 0x85, 0xC8, 0x76, 0x00, 0xD1, 0xCF, 0x3F, 0xF6, 0x0C, 0x3E, 0xBE, 0x07, + 0x8F, 0x76, 0x5F, 0x87, 0x9B, 0x91, 0xFD, 0x6E, 0xE4, 0x80, 0x93, 0x6E, 0xC4, 0x4B, 0x35, 0xE4, 0xBE, 0x66, 0xEB, 0xF9, 0x2F, 0x96, 0x1A, 0x42, + 0x69, 0x6C, 0x5A, 0xCF, 0xF4, 0x8B, 0xF8, 0x8D, 0x4E, 0x04, 0x86, 0xAE, 0x64, 0x3F, 0x8B, 0x76, 0x38, 0xC7, 0xDE, 0x34, 0xFB, 0xE2, 0x30, 0x2B, + 0x4F, 0x31, 0x77, 0x50, 0x2D, 0x93, 0xE4, 0x6C, 0x4E, 0x3A, 0xAE, 0xA4, 0x72, 0x28, 0x66, 0xBA, 0x9E, 0x62, 0x12, 0xDB, 0x5C, 0xCE, 0x88, 0x71, + 0x49, 0x22, 0xD5, 0x22, 0xC5, 0xC3, 0x12, 0x07, 0xA7, 0xD2, 0x27, 0x98, 0x85, 0x15, 0x15, 0x65, 0xD7, 0xC7, 0xE4, 0x1B, 0x01, 0x49, 0x05, 0x3A, + 0x91, 0x79, 0x74, 0xC8, 0x0E, 0x56, 0x8F, 0x88, 0x83, 0xF7, 0xC6, 0x36, 0xC7, 0x4C, 0x0B, 0x2B, 0x4E, 0x2F, 0x98, 0x36, 0xDA, 0x12, 0x32, 0xEE, + 0xBE, 0xA9, 0x78, 0xCE, 0x54, 0xA1, 0x81, 0x97, 0x02, 0x86, 0x76, 0xD1, 0xE6, 0x84, 0xA2, 0xD3, 0x72, 0x22, 0x15, 0x1E, 0x51, 0x4D, 0x05, 0x45, + 0xDB, 0xED, 0x21, 0x5D, 0xB3, 0x21, 0x9E, 0xF3, 0x09, 0x10, 0x2C, 0x69, 0x85, 0x49, 0xD1, 0x5C, 0x76, 0x4A, 0x0D, 0xB5, 0x26, 0x0E, 0x79, 0x9D, + 0x05, 0x53, 0x09, 0x84, 0xAC, 0xFF, 0xBF, 0xB4, 0x90, 0xF3, 0x57, 0x13, 0x89, 0x48, 0x14, 0xEF, 0x63, 0x18, 0x70, 0x73, 0x5A, 0xB1, 0x6C, 0x2F, + 0xB2, 0xC1, 0x73, 0xAD, 0x08, 0x48, 0x4F, 0x48, 0x43, 0xF8, 0xA7, 0xAD, 0x5C, 0x78, 0xF7, 0xAD, 0xFC, 0x7E, 0xEB, 0xCE, 0x4D, 0x7D, 0x2B, 0x3A, + 0xBB, 0xD5, 0xC2, 0xEF, 0xD1, 0x16, 0x77, 0x0D, 0xC8, 0xFB, 0x37, 0xC9, 0x3D, 0xB5, 0xF3, 0xFE, 0x2E, 0xF6, 0xAB, 0xB7, 0x03, 0xFB, 0xDB, 0x9D, + 0xFE, 0xC1, 0x3E, 0x8B, 0x77, 0x17, 0x01, 0x01, 0x84, 0xBB, 0x24, 0xEF, 0xAD, 0x17, 0xB6, 0x77, 0x89, 0xDD, 0x93, 0x55, 0xDD, 0x60, 0x9D, 0x6F, + 0x15, 0x62, 0x77, 0x9E, 0xF2, 0x1B, 0x68, 0xD5, 0xEE, 0x07, 0xFD, 0x46, 0xF3, 0x78, 0xCF, 0x49, 0xA6, 0x37, 0x34, 0x34, 0xE5, 0xEC, 0x0E, 0xCD, + 0xBA, 0x1D, 0x5C, 0x39, 0xDB, 0x8E, 0x29, 0xBA, 0xB1, 0xB9, 0x87, 0xB5, 0xB6, 0xD5, 0xC0, 0x4A, 0x33, 0x57, 0xC0, 0x9A, 0x9A, 0x20, 0x9A, 0xE8, + 0x02, 0xDE, 0xE2, 0x85, 0x94, 0xBC, 0xA3, 0xE4, 0xFF, 0xBF, 0xFE, 0xE9, 0x34, 0xDF, 0x2F, 0xBD, 0x74, 0x7D, 0xB3, 0xD6, 0xF6, 0xE1, 0x3F, 0xDB, + 0xF7, 0x82, 0x69, 0x25, 0x96, 0x9C, 0x81, 0x04, 0xAC, 0x98, 0x74, 0x84, 0x1F, 0xFA, 0x35, 0xF1, 0xF3, 0xBC, 0xBA, 0xCC, 0xDA, 0xB5, 0xD9, 0x02, + 0xFD, 0xA7, 0x37, 0xA4, 0x33, 0xFC, 0xCF, 0xDD, 0x57, 0xD6, 0x9B, 0xA9, 0x8F, 0x43, 0x45, 0x80, 0x3E, 0x48, 0xBF, 0xF0, 0x65, 0xF5, 0x76, 0x59, + 0x94, 0xC4, 0xD8, 0xAF, 0x09, 0x6B, 0xF4, 0xD9, 0x2A, 0x26, 0xC7, 0x5A, 0x80, 0x8F, 0x14, 0x78, 0xC5, 0x28, 0x73, 0xE9, 0xE8, 0x87, 0xA9, 0x68, + 0xCB, 0xEF, 0x1C, 0x54, 0xC8, 0x14, 0x0C, 0xD8, 0x05, 0x5B, 0x8C, 0xCE, 0xB9, 0x8E, 0xFD, 0xB0, 0xC9, 0x65, 0xEA, 0xF0, 0xE5, 0xC8, 0x7B, 0x6E, + 0x79, 0x73, 0xB2, 0x67, 0x51, 0x25, 0xB4, 0x9F, 0x74, 0xFB, 0xDA, 0xE7, 0x3D, 0x7F, 0x78, 0x29, 0x7A, 0x81, 0xF5, 0x4B, 0x62, 0x87, 0xAB, 0xCC, + 0xF9, 0xF8, 0x8F, 0xF4, 0x0E, 0x77, 0x6A, 0x2F, 0xDF, 0x82, 0xAC, 0xFF, 0x3F, 0x47, 0x26, 0x9E, 0xD9, 0x54, 0xDE, 0x1D, 0xC6, 0xD9, 0x81, 0xCE, + 0x7F, 0xF1, 0x6D, 0xFF, 0xEB, 0x77, 0xFD, 0xAD, 0x9F, 0xF5, 0xAB, 0x7E, 0xFC, 0xCF, 0xFC, 0x8D, 0x9F, 0xF0, 0x07, 0xFE, 0x10, 0xFF, 0xEE, 0x53, + 0xF8, 0x0C, 0x3E, 0x82, 0x5F, 0xF6, 0xBB, 0xFE, 0xD3, 0x77, 0xEA, 0x64, 0x23, 0x0F, 0xE1, 0x25, 0xF0, 0x82, 0xB0, 0x4C, 0xF9, 0x7F, 0xBD, 0x72, + 0xC1, 0xF7, 0x47, 0x63, 0x52, 0x61, 0x2A, 0xEA, 0x3D, 0x8B, 0xF7, 0x46, 0x29, 0xE4, 0x10, 0xDC, 0x7E, 0x80, 0x32, 0x85, 0x20, 0x62, 0x1E, 0x21, + 0x61, 0x38, 0x23, 0x5F, 0x54, 0x5D, 0x70, 0x55, 0x5B, 0x8A, 0x7F, 0x4B, 0x5A, 0x70, 0x01, 0x03, 0x67, 0x3D, 0x99, 0xF8, 0x67, 0xE7, 0x02, 0x2D, + 0x50, 0xE3, 0xA8, 0x5D, 0xFE, 0xE5, 0x8F, 0x0B, 0x31, 0x9C, 0xB7, 0xD0, 0xF2, 0xD2, 0x07, 0x83, 0x31, 0x55, 0xE5, 0xC5, 0x0B, 0x88, 0x86, 0x29, + 0x57, 0xB4, 0x69, 0x53, 0xB4, 0x29, 0x96, 0x8B, 0xA6, 0xD0, 0x2A, 0x01, 0x1F, 0x49, 0x4D, 0x9E, 0x2D, 0x4F, 0xBF, 0x0D, 0x0F, 0x95, 0x1B, 0xE9, + 0xF4, 0xDF, 0xAF, 0xFC, 0x6E, 0x9F, 0xED, 0x7F, 0x4D, 0xAE, 0x44, 0x4F, 0xCE, 0x39, 0x1C, 0xB3, 0xE1, 0xB4, 0x37, 0xFE, 0x57, 0x0F, 0xBE, 0xB8, + 0x5D, 0x39, 0xCD, 0x45, 0xF2, 0xE8, 0x4F, 0x94, 0x5F, 0x42, 0x2A, 0x1D, 0x0E, 0xA6, 0xFE, 0xD6, 0x31, 0xD9, 0x26, 0x43, 0xA2, 0xC0, 0x00, 0x53, + 0x02, 0x50, 0x2C, 0xD8, 0x28, 0x00, 0xCB, 0xD7, 0x5C, 0xD7, 0x00, 0x51, 0xD5, 0x2A, 0xC8, 0x18, 0x20, 0x19, 0x9C, 0x66, 0x2F, 0x11, 0xE0, 0xFA, + 0x81, 0x46, 0x79, 0x7C, 0x36, 0x43, 0xC7, 0x0C, 0xD6, 0xC4, 0x0C, 0xC5, 0xAA, 0x9D, 0xFC, 0x2E, 0xF3, 0xD9, 0x21, 0x53, 0xF1, 0x1A, 0xE3, 0xBA, + 0x12, 0x43, 0x4A, 0x10, 0x96, 0xC0, 0x0D, 0x2C, 0xC0, 0x86, 0x38, 0x1F, 0x86, 0xAF, 0x05, 0x0B, 0xBC, 0x18, 0x0B, 0xBB, 0x3C, 0xF0, 0x71, 0x99, + 0x6E, 0x6E, 0xAD, 0x48, 0xA1, 0xA5, 0x6B, 0x98, 0x85, 0x2A, 0xEA, 0xD2, 0xB6, 0xDA, 0xA8, 0xE3, 0x29, 0xB5, 0xDF, 0x6A, 0xA0, 0x02, 0x5F, 0x9E, + 0xF2, 0xA2, 0x96, 0x9A, 0x10, 0xD7, 0xCC, 0xEA, 0x99, 0x53, 0x0F, 0xEA, 0xB6, 0x6C, 0x80, 0xF5, 0xE7, 0x0A, 0x47, 0x43, 0x75, 0x46, 0x30, 0x26, + 0x8A, 0xC2, 0x42, 0x10, 0x39, 0x5D, 0xB6, 0x0D, 0xB0, 0x7F, 0xFF, 0x57, 0xFF, 0x8F, 0x26, 0x5C, 0xD8, 0x71, 0x66, 0x07, 0x41, 0xF9, 0x9E, 0xDB, + 0x45, 0xA0, 0xD7, 0xB2, 0xA5, 0x25, 0x7C, 0x48, 0x5D, 0x7D, 0x74, 0x34, 0xAE, 0x60, 0x93, 0xDC, 0x67, 0x12, 0x2D, 0x56, 0xFA, 0x4D, 0x2B, 0xBD, + 0x70, 0x4D, 0xAA, 0x84, 0x80, 0x84, 0x5C, 0x69, 0x6F, 0xB5, 0x6C, 0x23, 0xED, 0xDA, 0x73, 0x09, 0xB4, 0xCD, 0xD4, 0x76, 0x90, 0x16, 0x75, 0x01, + 0x6E, 0x22, 0xCE, 0xBA, 0x3D, 0xC7, 0x5E, 0x37, 0x5A, 0x1F, 0xA5, 0xBB, 0xE5, 0xEA, 0x31, 0x94, 0xDD, 0x8A, 0xC0, 0xF5, 0x0F, 0x4F, 0x7B, 0x28, + 0x8B, 0x36, 0x58, 0x8C, 0x7B, 0xA4, 0x5D, 0xC7, 0x97, 0xB9, 0x37, 0xE2, 0x6D, 0x11, 0xC5, 0xF6, 0xB1, 0x9B, 0xB6, 0x2D, 0x9F, 0x3B, 0x30, 0xDF, + 0x6E, 0x66, 0xBB, 0x2D, 0xB7, 0xDA, 0x2C, 0xAC, 0xF6, 0x18, 0xC1, 0xEE, 0x24, 0xBB, 0xFB, 0xF6, 0xAD, 0x5D, 0x8C, 0xE3, 0x7E, 0x1E, 0xAA, 0x93, + 0x30, 0xE5, 0xDD, 0xDA, 0x72, 0xDA, 0x86, 0x3F, 0xE5, 0x82, 0xAF, 0xD5, 0xB4, 0x9A, 0xC1, 0x77, 0x1C, 0x3C, 0x94, 0x33, 0x2B, 0x9B, 0x31, 0x77, + 0x9C, 0x2D, 0x93, 0x34, 0x29, 0xEB, 0x40, 0x48, 0x0E, 0x42, 0x43, 0x86, 0x12, 0x30, 0xE3, 0xAB, 0xEE, 0x78, 0x2D, 0x82, 0x0C, 0xB9, 0x10, 0xC6, + 0x15, 0x44, 0x14, 0xF7, 0x49, 0xEE, 0x09, 0x27, 0x89, 0x1D, 0x57, 0x87, 0x37, 0x59, 0x85, 0x41, 0x27, 0x83, 0x5F, 0x29, 0x63, 0xF0, 0xB2, 0x02, + 0x23, 0xB7, 0x02, 0x73, 0x14, 0xFF, 0xA6, 0x18, 0xFB, 0xE6, 0x90, 0xF4, 0x22, 0xB5, 0x79, 0xAF, 0x7E, 0x60, 0x04, 0x00, 0xDA, 0x55, 0x2B, 0xD1, + 0xCD, 0xD2, 0xC9, 0xBD, 0x0B, 0xC2, 0x8D, 0xB3, 0xD2, 0x0F, 0x76, 0xBD, 0xD8, 0x6B, 0xBB, 0xD5, 0x44, 0x60, 0xBB, 0x78, 0xA1, 0xF6, 0x76, 0x8F, + 0x16, 0xEF, 0x36, 0x0B, 0x9D, 0x28, 0xAB, 0xC7, 0x20, 0x8B, 0xB2, 0xE1, 0xD5, 0xBD, 0xE9, 0x4A, 0x06, 0xDA, 0x0A, 0x0F, 0xFF, 0xFF, 0x2F, 0x55, + 0xE5, 0x21, 0x0A, 0x03, 0x27, 0xDC, 0x8D, 0x11, 0xAA, 0x04, 0x8A, 0xA7, 0x0C, 0xA4, 0x4E, 0x2D, 0x5C, 0x34, 0xA1, 0xF0, 0x65, 0x9A, 0xC5, 0x5D, + 0xC2, 0x2C, 0x55, 0x62, 0x8E, 0x4E, 0xAA, 0xFD, 0x4D, 0x72, 0x81, 0x39, 0x7A, 0x66, 0x1F, 0x0D, 0x7D, 0x23, 0x98, 0x9B, 0xA2, 0xB0, 0x18, 0x22, + 0xA7, 0xA9, 0xA1, 0xB9, 0x26, 0xA1, 0x01, 0x6C, 0xEF, 0x3F, 0xB4, 0x20, 0xBA, 0x2A, 0x20, 0xC8, 0xBA, 0x1F, 0x0E, 0x3A, 0x3E, 0xAB, 0x21, 0x7A, + 0x46, 0xA8, 0xF2, 0xFC, 0x4A, 0xD8, 0x29, 0x6D, 0xDB, 0xF1, 0x18, 0x91, 0xCA, 0x9A, 0xB3, 0x43, 0x89, 0xA3, 0x7E, 0xBB, 0xC9, 0x6A, 0xB5, 0xA1, + 0xC1, 0xAB, 0x89, 0x33, 0xA6, 0x91, 0x3A, 0x31, 0x43, 0x77, 0x75, 0x9F, 0x65, 0x90, 0x11, 0x61, 0x19, 0x13, 0xC1, 0x10, 0x86, 0xB3, 0xE4, 0x45, + 0x8F, 0xCB, 0x05, 0x37, 0x28, 0xF1, 0x40, 0x4B, 0xBA, 0x2B, 0x54, 0xC3, 0xCA, 0x0C, 0x82, 0x5E, 0xC4, 0x94, 0xA4, 0x2F, 0xE8, 0x0D, 0x00, 0xCC, + 0x14, 0x9C, 0xC4, 0x28, 0x9A, 0xD4, 0x71, 0x28, 0x79, 0x02, 0x6D, 0x8F, 0x58, 0x24, 0x51, 0xDB, 0x1D, 0xA9, 0x0C, 0x15, 0xA9, 0xA0, 0x0E, 0x89, + 0x85, 0x01, 0x42, 0xE8, 0xFE, 0x20, 0x16, 0xA5, 0x5C, 0x7B, 0x90, 0xF0, 0xBE, 0xCE, 0xB0, 0xDF, 0x1A, 0xC8, 0x50, 0x1B, 0x71, 0x1A, 0x0D, 0x91, + 0x9A, 0xF5, 0x1C, 0x9E, 0xAA, 0xF7, 0x46, 0xB5, 0x4B, 0x38, 0x4D, 0xF4, 0x32, 0x65, 0x31, 0x20, 0x34, 0x41, 0xE9, 0x58, 0x0B, 0xCC, 0xA3, 0x0E, + 0x41, 0xAF, 0x51, 0x0D, 0x13, 0x4C, 0xD6, 0xF3, 0x06, 0x29, 0x1C, 0x00, 0x7C, 0xB6, 0x2C, 0xD9, 0xA8, 0x27, 0x06, 0xA1, 0x2D, 0x52, 0x3F, 0x2D, + 0xC3, 0xAF, 0x2C, 0x60, 0x47, 0x2C, 0x17, 0x0A, 0xB0, 0x3E, 0x4E, 0xAD, 0x66, 0xC1, 0xAC, 0x66, 0x1E, 0xA9, 0x98, 0xE5, 0xA8, 0xA2, 0x52, 0xA7, + 0x5A, 0x3A, 0x48, 0xB1, 0x09, 0x47, 0x2D, 0xA9, 0x80, 0x5F, 0x00, 0x41, 0x1B, 0x95, 0x9F, 0xD8, 0x61, 0xC0, 0xA8, 0xEF, 0xBC, 0xF2, 0x23, 0xD5, + 0x2F, 0xC9, 0xF2, 0xE4, 0x95, 0x2E, 0xD9, 0x49, 0xCB, 0x3E, 0x48, 0xB4, 0x37, 0x48, 0x2C, 0x5A, 0x46, 0xCD, 0x53, 0x46, 0x4A, 0x06, 0x8A, 0x5C, + 0xD8, 0x88, 0xCE, 0xF2, 0xEE, 0x4C, 0x15, 0xE0, 0x11, 0x0E, 0xEF, 0x61, 0x04, 0xF0, 0x75, 0x0D, 0xEF, 0x39, 0x3A, 0xFE, 0x8E, 0xF8, 0xFE, 0x1B, + 0xC4, 0xE7, 0x3D, 0xDF, 0x90, 0x98, 0xF8, 0x7D, 0xEE, 0x7B, 0x75, 0x16, 0x5F, 0xF2, 0xDF, 0xBF, 0x9A, 0x70, 0xA1, 0x98, 0xB7, 0x47, 0x2D, 0x1C, + 0x2B, 0x7D, 0xDF, 0x61, 0x86, 0x1B, 0x90, 0xB9, 0x6B, 0xAD, 0xC0, 0x35, 0x38, 0xDD, 0x0F, 0x1C, 0xC1, 0x15, 0x05, 0xDC, 0x37, 0x58, 0xBD, 0x55, + 0x11, 0xDD, 0x29, 0xDA, 0xDE, 0xC5, 0x9E, 0x6E, 0x56, 0xCC, 0x3B, 0x4B, 0x09, 0xF4, 0xE9, 0x91, 0x05, 0x53, 0x16, 0xD1, 0xA5, 0x9A, 0x9F, 0xA4, + 0xB1, 0x30, 0xA3, 0xB7, 0xBA, 0xA2, 0xCA, 0x4C, 0xA1, 0xD1, 0xE9, 0xD0, 0x95, 0x33, 0x38, 0x28, 0x0A, 0x8C, 0xCF, 0xA0, 0x26, 0xCF, 0xA3, 0xB5, + 0x8B, 0x2F, 0xB4, 0x0F, 0x54, 0x6B, 0x4D, 0x55, 0xB6, 0x71, 0x79, 0xCF, 0xF8, 0x17, 0xF7, 0x5E, 0xE7, 0xC2, 0xF7, 0xFB, 0xF6, 0xEF, 0xF8, 0x5D, + 0x60, 0x60, 0x61, 0xFD, 0x5B, 0xD1, 0x2D, 0x94, 0x71, 0x0F, 0x61, 0xFE, 0xCB, 0xBA, 0x55, 0x32, 0xC6, 0x94, 0xD7, 0x05, 0x92, 0x4F, 0xE6, 0x90, + 0x6B, 0x2C, 0xCC, 0x20, 0xAA, 0x1F, 0x4F, 0x11, 0xCA, 0x10, 0x5B, 0x61, 0x5C, 0x20, 0xB3, 0xF8, 0xC0, 0xDF, 0x5E, 0x42, 0x21, 0xF1, 0x86, 0xFB, + 0x70, 0x89, 0x4D, 0xE1, 0x14, 0xA8, 0xC1, 0x2D, 0x6C, 0x63, 0x90, 0x06, 0x03, 0xCF, 0x36, 0xFF, 0xC6, 0xF8, 0x68, 0x66, 0xF1, 0x05, 0xD1, 0xE9, + 0x75, 0x41, 0xE2, 0xA5, 0x01, 0x81, 0x31, 0xD4, 0xB2, 0x2B, 0xB5, 0xA3, 0x1B, 0x96, 0x94, 0x4B, 0xE0, 0x0A, 0x77, 0xAE, 0xEC, 0x7E, 0xC1, 0xED, + 0xFE, 0x47, 0x77, 0x3F, 0x81, 0xE1, 0x0E, 0xF9, 0x77, 0xA7, 0x1D, 0x7D, 0x30, 0x2B, 0x9B, 0x41, 0xF6, 0x17, 0x70, 0xD9, 0x30, 0xD6, 0x03, 0x12, + 0x96, 0x85, 0xF3, 0x75, 0x27, 0xEF, 0xAA, 0xF4, 0xE2, 0xDD, 0x9A, 0xE5, 0xC9, 0x7A, 0xC6, 0xBA, 0x9A, 0xC1, 0x6F, 0x75, 0x88, 0x4E, 0x95, 0x2F, + 0x80, 0x2A, 0x19, 0x3B, 0x8F, 0xC2, 0x31, 0x1F, 0xF6, 0xC7, 0xE8, 0x20, 0xD5, 0xC1, 0x0D, 0xEA, 0xE7, 0x29, 0xEA, 0xDC, 0x7D, 0xEF, 0xE2, 0x6C, + 0x7E, 0x0A, 0x62, 0xAA, 0xD6, 0x94, 0x7E, 0x16, 0xFC, 0x38, 0xC9, 0x46, 0x9A, 0xCB, 0xE0, 0x17, 0x03, 0xAD, 0xF5, 0xF4, 0x16, 0xA0, 0x4B, 0x28, + 0x3E, 0x93, 0xA0, 0x3C, 0xA1, 0xCC, 0x06, 0x74, 0x1A, 0x48, 0xC0, 0x59, 0x37, 0x01, 0x5F, 0x22, 0x7A, 0x73, 0x04, 0x09, 0x4D, 0x42, 0x05, 0x99, + 0x95, 0x2C, 0x30, 0x45, 0x41, 0xBF, 0x25, 0x71, 0x65, 0x74, 0x68, 0x25, 0xC9, 0x2B, 0x8B, 0x21, 0x34, 0xC9, 0xB8, 0x49, 0xE4, 0x5C, 0x08, 0xFA, + 0x00, 0x3A, 0xE5, 0x33, 0x8A, 0xAF, 0xC7, 0xC3, 0x9A, 0x1D, 0xC3, 0x05, 0x14, 0x4E, 0x44, 0xCD, 0x28, 0xE4, 0xA0, 0x6C, 0x5F, 0x9B, 0x13, 0xA6, + 0xF8, 0xFC, 0x83, 0x77, 0x4E, 0x6D, 0x13, 0xA3, 0x7E, 0x82, 0x26, 0x3C, 0xA0, 0x5D, 0xEB, 0x81, 0x5B, 0x18, 0xD2, 0x67, 0x69, 0xB3, 0x65, 0x45, + 0x0E, 0x0A, 0x0E, 0xCD, 0xD4, 0xBF, 0xC7, 0x2A, 0xC9, 0xF0, 0x55, 0x3A, 0x3B, 0x10, 0x82, 0xEE, 0xE2, 0xFA, 0xD1, 0x6F, 0x8D, 0x4A, 0x76, 0x23, + 0x6A, 0xD8, 0xFC, 0xA5, 0x5E, 0x24, 0x35, 0x6F, 0x02, 0x8F, 0x17, 0x0A, 0x10, 0x6F, 0x75, 0xAF, 0x6C, 0xF1, 0x36, 0xD8, 0xAE, 0xDD, 0x68, 0x0F, + 0x15, 0x69, 0x6B, 0x30, 0xC8, 0x7A, 0x82, 0xCA, 0x2E, 0xBD, 0xC1, 0xEE, 0xEE, 0xC2, 0xA2, 0xE1, 0xBD, 0x8E, 0x34, 0xB9, 0x32, 0x30, 0xB0, 0xDA, + 0x67, 0xA2, 0x4A, 0x26, 0x20, 0xEF, 0xF8, 0x8E, 0x47, 0x90, 0xA3, 0x82, 0x9E, 0x9C, 0x0E, 0xAA, 0x9A, 0xB2, 0x62, 0x96, 0x12, 0x40, 0xD4, 0x4B, + 0xBA, 0x80, 0xE1, 0xC5, 0xAB, 0x3C, 0xAA, 0x54, 0x00, 0xCA, 0x62, 0xEB, 0x48, 0xD0, 0x74, 0xC5, 0xC9, 0xDA, 0xFF, 0x1D, 0x6C, 0x18, 0xBD, 0x7B, + 0x1F, 0x99, 0xCE, 0x1E, 0x49, 0x65, 0xA7, 0x11, 0xF7, 0xB2, 0xAE, 0x98, 0x0C, 0x02, 0xCA, 0x6B, 0x06, 0xC9, 0x27, 0x74, 0xE4, 0x9A, 0xBE, 0x19, + 0x44, 0x83, 0xC7, 0x53, 0x8D, 0x32, 0xC4, 0x30, 0x8D, 0x0B, 0x94, 0x16, 0x1F, 0xB0, 0xEF, 0x25, 0x38, 0x12, 0x6F, 0xD0, 0x1C, 0x2E, 0x71, 0x2A, + 0x9C, 0xA2, 0x36, 0xB8, 0x45, 0x8C, 0x18, 0xA4, 0xCC, 0xC0, 0xB4, 0x1E, 0xBF, 0x31, 0x56, 0x9A, 0x73, 0x7C, 0x41, 0x8E, 0x7A, 0x5D, 0xAA, 0x78, + 0x69, 0x58, 0x60, 0x0C, 0xE9, 0xEC, 0x4A, 0x21, 0xE9, 0x86, 0x59, 0xE5, 0x12, 0x20, 0xC3, 0x9D, 0x6B, 0xC3, 0x5F, 0x68, 0x80, 0xFF, 0xBB, 0x80, + 0x3F, 0xE1, 0x87, 0x87, 0xB4, 0xE3, 0x69, 0x47, 0xF1, 0x66, 0x65, 0x3F, 0xC8, 0xFE, 0x9E, 0x58, 0x7E, 0x8C, 0xF5, 0xC0, 0xC3, 0xB2, 0xA4, 0xBE, + 0xEE, 0xDC, 0xBA, 0x2A, 0x09, 0xC3, 0x5B, 0xB3, 0x56, 0x59, 0xCF, 0x70, 0x57, 0x33, 0x10, 0xAE, 0x0E, 0x61, 0x50, 0xE5, 0x7B, 0x53, 0x25, 0x43, + 0xC9, 0xA3, 0xC8, 0xCC, 0x87, 0x15, 0x32, 0xE2, 0xA5, 0x3A, 0x20, 0x42, 0xFD, 0xA4, 0x45, 0x9D, 0xDB, 0xFC, 0x2E, 0xE0, 0xE8, 0xA7, 0x20, 0xC0, + 0x6A, 0x37, 0x4D, 0xE9, 0x06, 0x82, 0xF1, 0xBF, 0x74, 0x52, 0x8E, 0x34, 0xB7, 0x42, 0xBB, 0xB8, 0x69, 0x74, 0x3D, 0x2C, 0xDB, 0x1C, 0x6A, 0x26, + 0x0A, 0xBA, 0x14, 0xF9, 0x99, 0xD4, 0xE5, 0x09, 0x35, 0xE3, 0xC2, 0x0C, 0x41, 0xA7, 0x01, 0x09, 0x9C, 0x75, 0x7B, 0xF8, 0x40, 0x91, 0xCD, 0x11, + 0x89, 0x9A, 0x84, 0x13, 0x32, 0x2B, 0x3F, 0x31, 0x45, 0x5B, 0x2D, 0x89, 0x41, 0x2B, 0xA3, 0x5D, 0x2B, 0x49, 0x76, 0x59, 0x0C, 0x19, 0x90, 0x8C, + 0xBB, 0x23, 0xE7, 0x0E, 0x21, 0xE7, 0x4F, 0x8F, 0x7B, 0x1A, 0xEE, 0x7A, 0x34, 0x8E, 0x76, 0x04, 0x2B, 0x12, 0xE1, 0x8D, 0xA3, 0x9E, 0x29, 0x7A, + 0xED, 0x52, 0x70, 0x80, 0xA0, 0xF8, 0xDA, 0x3C, 0xAC, 0x41, 0x32, 0x5C, 0xC0, 0xE1, 0x84, 0xD4, 0xBA, 0x90, 0x8F, 0xC3, 0xBE, 0x76, 0x47, 0x98, + 0x82, 0xB5, 0x3D, 0x78, 0xB7, 0xE5, 0x36, 0x31, 0x4A, 0x28, 0x68, 0x42, 0x05, 0x5A, 0x37, 0x70, 0x6B, 0xEF, 0x8F, 0x37, 0xC5, 0xCF, 0x73, 0xA7, + 0xC5, 0x2A, 0xBD, 0x18, 0x21, 0x74, 0x79, 0x60, 0xE3, 0x32, 0x05, 0xB1, 0xB5, 0xA2, 0x82, 0x96, 0x6E, 0x1D, 0xAA, 0x89, 0xAC, 0x75, 0x88, 0xE1, + 0xCB, 0xAB, 0x1A, 0x49, 0xAB, 0x0D, 0xC2, 0xAA, 0xA9, 0x55, 0xAA, 0x9B, 0xCC, 0xA9, 0x02, 0x7B, 0xA9, 0x2A, 0x5A, 0xF9, 0xBB, 0xCD, 0x2F, 0x88, + 0xCE, 0x0E, 0x84, 0xE7, 0xF8, 0x03, 0xA8, 0xE9, 0x73, 0x78, 0xDA, 0x23, 0x59, 0x3B, 0x2F, 0xF1, 0xF4, 0x35, 0x38, 0xD4, 0x45, 0x9C, 0x3F, 0x49, + 0x96, 0x2B, 0x0D, 0xEF, 0xF2, 0x20, 0xC6, 0x65, 0xAA, 0xB7, 0xB5, 0x82, 0x81, 0x96, 0xEE, 0x01, 0xD4, 0xBE, 0xAC, 0xB5, 0x86, 0xE1, 0xC6, 0xAB, + 0x1A, 0x44, 0xAB, 0x0D, 0xBF, 0xAA, 0x29, 0x4F, 0xAA, 0x1B, 0xC7, 0xA9, 0x02, 0xB9, 0x52, 0x55, 0xA7, 0xF1, 0x42, 0x93, 0xC7, 0xE8, 0xC0, 0x35, + 0x8F, 0x1C, 0xA9, 0x8F, 0x34, 0x58, 0x1A, 0x09, 0x2D, 0x48, 0xB5, 0x04, 0x5C, 0xA9, 0xB1, 0xF3, 0x8A, 0x71, 0x03, 0xB0, 0x75, 0x84, 0x13, 0xC0, + 0x6A, 0x51, 0x13, 0x0C, 0x8D, 0x06, 0x4C, 0xB6, 0x85, 0xE4, 0xFA, 0x3C, 0xA3, 0xBC, 0x31, 0x5E, 0xA7, 0x8F, 0x90, 0xAF, 0x92, 0x53, 0xEE, 0x13, + 0xCF, 0xAE, 0x06, 0xAC, 0x37, 0xD8, 0x1B, 0x1C, 0xEA, 0x3C, 0x2B, 0x2F, 0x05, 0xC7, 0x70, 0xDB, 0x16, 0x52, 0x5C, 0x69, 0x98, 0x97, 0x3B, 0x74, + 0x8B, 0xB6, 0xAD, 0xB4, 0x56, 0x5A, 0xA3, 0x28, 0x00, 0x8C, 0xA9, 0xB2, 0x19, 0x76, 0x65, 0x1B, 0x6C, 0x64, 0x28, 0x25, 0xAA, 0x60, 0xC0, 0xDA, + 0x54, 0x36, 0x44, 0x53, 0x45, 0x45, 0x52, 0x54, 0x60, 0x51, 0x63, 0x61, 0xF0, 0x36, 0x39, 0x28, 0xBA, 0xF9, 0x13, 0x5E, 0x07, 0x27, 0x40, 0x0F, + 0xF5, 0x43, 0x15, 0x76, 0x49, 0xC6, 0xFA, 0x6F, 0xA4, 0x5D, 0x24, 0x1D, 0x43, 0xFF, 0x91, 0x69, 0xA2, 0x77, 0x39, 0xA1, 0xD1, 0x9F, 0x7E, 0xDA, + 0x97, 0xF0, 0x47, 0x7C, 0x4A, 0x12, 0x74, 0x16, 0x74, 0x57, 0x19, 0xF4, 0x12, 0x7A, 0x10, 0xFD, 0x3D, 0x27, 0x01, 0xA9, 0x65, 0x1D, 0xE6, 0x1A, + 0xFA, 0x4A, 0xCC, 0x52, 0xC6, 0xA3, 0xFE, 0xDE, 0x61, 0x78, 0xC9, 0xA6, 0xA8, 0x01, 0xA4, 0xAF, 0xD6, 0xD1, 0x30, 0xB4, 0xEC, 0xCF, 0xB4, 0x17, + 0x3E, 0xDB, 0xC3, 0x3E, 0xA9, 0xDD, 0x3A, 0x0F, 0xE7, 0x1E, 0x56, 0xE9, 0x2A, 0xB3, 0x3F, 0x16, 0x32, 0xC3, 0xD6, 0xA5, 0xE8, 0xCA, 0x8B, 0x42, + 0x67, 0x92, 0x9E, 0x12, 0xFA, 0xFF, 0x5D, 0xA0, 0xE7, 0x8D, 0x40, 0x92, 0x9E, 0x4D, 0x6B, 0x48, 0x1E, 0x80, 0x71, 0x0D, 0xAE, 0x51, 0xCD, 0x41, + 0xCE, 0x80, 0x3C, 0x09, 0x69, 0x1F, 0x8E, 0x05, 0xA0, 0xB0, 0x42, 0x83, 0xC4, 0x9F, 0x79, 0x9E, 0x98, 0xA9, 0x76, 0x08, 0x80, 0xEB, 0xA1, 0x8C, + 0xB8, 0xA3, 0xEC, 0xA3, 0x91, 0x89, 0xB4, 0x8E, 0xC9, 0xE4, 0x88, 0xF9, 0x14, 0x86, 0x39, 0xC9, 0x00, 0xDB, 0x52, 0x10, 0x17, 0xB0, 0xE0, 0xCB, + 0x80, 0xAF, 0x97, 0x04, 0xA6, 0x2E, 0xBD, 0x49, 0x2E, 0x12, 0xEC, 0x2D, 0x44, 0x0B, 0x5A, 0x2C, 0x5A, 0xB3, 0x3E, 0xBD, 0xB0, 0x5C, 0xBF, 0xAE, + 0x72, 0x47, 0xA7, 0x84, 0x24, 0xA5, 0xA0, 0x80, 0xA2, 0xBE, 0x82, 0xE0, 0x69, 0x8B, 0x50, 0x0A, 0x9C, 0x9F, 0x26, 0x3C, 0x70, 0xE2, 0x13, 0x6D, + 0x2A, 0x21, 0xC5, 0xA4, 0x02, 0xC4, 0x92, 0x25, 0x89, 0xD2, 0x68, 0x3B, 0xE9, 0x75, 0x03, 0x52, 0x6F, 0xED, 0xD1, 0x8C, 0xB2, 0x23, 0x8E, 0x45, + 0x23, 0x00, 0x35, 0x45, 0x37, 0x0E, 0x88, 0x86, 0x88, 0x87, 0xA4, 0xF6, 0x95, 0xF1, 0x03, 0xA2, 0x6C, 0x99, 0x49, 0x72, 0x48, 0x58, 0xF4, 0xBD, + 0x4A, 0x0F, 0x6B, 0x51, 0xC2, 0xB2, 0x24, 0xC6, 0x3C, 0x16, 0x8F, 0x26, 0xCD, 0x4E, 0xA9, 0xA0, 0x0E, 0xAD, 0x09, 0x1D, 0xF7, 0x03, 0x00, 0x3F, + 0x28, 0x27, 0x48, 0xC1, 0x26, 0x55, 0x5A, 0x25, 0x8C, 0x07, 0x44, 0x17, 0x9F, 0xF1, 0x3A, 0xA4, 0xF8, 0x08, 0x0D, 0xE0, 0x8D, 0x27, 0x95, 0x80, + 0x54, 0x49, 0x9B, 0xDF, 0x14, 0xCB, 0x6A, 0x27, 0xBA, 0xEA, 0xF7, 0x65, 0x0F, 0xB7, 0x0D, 0x2D, 0x3B, 0x7B, 0xDF, 0xC6, 0x4B, 0xA4, 0x87, 0x92, + 0x31, 0x78, 0x9C, 0xA5, 0xE1, 0x0C, 0x7C, 0x4D, 0xC6, 0x6C, 0x4B, 0x68, 0x0B, 0x3F, 0x50, 0x33, 0xF7, 0x1E, 0xB6, 0x7B, 0xF4, 0x0E, 0xE1, 0x0D, + 0x6C, 0xE7, 0xB2, 0x1F, 0x41, 0x79, 0x2E, 0x1B, 0x44, 0x1F, 0xE1, 0xB9, 0x4F, 0x76, 0xFE, 0x94, 0x50, 0xFB, 0x4F, 0x10, 0xBA, 0x6B, 0xC8, 0x5C, + 0x37, 0xF6, 0xCB, 0x88, 0xF5, 0x55, 0x1F, 0xD2, 0x4D, 0x50, 0xCC, 0x67, 0x18, 0xFC, 0xB7, 0xFB, 0x29, 0xF8, 0x43, 0x28, 0x9D, 0x0F, 0xA8, 0xA4, + 0xDB, 0x65, 0x78, 0x31, 0xD9, 0x76, 0x3B, 0xD7, 0xC0, 0x36, 0xC5, 0xAF, 0xD5, 0x9F, 0xD1, 0x8A, 0x9E, 0xCE, 0x65, 0x7B, 0x49, 0x8C, 0x9D, 0xB9, + 0x20, 0xCB, 0xA2, 0x43, 0xDD, 0xAF, 0xEC, 0xD4, 0x5F, 0x88, 0x76, 0x37, 0x34, 0x38, 0xD2, 0xD2, 0x4F, 0xE9, 0x9A, 0x01, 0x7E, 0xC3, 0x7F, 0xAD, + 0x83, 0x34, 0x12, 0x06, 0xFE, 0x63, 0x57, 0xDE, 0x02, 0xCE, 0xAB, 0x9E, 0x87, 0x21, 0x83, 0x21, 0x3B, 0x27, 0x7D, 0x21, 0xED, 0x94, 0x6E, 0xA7, + 0x39, 0xD2, 0x1B, 0x0C, 0x60, 0x57, 0xE1, 0x3A, 0xEC, 0x2B, 0xB7, 0xB1, 0x5A, 0x8E, 0x9B, 0xDB, 0xC4, 0xAE, 0x7D, 0x85, 0xC1, 0xBD, 0xB3, 0x06, + 0x57, 0xE8, 0xCE, 0xA2, 0x70, 0x87, 0x67, 0x8F, 0x0B, 0x6C, 0x11, 0xE6, 0x8E, 0xB2, 0x83, 0x31, 0xA6, 0x73, 0xBC, 0xCD, 0x9B, 0x36, 0x3F, 0xD7, + 0x66, 0x15, 0x0D, 0x87, 0x09, 0xF4, 0x52, 0x3B, 0x78, 0xE9, 0xC6, 0x86, 0x3D, 0x6B, 0xE6, 0x1F, 0xF5, 0x58, 0x9E, 0x8B, 0x9E, 0xA9, 0x15, 0x46, + 0xD0, 0xD8, 0xDB, 0x45, 0x9C, 0xA0, 0xDF, 0x1D, 0x4D, 0xED, 0xA8, 0xD1, 0xD2, 0x4D, 0x10, 0x3A, 0xBC, 0xB2, 0x30, 0x48, 0x2D, 0x80, 0x33, 0x94, + 0xD7, 0xF7, 0x46, 0x0C, 0x86, 0xF5, 0x4A, 0x08, 0xA7, 0xA6, 0x04, 0x27, 0x56, 0xC6, 0x20, 0x2E, 0x02, 0x0E, 0x7D, 0x05, 0x26, 0x09, 0xF3, 0xED, + 0x3D, 0xF6, 0x0D, 0x9A, 0xF7, 0x96, 0x70, 0xF9, 0xF2, 0x12, 0x58, 0xC3, 0x38, 0x59, 0x31, 0xB0, 0x8B, 0x80, 0x05, 0x5F, 0xB1, 0x9E, 0x37, 0x77, + 0xDF, 0x48, 0xA2, 0x87, 0xDD, 0xB0, 0x97, 0x3D, 0xFD, 0xD1, 0xC3, 0x0E, 0x9B, 0x90, 0xC3, 0xBA, 0xF5, 0xED, 0xEB, 0x5E, 0xD6, 0xEA, 0xA7, 0xD1, + 0x0C, 0x48, 0x1A, 0x77, 0xF5, 0x9F, 0x41, 0xB4, 0x0C, 0x19, 0xB2, 0xC5, 0x7E, 0x10, 0x73, 0xF6, 0x33, 0x2B, 0xFF, 0x14, 0xA1, 0x65, 0x15, 0xFA, + 0xEA, 0x1B, 0x72, 0x9F, 0xB7, 0x3F, 0xAD, 0x4C, 0x27, 0xA5, 0x6F, 0x7E, 0xF1, 0x17, 0xEE, 0x31, 0x75, 0x75, 0x39, 0x92, 0xDC, 0x58, 0x3B, 0xC9, + 0xD3, 0x5C, 0x62, 0xED, 0x79, 0x76, 0xA6, 0x43, 0x0D, 0x69, 0x45, 0x45, 0xBF, 0x39, 0xAE, 0xB1, 0xE1, 0x0F, 0x6F, 0xE2, 0x0D, 0x41, 0xC3, 0x77, + 0xB0, 0x8B, 0x16, 0xEC, 0x80, 0x0C, 0x55, 0x3D, 0xFF, 0xE3, 0x4D, 0x51, 0xE6, 0x00, 0x5B, 0x2C, 0xA8, 0x41, 0x60, 0xFE, 0xDF, 0xE8, 0xB3, 0x74, + 0xF4, 0x08, 0x87, 0x1D, 0x2F, 0x3E, 0x5B, 0x83, 0x63, 0xC3, 0xA6, 0x50, 0xBE, 0x29, 0xB7, 0x95, 0xD7, 0x12, 0x51, 0x91, 0x16, 0x46, 0xC2, 0x29, + 0xBB, 0x30, 0x03, 0x7C, 0x30, 0xC5, 0x43, 0x7B, 0xD1, 0xB2, 0xD8, 0x80, 0xE1, 0x53, 0xAC, 0xB8, 0xF1, 0xB6, 0x69, 0x1F, 0x2C, 0x0F, 0x22, 0x0D, + 0x06, 0x06, 0xA2, 0xA3, 0x65, 0x7C, 0x1F, 0x15, 0xCB, 0x36, 0xFF, 0x48, 0x9E, 0x48, 0xA0, 0xF3, 0x8F, 0x14, 0x90, 0x40, 0xE9, 0xAF, 0x3E, 0xC2, + 0x50, 0xDD, 0xEA, 0xE2, 0x5B, 0x43, 0x05, 0xFE, 0xCE, 0xF4, 0x0A, 0xA7, 0xE0, 0xF1, 0x84, 0x4B, 0x09, 0x70, 0x00, 0xB8, 0xB5, 0x2B, 0x23, 0xE9, + 0xAC, 0xF4, 0x8E, 0xDC, 0x5E, 0x03, 0x4C, 0x8A, 0x6B, 0x7D, 0xDD, 0x21, 0x80, 0x8B, 0xE0, 0x67, 0xD4, 0xC3, 0xCC, 0x53, 0xE6, 0x4C, 0xF3, 0xA2, + 0xF9, 0xD9, 0x3C, 0x6C, 0xDE, 0xB4, 0x9F, 0xCF, 0xD1, 0xF6, 0x1E, 0xE6, 0x75, 0x7B, 0xC6, 0x79, 0x88, 0x7D, 0xDF, 0x5E, 0x72, 0xDF, 0xB8, 0x5F, + 0xDD, 0x97, 0xEE, 0x29, 0xE7, 0xCC, 0xBF, 0xFB, 0xD6, 0x39, 0x7B, 0xEF, 0x6C, 0x3C, 0x17, 0x8A, 0x31, 0x6F, 0xCF, 0x3D, 0xE6, 0x40, 0xF3, 0x9C, + 0x39, 0xD7, 0xDC, 0xBD, 0x0F, 0xDA, 0x3F, 0xED, 0xBB, 0xF6, 0x69, 0x7B, 0x04, 0x7B, 0x09, 0xFB, 0xBD, 0x7D, 0xDD, 0xD7, 0x4F, 0xDC, 0x53, 0xEE, + 0x39, 0xCC, 0x4B, 0xCC, 0x17, 0xE7, 0x95, 0xF3, 0xD0, 0xF9, 0xEB, 0x1C, 0x01, 0x8C, 0xF9, 0x84, 0xE3, 0xF9, 0x7A, 0x6E, 0x32, 0x9F, 0x99, 0xBF, + 0xE7, 0x35, 0xF1, 0x55, 0xFC, 0x60, 0x9C, 0x10, 0x7E, 0x20, 0x8F, 0x00, 0x8F, 0x14, 0x57, 0xD4, 0xA7, 0x60, 0x39, 0x4A, 0xE7, 0xA4, 0x71, 0xE6, + 0x8C, 0x56, 0xC4, 0x56, 0x46, 0x84, 0x61, 0xAC, 0x85, 0xD8, 0x0D, 0x02, 0xD1, 0x7D, 0x10, 0x21, 0xF7, 0x6B, 0x07, 0x37, 0x84, 0x08, 0xBD, 0x05, + 0xCC, 0x17, 0x94, 0x93, 0xB7, 0x85, 0xB3, 0xB6, 0xA8, 0xC0, 0xB5, 0x95, 0x9A, 0xB4, 0xC2, 0x2C, 0x62, 0x6B, 0x67, 0x45, 0x5C, 0x63, 0x95, 0x99, + 0x63, 0x83, 0xA8, 0x60, 0xA1, 0xC4, 0x5E, 0xE9, 0xB8, 0x5C, 0xB7, 0x54, 0xB4, 0x4A, 0x35, 0xB2, 0xD6, 0x29, 0xAF, 0xB2, 0x49, 0x98, 0xA3, 0x9A, + 0x40, 0x91, 0x3F, 0x65, 0x85, 0x96, 0x9B, 0x36, 0xB7, 0x28, 0x35, 0x26, 0xD5, 0x97, 0x5E, 0x39, 0xC8, 0x10, 0x27, 0xC0, 0xC3, 0xD5, 0xFF, 0xE9, + 0xB4, 0x4D, 0xFA, 0x6B, 0xDC, 0xE7, 0x58, 0x0A, 0xF6, 0x7E, 0x66, 0xA5, 0x4D, 0x32, 0x48, 0x3D, 0xA3, 0x47, 0x05, 0x6C, 0x8A, 0xEA, 0x9A, 0x86, + 0x46, 0x58, 0x0A, 0x4D, 0x5F, 0x7D, 0x8E, 0x60, 0x7F, 0xBA, 0x4F, 0xE8, 0x94, 0xAC, 0x79, 0x17, 0x4F, 0xFA, 0xEF, 0x6A, 0xE7, 0x1C, 0xC0, 0x48, + 0x97, 0xE1, 0x12, 0xDF, 0x9C, 0x90, 0x43, 0x87, 0xBB, 0xD2, 0xD0, 0xB8, 0x81, 0xC3, 0x64, 0x4E, 0x0F, 0x30, 0x02, 0xC3, 0x8D, 0x74, 0x47, 0xF0, + 0x26, 0xBB, 0x7B, 0xDD, 0x1B, 0xDC, 0x13, 0xDC, 0xFD, 0xEE, 0x1B, 0xEE, 0x0E, 0xDE, 0x8A, 0xF7, 0x0F, 0x6F, 0xD0, 0xFB, 0xE3, 0x7B, 0xF7, 0x9E, + 0xFA, 0x16, 0x7D, 0x0B, 0xBF, 0x79, 0xDF, 0x88, 0x20, 0x6F, 0x5A, 0x8D, 0xF7, 0xF0, 0x9D, 0xE6, 0x6D, 0x1B, 0x72, 0x87, 0xBF, 0x79, 0xEE, 0x35, + 0x77, 0xAC, 0x7B, 0xD4, 0xFD, 0xED, 0xBE, 0x76, 0xC7, 0xBB, 0x9F, 0xBD, 0x97, 0x45, 0x8C, 0x35, 0xD4, 0x1B, 0xE9, 0x99, 0xB4, 0xFA, 0x6F, 0x59, + 0xFD, 0xB0, 0x58, 0x3E, 0xCC, 0x16, 0x53, 0xBD, 0x31, 0xDE, 0x38, 0x2D, 0x56, 0x74, 0xD6, 0x1B, 0x6C, 0x8E, 0x8D, 0x12, 0xF7, 0x0A, 0x28, 0x5E, + 0x0B, 0xD4, 0xF1, 0x2E, 0x0F, 0x22, 0x5C, 0xA6, 0x51, 0x5B, 0x2B, 0x7A, 0xE8, 0xBA, 0x36, 0x74, 0xD4, 0x2C, 0xFA, 0x5A, 0x8A, 0x3E, 0x0C, 0x47, + 0xAF, 0x91, 0xD3, 0xA7, 0xEE, 0x6E, 0xE2, 0x7E, 0x01, 0x41, 0x0C, 0x2D, 0x8C, 0x77, 0xE7, 0xBB, 0x31, 0xA6, 0x64, 0xD2, 0x31, 0x3F, 0xFE, 0xE5, + 0xBC, 0xF2, 0x56, 0x2C, 0x34, 0xA6, 0x80, 0xA7, 0xFE, 0x5F, 0x7D, 0x93, 0x7E, 0x79, 0xAA, 0xD5, 0x0A, 0x9E, 0xE0, 0xDE, 0xB5, 0xCD, 0x02, 0xB9, + 0xC2, 0x8A, 0xB2, 0xBF, 0x09, 0x75, 0x1C, 0xAB, 0xEE, 0xB6, 0x8A, 0xFA, 0x55, 0x3A, 0x93, 0xBD, 0x3B, 0xE7, 0xC3, 0x0F, 0x40, 0xCC, 0x34, 0xFC, + 0x80, 0x7B, 0xCE, 0x0E, 0xBC, 0x44, 0x3E, 0x31, 0x2C, 0x84, 0x27, 0xFC, 0xAB, 0xD3, 0x1F, 0x0A, 0x0B, 0x9E, 0x5F, 0x86, 0x8D, 0xCB, 0x2B, 0x61, + 0xD7, 0x50, 0x9F, 0xA4, 0xA9, 0xD2, 0x2C, 0xDF, 0xAD, 0xCC, 0x91, 0x20, 0x6B, 0x2E, 0x4B, 0x57, 0x93, 0xDA, 0x27, 0xD3, 0xF5, 0x02, 0xE7, 0x20, + 0x50, 0xE8, 0x7C, 0x1E, 0x7B, 0x15, 0xCB, 0x5F, 0x53, 0x70, 0x6F, 0xAA, 0xF2, 0x7B, 0x67, 0xCC, 0x8D, 0x7E, 0x70, 0x81, 0x7D, 0x88, 0x58, 0x0C, + 0xF2, 0xDE, 0x87, 0xC1, 0xC7, 0xFA, 0x9A, 0xC7, 0x0F, 0xE5, 0x0D, 0x8E, 0xE6, 0x76, 0x84, 0x7A, 0x0C, 0x17, 0xE6, 0x76, 0x48, 0xB9, 0xA1, 0x7D, + 0xBE, 0x42, 0x80, 0x3C, 0x2F, 0x3C, 0xAF, 0x5D, 0xD6, 0x23, 0xAF, 0xD1, 0x53, 0xD3, 0x73, 0x8D, 0x0E, 0x7A, 0x31, 0x62, 0xBC, 0x04, 0x44, 0x0B, + 0x74, 0x5E, 0x28, 0xB2, 0x69, 0x41, 0x1C, 0x2B, 0x84, 0xDE, 0xD7, 0x57, 0x82, 0x2F, 0x4E, 0x63, 0x6F, 0xC9, 0x2A, 0x2F, 0xDD, 0x1E, 0x46, 0x4A, + 0xD4, 0xEE, 0x20, 0x96, 0xEE, 0xD1, 0x5A, 0xAE, 0xE6, 0x1B, 0x6E, 0x19, 0x05, 0x3D, 0x87, 0x07, 0x2F, 0x0E, 0x37, 0x6F, 0x25, 0x51, 0x6D, 0xF5, + 0x1D, 0x6A, 0x2D, 0x9D, 0x68, 0x25, 0x8B, 0x62, 0xE4, 0x67, 0xDB, 0xC9, 0xB2, 0x31, 0x05, 0x62, 0x83, 0x5C, 0xC0, 0xBE, 0x30, 0x43, 0x7B, 0xD3, + 0x07, 0xDF, 0x55, 0x1A, 0x98, 0x3F, 0xFB, 0xD6, 0x2D, 0xC3, 0x08, 0x0C, 0xBE, 0x27, 0x0C, 0xE4, 0xCD, 0x2C, 0xF7, 0x9C, 0x23, 0x36, 0xD6, 0xEA, + 0xB8, 0xBA, 0x0F, 0xE7, 0x6E, 0x73, 0x1F, 0x4F, 0x6A, 0xCE, 0x46, 0xE3, 0x7C, 0xD8, 0x26, 0xD0, 0x8E, 0xD5, 0xB2, 0xE1, 0xF9, 0x26, 0x06, 0x0D, + 0x2D, 0x52, 0x6E, 0xE5, 0x8B, 0x75, 0x19, 0xF4, 0x6C, 0x9C, 0xB0, 0xED, 0x1D, 0xFB, 0x00, 0xF7, 0x95, 0x96, 0x2E, 0x3C, 0x0B, 0xD5, 0x2D, 0x6B, + 0xAD, 0x36, 0x8C, 0xC1, 0x6E, 0x67, 0xDF, 0x80, 0x73, 0x97, 0xB0, 0x67, 0x70, 0x57, 0xDA, 0x0D, 0xDD, 0xAF, 0x76, 0x4E, 0x77, 0x0B, 0x77, 0x86, + 0x17, 0xEE, 0x58, 0x37, 0x8A, 0x67, 0xF7, 0x2C, 0xB2, 0x1B, 0x53, 0x6F, 0x07, 0xE0, 0xAE, 0x85, 0xB6, 0xBB, 0x0C, 0xB9, 0x9F, 0x5F, 0x8E, 0x86, + 0x50, 0x8C, 0x60, 0x96, 0x8A, 0xC2, 0x88, 0x88, 0x9C, 0xCC, 0x86, 0xE6, 0xC0, 0x06, 0x3C, 0xB0, 0xD3, 0xA1, 0xD5, 0x85, 0x90, 0x74, 0x47, 0x78, + 0xAB, 0xBE, 0x57, 0xDD, 0x1A, 0xB8, 0xEE, 0x49, 0xBB, 0x8B, 0xA7, 0x9D, 0xD5, 0x9E, 0x6B, 0x2F, 0xB6, 0xA7, 0x7D, 0x3B, 0x89, 0x3D, 0xC6, 0xFE, + 0x63, 0x6F, 0xB2, 0x6F, 0xD9, 0x31, 0xD1, 0xEC, 0xA6, 0x5D, 0x74, 0xE7, 0xBD, 0x28, 0x7D, 0x74, 0xDE, 0x01, 0xE2, 0xAF, 0x80, 0xD8, 0xE7, 0xB0, + 0xD1, 0x59, 0xDB, 0x27, 0x4C, 0x48, 0x36, 0xA3, 0xC8, 0x82, 0x03, 0xC0, 0x00, 0x2B, 0x9B, 0xB1, 0xA1, 0x6C, 0x43, 0x8E, 0x0C, 0x45, 0xB1, 0x0A, + 0x66, 0xCD, 0x4D, 0x65, 0x13, 0x35, 0x55, 0x24, 0x25, 0x45, 0xB5, 0x16, 0x35, 0x26, 0x87, 0xB7, 0x51, 0x80, 0xA2, 0xBB, 0x7B, 0xC2, 0x0B, 0x74, + 0x02, 0x14, 0x6C, 0x3A, 0xB4, 0x64, 0x92, 0x6C, 0x61, 0x5F, 0xFA, 0xE5, 0xBC, 0x8B, 0x90, 0xD0, 0x7F, 0x7E, 0xE8, 0x5D, 0x5B, 0xF4, 0xA0, 0xDF, + 0xF5, 0x11, 0xFC, 0xBD, 0x9F, 0xF8, 0x3F, 0xBF, 0x22, 0x1D, 0x94, 0xBE, 0x4B, 0x57, 0xD3, 0xDD, 0xF4, 0x27, 0x3A, 0x09, 0x08, 0xB0, 0x3D, 0x8F, + 0xD5, 0x19, 0x70, 0xE8, 0xFF, 0x75, 0x5A, 0x63, 0x9D, 0x3E, 0x61, 0x77, 0x20, 0xF8, 0x30, 0x91, 0x4B, 0x50, 0x12, 0xA8, 0x14, 0x02, 0xCA, 0x07, + 0xF2, 0xBA, 0xF8, 0xC1, 0x9B, 0xC2, 0x03, 0x39, 0xD4, 0x83, 0x43, 0x94, 0x8D, 0xC1, 0x89, 0x8D, 0xC3, 0xCB, 0x81, 0xB4, 0x4E, 0xDA, 0xB8, 0xD2, + 0xD0, 0xD1, 0xE8, 0xE2, 0x5D, 0x0F, 0xE8, 0x55, 0x2F, 0xD0, 0x48, 0xDF, 0x6D, 0x7C, 0x0F, 0x34, 0xD1, 0x83, 0x35, 0xD0, 0x2B, 0xE0, 0xCF, 0x9A, + 0x51, 0xCE, 0xA8, 0x6A, 0xCD, 0xB7, 0x6B, 0x8A, 0xCC, 0x30, 0xA4, 0x96, 0x67, 0x4C, 0x2D, 0x6F, 0xC8, 0x95, 0x51, 0xD8, 0x92, 0x6F, 0xEE, 0x90, + 0xAF, 0x8E, 0x67, 0xB8, 0x21, 0x8F, 0x0D, 0x98, 0xC8, 0x80, 0xE7, 0x8D, 0x35, 0xBC, 0x8B, 0x03, 0x44, 0xEE, 0x15, 0xBD, 0x88, 0x21, 0xA8, 0x0E, + 0x8B, 0x26, 0x10, 0x16, 0x41, 0x1C, 0xFC, 0xE2, 0x2B, 0x46, 0xA5, 0x08, 0x70, 0xB4, 0x82, 0xDF, 0xD8, 0x9E, 0x5F, 0x19, 0x0E, 0xBD, 0xCA, 0x59, + 0xBD, 0x50, 0x8B, 0xBC, 0x24, 0x3F, 0x30, 0xD6, 0x42, 0x15, 0x77, 0x83, 0xB6, 0x74, 0x1F, 0xA8, 0xC8, 0xFD, 0x8A, 0xC3, 0x0D, 0x31, 0xAA, 0xA3, + 0xB7, 0xE0, 0xFC, 0x82, 0x72, 0xC6, 0xED, 0x89, 0x16, 0xDB, 0xD3, 0xD8, 0xDA, 0xCA, 0x67, 0x5A, 0x61, 0x64, 0x59, 0x97, 0xD9, 0x11, 0x00, 0xCB, + 0x4A, 0xB1, 0x40, 0x43, 0xB0, 0x4F, 0x51, 0xAF, 0x0D, 0x96, 0x5C, 0xA5, 0xEE, 0x49, 0xAD, 0x1F, 0xCC, 0x2A, 0x59, 0x11, 0xC0, 0xD2, 0x57, 0xED, + 0xB7, 0xA5, 0x5B, 0x0C, 0xEA, 0x68, 0x3F, 0x90, 0x76, 0x09, 0xBD, 0x33, 0xC4, 0x15, 0xA8, 0x57, 0x4D, 0x48, 0x2B, 0xA5, 0x4D, 0x0A, 0x7C, 0x38, + 0x85, 0x0A, 0x07, 0x8D, 0xD8, 0xA5, 0x34, 0xAE, 0xBB, 0x0E, 0x5D, 0xB6, 0x57, 0x99, 0x9E, 0xF6, 0xAA, 0x67, 0xA8, 0xF3, 0x53, 0x23, 0x5E, 0xBA, + 0x9F, 0x61, 0xCF, 0x47, 0xC7, 0x4F, 0xAB, 0x7B, 0xF1, 0x6A, 0xE3, 0x69, 0x20, 0x7A, 0x15, 0xB5, 0xFA, 0x4B, 0x8E, 0x38, 0x0B, 0xD2, 0xFF, 0xFF, + 0xBB, 0xE3, 0xB6, 0x25, 0xA8, 0x6A, 0x33, 0x40, 0xA0, 0x6D, 0x41, 0x80, 0x38, 0x6E, 0x96, 0x85, 0xF3, 0x2C, 0x0A, 0x10, 0xB2, 0xB3, 0x74, 0xD9, + 0x19, 0xE7, 0x58, 0xDC, 0xB1, 0x58, 0xCC, 0x08, 0xCC, 0x83, 0xB0, 0x5B, 0x64, 0xB0, 0x1F, 0x8D, 0xAF, 0xB5, 0x22, 0x5E, 0x5B, 0x30, 0x5D, 0xE9, + 0x1A, 0x5D, 0x9D, 0xE0, 0xAD, 0xCE, 0x93, 0xAD, 0x42, 0x84, 0xAC, 0x89, 0x70, 0xD6, 0xB7, 0x11, 0xAC, 0x2F, 0xAC, 0xAB, 0x60, 0x99, 0xAA, 0x79, + 0x12, 0xAA, 0x24, 0x7A, 0x54, 0x9B, 0x8A, 0xF3, 0x0C, 0x68, 0x53, 0x97, 0x8B, 0x53, 0x3B, 0xF1, 0x52, 0x07, 0x90, 0xA0, 0xFA, 0x2D, 0xA3, 0xFA, + 0xE0, 0x9D, 0xC6, 0xA8, 0x3D, 0x6D, 0x60, 0x6C, 0x0A, 0xA9, 0x62, 0x4A, 0x66, 0x6B, 0x1A, 0x23, 0x57, 0x0A, 0xD8, 0x26, 0x5D, 0x35, 0x22, 0xD5, + 0x30, 0x27, 0xBD, 0x12, 0x1D, 0x95, 0x04, 0x12, 0xFD, 0x65, 0x11, 0x7D, 0x14, 0x15, 0x65, 0xE0, 0x0E, 0x6D, 0xE5, 0x0A, 0xF5, 0x40, 0x02, 0xA5, + 0x9D, 0x01, 0x35, 0x8C, 0xFC, 0x3C, 0x3E, 0xF0, 0xB9, 0x43, 0xF6, 0x29, 0x22, 0xE9, 0x79, 0x1A, 0xE2, 0x09, 0xE2, 0xE5, 0x22, 0xAB, 0x81, 0x0B, + 0xA4, 0x90, 0xCE, 0x68, 0xC2, 0xCE, 0x9E, 0x04, 0x9C, 0x71, 0x7E, 0x9C, 0x72, 0x37, 0x4E, 0x9D, 0x64, 0xFC, 0xD6, 0x86, 0xCD, 0xB0, 0xB8, 0x26, + 0x02, 0xC5, 0x4C, 0x3C, 0x5D, 0x4C, 0x0E, 0xA0, 0x97, 0x2B, 0x98, 0x5A, 0xA8, 0xD8, 0xB5, 0x84, 0x05, 0xAC, 0xEC, 0x0C, 0xAD, 0xFC, 0xC1, 0x94, + 0xB9, 0x30, 0x28, 0x67, 0x3E, 0x26, 0xD7, 0x6B, 0x49, 0xA4, 0xE1, 0xC8, 0x9A, 0x19, 0x48, 0xB3, 0x90, 0xC7, 0x29, 0xA8, 0x7B, 0x1D, 0x8F, 0x23, + 0x5A, 0xCD, 0x8A, 0x11, 0x58, 0x8D, 0x12, 0xA2, 0x18, 0x2B, 0xDF, 0x54, 0x94, 0x58, 0x4B, 0x11, 0x8B, 0xB7, 0xD8, 0x82, 0x82, 0x22, 0x31, 0x5C, + 0xE2, 0x6C, 0x60, 0x22, 0x49, 0x06, 0xC4, 0xB5, 0x0C, 0x14, 0x41, 0x86, 0x87, 0x3F, 0x5C, 0x86, 0x5F, 0x9C, 0x27, 0xD6, 0x5E, 0xFC, 0x42, 0xB9, + 0x17, 0xF6, 0x3D, 0x24, 0xC2, 0x3C, 0x17, 0x83, 0x97, 0xA4, 0x83, 0x13, 0x68, 0x06, 0x19, 0x20, 0x9B, 0x40, 0xC4, 0x15, 0x84, 0x51, 0x23, 0x78, + 0x38, 0x41, 0xF0, 0x0F, 0x40, 0x20, 0x68, 0x74, 0xE0, 0xC8, 0x84, 0x12, 0xB0, 0x23, 0x25, 0x20, 0x87, 0x7A, 0x61, 0x48, 0x44, 0x8D, 0x90, 0xF8, + 0x6F, 0x23, 0x46, 0x53, 0x46, 0xB0, 0x99, 0x44, 0x1C, 0x80, 0x13, 0x31, 0xB4, 0x1C, 0xE2, 0xB7, 0x28, 0x44, 0xCE, 0xD9, 0x87, 0x4D, 0x10, 0x69, + 0x61, 0x20, 0x3C, 0xC2, 0x00, 0x9F, 0x9A, 0x3E, 0x80, 0x86, 0x7D, 0xC8, 0x90, 0xE2, 0xC3, 0xCE, 0xFC, 0x4F, 0x0D, 0x8D, 0x58, 0x85, 0x5F, 0xA5, + 0x93, 0x5F, 0x96, 0x87, 0xFA, 0x5D, 0x5D, 0x9D, 0xE6, 0xA9, 0x0F, 0x37, 0x44, 0x9F, 0x9C, 0x81, 0x87, 0xC1, 0x10, 0x1E, 0xB6, 0x42, 0x78, 0x00, + 0xB0, 0xD3, 0x81, 0xDE, 0xC7, 0xA7, 0x29, 0xC9, 0x47, 0x47, 0xCC, 0xE7, 0x64, 0x81, 0x83, 0xBD, 0x71, 0x83, 0xEB, 0x88, 0x0D, 0x89, 0x17, 0x36, + 0xBC, 0xCD, 0xEE, 0xE1, 0x4B, 0x67, 0x50, 0x6A, 0xC8, 0xCF, 0x6A, 0x20, 0xA1, 0x40, 0x4F, 0xFF, 0xAB, 0x87, 0xD2, 0x9A, 0xC7, 0x4C, 0x94, 0xD7, + 0xF9, 0x99, 0x97, 0x66, 0xD3, 0x8D, 0x8C, 0x33, 0xF8, 0x80, 0xE2, 0x05, 0xC7, 0xE0, 0xA9, 0xC4, 0xC0, 0x10, 0xF3, 0x78, 0x21, 0xC9, 0xC3, 0x02, + 0x96, 0x07, 0xDD, 0x2C, 0xA7, 0x82, 0x04, 0xC1, 0xBB, 0xBA, 0x2A, 0x0A, 0x86, 0x33, 0xEC, 0x46, 0x14, 0xF8, 0x13, 0x4E, 0xBB, 0x24, 0x38, 0x5A, + 0x45, 0x10, 0x46, 0x50, 0x97, 0xDA, 0x56, 0x27, 0xB2, 0xF7, 0x80, 0xF8, 0xC2, 0x83, 0x9F, 0x44, 0x07, 0x24, 0x76, 0x3A, 0x2A, 0x0E, 0x0D, 0x82, + 0x34, 0xE7, 0xDA, 0x16, 0x19, 0x7C, 0xD5, 0xCE, 0xF1, 0x42, 0xE5, 0xDE, 0xF0, 0x0B, 0x0E, 0x61, 0x28, 0xC8, 0xBB, 0x4D, 0xF0, 0xB9, 0x9E, 0x23, + 0x40, 0x74, 0x3E, 0x40, 0xCB, 0x1B, 0x17, 0xDA, 0x62, 0xC0, 0x59, 0x03, 0x6E, 0xB9, 0xF1, 0xC3, 0xBD, 0xD0, 0xBC, 0xD5, 0x6C, 0xD0, 0xDD, 0x9A, + 0xE0, 0x6D, 0x5C, 0x6A, 0x3F, 0x4D, 0x6D, 0x0F, 0xC5, 0xA7, 0x76, 0x26, 0xFF, 0x10, 0x26, 0xBF, 0x83, 0x20, 0x8F, 0x24, 0x10, 0x67, 0xF5, 0x20, + 0x9F, 0xCC, 0xDB, 0xCB, 0x60, 0x94, 0xBB, 0x1E, 0xEE, 0x4F, 0x48, 0xE5, 0x33, 0x3A, 0xF7, 0x3B, 0x69, 0x72, 0x94, 0xD5, 0xB1, 0xAC, 0x04, 0x54, + 0x76, 0x01, 0x7E, 0x7A, 0xA3, 0x4E, 0xC1, 0x46, 0x20, 0x41, 0x7B, 0x93, 0xAF, 0xDC, 0x7C, 0x44, 0x36, 0x8A, 0xC5, 0x5E, 0xAD, 0x37, 0xCD, 0x42, + 0x85, 0x0D, 0x7D, 0x1F, 0x47, 0x9E, 0xB0, 0x46, 0xEF, 0x68, 0x93, 0xDF, 0x8C, 0xD2, 0xA7, 0x4A, 0xE5, 0x5F, 0xAC, 0x11, 0xCB, 0xF3, 0xD1, 0x14, + 0x92, 0x38, 0xA8, 0xE2, 0x29, 0x6C, 0x58, 0x9F, 0xF9, 0x09, 0x3B, 0xFA, 0xB5, 0xC5, 0xBD, 0xF4, 0xA2, 0x4C, 0x1E, 0xBF, 0x8E, 0x91, 0xAA, 0x7F, + 0xE5, 0xCD, 0x7F, 0x28, 0x1B, 0xB4, 0x77, 0x8D, 0x7B, 0x00, 0x8D, 0xDA, 0xE0, 0x4C, 0xD6, 0xA4, 0xFB, 0xC2, 0xA3, 0x8C, 0x9C, 0x44, 0x3C, 0xC6, + 0x34, 0x1A, 0x06, 0x82, 0xDD, 0x8B, 0xA6, 0xB2, 0xDE, 0xC5, 0xC3, 0x82, 0x16, 0x66, 0x50, 0x00, 0x33, 0x02, 0x4E, 0x7E, 0x9D, 0x3F, 0x10, 0x89, + 0x3C, 0x90, 0x81, 0xE5, 0xCF, 0x77, 0x3B, 0x0E, 0xFA, 0x1C, 0xA9, 0x78, 0x6B, 0x02, 0x10, 0x56, 0xB7, 0xFB, 0xEA, 0x06, 0x58, 0x55, 0x3C, 0x0A, + 0xF9, 0xC5, 0xC3, 0xD4, 0x3E, 0x0C, 0xA8, 0xA1, 0x32, 0xA7, 0x8C, 0xD0, 0xA6, 0x30, 0x62, 0x8C, 0x26, 0x09, 0xD2, 0x99, 0x11, 0x45, 0xCF, 0x52, + 0x3F, 0x85, 0x4C, 0x92, 0xFF, 0x3B, 0x74, 0xD2, 0x46, 0x32, 0xAD, 0x01, 0xF2, 0x15, 0xF2, 0xC1, 0xC2, 0x2E, 0xE0, 0x58, 0x58, 0x0D, 0xAC, 0xE8, + 0x66, 0x50, 0x91, 0x91, 0xA7, 0x12, 0x9B, 0x7E, 0xA8, 0x94, 0xE4, 0xC2, 0xA7, 0x38, 0x3C, 0x00, 0x00, 0x20, 0x82, 0x20, 0x00, 0x63, 0x89, 0x22, + 0x8C, 0xC3, 0x18, 0x40, 0x8C, 0x31, 0xE8, 0xD4, 0x00, 0x04, 0x00, 0xC5, 0xDE, 0x4C, 0x01, 0x1C, 0x07, 0x40, 0x20, 0x0A, 0x01, 0x08, 0x03, 0x30, + 0x10, 0x44, 0x22, 0x00, 0x00, 0x42, 0x10, 0x00, 0x06, 0x00, 0x03, 0xC0, 0x10, 0x22, 0x1A, 0x2A, 0x0B, 0x1C, 0xF4, 0x1F, 0x33, 0x6C, 0x4B, 0x6A, + 0x86, 0xAF, 0x48, 0xE0, 0x67, 0xA3, 0x93, 0x7E, 0x51, 0xFC, 0x82, 0xA2, 0x0C, 0x5C, 0xD9, 0xF8, 0xEA, 0xBB, 0x7A, 0xFF, 0x43, 0x27, 0x5A, 0x06, + 0x65, 0xF7, 0xB6, 0xDE, 0x25, 0xEC, 0xCD, 0x0B, 0x1F, 0x7D, 0x32, 0xB3, 0xB2, 0xAC, 0x8B, 0xF7, 0x90, 0xB7, 0x67, 0x68, 0x0F, 0x5E, 0xA4, 0xA1, + 0x4B, 0xAE, 0x55, 0x68, 0x26, 0xEA, 0x8B, 0x6B, 0xA3, 0x9C, 0xC3, 0xD2, 0xAD, 0x5F, 0x3F, 0xF0, 0xDF, 0x76, 0x4C, 0x88, 0xBD, 0x7A, 0xA5, 0xD2, + 0x56, 0xA7, 0x6C, 0x40, 0x0B, 0x71, 0x21, 0xE3, 0xF4, 0x22, 0xDA, 0x21, 0x97, 0x80, 0x2C, 0xDD, 0x0C, 0xC8, 0x29, 0xCB, 0x4D, 0x4E, 0x31, 0xD4, + 0xB4, 0x0F, 0x9C, 0x76, 0xDE, 0xB6, 0x2C, 0x6D, 0x52, 0x8C, 0x3B, 0x23, 0x21, 0xEE, 0xAF, 0x2C, 0x0A, 0xFA, 0x00, 0xA9, 0x5D, 0x1C, 0xF5, 0xEB, + 0x59, 0x8D, 0xEC, 0x09, 0xA2, 0x0F, 0xEE, 0xCE, 0xFC, 0x8C, 0xEF, 0xCE, 0x6E, 0x20, 0x63, 0x35, 0x47, 0x69, 0xC9, 0x00, 0x5C, 0xA2, 0x8B, 0x16, + 0x23, 0x61, 0xD0, 0xDB, 0xE5, 0x46, 0x5C, 0x03, 0x75, 0x50, 0xA7, 0x66, 0x5B, 0x83, 0x1E, 0x12, 0xD9, 0xFC, 0x04, 0x98, 0xED, 0x4F, 0x22, 0x92, + 0x16, 0xFD, 0x91, 0xC3, 0xEF, 0xC6, 0x6A, 0x89, 0x67, 0x78, 0x90, 0x3D, 0x71, 0x85, 0x1E, 0x78, 0x2A, 0x67, 0xDA, 0xE7, 0x94, 0xED, 0x77, 0x1A, + 0x7A, 0x94, 0xDC, 0x4C, 0x80, 0x3A, 0x46, 0xEA, 0x82, 0x24, 0xFD, 0xDE, 0x35, 0xC8, 0xF2, 0xD7, 0x7B, 0xA7, 0xD8, 0xFD, 0x4B, 0x68, 0x1A, 0x9B, + 0x2A, 0x1C, 0xCF, 0xAD, 0xBE, 0xAF, 0x38, 0xD1, 0xEE, 0x9A, 0x69, 0x91, 0xE1, 0x79, 0x9F, 0x81, 0x43, 0x51, 0xD9, 0x1F, 0xFC, 0xFB, 0x2E, 0x13, + 0x8B, 0x3E, 0xC3, 0x9F, 0x96, 0xFA, 0xCB, 0xEA, 0x98, 0xD4, 0x8D, 0x7F, 0x4A, 0xBF, 0x6D, 0xE2, 0x1B, 0x3C, 0xB4, 0x32, 0x7B, 0xE7, 0x79, 0x99, + 0xE1, 0xDD, 0x60, 0x17, 0x36, 0x60, 0x44, 0xCF, 0x59, 0xBD, 0xDB, 0xE5, 0x7F, 0x2D, 0xCE, 0x98, 0xFB, 0x47, 0x17, 0x86, 0xE9, 0xB4, 0xF1, 0xE8, + 0x1F, 0xA9, 0xED, 0x56, 0xC1, 0x12, 0x3F, 0x67, 0xCA, 0xA3, 0xB8, 0x65, 0x48, 0x4F, 0x78, 0x9E, 0xDA, 0x7D, 0x19, 0x22, 0x0A, 0xED, 0xE5, 0x9F, + 0xEE, 0xEA, 0x2D, 0x63, 0x10, 0xEC, 0x94, 0x9A, 0x4E, 0x75, 0x6B, 0x4F, 0xCD, 0x08, 0x0E, 0x7F, 0x81, 0x40, 0xFC, 0x70, 0x9E, 0x63, 0x08, 0xF8, + 0x82, 0xB3, 0x0F, 0x2A, 0x8B, 0x3F, 0x06, 0x72, 0xAA, 0xF7, 0x23, 0x2C, 0x14, 0xD3, 0x4B, 0xC8, 0x67, 0xF9, 0x5C, 0x34, 0xD9, 0xDF, 0x3B, 0xE5, + 0x6E, 0xD7, 0x6D, 0x09, 0xEE, 0x1D, 0x17, 0x4A, 0xCE, 0x24, 0xBB, 0x5F, 0x66, 0xC7, 0x44, 0xD7, 0x8D, 0x50, 0x1E, 0x49, 0xEA, 0xE4, 0x59, 0x79, + 0x93, 0x54, 0x23, 0xDD, 0x9A, 0x56, 0x5A, 0x6D, 0x9F, 0x65, 0x08, 0xD7, 0x93, 0x34, 0x50, 0xB6, 0x99, 0x2D, 0xBA, 0x62, 0x55, 0x0E, 0x5C, 0xAC, + 0xCA, 0xC5, 0x42, 0xF3, 0xC6, 0x73, 0xDF, 0x88, 0xFE, 0x1A, 0xB0, 0xE5, 0xB1, 0x3A, 0xB1, 0x49, 0x50, 0x6C, 0xF5, 0x71, 0x7B, 0xC8, 0x39, 0xED, + 0x2A, 0x10, 0x33, 0x0E, 0x07, 0xAB, 0xCB, 0xAA, 0x1F, 0xAE, 0xC4, 0xC4, 0x2A, 0x4C, 0x60, 0xCC, 0xAA, 0x46, 0xCA, 0xA8, 0xED, 0x9B, 0x9D, 0xAA, + 0xF9, 0xED, 0xB0, 0x68, 0xD9, 0x90, 0x82, 0x0D, 0x70, 0xFF, 0x8E, 0x89, 0x9A, 0x09, 0xBF, 0x12, 0x9A, 0x6B, 0xBE, 0x37, 0x2D, 0x47, 0x8B, 0x0A, + 0x5C, 0xB3, 0x65, 0x56, 0xC0, 0xBB, 0x02, 0x32, 0xDD, 0xB8, 0x3C, 0xF3, 0x7C, 0x02, 0x33, 0x09, 0x6E, 0x3A, 0x33, 0x21, 0x5F, 0xEE, 0xF7, 0x11, + 0xFA, 0xBF, 0x34, 0xA5, 0xDC, 0x83, 0xAE, 0x3D, 0x63, 0x77, 0xD9, 0x45, 0xEC, 0x06, 0x1C, 0xFB, 0xB2, 0x8F, 0xF1, 0x55, 0x79, 0x37, 0xC6, 0x3F, + 0x0B, 0x9C, 0xD1, 0x73, 0x6B, 0xC3, 0x72, 0x6B, 0x17, 0xA0, 0xAB, 0xFD, 0x36, 0x6A, 0x96, 0xC3, 0xFB, 0x86, 0x3E, 0x50, 0x97, 0x22, 0xF1, 0xFB, + 0xED, 0xEA, 0xF0, 0x6F, 0x2A, 0xBD, 0x18, 0xEA, 0x24, 0x8F, 0x21, 0xA6, 0x6B, 0xC9, 0x2D, 0xDC, 0x30, 0x60, 0xCA, 0xDD, 0x8B, 0xBC, 0x76, 0x91, + 0xB7, 0x7E, 0xA7, 0x68, 0xFF, 0xF4, 0x56, 0x0E, 0x55, 0xBE, 0xBA, 0xD5, 0x31, 0x76, 0xA2, 0x6F, 0x94, 0xBA, 0x52, 0x14, 0x98, 0x08, 0x51, 0x7D, + 0x33, 0x5C, 0x57, 0x3F, 0x20, 0xD9, 0x0C, 0x30, 0xEF, 0x6E, 0x7C, 0x17, 0xD2, 0x03, 0x46, 0x8A, 0x40, 0x25, 0x17, 0x56, 0x21, 0x3A, 0xE2, 0xED, + 0xC8, 0xC5, 0xC0, 0x00, 0xB4, 0x8F, 0xD2, 0xA9, 0xD6, 0xFC, 0xE8, 0xCD, 0xB6, 0xFE, 0xCC, 0x4A, 0xCC, 0x72, 0x68, 0x9B, 0xB5, 0x0A, 0xC9, 0xFA, + 0xF4, 0xEA, 0x66, 0x98, 0x0F, 0x5B, 0x55, 0xF5, 0x6A, 0x98, 0x79, 0xDB, 0xA0, 0xBF, 0x95, 0x47, 0xAE, 0x77, 0xD6, 0x2A, 0x1C, 0x48, 0xD0, 0xBB, + 0xE3, 0xFB, 0x34, 0xB5, 0x44, 0x7D, 0xDB, 0xBC, 0x2B, 0x58, 0x39, 0xB0, 0x76, 0xCC, 0x54, 0x6D, 0x4B, 0x60, 0x3E, 0x5C, 0x70, 0x0E, 0xF0, 0x60, + 0x63, 0xB7, 0xF8, 0x24, 0x73, 0x1D, 0xF1, 0x5A, 0xB3, 0xAD, 0xD1, 0x81, 0xD1, 0xDD, 0xC0, 0xEE, 0x15, 0x95, 0x21, 0x53, 0x64, 0xD6, 0xAA, 0xDA, + 0xEF, 0x33, 0x9D, 0x31, 0x6B, 0x79, 0x6B, 0x90, 0xF3, 0xE7, 0x85, 0x3B, 0x8C, 0xC2, 0xF6, 0x28, 0x35, 0x10, 0xBA, 0xDA, 0x50, 0x53, 0xF4, 0xB6, + 0xB6, 0x46, 0xEB, 0xCD, 0xB1, 0xBF, 0x62, 0xD7, 0x99, 0xDC, 0x00, 0xF6, 0x5B, 0x94, 0xA7, 0x72, 0xC5, 0x1C, 0xA6, 0xC5, 0x2E, 0x0C, 0x2E, 0xCD, + 0xF4, 0x20, 0xEE, 0xEE, 0xBF, 0x19, 0x96, 0xF7, 0x77, 0x7B, 0xA6, 0x03, 0x86, 0x97, 0x8B, 0x50, 0x0C, 0x15, 0x93, 0x43, 0x29, 0xC6, 0x7E, 0xD5, + 0x93, 0x7B, 0x1D, 0x6A, 0x5E, 0x2F, 0x21, 0xA7, 0x5F, 0xB0, 0x72, 0xF7, 0x54, 0x7F, 0x63, 0xEA, 0x6D, 0x3B, 0x1B, 0xA9, 0xEE, 0x6C, 0xCC, 0xAE, + 0x47, 0xAF, 0xA2, 0xF2, 0x36, 0x83, 0x89, 0xA5, 0xEC, 0xEA, 0x6D, 0xBE, 0x48, 0x63, 0xD0, 0xA2, 0x1E, 0x81, 0x56, 0x81, 0x76, 0x9E, 0x9F, 0xFE, + 0xBD, 0xAD, 0xA0, 0x2C, 0x18, 0x3C, 0x71, 0x01, 0xF0, 0x93, 0x2E, 0x71, 0x8C, 0xCE, 0x17, 0x71, 0xC6, 0x77, 0xCF, 0x96, 0x54, 0x90, 0xB5, 0xB9, + 0x0E, 0x7D, 0x09, 0xF9, 0xDF, 0x31, 0xE9, 0x87, 0xD9, 0xA2, 0x55, 0xA0, 0x77, 0xAB, 0x68, 0xD1, 0x31, 0xD6, 0xBD, 0x84, 0xA3, 0x94, 0x20, 0x76, + 0xB7, 0x90, 0xA3, 0x2B, 0x31, 0x88, 0x04, 0xBF, 0xBF, 0x7F, 0x2A, 0xBF, 0x39, 0xA0, 0x9D, 0x47, 0xF8, 0xE1, 0xB5, 0x9C, 0x19, 0x76, 0xF2, 0x50, + 0xC7, 0xEB, 0x74, 0x28, 0x47, 0xB2, 0x41, 0x62, 0x28, 0x4C, 0x93, 0x51, 0x03, 0x81, 0xE1, 0xA5, 0x3F, 0x10, 0xD9, 0x12, 0xA0, 0x51, 0x44, 0x12, + 0xFC, 0x35, 0x8B, 0x0E, 0xAE, 0x96, 0xF6, 0x97, 0x70, 0xF3, 0x80, 0x01, 0x96, 0xBD, 0x66, 0x22, 0xE8, 0xD5, 0x06, 0x51, 0x7B, 0x6D, 0xB5, 0xEE, + 0x9E, 0xF9, 0x1B, 0xAE, 0xDD, 0x5D, 0x66, 0xDD, 0xF5, 0x88, 0xF9, 0xCC, 0x9B, 0xB6, 0x4B, 0x84, 0x27, 0xDE, 0x61, 0xC1, 0xB3, 0xAB, 0xF1, 0x34, + 0xDD, 0x5C, 0x1D, 0xC2, 0xA9, 0xD8, 0xC2, 0x3B, 0xCA, 0xB0, 0xBF, 0xD3, 0x03, 0xCA, 0x0C, 0xEF, 0x24, 0x97, 0xE3, 0x7E, 0x72, 0xED, 0x33, 0xC1, + 0x5F, 0xA0, 0x01, 0xAD, 0x6B, 0x63, 0x75, 0x07, 0x77, 0x9B, 0x20, 0x1B, 0xFF, 0x50, 0xB2, 0x3F, 0xBC, 0x55, 0xCF, 0xEC, 0x66, 0xD9, 0xAC, 0xA7, + 0x34, 0xBC, 0x01, 0x97, 0x37, 0x23, 0x09, 0xF0, 0xAA, 0xDD, 0x15, 0xD4, 0x7B, 0xD3, 0xCC, 0x38, 0xF2, 0xBC, 0x4A, 0xAB, 0x71, 0x33, 0x35, 0x1F, + 0xDA, 0x86, 0x8F, 0xA8, 0x06, 0x1A, 0xDB, 0x8C, 0x62, 0xDE, 0x36, 0xD2, 0x83, 0x57, 0x17, 0x87, 0x28, 0x16, 0x64, 0xF8, 0xC5, 0x8E, 0x0D, 0x54, + 0xCC, 0x3E, 0x59, 0x89, 0xB1, 0x81, 0x7A, 0xF4, 0x33, 0xC2, 0xB8, 0x5D, 0x4D, 0x64, 0xAE, 0xC6, 0x49, 0xC2, 0xE2, 0xA3, 0x40, 0x27, 0xDC, 0x99, + 0x12, 0x76, 0x44, 0xE4, 0x68, 0x76, 0xD5, 0x2F, 0xD6, 0xBC, 0x04, 0x11, 0x14, 0x04, 0x8B, 0xCA, 0xED, 0xA5, 0x72, 0xB1, 0xCE, 0x59, 0xFA, 0x42, + 0x6C, 0xC4, 0x9B, 0x2F, 0xD6, 0x4A, 0x91, 0x39, 0xCF, 0xEE, 0x41, 0xEA, 0x2F, 0x8C, 0x0D, 0x26, 0xF4, 0xBD, 0x4B, 0xA1, 0xE3, 0x79, 0xC9, 0xAF, + 0xD9, 0x5F, 0x9C, 0x37, 0xB1, 0xF2, 0x23, 0x4A, 0x36, 0x0B, 0xDC, 0xBB, 0xE7, 0x3E, 0xD4, 0x0A, 0xD7, 0x52, 0xE7, 0xFF, 0xE4, 0xDA, 0xC7, 0xD1, + 0xB3, 0x1D, 0x7D, 0x9F, 0xCF, 0x0C, 0xCE, 0xF1, 0x86, 0x0A, 0x21, 0x98, 0xD1, 0x1A, 0xE5, 0x7D, 0x62, 0x6F, 0x60, 0x83, 0xB9, 0xF9, 0xC7, 0x45, + 0xB2, 0x57, 0x55, 0xA4, 0x5E, 0x03, 0x6E, 0x5B, 0x28, 0xB4, 0x16, 0x72, 0xFE, 0x3A, 0x87, 0x82, 0xB7, 0x06, 0xA9, 0x24, 0xA5, 0xEB, 0x95, 0x76, + 0xF1, 0x8D, 0xF1, 0x10, 0xF7, 0x3C, 0xB6, 0x7C, 0x1F, 0x0D, 0x79, 0xCB, 0x3B, 0xC3, 0xD7, 0x72, 0xD0, 0xD9, 0xB5, 0x67, 0xA9, 0xD2, 0xF5, 0x60, + 0x85, 0x5B, 0x25, 0xAE, 0x63, 0xD1, 0xE0, 0x06, 0x10, 0xC7, 0x57, 0x6E, 0x44, 0x17, 0x76, 0x33, 0x07, 0x70, 0x2C, 0xDB, 0xA6, 0x95, 0xD9, 0xC8, + 0xC9, 0x91, 0xA3, 0x39, 0x2D, 0xCB, 0x32, 0xCC, 0x9F, 0x72, 0x7E, 0xB8, 0xAA, 0x53, 0xE0, 0x6E, 0x64, 0x1F, 0x6C, 0xF5, 0x56, 0x63, 0xA5, 0xA3, + 0x8C, 0x8B, 0x9A, 0x8C, 0xCA, 0xD6, 0xD8, 0xF9, 0x31, 0x13, 0xD8, 0x50, 0x38, 0x3E, 0xA6, 0xEF, 0x8F, 0xD1, 0x7B, 0x54, 0xB6, 0xFE, 0x44, 0xAB, + 0x8B, 0x8F, 0x96, 0xAB, 0x75, 0x46, 0x39, 0x6F, 0xEB, 0x60, 0x07, 0x83, 0x05, 0xD7, 0xBC, 0x09, 0xBE, 0xB6, 0x69, 0x0C, 0xA9, 0x6F, 0x43, 0xEF, + 0xCE, 0xCD, 0xCF, 0x45, 0x77, 0x73, 0xF3, 0x37, 0xBF, 0xC1, 0xE3, 0xDD, 0x3A, 0x14, 0x27, 0x1C, 0xD9, 0x88, 0x86, 0xD4, 0x80, 0xBD, 0xD5, 0x32, + 0x78, 0x18, 0xFF, 0x50, 0xDD, 0x5B, 0xA3, 0x37, 0x45, 0xBB, 0xF5, 0x20, 0xC9, 0xBB, 0x24, 0x36, 0x26, 0xA4, 0x02, 0x3B, 0x1E, 0x7A, 0xA2, 0xE6, + 0xEF, 0x1A, 0xFD, 0x48, 0x77, 0xE2, 0xB0, 0xE7, 0x79, 0xDC, 0x3D, 0xCC, 0xAE, 0xEE, 0x96, 0x6A, 0x70, 0x9B, 0x8A, 0x8F, 0x05, 0xF8, 0xFE, 0x38, + 0x7B, 0x7A, 0xE7, 0x2C, 0x72, 0xF8, 0xEF, 0xAE, 0x11, 0x3B, 0x2A, 0x17, 0x14, 0xE3, 0xED, 0xF4, 0xFC, 0xAD, 0x07, 0x75, 0xA5, 0x35, 0x6A, 0xC7, + 0xAA, 0x11, 0x5F, 0x5B, 0x03, 0xEB, 0x4B, 0x93, 0xF2, 0x78, 0xEB, 0xB5, 0xAF, 0xB4, 0xA2, 0x5A, 0x69, 0x7B, 0xEE, 0x00, 0x0D, 0xC3, 0x3B, 0x1D, + 0xBA, 0xEE, 0x3B, 0x4D, 0x8E, 0x31, 0x47, 0x58, 0xCB, 0xA6, 0x36, 0xE7, 0x0C, 0xCA, 0x77, 0xA7, 0x64, 0xD0, 0x80, 0x97, 0x8B, 0x2D, 0x02, 0xF1, + 0xB7, 0xFC, 0x94, 0xC9, 0x60, 0xB7, 0xF2, 0x85, 0x36, 0x8C, 0xB6, 0xA6, 0xA2, 0x35, 0x0B, 0x5F, 0xFF, 0x02, 0x11, 0xD1, 0x77, 0x95, 0xA9, 0x3B, + 0x14, 0x92, 0x1C, 0xF4, 0xF0, 0xDE, 0xE5, 0xAD, 0xC9, 0x94, 0x0E, 0x15, 0x03, 0x1D, 0x93, 0x02, 0x53, 0x37, 0xE0, 0x3B, 0xEB, 0x13, 0x5A, 0xAC, + 0x44, 0x79, 0xD9, 0xC6, 0xDC, 0xF0, 0x19, 0xCA, 0xC7, 0xAD, 0xD7, 0xBA, 0xA2, 0x8D, 0x6E, 0xAD, 0xED, 0xB9, 0x03, 0xD2, 0x23, 0xD0, 0x4A, 0xE3, + 0x80, 0xDE, 0x5D, 0x73, 0xD9, 0x34, 0xD7, 0xA9, 0xF0, 0xCE, 0x0A, 0x44, 0x47, 0x71, 0xB8, 0xAD, 0x7E, 0xC5, 0x37, 0xB1, 0xDD, 0xB1, 0x89, 0x3D, + 0xA9, 0x39, 0xC1, 0x3C, 0xEC, 0xAC, 0xCF, 0xC1, 0x6A, 0xE0, 0x1A, 0x3F, 0x7C, 0x81, 0x72, 0xD8, 0x29, 0xCB, 0x4C, 0xCF, 0x9C, 0xB9, 0xB9, 0x44, + 0x18, 0x12, 0x6B, 0xEE, 0xBB, 0xBA, 0xD6, 0xE4, 0xC6, 0x48, 0x53, 0xA7, 0xD6, 0xEE, 0xB4, 0xEF, 0x3E, 0x3C, 0x0F, 0x66, 0x06, 0x9A, 0x2C, 0xB0, + 0x18, 0x72, 0x27, 0xDD, 0x0B, 0xD6, 0x02, 0xD4, 0xE0, 0xEC, 0xB4, 0x5C, 0x1F, 0x13, 0x5E, 0x6B, 0x46, 0xAD, 0x6D, 0x86, 0x83, 0x5F, 0xA6, 0x65, + 0xAA, 0x8D, 0x31, 0x94, 0x46, 0x02, 0x28, 0x80, 0x28, 0x82, 0x0C, 0xC1, 0xF9, 0xC5, 0xBD, 0xC4, 0xDF, 0xC9, 0x21, 0x92, 0x87, 0x9B, 0xD8, 0xC8, + 0xCC, 0xFB, 0x36, 0xB0, 0xA0, 0x6F, 0x2E, 0x3B, 0xB9, 0x0A, 0xD2, 0xCA, 0xE0, 0xC4, 0x75, 0xB1, 0xB0, 0x3D, 0x67, 0xB8, 0xBF, 0xAF, 0x2F, 0x4F, + 0xE7, 0xB7, 0x03, 0xD6, 0x0E, 0x74, 0x9A, 0xCE, 0x92, 0x75, 0xF9, 0x59, 0x94, 0x90, 0x06, 0x1B, 0x59, 0x8B, 0x8F, 0x68, 0x0B, 0x9A, 0x7D, 0x79, + 0xC9, 0xD4, 0xC7, 0xA3, 0x1D, 0x50, 0x98, 0x35, 0x4D, 0x89, 0xFD, 0xF2, 0xFE, 0xE7, 0xB2, 0xF9, 0x0F, 0x97, 0xB1, 0x3F, 0x69, 0x32, 0x21, 0x86, + 0xF1, 0x71, 0xBF, 0xE2, 0x71, 0x52, 0xE7, 0xEC, 0xAB, 0x2D, 0xDF, 0x56, 0x71, 0x63, 0xE6, 0x72, 0x98, 0xB7, 0x22, 0x3C, 0x2E, 0xAC, 0xBB, 0xFC, + 0xF4, 0x30, 0x84, 0x5E, 0x9F, 0x75, 0xFE, 0xCF, 0x10, 0xC1, 0xBA, 0xBD, 0xF8, 0xB3, 0x66, 0x7E, 0x7B, 0xB1, 0xCC, 0xF0, 0xD5, 0xF6, 0xAE, 0x6B, + 0xF0, 0x2F, 0xC0, 0x86, 0x54, 0xEF, 0x54, 0xA0, 0xFB, 0x8F, 0x8F, 0x5A, 0x21, 0x2D, 0xBB, 0xBB, 0x47, 0xD1, 0x5A, 0x90, 0x0C, 0xB6, 0xDC, 0x36, + 0x6F, 0x8E, 0x36, 0xF0, 0xB3, 0x48, 0x09, 0x36, 0x8C, 0x2C, 0xE2, 0xE6, 0xA0, 0xB4, 0xA0, 0xE7, 0x9C, 0x8E, 0xD0, 0xDA, 0xF1, 0x1E, 0x47, 0x57, + 0x68, 0x8B, 0xA2, 0xD7, 0x57, 0x1A, 0x62, 0xC3, 0x37, 0x22, 0xFD, 0xC2, 0x58, 0xB1, 0x5E, 0x47, 0xEA, 0x3C, 0x5D, 0xAC, 0xFB, 0x6D, 0x85, 0x6A, + 0x76, 0x61, 0xA1, 0x1A, 0x6D, 0x6F, 0x14, 0x18, 0xEC, 0x95, 0x8E, 0x29, 0xF9, 0x9E, 0x7B, 0x1A, 0x04, 0x96, 0x38, 0x5A, 0xB0, 0x8B, 0xE6, 0x32, + 0x9C, 0x69, 0x44, 0x5C, 0x8D, 0x35, 0x8B, 0x69, 0x09, 0x2C, 0xE0, 0xF1, 0x8C, 0x05, 0xAD, 0x6A, 0x4C, 0x53, 0x4B, 0xD7, 0x55, 0xF1, 0x86, 0x0E, + 0x35, 0xB4, 0x0F, 0x9D, 0x34, 0x4A, 0xD1, 0x7A, 0x87, 0x1E, 0x7A, 0xE0, 0x61, 0x70, 0xD0, 0xA6, 0x51, 0x06, 0xC5, 0x74, 0x23, 0x67, 0x98, 0x1A, + 0x1C, 0x15, 0x3C, 0x64, 0xF4, 0x8B, 0x8B, 0x94, 0xE7, 0x23, 0x04, 0xC2, 0xF2, 0x06, 0x89, 0x42, 0x23, 0xE7, 0x86, 0x42, 0x9B, 0xF3, 0x77, 0x15, + 0xA0, 0x0B, 0xC3, 0x15, 0x22, 0x3C, 0x5B, 0x8A, 0xB0, 0x9A, 0x35, 0x10, 0x8F, 0xD4, 0x31, 0xBD, 0x2D, 0x01, 0x7F, 0xD6, 0x55, 0xB4, 0xA7, 0x80, + 0x64, 0x29, 0xF9, 0x86, 0xC9, 0xA9, 0xEB, 0xCD, 0x1F, 0x18, 0xEB, 0x18, 0xAE, 0x97, 0xCC, 0xCD, 0x99, 0x61, 0x1D, 0xA3, 0x7A, 0x6B, 0x5B, 0xAF, + 0xAD, 0x95, 0xEA, 0x1B, 0x46, 0x10, 0x25, 0xD7, 0x4C, 0x33, 0x4F, 0xE0, 0x86, 0xA7, 0x3D, 0xF5, 0x2C, 0xA0, 0x23, 0x92, 0x86, 0x5E, 0x51, 0x47, + 0x66, 0x3E, 0xF0, 0xBC, 0x46, 0x46, 0x99, 0x75, 0xFD, 0x4D, 0x2C, 0xC1, 0x17, 0xA6, 0x1B, 0x0F, 0x26, 0xE4, 0x14, 0x80, 0x57, 0xC4, 0xD0, 0x7F, + 0x90, 0x18, 0x22, 0x95, 0xC0, 0x28, 0x05, 0xF8, 0x5C, 0x4C, 0xBD, 0xC7, 0xFA, 0x36, 0x75, 0xAB, 0x8C, 0x40, 0x8C, 0xCE, 0xFB, 0x9B, 0x06, 0x30, + 0x0F, 0x67, 0x00, 0xDE, 0x21, 0x52, 0xA2, 0x3D, 0x9F, 0xCE, 0x01, 0x28, 0x35, 0xC6, 0xDA, 0xD2, 0xA9, 0xD7, 0x95, 0xCE, 0x04, 0x02, 0xD7, 0x08, + 0x66, 0x41, 0x74, 0x14, 0x23, 0x0A, 0xB7, 0x0A, 0x95, 0x95, 0x66, 0x52, 0x28, 0x08, 0x1A, 0x8D, 0xD9, 0xF4, 0xA3, 0x1B, 0x0E, 0x74, 0x9C, 0x3B, + 0x0D, 0xE8, 0xD5, 0x30, 0xB5, 0x70, 0x52, 0xCD, 0x4E, 0xF5, 0x21, 0x44, 0x92, 0x17, 0xD5, 0x51, 0x2A, 0x62, 0x7C, 0x9A, 0xFD, 0x3A, 0xB2, 0xC0, + 0x0E, 0x93, 0x23, 0xCB, 0xEE, 0xB1, 0x23, 0xDF, 0xAD, 0x64, 0xAD, 0x14, 0x15, 0xD8, 0x03, 0x9A, 0xD1, 0x78, 0xAD, 0xB5, 0x97, 0x11, 0x3D, 0x1C, + 0x6C, 0xB5, 0xCF, 0x8F, 0x73, 0xBA, 0x58, 0x06, 0xB4, 0xFA, 0xD2, 0x7E, 0x1B, 0x04, 0x8C, 0x6B, 0x38, 0xC6, 0xD8, 0x77, 0xBF, 0x56, 0x8F, 0x38, + 0x46, 0x7C, 0x1B, 0xF5, 0x0D, 0x80, 0x40, 0x50, 0x31, 0xE2, 0xA0, 0xD4, 0xE2, 0x9A, 0x99, 0x6E, 0x5B, 0xC3, 0x07, 0x1A, 0x92, 0x88, 0x54, 0xA7, + 0xF6, 0xFC, 0x1C, 0xAB, 0x9C, 0x38, 0x3B, 0xEF, 0xF3, 0xDA, 0xDB, 0x49, 0x81, 0xB3, 0x42, 0x58, 0x69, 0x3C, 0x4E, 0xC7, 0x7A, 0x6A, 0x6D, 0xBF, + 0xDD, 0xFA, 0xCC, 0xB9, 0xBA, 0x39, 0x8A, 0x47, 0xF6, 0x7F, 0xEE, 0xE6, 0x8F, 0x98, 0x29, 0x62, 0x13, 0x97, 0xC8, 0xA1, 0x74, 0x77, 0xA4, 0x1F, + 0xD3, 0x5E, 0x1D, 0x3C, 0xD1, 0xE4, 0x31, 0x22, 0x1E, 0x8F, 0x22, 0x16, 0x76, 0x9F, 0x87, 0xEC, 0x04, 0x30, 0xE7, 0x34, 0x10, 0x03, 0x9B, 0x5E, + 0xEE, 0x0B, 0xCA, 0x31, 0xE7, 0xC4, 0x09, 0x9A, 0x56, 0xF4, 0x6D, 0x3D, 0xAE, 0x3E, 0xAB, 0xB6, 0xA1, 0xCB, 0x3E, 0xA4, 0xAD, 0x91, 0xEB, 0x80, + 0x80, 0x02, 0xB7, 0x7D, 0xAB, 0xD8, 0x1B, 0xC3, 0x6D, 0x00, 0x41, 0x79, 0x8C, 0xF7, 0xB9, 0x25, 0xF8, 0xB2, 0xF8, 0xFE, 0x75, 0xB4, 0x58, 0x6D, + 0x04, 0xAE, 0x10, 0x2B, 0x8B, 0xF1, 0x5F, 0x3A, 0x4F, 0x1E, 0x29, 0xF3, 0xB2, 0xD0, 0x68, 0xED, 0x80, 0x5A, 0x85, 0x15, 0x1D, 0xF6, 0xF7, 0xC0, + 0xC6, 0xF8, 0x15, 0xD7, 0x03, 0x66, 0x3F, 0xD0, 0x6A, 0x9A, 0x05, 0xD0, 0xF2, 0xFA, 0x43, 0xDF, 0x60, 0xAE, 0x59, 0x3B, 0x9F, 0x4F, 0x0A, 0xB9, + 0xA4, 0xDF, 0xDD, 0xDE, 0xE8, 0x35, 0xA4, 0xDE, 0xBF, 0xBA, 0x00, 0x66, 0x42, 0x66, 0xD1, 0xF0, 0x57, 0x84, 0xAA, 0x71, 0xB3, 0x6A, 0x13, 0x46, + 0x0C, 0x35, 0x94, 0xB3, 0x22, 0x68, 0xAB, 0xAD, 0xE2, 0x33, 0xF3, 0x47, 0xE5, 0x34, 0xC3, 0x8E, 0xCB, 0x62, 0x9E, 0xAC, 0xCC, 0xB3, 0x69, 0x99, + 0x06, 0x13, 0xF7, 0xF5, 0xC4, 0x7C, 0xA4, 0xF6, 0x71, 0x5A, 0x7E, 0x3F, 0x5A, 0xE7, 0x53, 0x97, 0x20, 0xB8, 0x99, 0x36, 0x6C, 0xB9, 0x9E, 0x9F, + 0xEB, 0x1C, 0x60, 0xAA, 0xA6, 0x77, 0xAE, 0x7A, 0x27, 0xA2, 0x76, 0xED, 0x43, 0x3B, 0xE9, 0x30, 0xB8, 0x81, 0xB5, 0xC9, 0xE5, 0xBE, 0x2F, 0xB8, + 0x9A, 0x91, 0x7B, 0xA1, 0x0D, 0x0C, 0xC7, 0xFA, 0x15, 0xDE, 0xF2, 0x3A, 0xD4, 0x29, 0xD3, 0xDA, 0x65, 0xA2, 0x9D, 0xA9, 0xE5, 0xA2, 0x48, 0xEB, + 0x20, 0x3E, 0x8E, 0xB5, 0x25, 0x66, 0x06, 0xCB, 0x6C, 0x33, 0xB6, 0xC5, 0xFE, 0x40, 0x8E, 0x0D, 0xC0, 0x21, 0xBF, 0x0A, 0x0B, 0x29, 0xDC, 0xAD, + 0x8B, 0xF2, 0xB9, 0x10, 0x7E, 0x9A, 0xCD, 0xA6, 0x80, 0x9C, 0x4A, 0xD1, 0x8A, 0x89, 0xDC, 0x40, 0xB5, 0x18, 0xB5, 0x48, 0x5D, 0x4C, 0x4C, 0xD2, + 0x5C, 0x4A, 0x2A, 0x36, 0x63, 0x81, 0x4D, 0xAF, 0xD3, 0x25, 0x48, 0xEC, 0xEE, 0x41, 0xD3, 0x78, 0x23, 0x06, 0xFE, 0xDE, 0xF5, 0x8D, 0xF8, 0xAD, + 0x33, 0x23, 0x56, 0x73, 0x79, 0x52, 0x10, 0x00, 0xBA, 0x41, 0xB0, 0x42, 0x97, 0x09, 0x24, 0x27, 0x39, 0x3A, 0x0E, 0xF4, 0x17, 0x8B, 0xDA, 0xF2, + 0xA7, 0x9E, 0xC8, 0xF7, 0xF4, 0x50, 0x5A, 0xCE, 0x67, 0x25, 0x20, 0x4C, 0xCB, 0x6E, 0xF0, 0x92, 0xD8, 0x66, 0xD5, 0x5E, 0x9D, 0x6A, 0x45, 0x3A, + 0xFE, 0x57, 0x66, 0xC2, 0x27, 0x7B, 0x6C, 0xD6, 0x9F, 0x1E, 0xBB, 0x90, 0xEB, 0x00, 0xF4, 0xBF, 0x8C, 0xB4, 0xB5, 0x39, 0x10, 0xD9, 0x96, 0x2E, + 0x97, 0x05, 0x0D, 0x78, 0xC8, 0x5E, 0x7F, 0xCB, 0x24, 0xCF, 0x12, 0x37, 0xA6, 0xAC, 0xDA, 0x2E, 0x55, 0x35, 0xA5, 0x68, 0x60, 0x69, 0x90, 0xDD, + 0x76, 0x34, 0x32, 0x69, 0xA7, 0x8E, 0xAD, 0xD9, 0xA2, 0x3F, 0x85, 0x54, 0x8C, 0x94, 0x8A, 0x8B, 0xCE, 0x7B, 0x59, 0xE5, 0x88, 0x0A, 0x71, 0xCA, + 0xB7, 0x95, 0x39, 0x78, 0x73, 0x5C, 0xB7, 0x2F, 0x11, 0xB1, 0x47, 0x47, 0x15, 0x7E, 0x34, 0x4E, 0x21, 0xD0, 0x77, 0x5D, 0x51, 0xF9, 0xD7, 0x23, + 0xEC, 0x36, 0x8C, 0x76, 0xD4, 0x3D, 0x79, 0xC5, 0xFD, 0x53, 0x15, 0xB1, 0xA0, 0x0E, 0xD5, 0x25, 0x0F, 0x32, 0x14, 0x2D, 0xC7, 0xB4, 0x8A, 0x9B, + 0x79, 0xBE, 0x70, 0xE4, 0xE0, 0xDC, 0xCB, 0xB1, 0x19, 0x13, 0xE6, 0xC5, 0x9D, 0x39, 0xB8, 0x17, 0xDB, 0xF1, 0x2F, 0xAA, 0x9C, 0x4B, 0x3C, 0x86, + 0x94, 0x71, 0x3A, 0xEE, 0x0C, 0x12, 0x71, 0x35, 0x0A, 0xB4, 0x41, 0x0A, 0x16, 0xCB, 0xAE, 0x76, 0x42, 0x31, 0x41, 0x9E, 0x60, 0xB8, 0x73, 0x0B, + 0x51, 0x72, 0xB3, 0x74, 0xC9, 0xFB, 0xB2, 0x19, 0x31, 0xC1, 0x41, 0x86, 0xFA, 0x2C, 0x60, 0xE8, 0xB2, 0x1F, 0xA9, 0x30, 0xE6, 0xFF, 0x51, 0x80, + 0xAD, 0x20, 0x86, 0xDA, 0xA0, 0xB6, 0xA6, 0xD2, 0x26, 0x30, 0xB2, 0xB3, 0xF3, 0x45, 0x31, 0xBE, 0x56, 0xC4, 0xD1, 0xD8, 0x7C, 0x5F, 0x9A, 0xD6, + 0x28, 0x62, 0x61, 0x76, 0x60, 0x70, 0x21, 0x2D, 0xEC, 0x37, 0x83, 0x3A, 0x4F, 0x70, 0x8D, 0xB4, 0x04, 0xA7, 0x54, 0x6F, 0xF8, 0xCF, 0xD8, 0x6E, + 0x38, 0x7A, 0x37, 0xB4, 0x4D, 0x70, 0x1C, 0x7C, 0x5A, 0x09, 0x7E, 0x68, 0x08, 0x1A, 0xAA, 0xE7, 0xEF, 0x71, 0x9A, 0xFD, 0x0B, 0xFA, 0x89, 0x2E, + 0x10, 0xCA, 0x7E, 0xA1, 0x0A, 0x7A, 0x6A, 0xA1, 0x98, 0xE4, 0x53, 0xAD, 0x5F, 0xD7, 0xF6, 0x49, 0x31, 0x70, 0x2B, 0x82, 0xE8, 0xA4, 0x02, 0xD7, + 0xA7, 0xA3, 0x76, 0xE9, 0x70, 0x53, 0x2C, 0x2C, 0x0E, 0x30, 0x39, 0x26, 0xA0, 0x34, 0x9D, 0x87, 0x3F, 0x6B, 0xA7, 0x4C, 0x36, 0x8E, 0xE8, 0x67, + 0xA8, 0xFB, 0x0A, 0x2F, 0x7F, 0x20, 0x6A, 0xF2, 0x0F, 0x6D, 0xF3, 0x6C, 0xD7, 0x86, 0x10, 0xF0, 0xC6, 0xB1, 0xA8, 0x78, 0x99, 0x2A, 0xB0, 0x69, + 0x68, 0xD4, 0xD3, 0x4B, 0xA4, 0x4E, 0x27, 0xDB, 0x56, 0x01, 0xA6, 0xFD, 0x6F, 0x2D, 0xEC, 0x5B, 0x9A, 0x54, 0x97, 0xC6, 0x36, 0xE6, 0xEC, 0xCC, + 0x4B, 0x5C, 0x77, 0x6E, 0x74, 0xC0, 0x9B, 0x8A, 0x3B, 0xEF, 0x5D, 0xA4, 0xF3, 0x35, 0x2E, 0xBE, 0xE7, 0x2F, 0xA0, 0x34, 0xD3, 0xC9, 0x6E, 0x3E, + 0x0F, 0x3F, 0x75, 0x1E, 0xDB, 0xB2, 0xCF, 0x39, 0xC3, 0xB1, 0x53, 0x2D, 0xE6, 0xCF, 0xA9, 0x26, 0x1B, 0xCA, 0x20, 0x1A, 0xE5, 0xED, 0x5A, 0x46, + 0xAE, 0x74, 0x44, 0xC9, 0x83, 0x22, 0xB3, 0xB4, 0x15, 0x08, 0x03, 0xB6, 0x61, 0x8C, 0x90, 0x44, 0x32, 0x8A, 0x45, 0x15, 0x6C, 0xB1, 0xB2, 0x9F, + 0x70, 0x05, 0xE7, 0x67, 0x28, 0x3C, 0x97, 0x8F, 0xEA, 0x48, 0x18, 0xDE, 0x29, 0x62, 0x68, 0x01, 0x0B, 0x64, 0x6F, 0x3F, 0x7C, 0x53, 0x0D, 0x67, + 0x67, 0xAF, 0x9B, 0xDA, 0x65, 0xFD, 0xBF, 0x1D, 0x9A, 0xB0, 0xE3, 0x32, 0xF9, 0xD9, 0x99, 0x73, 0x03, 0xD5, 0xEA, 0x6E, 0xD5, 0x97, 0x74, 0x60, + 0xDF, 0x27, 0x7D, 0x2E, 0x4F, 0x09, 0x51, 0x2B, 0x9D, 0xBD, 0x8B, 0xDC, 0xB1, 0xB6, 0x4E, 0x45, 0xC8, 0xB2, 0x05, 0x4D, 0xB4, 0x8A, 0xE6, 0xD8, + 0x36, 0x86, 0xDF, 0x2C, 0x77, 0xB7, 0x94, 0x45, 0xC2, 0x0C, 0xBB, 0x6C, 0xBA, 0xDE, 0xD8, 0xB9, 0xF0, 0x33, 0x3F, 0x00, 0x39, 0xC4, 0x62, 0xA1, + 0x56, 0x9F, 0x77, 0xE7, 0x6C, 0xFE, 0x74, 0x96, 0xBB, 0xF7, 0xC6, 0xBD, 0xDB, 0x31, 0x27, 0x5A, 0x1F, 0x08, 0xE3, 0xB2, 0xA0, 0xF7, 0x00, 0xEE, + 0xA3, 0xFA, 0x85, 0x9B, 0x12, 0x92, 0x16, 0x0B, 0x20, 0xEE, 0xD6, 0x14, 0x84, 0x1F, 0xB9, 0x08, 0x3B, 0xA5, 0xAB, 0xCF, 0xBB, 0x89, 0x39, 0x46, + 0xE8, 0x12, 0xDD, 0x0C, 0x16, 0x92, 0x6E, 0x32, 0x03, 0x6E, 0x03, 0x73, 0x2F, 0x81, 0x67, 0xB2, 0xEB, 0x74, 0x49, 0x78, 0x2F, 0x5E, 0x78, 0x9F, + 0x73, 0xD8, 0xB9, 0x59, 0xDD, 0x0C, 0x47, 0x78, 0x80, 0x30, 0x0E, 0xDD, 0x3E, 0x76, 0xA5, 0x7D, 0x3B, 0x5F, 0xF3, 0x9D, 0xD5, 0x34, 0x60, 0x9B, + 0x82, 0xF1, 0xF5, 0xB8, 0x29, 0x3C, 0x45, 0xBF, 0x7B, 0x0A, 0x8D, 0x48, 0x01, 0xD1, 0xD3, 0x59, 0x59, 0x03, 0x23, 0xFC, 0xD6, 0x3C, 0xF0, 0x11, + 0xAD, 0xB2, 0xB0, 0x82, 0x22, 0x19, 0xE4, 0xD7, 0x70, 0x7F, 0x61, 0x12, 0xF4, 0x5F, 0x08, 0x42, 0x54, 0xA4, 0xC6, 0x46, 0xB4, 0x3C, 0x7D, 0x6A, + 0xDA, 0x40, 0xB1, 0x0C, 0x5B, 0x26, 0x0B, 0x9C, 0xD4, 0xD1, 0x78, 0xFB, 0xEE, 0x42, 0x32, 0xD7, 0x67, 0xEC, 0x48, 0x32, 0x1D, 0x48, 0x0E, 0xBA, + 0x5D, 0xFB, 0x51, 0x1A, 0x23, 0x3D, 0x8C, 0x56, 0x41, 0x48, 0x36, 0xED, 0xC0, 0x34, 0xE1, 0xDC, 0x11, 0xC2, 0xC6, 0x5D, 0x18, 0x63, 0x38, 0xD2, + 0x86, 0x11, 0xBF, 0x63, 0x47, 0x8C, 0x49, 0x3C, 0x36, 0xC0, 0xB8, 0xAB, 0x11, 0x47, 0x23, 0x67, 0xA3, 0x63, 0x86, 0x93, 0xF3, 0xD6, 0x77, 0x87, + 0x35, 0x45, 0x0E, 0x2D, 0x4C, 0x70, 0xBE, 0x01, 0xC7, 0xD8, 0x31, 0xC1, 0xD4, 0x87, 0xC6, 0xCD, 0xDB, 0xEC, 0x22, 0x0C, 0xD7, 0x1F, 0x09, 0x35, + 0x14, 0x3B, 0x1D, 0x28, 0x9C, 0xBC, 0x19, 0xC3, 0xF0, 0x2A, 0x07, 0xF9, 0xE9, 0xF5, 0x7D, 0x0D, 0xD8, 0x45, 0x2F, 0x95, 0xC1, 0xC4, 0x7B, 0x9C, + 0x9A, 0x9E, 0x8A, 0x7E, 0xF9, 0x9C, 0xA0, 0xA3, 0x43, 0x1E, 0x4F, 0x5B, 0xB3, 0x7D, 0x6A, 0x04, 0xFF, 0xFC, 0x10, 0xA1, 0x34, 0x4A, 0xD5, 0xE1, + 0xE9, 0x5D, 0x27, 0x4D, 0x78, 0x97, 0xB3, 0xB7, 0xA3, 0x3F, 0x4C, 0x3A, 0xDC, 0xA9, 0x7D, 0x2C, 0x1C, 0xAF, 0x57, 0x9F, 0x97, 0x52, 0xB2, 0x5A, + 0xD6, 0x5D, 0xBD, 0x9A, 0x33, 0x4A, 0x1A, 0xD3, 0xB9, 0xAB, 0xD3, 0xF3, 0xE7, 0x17, 0x14, 0xCC, 0x6F, 0xA3, 0x2B, 0xD9, 0xBA, 0xC7, 0x5C, 0x71, + 0xAE, 0x15, 0xDC, 0x9C, 0x88, 0x2E, 0xC7, 0xF8, 0x45, 0xC9, 0x7D, 0xAA, 0x8F, 0x3C, 0x88, 0x46, 0x47, 0x6C, 0x06, 0xBB, 0xE6, 0xF7, 0x44, 0x80, + 0x5E, 0x55, 0xF9, 0xA2, 0x63, 0xA3, 0x9F, 0x87, 0x1E, 0xB4, 0x71, 0xAB, 0xC6, 0x04, 0xB5, 0xE4, 0xCC, 0xD2, 0x81, 0xEA, 0x8B, 0x5A, 0xF5, 0x4C, + 0x1E, 0x7A, 0xB1, 0x7B, 0x0A, 0xF6, 0x37, 0xBC, 0x95, 0xB5, 0xB3, 0xAD, 0xDB, 0xAB, 0x2D, 0xBE, 0x32, 0xD0, 0x91, 0x53, 0x24, 0x22, 0x35, 0xD2, + 0x36, 0xA6, 0x9E, 0x97, 0xAF, 0xD5, 0xB6, 0xF8, 0x71, 0xAB, 0xF8, 0xCF, 0x7C, 0xF3, 0x6D, 0x5A, 0x93, 0x0F, 0x59, 0xBA, 0xE1, 0x04, 0x53, 0x26, + 0xF3, 0xB4, 0xB3, 0x21, 0xE6, 0xB2, 0x75, 0xEA, 0x9B, 0x36, 0x24, 0x2E, 0x4D, 0x6B, 0x79, 0xE2, 0x84, 0xEB, 0xD2, 0xFF, 0x63, 0x63, 0x89, 0xFA, + 0xEE, 0xC9, 0x28, 0x4E, 0x75, 0xD8, 0x7D, 0x68, 0x26, 0xB3, 0xF8, 0x35, 0x95, 0x34, 0xAA, 0xDC, 0x33, 0xAD, 0x7D, 0xB0, 0xC0, 0x8D, 0x76, 0x25, + 0xC3, 0x90, 0x93, 0xCD, 0x06, 0xD0, 0xB1, 0x2C, 0x86, 0xB8, 0x7D, 0x04, 0x2D, 0x6E, 0x2C, 0xBA, 0x76, 0xA5, 0x33, 0x47, 0x9B, 0x07, 0x3A, 0x4A, + 0xC9, 0x52, 0xA9, 0x19, 0xE5, 0x36, 0xBE, 0xA7, 0x2C, 0xD6, 0xF1, 0x4E, 0x4F, 0x84, 0x18, 0x10, 0xF4, 0x8D, 0xAB, 0x30, 0x30, 0x98, 0x3D, 0xB5, + 0xC8, 0x82, 0x49, 0x96, 0x63, 0x8E, 0x68, 0xCF, 0xD8, 0xC0, 0x38, 0xF2, 0x60, 0x1A, 0x39, 0x76, 0xBE, 0xE5, 0xEE, 0x86, 0x96, 0x33, 0x6C, 0x76, + 0xF4, 0xB2, 0x2B, 0x1D, 0xFD, 0x01, 0x42, 0x1B, 0x9D, 0x08, 0x7F, 0x12, 0x91, 0xD4, 0xCD, 0x21, 0xB8, 0xAD, 0xC8, 0xAA, 0x09, 0xFC, 0x8E, 0x34, + 0x4F, 0x07, 0xA3, 0x1B, 0x9C, 0x81, 0xA3, 0xB1, 0x09, 0xCE, 0x95, 0x7F, 0x64, 0x2C, 0x6E, 0x8E, 0x19, 0xDC, 0x07, 0xD0, 0x2B, 0x4D, 0x64, 0x01, + 0x12, 0x2B, 0x99, 0xAA, 0x31, 0x6E, 0xDF, 0xD1, 0x6F, 0x60, 0xDB, 0x29, 0x6E, 0x62, 0xE1, 0xE6, 0xF9, 0xDB, 0x23, 0xEC, 0xC7, 0x0C, 0x1E, 0xCF, + 0xC6, 0x01, 0x39, 0xE1, 0xA6, 0x08, 0xBC, 0x17, 0x29, 0xA7, 0xC7, 0xDB, 0x54, 0x6D, 0x3A, 0x96, 0x48, 0x5E, 0xCF, 0x6B, 0x9F, 0x47, 0x14, 0x7E, + 0x15, 0xA5, 0x27, 0x7E, 0x0F, 0xF6, 0xE7, 0xAC, 0xBD, 0x88, 0x84, 0x0E, 0x17, 0xAC, 0x02, 0xF8, 0xDE, 0x6D, 0x74, 0x6D, 0x49, 0x68, 0xEA, 0x0B, + 0x47, 0xCB, 0x3F, 0x65, 0x92, 0x75, 0x5E, 0xB5, 0x4D, 0xEE, 0xD5, 0xCB, 0xB1, 0xED, 0x5F, 0x0D, 0x7E, 0x61, 0x3C, 0xA2, 0xEC, 0x0C, 0x4F, 0x51, + 0xE2, 0x40, 0xCA, 0x6D, 0x29, 0x25, 0xBE, 0x25, 0x04, 0xFB, 0x94, 0xF6, 0x8B, 0x89, 0xA8, 0x7C, 0xE6, 0xE7, 0x91, 0x87, 0xA9, 0x86, 0xF0, 0x29, + 0x12, 0xBB, 0xEA, 0x57, 0x5C, 0xA0, 0x65, 0xAF, 0xA6, 0x62, 0xA6, 0xF0, 0xD1, 0x7E, 0x98, 0x76, 0x9C, 0xD2, 0x39, 0xDE, 0x59, 0x1F, 0xAA, 0x38, + 0x7A, 0x41, 0xA3, 0x7B, 0x50, 0x9E, 0x0C, 0x03, 0xF1, 0xAB, 0xB6, 0x2B, 0xEB, 0x1F, 0xBE, 0x70, 0x0B, 0xF4, 0x30, 0x0C, 0x85, 0x29, 0xD8, 0x92, + 0x9D, 0xF5, 0x27, 0x5D, 0xD9, 0xD8, 0xAA, 0xB9, 0x87, 0x21, 0xD7, 0xFE, 0x43, 0x5C, 0x2D, 0x59, 0xF2, 0xEC, 0x12, 0xA1, 0xBC, 0x32, 0xB8, 0xBF, + 0xC9, 0x5F, 0x54, 0xEA, 0x5F, 0xEB, 0x3E, 0x51, 0xD1, 0xA5, 0x22, 0x8F, 0x54, 0xE8, 0x15, 0xAD, 0x23, 0xC8, 0x3B, 0xE8, 0x54, 0xD4, 0x6B, 0xEC, + 0xA9, 0xE1, 0x6F, 0xD8, 0xD3, 0xA2, 0xF3, 0xF1, 0x67, 0x99, 0xBD, 0x47, 0x13, 0xFE, 0x4E, 0x23, 0xFA, 0xBA, 0xDE, 0x5F, 0x3E, 0x43, 0x3B, 0x9F, + 0x4F, 0x6B, 0x66, 0xFE, 0xAC, 0x87, 0xE3, 0x84, 0xA5, 0x46, 0x43, 0xC8, 0xDD, 0x0E, 0x55, 0xD0, 0xF2, 0x46, 0x3D, 0x4C, 0x6F, 0x87, 0x3C, 0xEC, + 0x33, 0x7D, 0xD4, 0x96, 0x0F, 0x7B, 0xF2, 0xAA, 0x59, 0x67, 0xCB, 0x42, 0xD3, 0x98, 0x3F, 0xD2, 0x10, 0x1C, 0xA7, 0x74, 0x79, 0x70, 0x6E, 0xC0, + 0x6F, 0xE6, 0x30, 0x55, 0x7F, 0x63, 0xF5, 0xD0, 0xBB, 0x14, 0x47, 0xC7, 0x01, 0x4E, 0x9D, 0xB2, 0xB4, 0xEB, 0x2C, 0xA0, 0xBF, 0x58, 0x0D, 0xD6, + 0xA7, 0x4C, 0x7A, 0xE4, 0x14, 0x6E, 0x30, 0xC1, 0xB0, 0x91, 0x38, 0x76, 0x57, 0xF7, 0xBC, 0xD7, 0x69, 0x3C, 0x14, 0x71, 0x24, 0xD9, 0xCD, 0x63, + 0xA2, 0xAB, 0x1F, 0x9B, 0x98, 0x4B, 0x61, 0xBD, 0x2D, 0x3B, 0x6B, 0x6E, 0xE7, 0xD4, 0x29, 0xC2, 0x49, 0x7F, 0xAE, 0x05, 0x66, 0xD7, 0xF1, 0x55, + 0xFC, 0x71, 0x3C, 0xAF, 0x2D, 0xF4, 0x3C, 0xF5, 0xBB, 0xFA, 0x5F, 0x07, 0x1E, 0xEF, 0xEF, 0xE0, 0x5E, 0x74, 0xC5, 0x67, 0x97, 0x37, 0xC1, 0x66, + 0xEC, 0x0E, 0x1C, 0x4D, 0x76, 0x5E, 0x7A, 0x3F, 0xB4, 0x5E, 0x29, 0xF9, 0xB0, 0xCA, 0x23, 0xA9, 0x67, 0xEC, 0xBC, 0x4D, 0xE8, 0x42, 0x56, 0x0F, + 0x6C, 0x94, 0x9C, 0x9A, 0x46, 0xE5, 0x4F, 0xF7, 0xE9, 0x11, 0xB5, 0xD6, 0x61, 0x53, 0x62, 0x74, 0x4B, 0xC8, 0xDB, 0x7F, 0x2F, 0xE2, 0xFD, 0x0B, + 0x28, 0x13, 0x1C, 0xF7, 0xC6, 0x59, 0xCA, 0x93, 0x02, 0xEE, 0x2B, 0x21, 0x3B, 0xA9, 0x0D, 0xE6, 0x0D, 0x28, 0xB1, 0xDE, 0xBB, 0x55, 0x37, 0xEA, + 0xDD, 0x16, 0xE5, 0x2A, 0x3F, 0x0A, 0x89, 0xB5, 0xA3, 0xFC, 0x91, 0x90, 0xBF, 0xA7, 0x30, 0xDB, 0xA2, 0xB2, 0xAE, 0x58, 0xDD, 0xA1, 0xEB, 0xC1, + 0x24, 0x96, 0x02, 0xEE, 0xC3, 0x9C, 0x32, 0x80, 0xBE, 0xE0, 0xE1, 0xCB, 0xD9, 0xB4, 0x3E, 0x39, 0x9F, 0xF0, 0xDC, 0x3B, 0x0C, 0xE9, 0x09, 0x5E, + 0x04, 0x73, 0x3D, 0x69, 0x98, 0xF8, 0x70, 0x59, 0x45, 0x03, 0x84, 0xAE, 0xFF, 0xEB, 0xFB, 0x10, 0xFA, 0xD3, 0x83, 0x28, 0x9B, 0x79, 0xB6, 0x6C, + 0xB1, 0x2B, 0x8D, 0xE8, 0x6C, 0xDA, 0x49, 0x0C, 0xB1, 0x5F, 0x65, 0xAE, 0x64, 0x51, 0x6E, 0xEC, 0xF2, 0x1A, 0xBC, 0x53, 0x3E, 0xA3, 0x95, 0xC3, + 0x73, 0x9A, 0x9F, 0x06, 0x96, 0x1E, 0x9D, 0x9E, 0x89, 0x94, 0x3F, 0x96, 0xFD, 0x82, 0xF9, 0x15, 0xDD, 0xD6, 0x27, 0x17, 0x44, 0xAD, 0x36, 0xEE, + 0x57, 0xDE, 0xAF, 0x45, 0x6E, 0x4A, 0x59, 0x38, 0x25, 0x7B, 0x6E, 0xB4, 0xAA, 0x3D, 0x5E, 0xA0, 0xD2, 0xB9, 0x67, 0xA3, 0x1B, 0x36, 0xC5, 0x44, + 0xFC, 0x2E, 0xDA, 0xA6, 0xC8, 0x2D, 0x86, 0x69, 0x85, 0x0B, 0x02, 0x12, 0x60, 0xAD, 0x0B, 0x51, 0x9D, 0x45, 0x5A, 0xEA, 0x5D, 0xBF, 0x49, 0x9B, + 0x67, 0xDF, 0x17, 0xFB, 0x25, 0xB3, 0xA3, 0x48, 0xC4, 0x84, 0x71, 0x7B, 0xC5, 0xE1, 0xAF, 0x94, 0xF9, 0x5B, 0x8E, 0x35, 0xF4, 0xC2, 0x8D, 0x24, + 0xC2, 0x01, 0x0E, 0x7B, 0x76, 0xF7, 0x1D, 0x61, 0x6B, 0x0F, 0x5E, 0x51, 0x75, 0x1A, 0xA4, 0x97, 0xCB, 0x3D, 0x4E, 0x8A, 0x2F, 0xB0, 0xF6, 0x46, + 0xDE, 0x48, 0x55, 0xC4, 0x38, 0x7D, 0xA9, 0xBE, 0x03, 0x0B, 0x56, 0xEA, 0x06, 0xAB, 0x15, 0xCA, 0x72, 0x59, 0x75, 0xAD, 0x7A, 0xF7, 0x53, 0xA0, + 0x26, 0x8C, 0x5E, 0xEA, 0x7A, 0x53, 0xD6, 0x5C, 0x1C, 0x1E, 0xC8, 0xA0, 0x8C, 0x6A, 0x20, 0xDD, 0x6A, 0x76, 0x49, 0x49, 0x3D, 0x37, 0x24, 0x26, + 0x3D, 0x1E, 0x34, 0x05, 0xE7, 0xAD, 0xA0, 0xCC, 0xC0, 0x13, 0x40, 0x86, 0x6A, 0x4A, 0x7B, 0x56, 0x50, 0x1D, 0x6A, 0x56, 0xCE, 0x8B, 0x1D, 0xD3, + 0x9A, 0x02, 0x4A, 0xF5, 0xA1, 0x32, 0xB5, 0x83, 0xCB, 0x6C, 0xF9, 0xF9, 0x37, 0x98, 0xD2, 0x9B, 0x8A, 0x0B, 0x54, 0x5D, 0x40, 0x49, 0x2E, 0x63, + 0xA6, 0xED, 0x49, 0xAA, 0x23, 0x99, 0x8A, 0xDF, 0x59, 0x2A, 0x83, 0x5D, 0x9C, 0x97, 0x27, 0x9C, 0xF4, 0xC6, 0x35, 0x58, 0x1D, 0x0E, 0xA0, 0xD6, + 0xC3, 0x02, 0xB8, 0xDD, 0x5C, 0x3A, 0x1D, 0x8A, 0xF6, 0x7E, 0xB4, 0xC9, 0x32, 0x4A, 0xBC, 0x8C, 0x32, 0xFC, 0x8C, 0x4B, 0xA9, 0xA3, 0x98, 0xE0, + 0x86, 0x44, 0x36, 0x67, 0x60, 0x2E, 0x03, 0xE9, 0x02, 0x77, 0xB0, 0x16, 0x6F, 0xEE, 0x0A, 0x24, 0x7B, 0xB6, 0x3B, 0x25, 0x1D, 0x38, 0x3E, 0x53, + 0xE5, 0xEF, 0x6C, 0x54, 0x1B, 0x82, 0x90, 0xD8, 0xC9, 0xE9, 0x06, 0x60, 0x2A, 0xF5, 0x03, 0x29, 0x8D, 0x44, 0x3B, 0x82, 0x89, 0xBE, 0xC3, 0xAE, + 0x8F, 0x5C, 0xF9, 0x17, 0x59, 0xB1, 0x13, 0x1E, 0xAE, 0xF6, 0x49, 0x16, 0xD5, 0xD3, 0x61, 0xE7, 0xDF, 0x9C, 0xA2, 0xD3, 0x26, 0x9D, 0xD1, 0x45, + 0xFF, 0x10, 0xC9, 0x1D, 0x1A, 0x68, 0x0B, 0xAA, 0x81, 0x5D, 0x83, 0xD0, 0x15, 0x31, 0x63, 0x95, 0x73, 0x6B, 0xED, 0x16, 0x06, 0x56, 0x83, 0x49, + 0xF6, 0xAB, 0xCD, 0x42, 0xDB, 0x25, 0x5D, 0x2C, 0x20, 0x4D, 0x61, 0xF6, 0x8A, 0xE6, 0xFC, 0x15, 0x95, 0x6E, 0x66, 0x3F, 0xE7, 0x9A, 0xB5, 0x53, + 0x53, 0x84, 0xF6, 0xCA, 0xA5, 0xA9, 0xC8, 0x32, 0x3F, 0xCD, 0xAD, 0x30, 0x7A, 0x45, 0x6F, 0x7B, 0xE8, 0xDE, 0x46, 0x5D, 0x19, 0x2B, 0x0E, 0xC2, + 0x34, 0x5F, 0x80, 0x0D, 0x02, 0x32, 0x85, 0xEE, 0xE4, 0x75, 0xCC, 0xEC, 0x4E, 0x8F, 0xF3, 0x62, 0xEF, 0x38, 0xA0, 0x47, 0x56, 0x13, 0x4D, 0x8E, + 0xEC, 0x79, 0x96, 0x5E, 0xEC, 0x82, 0x67, 0xC8, 0x9C, 0xE5, 0x63, 0x9F, 0x6D, 0x13, 0x16, 0xCD, 0xE6, 0xD7, 0xAD, 0x91, 0x19, 0x03, 0xF9, 0x35, + 0x2C, 0x48, 0xC8, 0x8F, 0x13, 0x88, 0xCD, 0xFF, 0xBB, 0x58, 0x73, 0x69, 0xB6, 0xCE, 0xE1, 0x0F, 0xA5, 0x2A, 0x83, 0x99, 0x24, 0x05, 0x83, 0x81, + 0xD1, 0x98, 0xEA, 0x5C, 0x9B, 0x18, 0x5C, 0x29, 0x7F, 0xFB, 0xEA, 0x5C, 0x2B, 0x5F, 0x06, 0xAB, 0xAC, 0xE6, 0xB7, 0x39, 0x69, 0xB3, 0x37, 0x77, + 0xA5, 0xD2, 0x5E, 0x04, 0xA5, 0xF0, 0xEB, 0x48, 0xCF, 0x76, 0x13, 0x8F, 0xEB, 0x58, 0xF4, 0xB0, 0x2D, 0x8E, 0x86, 0x7D, 0xFE, 0xA1, 0xBF, 0x0A, + 0x83, 0x3C, 0x3D, 0x46, 0x8A, 0x45, 0x1E, 0xCD, 0xC1, 0x3C, 0xE8, 0xC8, 0x14, 0xC0, 0x4C, 0x25, 0x46, 0x8D, 0x53, 0x46, 0xB8, 0x57, 0x5B, 0xA0, + 0xCB, 0xA7, 0xDD, 0x5D, 0x90, 0xFA, 0xE6, 0x21, 0x6C, 0x8D, 0xD1, 0xA8, 0x71, 0xCB, 0x08, 0x69, 0x8D, 0x5D, 0x35, 0xA2, 0x7D, 0x1F, 0xD3, 0xE2, + 0x36, 0xCE, 0x49, 0x22, 0x81, 0xEF, 0x2F, 0xAE, 0xB8, 0x22, 0x1A, 0x2C, 0x8B, 0x0A, 0xCA, 0x2B, 0x12, 0xC2, 0xE1, 0xDA, 0x47, 0xFD, 0xD3, 0x8E, + 0xB7, 0xAF, 0x5E, 0xB4, 0xBA, 0xCD, 0x1A, 0x45, 0x87, 0x9D, 0x25, 0xE9, 0xAB, 0x1B, 0xE5, 0x8D, 0xD6, 0x93, 0xF7, 0xFF, 0xD7, 0x9F, 0xAB, 0x91, + 0x00, 0x57, 0xCD, 0xD7, 0x37, 0xC3, 0xE6, 0xDD, 0x1A, 0x1E, 0xCC, 0xFD, 0xE8, 0xF5, 0x03, 0xB1, 0xD9, 0x6C, 0x6E, 0xAB, 0xDF, 0xE7, 0xC0, 0xC8, + 0x4B, 0xC1, 0x83, 0xBF, 0x43, 0x63, 0x81, 0xAE, 0x60, 0x96, 0x26, 0xE4, 0x64, 0x7A, 0x6C, 0x76, 0xD7, 0x77, 0x33, 0x3C, 0x08, 0x24, 0x64, 0x3D, + 0xD8, 0x15, 0x3D, 0x12, 0x36, 0xA8, 0x19, 0xA0, 0xA5, 0xCA, 0x8B, 0x3B, 0x2A, 0x79, 0x0D, 0x49, 0x91, 0x2C, 0x70, 0xC3, 0x58, 0x20, 0xFA, 0xDA, + 0x38, 0xD0, 0xB5, 0x03, 0x53, 0x81, 0x18, 0xE3, 0xD9, 0x34, 0xA2, 0x26, 0xBF, 0x8A, 0x2E, 0x1F, 0xDF, 0xE9, 0x59, 0x27, 0x60, 0xBD, 0xA6, 0x9A, + 0xCF, 0x99, 0x03, 0xE6, 0xCE, 0x3F, 0x1D, 0x16, 0xD1, 0xFB, 0xF6, 0xB9, 0x07, 0x98, 0x68, 0x4A, 0xB5, 0xF8, 0x49, 0xC7, 0x44, 0x52, 0xA6, 0xA4, + 0x07, 0x2D, 0xDB, 0x30, 0x5F, 0x49, 0x9B, 0x4A, 0x67, 0x97, 0x48, 0x02, 0xB5, 0x1D, 0x70, 0x96, 0x60, 0x90, 0x0E, 0x9B, 0x60, 0xF2, 0xCE, 0xBB, + 0x76, 0xF4, 0xDE, 0xC4, 0xE3, 0x2A, 0x8A, 0xCE, 0x86, 0x41, 0xA7, 0x5D, 0x60, 0xF3, 0x80, 0x18, 0x0C, 0xA5, 0x37, 0xEE, 0x33, 0x9A, 0x33, 0xA9, + 0xE0, 0xD8, 0x99, 0x61, 0x31, 0xE1, 0x8F, 0x2C, 0xB9, 0x00, 0x73, 0xCF, 0xBB, 0x90, 0xC4, 0x4F, 0xED, 0x02, 0xD3, 0xD5, 0xB4, 0x7E, 0x8D, 0x39, + 0x9D, 0xB8, 0x95, 0x8A, 0xC7, 0x68, 0x7B, 0xCB, 0xCC, 0x8D, 0x30, 0x35, 0xBA, 0x1E, 0xE0, 0x0E, 0x55, 0x11, 0x7B, 0x46, 0x03, 0xB4, 0xBE, 0x77, + 0x51, 0xC2, 0xD1, 0x47, 0x5A, 0x33, 0x7C, 0x72, 0xFE, 0x13, 0x2C, 0x0F, 0xA2, 0x57, 0x32, 0x5E, 0x67, 0x06, 0x8B, 0x03, 0x88, 0x92, 0xED, 0x0E, + 0x58, 0x64, 0xE5, 0xAC, 0x89, 0x6E, 0xA1, 0xE4, 0xBD, 0xAE, 0x81, 0x91, 0xC1, 0xF3, 0x60, 0x35, 0x5C, 0x70, 0x6C, 0x61, 0xCD, 0x99, 0xA4, 0xE9, + 0x6A, 0x7C, 0x7B, 0x7A, 0x40, 0xF3, 0x3F, 0xE0, 0xD4, 0x40, 0xD8, 0x44, 0x7C, 0x46, 0x83, 0xDD, 0x20, 0xF5, 0xF9, 0xA0, 0x3D, 0xC5, 0x47, 0x0C, + 0xB2, 0x48, 0x15, 0xEB, 0xEB, 0x35, 0xD3, 0xA9, 0x08, 0x67, 0x3A, 0xBD, 0x8D, 0x39, 0x93, 0x5F, 0xDF, 0xEC, 0x88, 0x3E, 0x91, 0x61, 0x07, 0x2A, + 0x42, 0x23, 0x7E, 0x3E, 0x76, 0xAE, 0x40, 0x27, 0x73, 0x8F, 0x76, 0x42, 0xBE, 0x63, 0x4B, 0x69, 0x2D, 0xCD, 0xC1, 0x9D, 0xE3, 0x82, 0x94, 0x73, + 0x3C, 0x90, 0xC9, 0xDE, 0xC5, 0xB9, 0xCC, 0xB5, 0x9D, 0xEB, 0x7D, 0xB0, 0x63, 0x7C, 0x71, 0x67, 0xDB, 0x1B, 0x51, 0xF7, 0x9B, 0xBB, 0x8D, 0xD0, + 0xDF, 0x95, 0xF6, 0xE9, 0xE2, 0x97, 0xAD, 0x8D, 0x45, 0xA3, 0x33, 0x50, 0xB2, 0x3E, 0xDB, 0xCD, 0xF2, 0x90, 0xC8, 0xF5, 0xF8, 0x96, 0xD8, 0x0F, + 0xDE, 0x7C, 0x03, 0x12, 0xD3, 0x01, 0x2E, 0xE6, 0xE3, 0x1F, 0x89, 0x42, 0xE1, 0xF2, 0x79, 0xDE, 0x87, 0x6D, 0x40, 0x0D, 0x92, 0xEB, 0x1B, 0xC4, + 0x06, 0x87, 0xF9, 0x09, 0x30, 0x81, 0x33, 0xB0, 0xAC, 0x54, 0x60, 0xDF, 0x02, 0x54, 0xDF, 0xAE, 0x34, 0xEC, 0x87, 0xD7, 0xC0, 0xD2, 0xBE, 0x2B, + 0x86, 0xFE, 0x72, 0x58, 0xF7, 0xEA, 0xCC, 0xE2, 0x9A, 0x69, 0x80, 0x52, 0xB5, 0x6E, 0x2A, 0xEE, 0x28, 0xB3, 0x75, 0xB4, 0x31, 0xDF, 0x88, 0xE6, + 0x62, 0xF7, 0x67, 0xBC, 0x99, 0x26, 0x9D, 0x51, 0x16, 0xEF, 0x74, 0xAA, 0xD0, 0xF2, 0x5C, 0xE5, 0x1F, 0x7C, 0x57, 0x30, 0x3B, 0x03, 0x75, 0xC0, + 0x0A, 0x26, 0x4C, 0x9B, 0x27, 0xD7, 0xDA, 0x97, 0x2C, 0x05, 0x4A, 0xCA, 0x38, 0x00, 0x2C, 0x66, 0x04, 0x0D, 0x34, 0xDE, 0xB1, 0x7C, 0x4C, 0xD7, + 0xA6, 0xDE, 0x06, 0x14, 0x34, 0xDB, 0x00, 0x53, 0xD0, 0xFF, 0x09, 0x66, 0x71, 0x90, 0x47, 0x59, 0x8B, 0x0C, 0xF1, 0x0F, 0x7F, 0x2C, 0x94, 0x8F, + 0x01, 0x74, 0x2F, 0x9B, 0x01, 0xEC, 0xD2, 0x8D, 0xF9, 0x5F, 0x2A, 0x75, 0x05, 0xED, 0x79, 0xA5, 0xDD, 0xEB, 0x2D, 0x21, 0x93, 0x88, 0x19, 0x8F, + 0x7D, 0x6E, 0x1F, 0x59, 0xFA, 0x8E, 0xB6, 0x1C, 0xA3, 0xD6, 0x5D, 0x59, 0x3A, 0x58, 0x8A, 0xAC, 0xF3, 0xC5, 0x91, 0x88, 0x1D, 0x0A, 0x22, 0x6C, + 0x22, 0x7E, 0xAC, 0x55, 0x45, 0x03, 0x2B, 0x06, 0xDA, 0x8D, 0x5C, 0x38, 0x8C, 0xED, 0xDC, 0x0F, 0x1A, 0x15, 0xEA, 0x97, 0x96, 0x8E, 0xC5, 0xEA, + 0x49, 0xF1, 0xA5, 0xDB, 0x45, 0xD6, 0xF1, 0xCC, 0x28, 0xC2, 0x63, 0x0B, 0x87, 0x0A, 0xCA, 0xD7, 0x92, 0x22, 0xED, 0x8F, 0x99, 0xD1, 0x91, 0xF3, + 0x64, 0x04, 0x7F, 0xB6, 0x5C, 0x14, 0xB1, 0x68, 0xE3, 0x88, 0x06, 0xEB, 0x74, 0xE2, 0xE9, 0xE1, 0xB8, 0x16, 0xAD, 0x3D, 0xC1, 0x9B, 0x06, 0xEF, + 0x1A, 0xC7, 0xC9, 0x02, 0x54, 0x8A, 0x49, 0xF4, 0x3D, 0x6D, 0x48, 0x79, 0x43, 0x24, 0x04, 0xB8, 0xC3, 0x3C, 0x43, 0x69, 0x46, 0xBD, 0x66, 0xD0, + 0xB3, 0xC1, 0x18, 0xEE, 0x7B, 0xCA, 0x0B, 0xE1, 0xF8, 0xB8, 0xBC, 0x2C, 0xA6, 0x5E, 0x54, 0x57, 0x11, 0xCB, 0x8B, 0x4A, 0x94, 0xB0, 0xC9, 0xB0, + 0x0C, 0x70, 0xFC, 0x36, 0xE5, 0x01, 0xC2, 0x10, 0x12, 0x6F, 0xEF, 0x7D, 0x22, 0xC2, 0x26, 0xFA, 0xCA, 0x4F, 0x61, 0xA6, 0x1A, 0x9B, 0x0B, 0xEF, + 0x4C, 0x70, 0x17, 0x70, 0x43, 0xB8, 0x9B, 0x96, 0x65, 0xCE, 0xD7, 0xEE, 0x65, 0x74, 0xA8, 0x39, 0xB0, 0x26, 0xD2, 0xEE, 0xE7, 0xA6, 0x6C, 0x04, + 0x65, 0xF8, 0x62, 0x4D, 0xB0, 0x03, 0x66, 0xE3, 0x73, 0x72, 0x1D, 0xA7, 0x6D, 0xB0, 0x7C, 0xED, 0xB6, 0xBA, 0x71, 0x96, 0x93, 0xB2, 0x35, 0xEC, + 0x3F, 0xB6, 0x27, 0x0A, 0x51, 0x77, 0xA5, 0xBC, 0xF5, 0x4F, 0xDC, 0xA2, 0x69, 0xF7, 0xA6, 0x1E, 0x52, 0xC3, 0x0A, 0x51, 0x5D, 0xB1, 0x53, 0x2D, + 0x1D, 0x3C, 0xEB, 0xB2, 0x91, 0x4A, 0xFF, 0xC9, 0xD1, 0x98, 0x78, 0x08, 0xD6, 0x7C, 0xFD, 0x8C, 0x95, 0x64, 0x90, 0x38, 0xA9, 0xAC, 0x7F, 0xE8, + 0x4A, 0x88, 0x7A, 0x94, 0xEE, 0x89, 0x7A, 0x9B, 0x88, 0x0D, 0x82, 0xA0, 0x43, 0xCB, 0x60, 0x31, 0x14, 0xD9, 0x2E, 0x94, 0x7B, 0x1E, 0x35, 0xF6, + 0xC9, 0xBA, 0xD4, 0xF0, 0x15, 0xEC, 0x89, 0x01, 0x33, 0x50, 0x91, 0x3C, 0xD6, 0xD1, 0x1E, 0x60, 0x36, 0xDA, 0x3C, 0x23, 0x4C, 0x63, 0x87, 0xBF, + 0xC1, 0x96, 0x18, 0x35, 0x05, 0x54, 0x6C, 0x5A, 0x16, 0xF4, 0x7A, 0x86, 0x6C, 0x2C, 0x95, 0x71, 0x0A, 0x2B, 0xF0, 0x0E, 0xBF, 0x36, 0xD8, 0x71, + 0xEF, 0x7F, 0xEF, 0x28, 0x95, 0xDA, 0xAC, 0x84, 0xDD, 0x8D, 0xEB, 0x55, 0xBA, 0x06, 0x6C, 0xD4, 0x4E, 0xEC, 0xE1, 0x52, 0xF0, 0x8C, 0x82, 0xE6, + 0x31, 0xA4, 0xC5, 0xB9, 0x91, 0x71, 0x20, 0x77, 0x4E, 0x00, 0x61, 0x3D, 0xBF, 0xC9, 0x88, 0xAE, 0x8F, 0xE6, 0xF3, 0x2B, 0x64, 0x96, 0x41, 0x52, + 0xCB, 0x03, 0x1E, 0x8A, 0xCF, 0xB1, 0x71, 0xD4, 0xC3, 0x68, 0xD9, 0x52, 0x98, 0xF9, 0x3C, 0xD2, 0x6A, 0x28, 0x9B, 0xF3, 0xF4, 0x90, 0xDD, 0x20, + 0x83, 0xD8, 0x88, 0xC8, 0xFA, 0x2D, 0x71, 0x84, 0xF6, 0x3E, 0xC5, 0x9B, 0xC1, 0x7C, 0x55, 0x5A, 0x77, 0xF1, 0x3E, 0x50, 0x0D, 0x12, 0x8B, 0x2F, + 0x7F, 0xC8, 0x5F, 0xA3, 0xFD, 0x1C, 0x7C, 0xB0, 0xE6, 0x42, 0x9C, 0xAC, 0x78, 0x07, 0x11, 0x6B, 0x63, 0xB3, 0xBF, 0x43, 0xA7, 0x98, 0x6E, 0xF3, + 0x41, 0x88, 0xDF, 0x5F, 0x4E, 0x4F, 0xB1, 0x6F, 0x7D, 0x5B, 0x70, 0x8B, 0x15, 0x3B, 0x2E, 0x35, 0xE6, 0xD5, 0x52, 0xE3, 0xB6, 0xF6, 0x00, 0x29, + 0x42, 0xB9, 0x26, 0x8B, 0x10, 0x9E, 0x64, 0x7F, 0x8F, 0xEB, 0x18, 0xF2, 0xE9, 0x22, 0x41, 0x33, 0xD3, 0xD4, 0x07, 0xB7, 0x05, 0x2C, 0x65, 0x98, + 0x70, 0xAB, 0x23, 0x0C, 0xF1, 0x47, 0xCD, 0xE9, 0x5E, 0x5D, 0xC1, 0xAD, 0xFF, 0xE4, 0x27, 0xEC, 0xD6, 0x8A, 0x10, 0x73, 0xD3, 0x95, 0x17, 0x8B, + 0x15, 0x52, 0x82, 0x0D, 0x23, 0x72, 0x7F, 0x33, 0x14, 0xAB, 0x59, 0xEE, 0x3C, 0x21, 0x52, 0x66, 0x8E, 0x71, 0x1A, 0x0C, 0x9F, 0x31, 0xF9, 0x23, + 0xFA, 0x96, 0xD9, 0x87, 0x41, 0x8A, 0x4A, 0x69, 0x22, 0xDE, 0xB5, 0x0F, 0x77, 0x2E, 0xF3, 0x0E, 0xBA, 0xCC, 0x48, 0xD5, 0x28, 0x7D, 0x54, 0xED, + 0xE6, 0xB1, 0x3B, 0x73, 0x30, 0x27, 0x76, 0xE9, 0x2E, 0xD1, 0xB6, 0xF3, 0x8E, 0xFA, 0xFD, 0x24, 0x9F, 0x22, 0xF7, 0xD3, 0x91, 0x14, 0x75, 0x7C, + 0x02, 0x28, 0x86, 0x99, 0x89, 0xB9, 0xD1, 0xD9, 0x99, 0x36, 0xE7, 0x6C, 0x1D, 0x30, 0x66, 0x1E, 0x6E, 0x2A, 0x60, 0x58, 0x31, 0x5C, 0xF5, 0x8C, + 0x6F, 0xE8, 0x45, 0x66, 0x8F, 0x8E, 0x58, 0x9C, 0x1E, 0xE4, 0xC8, 0x12, 0xCE, 0xD8, 0xB8, 0xB2, 0x15, 0x9A, 0x8D, 0x7B, 0xA6, 0xEF, 0xA9, 0x33, + 0x83, 0xC7, 0x56, 0x31, 0x0E, 0x9B, 0x0E, 0x95, 0xD6, 0xA0, 0xE0, 0xB9, 0x31, 0xB1, 0x2B, 0x15, 0x5D, 0x56, 0x0A, 0xED, 0xB8, 0x75, 0xED, 0xBE, + 0x34, 0xBA, 0xC7, 0xA9, 0x23, 0x1B, 0x0D, 0xA9, 0x7E, 0xBF, 0x72, 0x48, 0xE5, 0x80, 0x55, 0x25, 0xC3, 0xB4, 0x17, 0x6A, 0xFC, 0xCA, 0x08, 0xC6, + 0x50, 0x4F, 0x26, 0xE6, 0x81, 0x2B, 0x59, 0x16, 0xC3, 0xA1, 0x7E, 0xAE, 0x33, 0x0E, 0x2C, 0x54, 0x96, 0x2A, 0xFA, 0x67, 0xB7, 0xB7, 0x95, 0xAF, + 0x0F, 0xC1, 0x90, 0x75, 0xAC, 0xA9, 0x75, 0x6A, 0xCD, 0x2D, 0xE2, 0xED, 0x01, 0x5A, 0xBD, 0x02, 0xAC, 0x97, 0x2C, 0xC5, 0xFA, 0x2D, 0x7C, 0xE2, + 0xCE, 0xFC, 0xA0, 0x8C, 0x38, 0x1A, 0x70, 0xAF, 0x1C, 0x3F, 0xF8, 0xD8, 0x93, 0xB4, 0xF9, 0xE8, 0x60, 0x8F, 0xCC, 0x86, 0x7A, 0x33, 0x8F, 0x03, + 0xD3, 0xF1, 0xD5, 0x93, 0x0B, 0x0F, 0x38, 0xD0, 0x72, 0xCB, 0x95, 0xE0, 0xB5, 0x33, 0xC7, 0xCD, 0x18, 0xA9, 0x65, 0x5C, 0xA0, 0xEA, 0x8B, 0x81, + 0xBD, 0xD6, 0x7D, 0xB6, 0x6B, 0xA3, 0x88, 0x32, 0x25, 0x33, 0xA2, 0x51, 0xEE, 0x7A, 0x9E, 0xC8, 0x83, 0xD9, 0x08, 0xA9, 0x19, 0xF4, 0xF6, 0x19, + 0x1C, 0x32, 0xD7, 0x0A, 0x75, 0x07, 0xE6, 0x40, 0x9A, 0x83, 0x46, 0x0B, 0xCC, 0xF2, 0xBB, 0xEC, 0x97, 0x1F, 0x10, 0x0F, 0xDB, 0x31, 0x48, 0x39, + 0xEF, 0x46, 0xA8, 0x71, 0x5B, 0xC1, 0x60, 0xD1, 0x0E, 0x6B, 0x48, 0x2F, 0x65, 0x51, 0xBD, 0x67, 0x56, 0x59, 0x9C, 0xF1, 0x4B, 0xC7, 0x13, 0xC4, + 0xF2, 0x19, 0x13, 0xA4, 0xB5, 0x83, 0xD2, 0x39, 0x60, 0x9B, 0x46, 0x47, 0xBA, 0xCB, 0x44, 0x40, 0x99, 0xBF, 0x17, 0xFD, 0xD4, 0x67, 0x62, 0x08, + 0x3E, 0x21, 0xE0, 0x2D, 0x67, 0x64, 0x0F, 0x1C, 0xF5, 0x5A, 0x1E, 0x83, 0x23, 0x67, 0x45, 0xBB, 0x74, 0xF6, 0x48, 0xF1, 0x03, 0x97, 0x61, 0xA4, + 0x7F, 0x60, 0xC5, 0x0B, 0xCF, 0x68, 0x86, 0x82, 0x4C, 0x64, 0x64, 0x6F, 0x1A, 0x41, 0x8B, 0x7A, 0xD5, 0x64, 0x1A, 0x76, 0x31, 0x6A, 0x29, 0x15, + 0xFD, 0x19, 0x45, 0xE3, 0xF9, 0x04, 0x66, 0x39, 0x90, 0x2C, 0xE8, 0xE6, 0x58, 0x65, 0x8C, 0x4C, 0x94, 0x98, 0xD9, 0xC4, 0xDC, 0x83, 0xE9, 0xA6, + 0xB1, 0x4C, 0x9C, 0x43, 0x93, 0x78, 0x38, 0x10, 0xDC, 0xB6, 0xCD, 0xC2, 0x70, 0x3B, 0xFB, 0x39, 0xBF, 0xFB, 0x3E, 0x0A, 0x2A, 0x2C, 0xCD, 0x11, + 0xE7, 0x25, 0x0D, 0x5B, 0x44, 0xCA, 0x0A, 0x2A, 0xE2, 0x71, 0x7A, 0x5B, 0x15, 0x34, 0x0C, 0xAE, 0xA9, 0x12, 0x00, 0x82, 0x34, 0xED, 0x73, 0xC7, + 0x2B, 0xB8, 0x10, 0x36, 0xF4, 0xD5, 0x86, 0x89, 0xEF, 0x8C, 0x6F, 0x42, 0xD2, 0x3A, 0x52, 0x4C, 0xB9, 0xF2, 0xCC, 0x9B, 0xEC, 0x28, 0xD0, 0x68, + 0x4C, 0x02, 0x4F, 0xF1, 0xF1, 0xBC, 0x64, 0x92, 0xF7, 0x77, 0x0C, 0x37, 0xFE, 0x4F, 0xC8, 0x30, 0xD0, 0x6C, 0x56, 0xE3, 0xDF, 0x68, 0x74, 0x2B, + 0xD1, 0x8C, 0x8B, 0x63, 0x9B, 0x6E, 0x7A, 0xA4, 0x80, 0x3D, 0x18, 0x73, 0x09, 0xC9, 0xFE, 0x4F, 0xA6, 0x64, 0xEB, 0xBD, 0x56, 0x7C, 0xD2, 0xB4, + 0xE8, 0x89, 0x69, 0x18, 0x93, 0x5E, 0x6F, 0x6A, 0x13, 0xB5, 0x1F, 0x05, 0x90, 0x90, 0x3D, 0x17, 0xAF, 0xB0, 0x77, 0x7E, 0x63, 0x0D, 0x35, 0xD6, + 0xE1, 0xB5, 0x1C, 0xC7, 0xF8, 0xBC, 0xF2, 0x71, 0xD1, 0x0D, 0xAD, 0xB1, 0xAC, 0x4C, 0x20, 0x9D, 0x63, 0x20, 0xB2, 0x75, 0x82, 0xED, 0x7C, 0x37, + 0x7D, 0x74, 0x68, 0x85, 0xA5, 0x1E, 0x74, 0x62, 0x21, 0xDE, 0xD9, 0xB8, 0x73, 0x80, 0x59, 0x25, 0x0A, 0x2A, 0xDA, 0x32, 0xCE, 0x69, 0x0E, 0x65, + 0x46, 0x01, 0xF9, 0x8B, 0x6F, 0x8D, 0xF3, 0xD0, 0xE5, 0xDA, 0xC0, 0xE0, 0xD8, 0x31, 0x85, 0x9D, 0x8A, 0x6A, 0x3D, 0xF1, 0x4A, 0x14, 0xA8, 0x24, + 0xE5, 0x86, 0x34, 0xE5, 0xF9, 0x57, 0x33, 0x81, 0xB5, 0x2A, 0x65, 0x05, 0x4C, 0x4C, 0x0C, 0x25, 0x46, 0xCD, 0x24, 0x0A, 0x2D, 0xF9, 0xE6, 0x6D, + 0x9C, 0x66, 0x94, 0x08, 0xCB, 0xE4, 0x31, 0x49, 0xD1, 0x48, 0xC3, 0xA3, 0xF5, 0xA4, 0x11, 0xFB, 0x12, 0xCD, 0x75, 0x20, 0x44, 0xDD, 0x63, 0x16, + 0xC1, 0x15, 0xB5, 0x8B, 0xF2, 0xE1, 0x61, 0x96, 0x9B, 0x69, 0x32, 0x25, 0x1B, 0xD8, 0x22, 0x6E, 0x87, 0x49, 0x93, 0xD6, 0x6B, 0x1E, 0xA6, 0x3D, + 0x40, 0x76, 0xA8, 0x21, 0x88, 0x88, 0x18, 0x3B, 0x4A, 0x36, 0x96, 0x31, 0xD3, 0xB1, 0x2F, 0xA7, 0xA2, 0xC0, 0x52, 0x5A, 0x8F, 0xF3, 0xCC, 0x68, + 0x64, 0xE7, 0x86, 0x1C, 0xA6, 0xE3, 0x08, 0x37, 0x22, 0x0A, 0x70, 0x18, 0x64, 0x5A, 0xE7, 0xB5, 0x3E, 0x92, 0x48, 0x3E, 0x62, 0x86, 0xB9, 0x1B, + 0x04, 0x34, 0x8B, 0x33, 0x13, 0x0D, 0x05, 0x85, 0x8D, 0xBF, 0x9E, 0xD2, 0x1C, 0x74, 0x68, 0x68, 0x49, 0xAA, 0x34, 0x1D, 0x25, 0x20, 0xD0, 0x69, + 0x52, 0x3B, 0xA4, 0x25, 0x8C, 0xEE, 0xCC, 0x2E, 0xC6, 0x64, 0x2A, 0xF7, 0x32, 0x3C, 0x28, 0x8D, 0x55, 0xA0, 0x98, 0x32, 0x5A, 0xE0, 0x3E, 0x07, + 0x70, 0x13, 0x3B, 0x69, 0x58, 0xC7, 0xCE, 0x97, 0x03, 0x43, 0x1F, 0x79, 0x03, 0x83, 0x48, 0xBB, 0xD2, 0x9C, 0xBE, 0x5E, 0x2C, 0xE3, 0x4C, 0xCE, + 0xE3, 0x2B, 0x82, 0xC1, 0x8C, 0x76, 0x10, 0xFA, 0x4C, 0xDB, 0x40, 0x64, 0x20, 0x89, 0xE9, 0x24, 0x4B, 0xEF, 0x5B, 0xE3, 0x59, 0x5A, 0xCE, 0xFB, + 0xC2, 0xF5, 0xB9, 0xEB, 0xCB, 0x35, 0x12, 0x3D, 0x2A, 0x54, 0x92, 0x91, 0x5A, 0x39, 0x66, 0x65, 0x62, 0x7D, 0x70, 0x6D, 0x62, 0x82, 0x3A, 0xA8, + 0x66, 0xD1, 0x71, 0x72, 0x93, 0xF3, 0x68, 0x5A, 0x03, 0x49, 0x12, 0xC4, 0xF8, 0x5C, 0xC5, 0xE3, 0x9E, 0x65, 0x00, 0xC4, 0x34, 0xC1, 0x7B, 0xBF, + 0x61, 0xD4, 0x82, 0xE5, 0x93, 0x68, 0x09, 0xD3, 0x38, 0x27, 0x71, 0x94, 0x7C, 0xC8, 0x72, 0x82, 0x1D, 0xE0, 0x02, 0xF9, 0xCC, 0xC9, 0x19, 0x7C, + 0x37, 0x4F, 0x68, 0xFB, 0xBA, 0x41, 0xB0, 0xF1, 0x2A, 0x6E, 0xED, 0xB9, 0x4C, 0xBB, 0xEF, 0x6B, 0x8B, 0x6F, 0xF1, 0x6C, 0x4E, 0xFB, 0x02, 0x99, + 0xD6, 0x6F, 0xD2, 0x61, 0xB1, 0xD0, 0xD6, 0x62, 0x64, 0x08, 0xCE, 0x10, 0x42, 0x73, 0xD0, 0x8F, 0x80, 0x7C, 0xC5, 0x4A, 0x03, 0x92, 0xE7, 0x38, + 0x9A, 0xA1, 0xBF, 0x1B, 0x70, 0x1D, 0x4E, 0x6A, 0x78, 0x5F, 0xE3, 0xEF, 0xD5, 0xD1, 0x5E, 0xD7, 0xD2, 0x2C, 0x00, 0x5E, 0xED, 0xC1, 0xA1, 0xAA, + 0x20, 0x68, 0x80, 0xE5, 0x50, 0xC4, 0x6D, 0xDD, 0x12, 0x19, 0x54, 0x5A, 0x64, 0x18, 0x85, 0xD9, 0x99, 0x03, 0x16, 0xE2, 0x0F, 0x36, 0x68, 0xC2, + 0x74, 0xA5, 0x9F, 0x27, 0x3E, 0x2C, 0x47, 0x1E, 0x27, 0xFA, 0xEA, 0xEA, 0xCB, 0x6F, 0x03, 0x8A, 0xC3, 0xC1, 0xB9, 0xCF, 0x17, 0x61, 0x06, 0xD0, + 0x7D, 0xC6, 0x61, 0xDD, 0x60, 0x37, 0x81, 0xBA, 0xE2, 0xFA, 0x8F, 0xAB, 0xD0, 0xB6, 0xDD, 0x36, 0xF6, 0x92, 0x9A, 0x06, 0xF3, 0x92, 0x85, 0xA5, + 0xAE, 0x1E, 0x53, 0x8D, 0x3C, 0x84, 0xBB, 0x29, 0x64, 0x13, 0x83, 0xC0, 0x26, 0x2A, 0xB1, 0xBD, 0x8E, 0x15, 0xC0, 0xC8, 0x60, 0xDC, 0xB2, 0xB0, + 0xD9, 0xA8, 0x8F, 0xC4, 0x36, 0x18, 0x57, 0x32, 0x1F, 0x0D, 0x77, 0x32, 0x88, 0xF7, 0x19, 0x5F, 0x25, 0x36, 0x19, 0xE9, 0xD2, 0x1B, 0x4B, 0x3A, + 0x55, 0x81, 0x00, 0x6B, 0x8F, 0xDE, 0xCC, 0xFC, 0x2E, 0xBB, 0x8D, 0xAA, 0x70, 0x5C, 0xE4, 0xE5, 0xB6, 0xAC, 0xF7, 0xE2, 0x12, 0x21, 0xEA, 0x1E, + 0x1A, 0x90, 0xC0, 0xE0, 0xC8, 0xB7, 0x89, 0x31, 0x9E, 0xB0, 0x39, 0x97, 0xFB, 0xA2, 0x08, 0xD0, 0x7D, 0x66, 0x40, 0x1D, 0xE0, 0xDD, 0x87, 0xB3, + 0x7C, 0x6F, 0xBB, 0x77, 0x86, 0x57, 0xD2, 0x5D, 0xE7, 0x09, 0x6D, 0x31, 0xFB, 0x9F, 0x39, 0x23, 0x02, 0x61, 0x43, 0x92, 0x2B, 0x87, 0x2B, 0xBE, + 0xBB, 0xC6, 0xC4, 0x82, 0x9A, 0xCC, 0xA1, 0x59, 0xD3, 0xE8, 0x49, 0xB7, 0x40, 0x40, 0x14, 0xB4, 0x8E, 0xFA, 0x41, 0xB2, 0x0A, 0xB6, 0x4C, 0x05, + 0xAC, 0x1D, 0xAD, 0xF5, 0x00, 0xDE, 0xA9, 0x18, 0x0A, 0x09, 0x0C, 0xC8, 0x18, 0xE3, 0xF8, 0x37, 0xCB, 0x0A, 0x57, 0x9F, 0x5D, 0xE4, 0xA7, 0x52, + 0x11, 0xB1, 0xDC, 0x26, 0x5D, 0xBB, 0x43, 0xEC, 0x4F, 0x23, 0x3A, 0x20, 0x59, 0x83, 0xA9, 0xAC, 0xCC, 0x4D, 0xB9, 0x39, 0x39, 0x04, 0x6E, 0x35, + 0x1E, 0x8E, 0x79, 0x26, 0xF1, 0xD4, 0x60, 0x7C, 0x4F, 0x64, 0xDB, 0x71, 0x07, 0xD9, 0x10, 0x20, 0x49, 0xDE, 0xA1, 0x09, 0xA6, 0x91, 0x2C, 0x70, + 0x63, 0x5B, 0x7E, 0x4F, 0xB1, 0xB5, 0xBE, 0xBD, 0xA9, 0x7A, 0xBF, 0x47, 0x14, 0xD6, 0x0F, 0xF5, 0xC2, 0x72, 0x62, 0x9F, 0x9A, 0x84, 0x89, 0xEF, + 0x7F, 0xA3, 0xC1, 0x85, 0xDD, 0xEF, 0xEF, 0x19, 0x26, 0x0D, 0x4C, 0x38, 0x9C, 0xE1, 0xE6, 0x9C, 0x1D, 0x5A, 0x9B, 0xBE, 0xAC, 0xDA, 0x3A, 0x9A, + 0xA2, 0x55, 0xB3, 0x1C, 0x21, 0xDC, 0x53, 0xBA, 0xF3, 0x80, 0x05, 0x72, 0x33, 0xD0, 0x29, 0x7D, 0xEF, 0xAC, 0xD3, 0x98, 0x8C, 0x39, 0xB1, 0x4D, + 0xDC, 0xDC, 0x6C, 0x84, 0x0E, 0xF6, 0x31, 0x6F, 0xA3, 0x21, 0x12, 0xA3, 0xE9, 0x34, 0x29, 0xFA, 0xFE, 0x7B, 0xCB, 0x98, 0x97, 0xC6, 0x10, 0x50, + 0x9C, 0x46, 0x63, 0x7B, 0x70, 0xCC, 0xA2, 0x73, 0x88, 0x2E, 0x2D, 0x52, 0x19, 0x4D, 0x5F, 0x47, 0x31, 0x0D, 0x58, 0x9F, 0x39, 0xA9, 0xB9, 0x0D, + 0xBE, 0xBD, 0x9D, 0x71, 0xB8, 0x9E, 0x5B, 0x94, 0x7C, 0x29, 0xCB, 0x1C, 0xED, 0xA2, 0xA6, 0xAC, 0x6D, 0x0D, 0x99, 0x5F, 0xD3, 0x58, 0xE4, 0x3A, + 0x2E, 0x82, 0xFE, 0x9B, 0xD3, 0xDF, 0x48, 0x88, 0x80, 0xEE, 0x6B, 0x46, 0x06, 0x17, 0xF5, 0xEA, 0xC0, 0xBD, 0x3B, 0x49, 0xE8, 0xB5, 0xA7, 0x9C, + 0x62, 0x74, 0x81, 0x43, 0xA3, 0x9C, 0x91, 0x56, 0xF2, 0x7B, 0xD7, 0xC4, 0x06, 0xBF, 0x2E, 0xE0, 0x25, 0xE1, 0x7E, 0xE5, 0xF8, 0x62, 0xEF, 0x1C, + 0x16, 0x9F, 0xBB, 0x46, 0x99, 0x6D, 0x37, 0xDD, 0x6F, 0x02, 0x95, 0x4F, 0x93, 0xA3, 0x9D, 0x92, 0x58, 0xAD, 0x0A, 0xAB, 0x9E, 0x09, 0x0D, 0xFA, + 0x82, 0xC4, 0xF0, 0x62, 0xDE, 0x3D, 0xA1, 0x50, 0x35, 0x9A, 0x17, 0x79, 0x03, 0x4F, 0xFF, 0xDE, 0x0C, 0xC1, 0xD6, 0x50, 0xFD, 0x15, 0x51, 0x2B, + 0x10, 0x53, 0x26, 0x24, 0x00, 0xD1, 0x8A, 0xFF, 0x7C, 0xD1, 0xEB, 0x07, 0xA7, 0x37, 0x0D, 0x54, 0xED, 0x11, 0x08, 0x8C, 0x4C, 0x9F, 0x73, 0xBB, + 0xE6, 0xD3, 0x27, 0x96, 0x43, 0x61, 0x06, 0x02, 0xF0, 0xAC, 0xE6, 0x04, 0x8A, 0x05, 0x3E, 0x45, 0x76, 0x26, 0xAA, 0xD3, 0x0E, 0x50, 0xF8, 0x57, + 0xCE, 0xB8, 0xCE, 0xBF, 0xA2, 0xD8, 0xEC, 0xAF, 0xB8, 0x11, 0x89, 0xF5, 0x70, 0x84, 0x48, 0x51, 0x45, 0x7D, 0x10, 0xBB, 0xEE, 0x4A, 0x3C, 0xA2, + 0xC8, 0x2F, 0x05, 0x27, 0xA4, 0xB4, 0x87, 0xE8, 0x60, 0xCD, 0x4A, 0x1B, 0x66, 0x3A, 0x2D, 0x0F, 0x5D, 0x75, 0x06, 0x62, 0xA2, 0x9F, 0xA7, 0xF3, + 0x57, 0x09, 0x89, 0x33, 0x6C, 0x54, 0x18, 0x10, 0x42, 0x35, 0xB3, 0xAA, 0x03, 0x35, 0xC4, 0x73, 0xE4, 0x01, 0x88, 0x22, 0x3E, 0x26, 0x9E, 0x65, + 0xC2, 0x79, 0x8B, 0xB2, 0x6C, 0x3D, 0xD4, 0x53, 0xC7, 0x00, 0xCD, 0xCC, 0x5B, 0xB0, 0x34, 0xDF, 0x72, 0x47, 0xD5, 0x0F, 0xD3, 0x39, 0x70, 0x23, + 0x96, 0x79, 0xFF, 0x7C, 0xE4, 0xCC, 0x7B, 0x93, 0xC6, 0x6F, 0x72, 0xF8, 0x35, 0x70, 0xF4, 0x8A, 0xF8, 0xA4, 0xA7, 0xBB, 0x28, 0xAB, 0x65, 0x3C, + 0x9F, 0x27, 0x8A, 0x03, 0x10, 0xE3, 0xC1, 0x18, 0x8E, 0x32, 0xDD, 0xFD, 0xDC, 0x07, 0xB7, 0x9A, 0xE5, 0xBD, 0x14, 0x06, 0x12, 0x1C, 0x8C, 0x5E, + 0x24, 0xDF, 0xC3, 0x79, 0xC1, 0x6A, 0x73, 0x23, 0x81, 0x35, 0xA4, 0xCE, 0xA6, 0x8B, 0x78, 0x98, 0x0C, 0x82, 0xA5, 0x9C, 0xA2, 0xED, 0x21, 0x22, + 0x0F, 0xFD, 0x3B, 0x29, 0xA2, 0xF4, 0x84, 0xDA, 0x64, 0x1C, 0xE2, 0x3D, 0x93, 0x54, 0x09, 0x73, 0x41, 0xC8, 0x6C, 0xA8, 0x83, 0xA2, 0xDE, 0xA1, + 0xAA, 0xC2, 0x7F, 0x19, 0xCB, 0x4B, 0x3D, 0x95, 0xB6, 0x20, 0xC6, 0x28, 0x34, 0x71, 0x58, 0x28, 0x4A, 0xC2, 0x4A, 0xD5, 0x2E, 0x7B, 0x76, 0x66, + 0xBF, 0xCD, 0x23, 0xBC, 0x10, 0xF8, 0x44, 0x10, 0x74, 0xB1, 0x25, 0xC8, 0x8D, 0x96, 0xB5, 0xB0, 0xC5, 0x1F, 0xFA, 0x3C, 0xD3, 0x83, 0x36, 0x03, + 0x77, 0x88, 0x71, 0x0B, 0x86, 0x41, 0x90, 0xAD, 0x0F, 0x86, 0x47, 0xC6, 0xA6, 0x6F, 0x0A, 0x94, 0x74, 0xE4, 0xD5, 0xDC, 0x8A, 0x66, 0x37, 0xAF, + 0xFD, 0x95, 0x90, 0x20, 0xB5, 0xAF, 0x9E, 0xFE, 0x44, 0xED, 0xAE, 0x1D, 0x63, 0xA6, 0xED, 0x63, 0xC2, 0x6E, 0xE0, 0x2C, 0x7F, 0x0F, 0x42, 0x6D, + 0xEB, 0x50, 0x9E, 0x8A, 0x17, 0xAD, 0xDA, 0x45, 0x9A, 0xE6, 0x42, 0xAC, 0x43, 0xA4, 0x06, 0xAC, 0x05, 0x10, 0xC4, 0xCA, 0x0A, 0xEF, 0xE0, 0x02, + 0xC8, 0x5D, 0xDF, 0x6D, 0x86, 0xAB, 0xFA, 0x9C, 0x45, 0xE4, 0xA1, 0x9C, 0xC3, 0x96, 0x6D, 0x9F, 0x1D, 0x90, 0xEA, 0x34, 0x4E, 0x4F, 0xB0, 0x86, + 0xA7, 0x53, 0xF1, 0x68, 0x83, 0x71, 0xE3, 0x1E, 0x4A, 0xB7, 0x70, 0xCD, 0xBA, 0x12, 0x22, 0xF4, 0xE0, 0x31, 0xA2, 0xC7, 0xED, 0x0F, 0xC8, 0x23, + 0x35, 0x9B, 0x69, 0x0E, 0x7E, 0x5D, 0xA6, 0x03, 0x9B, 0xD2, 0x40, 0x7F, 0x71, 0xAE, 0x7D, 0xD6, 0xFA, 0xF4, 0xB7, 0x73, 0x99, 0xCA, 0x8C, 0x6B, + 0x9C, 0x71, 0x01, 0x87, 0x09, 0x70, 0x84, 0xB7, 0x8C, 0x6B, 0x01, 0x49, 0x6D, 0x09, 0x13, 0x2B, 0x74, 0x06, 0xED, 0x06, 0xB5, 0xA6, 0xDA, 0x02, + 0xA0, 0x8B, 0x68, 0x0E, 0xA5, 0x57, 0x23, 0x57, 0xE8, 0x35, 0xAB, 0x01, 0xC6, 0x51, 0x20, 0x8D, 0x3E, 0x67, 0x91, 0x97, 0x43, 0x53, 0x99, 0x0F, + 0x21, 0xB7, 0x71, 0xFA, 0x74, 0xFC, 0x79, 0xDB, 0x2F, 0x3F, 0xAB, 0x1E, 0x84, 0x08, 0x99, 0xD8, 0xDF, 0x58, 0xEC, 0x2C, 0x09, 0x87, 0x6C, 0x57, + 0xEC, 0xA3, 0x85, 0x56, 0x42, 0x67, 0xF8, 0x5C, 0xFB, 0xF2, 0xCA, 0xE3, 0xE1, 0x5B, 0xA5, 0xE4, 0x27, 0xF4, 0xF6, 0x40, 0x63, 0xBC, 0x58, 0x56, + 0x23, 0xF8, 0xE7, 0x0A, 0x10, 0xD6, 0x46, 0xD6, 0x2F, 0xC9, 0xE0, 0x47, 0x90, 0x56, 0x15, 0x0E, 0x9E, 0x6F, 0xFC, 0x11, 0xC8, 0x1C, 0xA6, 0xC0, + 0x96, 0x5F, 0x4E, 0x8A, 0x1E, 0x45, 0xAA, 0xD7, 0x75, 0x6A, 0xBB, 0x21, 0xB6, 0x82, 0x5D, 0x79, 0x7F, 0x1E, 0xED, 0x55, 0xB4, 0x14, 0x97, 0x46, + 0x44, 0x9B, 0x86, 0x4B, 0x89, 0x30, 0xC8, 0x66, 0x31, 0xA6, 0xAF, 0xEB, 0x61, 0x56, 0x63, 0xC4, 0xE9, 0x98, 0x19, 0xE8, 0x83, 0x0E, 0x1D, 0x55, + 0xE9, 0x38, 0xA3, 0x8D, 0x79, 0x37, 0xF3, 0xE9, 0x05, 0x9D, 0xC0, 0x34, 0x45, 0x90, 0x2D, 0xF0, 0x3B, 0xF4, 0x7B, 0xB0, 0xE9, 0xCB, 0x4F, 0x08, + 0x27, 0xE7, 0x7C, 0x89, 0xC8, 0x24, 0x55, 0x4B, 0x1F, 0xEE, 0x21, 0xF2, 0x47, 0x15, 0x17, 0x3E, 0xEA, 0x0E, 0xCC, 0xD0, 0xD4, 0xC8, 0x07, 0x9D, + 0x99, 0x25, 0xD8, 0x62, 0x82, 0x42, 0x7C, 0x71, 0xD1, 0xAA, 0x85, 0xAB, 0xCD, 0xC8, 0x47, 0x65, 0x5A, 0xF0, 0x45, 0x06, 0xF9, 0xF3, 0x2C, 0x94, + 0x54, 0x91, 0x2A, 0xB9, 0xF9, 0x54, 0x53, 0xF4, 0xFF, 0x1A, 0x94, 0xBC, 0xD1, 0x5B, 0xD6, 0xF9, 0xAF, 0xA0, 0x82, 0x74, 0xD8, 0x5D, 0x6C, 0x67, + 0x30, 0x83, 0xA6, 0x12, 0xF9, 0xFC, 0xCD, 0xE8, 0xED, 0xE1, 0xC5, 0xBF, 0x83, 0x1C, 0x26, 0x17, 0x5D, 0xB2, 0x91, 0x10, 0x14, 0x86, 0xEA, 0x32, + 0x28, 0x2E, 0x38, 0x0B, 0xCB, 0xCB, 0xC9, 0xD0, 0xDA, 0x5E, 0x3C, 0x28, 0x58, 0x8F, 0xD6, 0xAA, 0xD9, 0x2E, 0x3C, 0xC5, 0x43, 0x83, 0x7E, 0x94, + 0xAC, 0x00, 0xFA, 0xC0, 0x4C, 0x2F, 0x33, 0x10, 0x68, 0x7B, 0x0E, 0xEC, 0xAD, 0x86, 0x63, 0x2A, 0x13, 0x39, 0xA9, 0x13, 0x63, 0x7F, 0xC9, 0x69, + 0x9C, 0x1A, 0xD5, 0x9A, 0xAE, 0xCA, 0xD5, 0xC8, 0x01, 0x91, 0xD6, 0x46, 0x5F, 0xA9, 0x46, 0x32, 0x6D, 0x84, 0x0B, 0x6A, 0x70, 0xE1, 0xE2, 0x43, + 0xB1, 0x72, 0x60, 0x91, 0x42, 0xAE, 0x53, 0x13, 0x92, 0x52, 0xD9, 0x02, 0xF6, 0x02, 0xE4, 0x02, 0x39, 0x0E, 0x9C, 0x14, 0xEB, 0x2B, 0x99, 0xB5, + 0x9B, 0x64, 0xB5, 0x46, 0x6F, 0x09, 0x83, 0xB0, 0xEA, 0x11, 0x24, 0x18, 0x31, 0xAD, 0xAB, 0x70, 0x4D, 0x75, 0x32, 0x15, 0xA3, 0x76, 0x18, 0x3A, + 0x0D, 0x0B, 0x2A, 0x0B, 0x7E, 0x40, 0x8F, 0x91, 0xD8, 0x92, 0x7A, 0x1D, 0xAD, 0xE7, 0xB3, 0xE6, 0x2C, 0xF0, 0x6D, 0x0F, 0x70, 0xB2, 0x0C, 0xA4, + 0x30, 0xF2, 0x8F, 0x95, 0xD1, 0x2F, 0x95, 0x49, 0x8E, 0xE3, 0x53, 0xBF, 0x18, 0x44, 0x91, 0xA6, 0xF5, 0xAF, 0xDE, 0x8A, 0xC7, 0x3D, 0xAA, 0xBF, + 0xDC, 0x69, 0x82, 0x2A, 0x0B, 0xF2, 0xB8, 0x41, 0x04, 0x8E, 0x02, 0x87, 0x76, 0x23, 0xE0, 0x5E, 0x16, 0xF2, 0x2A, 0x22, 0x4B, 0x5F, 0xD7, 0x63, + 0x21, 0x33, 0x8B, 0xEA, 0x46, 0x1D, 0x22, 0x31, 0x17, 0x9B, 0xC1, 0xE2, 0x16, 0xFC, 0x36, 0xC1, 0xE6, 0x71, 0xC2, 0x2E, 0x1C, 0x61, 0x5B, 0x06, + 0x76, 0x25, 0x8C, 0xFD, 0xE6, 0xA7, 0x4B, 0xAC, 0x17, 0x94, 0x22, 0x36, 0x50, 0x76, 0x00, 0xEB, 0xD2, 0xBB, 0x15, 0x9F, 0x74, 0xF0, 0x07, 0x4F, + 0xBC, 0xCA, 0x43, 0xC1, 0x88, 0x59, 0xA0, 0x5B, 0xC2, 0x26, 0x3B, 0x1B, 0x27, 0x69, 0xBC, 0xFA, 0xD9, 0x07, 0x6C, 0x21, 0xF1, 0x04, 0xAF, 0xF7, + 0x36, 0xC0, 0x21, 0x41, 0xCB, 0xA3, 0x75, 0x45, 0xE0, 0xC5, 0xD5, 0x28, 0x61, 0x07, 0xC6, 0x1E, 0x1C, 0xA6, 0xE8, 0x20, 0x1D, 0x62, 0xE5, 0x2D, + 0xD4, 0x02, 0x9A, 0x0F, 0x65, 0x52, 0x7D, 0x17, 0x7F, 0x14, 0x9E, 0x13, 0x89, 0x86, 0xE5, 0xE6, 0x63, 0x33, 0xFD, 0xEB, 0x20, 0x2A, 0xF0, 0x0D, + 0xA3, 0x2C, 0x7C, 0xCB, 0xA2, 0x12, 0xFF, 0x89, 0x14, 0xF9, 0xE3, 0x82, 0x49, 0x60, 0xEA, 0x8A, 0x40, 0xC0, 0x86, 0x10, 0x82, 0xED, 0xC1, 0x05, + 0x40, 0x26, 0xB4, 0xBD, 0xA5, 0x13, 0x95, 0x79, 0xEC, 0xCF, 0x57, 0xF0, 0x6D, 0x73, 0x21, 0x9B, 0xFC, 0x67, 0x4A, 0xCD, 0x0C, 0x35, 0x43, 0x93, + 0xFE, 0x88, 0x17, 0xEE, 0xB6, 0x75, 0x65, 0x74, 0xD9, 0xBA, 0x65, 0x7E, 0xD2, 0x17, 0xF1, 0x92, 0x3E, 0x92, 0xA6, 0xAD, 0xFC, 0x6D, 0xB0, 0xAF, + 0x55, 0x53, 0x65, 0x35, 0x41, 0x21, 0x29, 0x09, 0x89, 0x37, 0x71, 0xC9, 0x33, 0x22, 0x66, 0x9F, 0x99, 0xC7, 0xED, 0xF6, 0x7D, 0xD8, 0x40, 0xCA, + 0x43, 0xEE, 0x49, 0xB3, 0x27, 0x66, 0xEA, 0x79, 0x0A, 0xBE, 0x05, 0x95, 0x22, 0x2B, 0xAD, 0xEE, 0xBD, 0x77, 0x1F, 0xC6, 0xE7, 0x7A, 0x5C, 0x0F, + 0xE9, 0x1F, 0x7D, 0xA1, 0xDF, 0xF3, 0x7A, 0x36, 0xBD, 0xF7, 0x49, 0xF3, 0xA4, 0x99, 0x67, 0xDC, 0xBB, 0x47, 0xF3, 0x2D, 0xBC, 0x98, 0xAF, 0xBB, + 0xEF, 0xB1, 0x39, 0xA6, 0xB3, 0x7D, 0x70, 0xE2, 0x6C, 0x58, 0xF8, 0xC2, 0xF0, 0x2F, 0xCC, 0xFE, 0x2E, 0xC5, 0xA1, 0x62, 0x13, 0xB7, 0x8D, 0x1B, + 0xEC, 0xFE, 0xB9, 0x6D, 0xEF, 0xB0, 0x1B, 0xED, 0x76, 0xBB, 0x4B, 0xC5, 0x1D, 0xC4, 0xAD, 0x77, 0x0F, 0x95, 0x1D, 0x35, 0x6F, 0xB6, 0xE3, 0x8A, + 0x9D, 0x08, 0xC7, 0xB3, 0x35, 0xBC, 0xCE, 0xF6, 0xE7, 0xE9, 0xE6, 0x1A, 0x68, 0xA7, 0xF5, 0xE4, 0xF8, 0xD1, 0xF2, 0x65, 0x7E, 0xC5, 0x0C, 0xCD, + 0x1D, 0x62, 0x5E, 0x82, 0xB9, 0xF4, 0xDD, 0x86, 0x21, 0xAE, 0x35, 0x72, 0x52, 0xDE, 0xCF, 0x7B, 0x24, 0xEB, 0x41, 0xA2, 0xD3, 0x87, 0x52, 0xC8, + 0x3A, 0xE9, 0x2D, 0xE0, 0x24, 0xBB, 0x2B, 0xF2, 0xD8, 0xFE, 0x8E, 0x2C, 0xC8, 0x64, 0xC0, 0x8F, 0x86, 0x23, 0xF3, 0x55, 0xFE, 0xD7, 0xB2, 0xA3, + 0xC6, 0xC0, 0xA3, 0x9A, 0xB8, 0x74, 0xA9, 0x65, 0x7E, 0x98, 0x96, 0x6D, 0x92, 0x73, 0xA6, 0x5D, 0xE4, 0x53, 0xD2, 0x3C, 0x72, 0x4F, 0xF2, 0xFF, + 0x89, 0x69, 0x36, 0xBA, 0xEF, 0x25, 0x2B, 0x91, 0x1D, 0x20, 0x63, 0x91, 0x3D, 0x91, 0x3D, 0xCD, 0xC8, 0x4E, 0x90, 0x5D, 0xE5, 0xC8, 0xA0, 0xD2, + 0x63, 0x38, 0xFD, 0x0E, 0xB1, 0x3B, 0xCD, 0x29, 0x2A, 0xDA, 0x3E, 0xEC, 0x50, 0x3B, 0xAD, 0x0F, 0xA2, 0x0E, 0xE8, 0x3D, 0xCD, 0x93, 0xF9, 0x14, + 0x72, 0x42, 0x77, 0x1D, 0x15, 0x48, 0x59, 0x04, 0x68, 0xA3, 0x00, 0xC2, 0x44, 0xCA, 0x56, 0x4B, 0xEA, 0x54, 0x78, 0xD4, 0x33, 0x70, 0x3A, 0xF9, + 0x4C, 0xDA, 0x65, 0xE5, 0xD5, 0xD2, 0xC2, 0xB6, 0x61, 0x08, 0x8D, 0xEA, 0x6B, 0x62, 0xEA, 0x0C, 0xB2, 0xF1, 0x12, 0xEF, 0x88, 0x28, 0xC4, 0x21, + 0x8C, 0xB0, 0x1F, 0xF3, 0xE8, 0xF0, 0xCC, 0xF2, 0x70, 0xF1, 0x90, 0xF1, 0xAC, 0xF1, 0x6C, 0xE2, 0x41, 0xE1, 0xA1, 0xF2, 0xA8, 0x19, 0xDA, 0x98, + 0x77, 0x5C, 0xF8, 0xB1, 0xDE, 0x65, 0x20, 0xDA, 0x8D, 0x6D, 0x62, 0x7C, 0x0C, 0x1F, 0xF6, 0xF6, 0x37, 0xCE, 0x23, 0x3F, 0x36, 0x46, 0x12, 0xC9, + 0xCE, 0xFA, 0xE0, 0x94, 0x63, 0xC4, 0x04, 0xC1, 0xE1, 0xC4, 0x48, 0xF8, 0xEF, 0xC1, 0x7C, 0x90, 0x1B, 0x19, 0x8F, 0x6A, 0xEA, 0x7A, 0xE9, 0x28, + 0x91, 0x2C, 0xEC, 0x91, 0x9D, 0xD6, 0x37, 0xD8, 0x24, 0xEC, 0x14, 0xF6, 0x63, 0x77, 0xD0, 0x33, 0x6D, 0xB4, 0x2C, 0x81, 0x34, 0xDD, 0x7E, 0xE6, + 0x51, 0xB8, 0xC5, 0x56, 0xB9, 0xF6, 0xD1, 0x0A, 0xD9, 0x30, 0xA4, 0x82, 0xEA, 0x1B, 0x62, 0x2A, 0x2A, 0x87, 0x54, 0x52, 0x62, 0x54, 0x18, 0x21, + 0x5C, 0x52, 0x48, 0xEB, 0x31, 0x58, 0x09, 0x91, 0x3E, 0xBA, 0x56, 0x41, 0xD4, 0xB4, 0xC0, 0x1E, 0x57, 0x68, 0x4F, 0x51, 0xF9, 0x2B, 0x2E, 0x5A, + 0xBC, 0xB7, 0x4C, 0x6D, 0x62, 0xD4, 0x62, 0x3E, 0x7D, 0x98, 0x30, 0x60, 0x00, 0xC4, 0xED, 0x09, 0x89, 0x04, 0x3D, 0x7D, 0x9D, 0x3D, 0xB2, 0x01, + 0x80, 0xD4, 0x80, 0x43, 0x87, 0x32, 0x0A, 0x07, 0x6E, 0x1E, 0x04, 0xCB, 0x92, 0xC4, 0x45, 0x39, 0x4C, 0xCB, 0xFD, 0xFC, 0x20, 0x36, 0x75, 0x8E, + 0xB7, 0xEC, 0x2C, 0x0D, 0x0A, 0x60, 0x03, 0x07, 0x00, 0x81, 0x09, 0xFE, 0x91, 0x04, 0xE0, 0xAC, 0x55, 0xC7, 0x2C, 0x20, 0xA7, 0xEE, 0x16, 0xE7, + 0xAC, 0x74, 0xE3, 0x18, 0xBE, 0x6D, 0x72, 0xAC, 0xCF, 0xDC, 0x1A, 0xB0, 0xD9, 0xAB, 0xD0, 0x8C, 0x92, 0x9C, 0x4C, 0x0D, 0x85, 0x6F, 0x16, 0x62, + 0xCC, 0xD1, 0xD8, 0xFB, 0x71, 0x3D, 0x8F, 0xFC, 0xDB, 0x19, 0x43, 0x6C, 0xAF, 0x78, 0xC1, 0x60, 0x3E, 0xD6, 0xE6, 0xBA, 0xA6, 0x71, 0xD3, 0xB4, + 0x81, 0x2F, 0x6D, 0x97, 0xFD, 0xF2, 0x34, 0xE4, 0xE5, 0x40, 0x4E, 0x97, 0xAF, 0x0C, 0x5C, 0x38, 0x8C, 0x6D, 0xB1, 0xF1, 0x35, 0x8B, 0xC2, 0x2A, + 0x0F, 0xAC, 0x21, 0xEB, 0xA6, 0x42, 0x4B, 0x1F, 0x91, 0x2C, 0x8F, 0x60, 0x62, 0x29, 0x4B, 0xB1, 0x3C, 0x11, 0x01, 0xCB, 0x24, 0xCB, 0x2B, 0xEE, + 0x99, 0xED, 0xCD, 0x15, 0x1E, 0x2D, 0xD7, 0xA0, 0x23, 0x2B, 0x17, 0x16, 0xAB, 0x30, 0xE1, 0x50, 0xD1, 0x2A, 0x4F, 0x09, 0x81, 0x24, 0xA5, 0x4C, + 0x2D, 0x0A, 0x5A, 0x15, 0xDE, 0xE8, 0xCD, 0xD8, 0x03, 0x09, 0x7B, 0x6F, 0xD6, 0x3A, 0x11, 0x25, 0x6D, 0x52, 0xC5, 0x47, 0xE7, 0xAF, 0xD6, 0xE6, + 0xAD, 0x26, 0xD1, 0x2D, 0x61, 0x60, 0xA4, 0x8A, 0xA5, 0x98, 0x5A, 0xE0, 0x00, 0xAA, 0x15, 0x0E, 0xA2, 0x50, 0x06, 0x2E, 0x91, 0xDC, 0x26, 0x5B, + 0xAF, 0x7D, 0x52, 0xC0, 0xD8, 0xEE, 0x6C, 0xDE, 0xA1, 0xD4, 0x78, 0xB3, 0x31, 0x1E, 0x62, 0x2D, 0x82, 0xA2, 0x15, 0x3D, 0xCD, 0x86, 0xBC, 0xE6, + 0x89, 0xA9, 0x03, 0x12, 0xFB, 0x29, 0x96, 0x34, 0x22, 0x12, 0x83, 0x43, 0x05, 0x9D, 0x86, 0x44, 0x75, 0x90, 0x27, 0xDB, 0x42, 0x2C, 0x23, 0x84, + 0x33, 0x3E, 0x07, 0x53, 0xFC, 0x09, 0xC6, 0xB8, 0xBD, 0x73, 0x50, 0x8A, 0x03, 0xF7, 0xC2, 0x80, 0x7F, 0x40, 0x80, 0x14, 0x6A, 0xFE, 0x95, 0x2A, + 0xDD, 0xAA, 0x37, 0x01, 0xFC, 0x8A, 0x1E, 0xEB, 0x68, 0x66, 0xBC, 0x16, 0xDF, 0x19, 0xEE, 0x12, 0x44, 0xE3, 0xA4, 0xFE, 0xF2, 0xFC, 0xC2, 0xC3, + 0xF4, 0xB2, 0x51, 0xE5, 0x04, 0x64, 0xAB, 0x89, 0xDB, 0xDB, 0x85, 0x7A, 0x5B, 0x42, 0xD2, 0x0A, 0x97, 0x97, 0xF0, 0x78, 0x49, 0xCC, 0x78, 0x40, + 0x53, 0xA7, 0x45, 0x60, 0x57, 0xF1, 0xB1, 0x8B, 0xEC, 0xA8, 0x2B, 0x7C, 0x42, 0x4E, 0x95, 0x8F, 0xC8, 0xC5, 0xF2, 0xB4, 0xFC, 0x46, 0x5E, 0x97, + 0x57, 0xDE, 0x39, 0xAC, 0xCE, 0x99, 0xA6, 0x49, 0xD6, 0x8F, 0x13, 0x28, 0x05, 0x87, 0x67, 0xAC, 0x72, 0xBD, 0x56, 0x23, 0xEB, 0xB3, 0xF2, 0xAE, + 0x2C, 0x10, 0x87, 0x84, 0xE4, 0x67, 0xDA, 0xF5, 0x45, 0x00, 0x2A, 0x6F, 0xFF, 0xEE, 0x0F, 0x7E, 0x22, 0x1F, 0xF3, 0x97, 0xFE, 0xD6, 0xAF, 0xE0, + 0xCA, 0x6C, 0x66, 0x59, 0x0B, 0x07, 0x07, 0xC0, 0xCB, 0x6A, 0xB9, 0xE0, 0xA5, 0xDC, 0xF2, 0x8D, 0x43, 0x30, 0x88, 0x2D, 0x83, 0x88, 0x39, 0x50, + 0x10, 0x4D, 0xF0, 0x00, 0x3B, 0xCB, 0x50, 0x0E, 0xF4, 0xFF, 0x20, 0xE3, 0xA0, 0x5C, 0x22, 0x09, 0x3D, 0xE8, 0x0D, 0xFE, 0xB0, 0xA0, 0x18, 0xDB, + 0xDD, 0xB7, 0x09, 0x2E, 0xF3, 0xA9, 0xFB, 0x9B, 0xEA, 0x3F, 0xE4, 0x19, 0x11, 0x6C, 0x9B, 0x0E, 0xD4, 0x8D, 0xFA, 0x84, 0x4E, 0xD5, 0x47, 0x74, + 0xB1, 0x9E, 0xD6, 0x2F, 0x6D, 0x52, 0xFB, 0x89, 0x7D, 0xAE, 0x6F, 0xCE, 0x8B, 0xA6, 0x9E, 0x3F, 0x31, 0x9D, 0x46, 0x3B, 0x9C, 0x4D, 0x08, 0x36, + 0xAB, 0x96, 0x34, 0xC7, 0x50, 0x99, 0x64, 0x1F, 0x92, 0x90, 0xBD, 0x30, 0xE1, 0x5A, 0x5C, 0xF2, 0xD1, 0x40, 0x82, 0x38, 0x67, 0x69, 0xA4, 0xAF, + 0xF2, 0x53, 0x08, 0x7E, 0xA4, 0xB4, 0x8D, 0x12, 0x4A, 0x0F, 0xD9, 0xBF, 0x49, 0x0C, 0x5C, 0x6A, 0x33, 0x9A, 0x86, 0x74, 0x02, 0x90, 0x57, 0xF5, + 0x99, 0x9E, 0xD2, 0xB7, 0xF5, 0x98, 0xB0, 0x00, 0xAD, 0x9F, 0x00, 0x62, 0x0A, 0xC0, 0x6A, 0x12, 0x00, 0xBC, 0x4D, 0x95, 0x75, 0xE6, 0xC2, 0x39, + 0x85, 0x61, 0xE5, 0x3A, 0x17, 0x5E, 0x1C, 0x80, 0x54, 0x3B, 0x29, 0x24, 0xE1, 0x6C, 0xEA, 0xDA, 0x7C, 0x72, 0xA0, 0x39, 0x66, 0xCB, 0x24, 0x83, + 0x4B, 0x42, 0xDE, 0xC3, 0xF4, 0x0B, 0xBA, 0xE4, 0x8B, 0x44, 0x12, 0x18, 0x67, 0x69, 0xE4, 0xB4, 0xF2, 0x53, 0xCA, 0x91, 0xD5, 0x59, 0x4A, 0xD5, + 0xB9, 0x49, 0x59, 0xD4, 0x30, 0x53, 0x8C, 0x00, 0xD8, 0x52, 0x84, 0x29, 0x86, 0xA4, 0x12, 0x38, 0xD2, 0xAA, 0x84, 0x18, 0x32, 0x2B, 0xE9, 0x11, + 0xCD, 0xF1, 0xBE, 0xBA, 0xCB, 0xCC, 0x3B, 0xBE, 0x43, 0x8B, 0xA0, 0x87, 0x8A, 0x9E, 0x19, 0x86, 0x2C, 0xC9, 0x4A, 0x74, 0xFD, 0xCA, 0xB5, 0x40, + 0xF8, 0x48, 0xFE, 0x50, 0x81, 0x9F, 0x21, 0x51, 0x84, 0x20, 0x5E, 0x43, 0x6D, 0x47, 0x3E, 0x69, 0x5A, 0x89, 0xE8, 0xF3, 0x49, 0x59, 0xD9, 0x2D, + 0xAE, 0x7C, 0xF6, 0x31, 0xAF, 0xD7, 0x63, 0xF1, 0xAD, 0xDE, 0xD3, 0x63, 0xFA, 0x12, 0x3D, 0x3F, 0xDF, 0xA6, 0xEB, 0xF5, 0x13, 0x9B, 0x42, 0x8D, + 0xBA, 0x54, 0xCF, 0xF9, 0x43, 0x72, 0xEC, 0x53, 0x5D, 0x19, 0xF2, 0xEC, 0x18, 0x7F, 0x28, 0x1E, 0x6D, 0x3D, 0x4A, 0x37, 0x53, 0x5B, 0x72, 0xB5, + 0x2C, 0x28, 0x6B, 0xAB, 0x7E, 0x29, 0x67, 0xE6, 0xD8, 0xB4, 0x3C, 0x65, 0x26, 0x10, 0xBE, 0x4F, 0xCF, 0xB7, 0x49, 0x10, 0x7E, 0xF0, 0x73, 0xC4, + 0xC8, 0xBD, 0x1A, 0xD6, 0xBA, 0x7F, 0x25, 0x3C, 0x58, 0xE7, 0x74, 0x0C, 0x73, 0xE3, 0x31, 0xB7, 0xCA, 0x19, 0xF7, 0xC7, 0xED, 0x2D, 0xE4, 0x9F, + 0x84, 0xB4, 0x15, 0x42, 0x7F, 0xD6, 0x4D, 0xBC, 0xF6, 0x41, 0x64, 0xAE, 0x8A, 0xC5, 0x2E, 0xEF, 0xE5, 0x04, 0x68, 0x3F, 0x86, 0xA5, 0x2B, 0x74, + 0xFE, 0x69, 0x16, 0xE1, 0x2A, 0x5C, 0x9B, 0x98, 0xF0, 0x17, 0xEB, 0x5B, 0x08, 0x8F, 0xCB, 0xFD, 0x45, 0x7A, 0xCD, 0x29, 0x9A, 0x8F, 0xE2, 0x4D, + 0xE9, 0xFF, 0x2D, 0x4F, 0xC5, 0xB6, 0xBC, 0xB7, 0x3C, 0xE4, 0x70, 0x87, 0x04, 0xE5, 0x47, 0x84, 0x6C, 0x50, 0xD5, 0xBA, 0xD8, 0xFD, 0x1C, 0x25, + 0xAC, 0xAF, 0x5D, 0xAC, 0x05, 0xA8, 0x50, 0xA1, 0x66, 0x9C, 0x82, 0xCD, 0xA2, 0xEB, 0x1F, 0xA6, 0x38, 0x00, 0x9C, 0xED, 0x22, 0xA5, 0x84, 0x0D, + 0xEA, 0x3B, 0xF5, 0x8F, 0xE6, 0x9D, 0x89, 0x7A, 0x69, 0xAD, 0xBD, 0xD0, 0xE5, 0x07, 0xBA, 0x38, 0x9D, 0xD4, 0xEA, 0x16, 0x41, 0x78, 0xD5, 0x53, + 0x0E, 0x1A, 0x9B, 0xC3, 0x7D, 0x41, 0x37, 0x33, 0xFB, 0x2E, 0x07, 0xE5, 0xB7, 0x53, 0xA7, 0xE4, 0xCC, 0x65, 0xFC, 0xAD, 0xB7, 0xF5, 0xA9, 0x9E, + 0xD4, 0x8F, 0xFA, 0x50, 0x8F, 0x24, 0x4C, 0x64, 0xF8, 0x44, 0x8D, 0xE8, 0x8C, 0xEF, 0x76, 0x6B, 0x74, 0xC7, 0xFE, 0x94, 0x36, 0x0C, 0x27, 0xC7, + 0x2F, 0x68, 0x08, 0x52, 0x9F, 0x32, 0x81, 0x0B, 0x95, 0x77, 0xC4, 0xBD, 0x23, 0x36, 0x94, 0x76, 0x3F, 0xB8, 0x11, 0x55, 0x77, 0x8B, 0xB8, 0xEF, + 0xB0, 0xC6, 0x9B, 0xC5, 0x5B, 0x2E, 0xE3, 0x4E, 0x56, 0x6E, 0x30, 0x11, 0x33, 0xB4, 0x15, 0xF6, 0xF6, 0x26, 0x7C, 0x00, 0x57, 0x43, 0x10, 0x98, + 0xD3, 0x8D, 0x2D, 0xBB, 0xB1, 0x7B, 0x10, 0x86, 0xE3, 0xDB, 0x24, 0x17, 0x28, 0x99, 0x98, 0x75, 0x8D, 0xF5, 0x55, 0x47, 0x4D, 0xE1, 0x12, 0xA0, + 0x47, 0xD5, 0xA3, 0x4C, 0xAB, 0xC8, 0x53, 0xAE, 0x4D, 0x74, 0x0E, 0x1C, 0x68, 0xA6, 0x31, 0x1E, 0x56, 0xA6, 0x5A, 0xE9, 0x73, 0x10, 0xC1, 0x73, + 0x88, 0x37, 0x45, 0x15, 0xA5, 0x30, 0x7A, 0x72, 0xCE, 0x4B, 0xB4, 0x41, 0x5C, 0xB3, 0x43, 0xAD, 0x24, 0x0F, 0x82, 0x93, 0x51, 0xBB, 0x43, 0x2C, + 0x21, 0x2E, 0x1A, 0x19, 0x22, 0x54, 0x0A, 0x18, 0xE8, 0xAC, 0x18, 0xD4, 0x8B, 0xFE, 0x50, 0x3E, 0x05, 0x3D, 0xCE, 0x26, 0xA5, 0xCD, 0xA7, 0xAF, + 0xE6, 0x18, 0x2B, 0x93, 0xEC, 0x44, 0x12, 0xB2, 0x19, 0x66, 0x5F, 0x7E, 0xC9, 0x27, 0x87, 0x24, 0xF0, 0xCB, 0xD2, 0x08, 0x62, 0xE5, 0x67, 0x91, + 0x49, 0xD9, 0xC4, 0x30, 0x93, 0x46, 0x00, 0x7C, 0x16, 0x61, 0xBA, 0xFA, 0x31, 0x1F, 0xEE, 0x23, 0xF8, 0x41, 0x3E, 0x0C, 0x16, 0x0E, 0x05, 0x75, + 0x42, 0x17, 0x2F, 0x06, 0x33, 0xB8, 0x0A, 0xCE, 0xC1, 0xDE, 0x5F, 0x60, 0x81, 0x89, 0x92, 0x80, 0x6D, 0x0E, 0x3A, 0x10, 0x50, 0x1C, 0x7F, 0x7F, + 0xB6, 0x76, 0xAE, 0xA7, 0xED, 0xD7, 0xA1, 0xC5, 0xB7, 0xB3, 0x42, 0x47, 0xF7, 0xF5, 0xFA, 0xB4, 0xCF, 0x3D, 0xDA, 0x9F, 0x85, 0xFE, 0x7A, 0x88, + 0x49, 0x95, 0x20, 0x7E, 0x25, 0x49, 0x91, 0x85, 0x40, 0x89, 0x40, 0x87, 0x62, 0x31, 0x46, 0x3D, 0x89, 0x4F, 0xB0, 0x3B, 0x3D, 0x79, 0xBF, 0xDE, + 0x05, 0xDF, 0xB0, 0x8B, 0xF6, 0x40, 0x9B, 0xD1, 0xB6, 0xB4, 0x47, 0xED, 0x26, 0x36, 0xAC, 0x5D, 0x6B, 0xA7, 0xD2, 0xD8, 0x5C, 0x92, 0x78, 0xDE, + 0x5B, 0x4D, 0x63, 0x0D, 0xEF, 0xAA, 0xCA, 0xEA, 0x3D, 0xE6, 0xEB, 0xBB, 0x2C, 0xBC, 0x12, 0xDF, 0x13, 0x44, 0xD6, 0x83, 0x8C, 0x4A, 0x93, 0xB2, + 0x30, 0x00, 0x36, 0x21, 0x01, 0xFB, 0x78, 0x52, 0x9E, 0xC3, 0x91, 0xFB, 0x2D, 0xFD, 0x4E, 0xD9, 0x20, 0x2B, 0xE7, 0xDC, 0x89, 0x19, 0x8F, 0x33, + 0xFF, 0x74, 0x80, 0x2C, 0xC3, 0x45, 0x56, 0xA8, 0x1B, 0x22, 0xB9, 0xB6, 0x4D, 0xAD, 0x57, 0xCD, 0x59, 0xB4, 0x06, 0x88, 0xC6, 0x8C, 0x2D, 0x0C, + 0xA7, 0xBE, 0xEF, 0xE2, 0xEE, 0x7F, 0x31, 0xD0, 0xE4, 0x85, 0x4C, 0xA6, 0x0B, 0x98, 0xEC, 0x6C, 0x97, 0xC9, 0x27, 0x8E, 0x18, 0x9C, 0xA0, 0x9E, + 0x9B, 0xA0, 0x4D, 0x30, 0xC1, 0xF2, 0xC8, 0xFA, 0xFA, 0xC4, 0xDA, 0xDD, 0x5B, 0xAD, 0x39, 0xB1, 0x64, 0x81, 0xAC, 0xEA, 0xD1, 0x8C, 0xD4, 0xAB, + 0x1C, 0xD4, 0xA8, 0xEE, 0xE9, 0xA0, 0x13, 0xBA, 0xAC, 0x46, 0x54, 0x94, 0x31, 0x94, 0xD4, 0x06, 0xE5, 0xE0, 0x05, 0xD4, 0xEF, 0x7C, 0xBA, 0x3D, + 0x29, 0x6A, 0x2E, 0x0D, 0xA9, 0x8D, 0x4B, 0x8C, 0x82, 0x9B, 0x68, 0x64, 0x54, 0x23, 0x39, 0x97, 0xE7, 0xBC, 0xF0, 0xAD, 0xA6, 0x75, 0x56, 0x2F, + 0xEA, 0x93, 0x62, 0x14, 0xB3, 0x8A, 0x28, 0x29, 0x88, 0xBA, 0x30, 0xED, 0x45, 0x90, 0x90, 0xF8, 0x36, 0xD7, 0x7B, 0x43, 0xC1, 0xC1, 0x1A, 0x70, + 0x4F, 0xC3, 0x8E, 0xD0, 0x2B, 0x72, 0xC5, 0xB6, 0x4C, 0xE0, 0x72, 0xB4, 0x35, 0x3E, 0x19, 0xBC, 0xF0, 0xD4, 0xA9, 0x3B, 0xAF, 0x7A, 0xD4, 0x9C, + 0x49, 0x6D, 0x9B, 0x61, 0x5F, 0x13, 0xEB, 0x2F, 0x13, 0x07, 0x5D, 0x12, 0x17, 0x94, 0x98, 0x84, 0x8A, 0x97, 0x74, 0xAB, 0x48, 0x34, 0x43, 0x2D, + 0x19, 0xBF, 0x54, 0x4E, 0xB9, 0x72, 0x64, 0xF5, 0x03, 0xE5, 0xE8, 0xE1, 0x64, 0xBA, 0x85, 0x91, 0x58, 0x4E, 0xDC, 0xC8, 0xCF, 0x5C, 0x11, 0xAF, + 0x10, 0xC9, 0x26, 0x21, 0x91, 0x43, 0x9E, 0x90, 0x63, 0xCF, 0xC7, 0xA8, 0x2A, 0xB5, 0x23, 0xB9, 0x0A, 0x19, 0x11, 0x10, 0x3B, 0xC6, 0x66, 0x48, + 0xC7, 0x0C, 0x45, 0xAE, 0x10, 0x11, 0x31, 0x3B, 0x58, 0x77, 0x41, 0x37, 0xFC, 0xE5, 0x55, 0xD5, 0xCD, 0x76, 0x4D, 0xA6, 0xF6, 0xF5, 0xC2, 0xCA, + 0x0B, 0xCE, 0xEE, 0x84, 0x0F, 0x15, 0x26, 0x10, 0xCD, 0x5D, 0x8D, 0x39, 0x4A, 0x5C, 0xE2, 0x71, 0x75, 0x92, 0x8D, 0xA1, 0x6C, 0x59, 0xD1, 0x41, + 0x22, 0xCC, 0x99, 0x84, 0x4C, 0xE1, 0x08, 0x03, 0x5A, 0x45, 0x99, 0x22, 0xA0, 0x42, 0x50, 0xE1, 0x20, 0xEA, 0xAC, 0xB1, 0xDC, 0x0F, 0x6B, 0x39, + 0x38, 0xEE, 0xDC, 0x8D, 0x55, 0x43, 0xCA, 0xDE, 0x02, 0xFC, 0x2A, 0x50, 0x01, 0x13, 0xB0, 0x98, 0xA6, 0xBA, 0xEF, 0xAD, 0x8B, 0x0B, 0xA0, 0x3D, + 0xEC, 0xC3, 0xF6, 0x61, 0x03, 0x29, 0x5F, 0xD1, 0xC3, 0x9B, 0xA0, 0x7D, 0xB3, 0x40, 0xC5, 0xD9, 0xF8, 0x7E, 0x75, 0xBA, 0x38, 0x52, 0x57, 0xB2, + 0x38, 0xD0, 0xE4, 0x8B, 0x52, 0xB2, 0xF2, 0xC4, 0x1C, 0xD7, 0x46, 0xDB, 0x7B, 0xAF, 0xF5, 0xB3, 0x9E, 0x53, 0x06, 0x4C, 0xA7, 0xE9, 0xA3, 0x99, + 0x22, 0x3A, 0xED, 0x55, 0xA8, 0x0F, 0x8B, 0x7E, 0x86, 0x2A, 0xA3, 0x23, 0x41, 0x0E, 0x6B, 0x17, 0x6D, 0xF9, 0x2F, 0xE6, 0x58, 0x5B, 0x42, 0xB7, + 0xB1, 0x81, 0x6C, 0x23, 0x3B, 0x4C, 0xA0, 0xD7, 0xA0, 0x60, 0x53, 0xA8, 0xC0, 0x05, 0xAF, 0x00, 0xA4, 0x85, 0x5C, 0xC6, 0x9A, 0x2C, 0x6A, 0x09, + 0x2D, 0x7D, 0x79, 0x59, 0x12, 0x0B, 0x29, 0x1F, 0x63, 0x79, 0xF4, 0x3A, 0xAC, 0xA9, 0xDE, 0x6B, 0x94, 0x20, 0x36, 0xA4, 0x8D, 0xEE, 0x5E, 0x8B, + 0x60, 0x61, 0xD0, 0x72, 0x47, 0xEA, 0x3C, 0xBB, 0xFF, 0x46, 0xD9, 0x63, 0xB4, 0x1A, 0xD6, 0xA0, 0x21, 0x98, 0xC2, 0xF2, 0xEE, 0x93, 0xEC, 0x3F, + 0x10, 0x91, 0xCE, 0xDD, 0x1F, 0x15, 0x7E, 0xB9, 0x76, 0xA1, 0x66, 0xC9, 0xBD, 0x50, 0xCD, 0xF8, 0xAF, 0xEF, 0x21, 0xEB, 0x3B, 0xE6, 0x4A, 0xA5, + 0x0B, 0x5C, 0x48, 0x67, 0xC5, 0xD2, 0x3F, 0x46, 0xAE, 0x67, 0x95, 0x72, 0x70, 0xE0, 0xFB, 0x60, 0x20, 0x6B, 0x54, 0x0A, 0xB5, 0xD7, 0x00, 0x00, + 0x71, 0xAE, 0x35, 0xC1, 0xA6, 0x36, 0xA6, 0x08, 0xA5, 0xBA, 0xBE, 0x1C, 0x38, 0xF5, 0xEF, 0x8C, 0x00, 0xBE, 0x8E, 0xF7, 0x6F, 0x49, 0xF1, 0xA5, + 0xD4, 0x1D, 0xC7, 0xBA, 0x6A, 0xF2, 0x57, 0x98, 0xAC, 0x3F, 0xA6, 0x08, 0x2D, 0x75, 0xB9, 0x15, 0xA7, 0x36, 0xDF, 0x7E, 0x3C, 0xA4, 0x1A, 0x5D, + 0x96, 0x43, 0x56, 0xD5, 0xAF, 0x1F, 0xFE, 0xF9, 0x0C, 0x97, 0xC5, 0x60, 0xE4, 0x94, 0x1B, 0x79, 0x2D, 0xB7, 0xD8, 0xA1, 0x97, 0x08, 0x81, 0xEC, + 0xEB, 0xED, 0x3E, 0x10, 0xCE, 0x6A, 0xA2, 0x78, 0xE7, 0x9E, 0x39, 0x12, 0xBF, 0x12, 0xEC, 0x0B, 0x3E, 0x20, 0x57, 0x83, 0xD1, 0xD3, 0x3E, 0x13, + 0xE3, 0x1D, 0xE0, 0x04, 0xA7, 0xF4, 0x8C, 0xF9, 0x19, 0x64, 0x39, 0x47, 0x38, 0x80, 0x8F, 0x78, 0xC2, 0x03, 0x84, 0xC9, 0xA2, 0x25, 0x10, 0xA3, + 0x69, 0x4E, 0xF9, 0x21, 0x4D, 0x90, 0x24, 0x43, 0x13, 0xE3, 0xFD, 0x1A, 0xC0, 0x0D, 0xA4, 0xBD, 0xEC, 0xFB, 0x9C, 0xD9, 0x79, 0x2E, 0xEA, 0x91, + 0x94, 0x97, 0x06, 0x36, 0xE1, 0xA2, 0x31, 0x3D, 0x0A, 0xC5, 0x24, 0x24, 0x37, 0x6B, 0x3A, 0x78, 0x7D, 0x77, 0x01, 0xD3, 0x38, 0x0A, 0xEB, 0x43, + 0x25, 0x75, 0x89, 0xAD, 0xBB, 0x67, 0x97, 0xD9, 0xE2, 0xAB, 0xF8, 0x29, 0x37, 0x90, 0x22, 0x6E, 0xFF, 0x22, 0x94, 0x1F, 0xFE, 0x4A, 0x70, 0x3F, + 0x15, 0x3C, 0xC7, 0xD1, 0x71, 0xB2, 0x11, 0x75, 0xB2, 0x49, 0xDA, 0xFA, 0x58, 0xB6, 0xF2, 0x29, 0x0A, 0xF9, 0x0D, 0x8C, 0xDC, 0xC5, 0x5D, 0xA5, + 0xDB, 0xEF, 0xBD, 0xFB, 0xEE, 0xED, 0xDE, 0x41, 0x0F, 0x95, 0xE7, 0x72, 0xDC, 0x07, 0x4B, 0xD1, 0x28, 0x56, 0x2F, 0xBA, 0xCE, 0xB6, 0xDE, 0xA2, + 0x37, 0x6E, 0x38, 0xAA, 0x36, 0xBA, 0xDC, 0x1D, 0xB9, 0x7D, 0x06, 0x1D, 0xC1, 0x47, 0xF1, 0x49, 0x72, 0xE0, 0xFC, 0xBF, 0x6A, 0x4A, 0xED, 0xA2, + 0xDD, 0x41, 0x8A, 0x6D, 0x21, 0xB0, 0x19, 0xB0, 0x59, 0x29, 0x2C, 0x14, 0xDF, 0xC4, 0x97, 0xBB, 0x4B, 0x4E, 0x3D, 0x6E, 0xF6, 0xFC, 0x21, 0x8A, + 0x99, 0x02, 0xBC, 0x93, 0x52, 0xB5, 0x76, 0x60, 0xE5, 0x3B, 0xC8, 0xC7, 0x45, 0x3F, 0x45, 0xD7, 0xCB, 0xCC, 0xD0, 0x7C, 0x63, 0x68, 0x78, 0x27, + 0xBD, 0x09, 0x6A, 0x68, 0x6D, 0xC8, 0x09, 0xCC, 0x27, 0x5F, 0x1E, 0x16, 0x98, 0xCA, 0xBA, 0xE0, 0x0D, 0x32, 0x80, 0xEC, 0x02, 0x93, 0xB9, 0x10, + 0xDC, 0x42, 0xD0, 0x82, 0x21, 0xD4, 0xBD, 0x6A, 0xF6, 0xBA, 0x55, 0x4B, 0xEB, 0xB4, 0x02, 0x49, 0x4B, 0x2D, 0x86, 0x2D, 0x6C, 0x7E, 0x5F, 0x05, + 0x3C, 0x3D, 0xC8, 0xC4, 0x78, 0x3F, 0x81, 0x56, 0x03, 0x85, 0x94, 0xA8, 0x33, 0xF3, 0x40, 0x0A, 0x5B, 0x49, 0x41, 0x92, 0x61, 0x0C, 0xE3, 0xE7, + 0x21, 0x0E, 0xA4, 0x18, 0x84, 0x41, 0x51, 0x98, 0xA6, 0x16, 0xF2, 0x01, 0x23, 0xE0, 0xD0, 0x36, 0x2A, 0x84, 0xC2, 0x10, 0x86, 0x23, 0x11, 0x04, + 0x81, 0x10, 0x08, 0xA2, 0x18, 0x21, 0x02, 0x42, 0x88, 0x13, 0x12, 0x42, 0x0C, 0x21, 0xCC, 0xCC, 0x10, 0x8D, 0x79, 0x33, 0x2C, 0x37, 0x1A, 0x08, + 0x0E, 0x76, 0x4C, 0x3B, 0xC7, 0xA7, 0x78, 0x7C, 0x5F, 0x3A, 0x1C, 0x5D, 0x8C, 0x91, 0x56, 0xB6, 0x85, 0xC7, 0xBB, 0x70, 0xC6, 0xF0, 0xE0, 0x87, + 0x15, 0xBC, 0x3B, 0x5D, 0xE6, 0xF9, 0x7D, 0x21, 0xCA, 0xA4, 0xA5, 0x7B, 0xA8, 0x86, 0x1A, 0x60, 0x71, 0x54, 0x00, 0x7E, 0x21, 0x90, 0xF0, 0xCA, + 0xD8, 0x41, 0xB6, 0xAE, 0x5F, 0xAC, 0x71, 0x0C, 0xAA, 0x0E, 0x4D, 0xEA, 0x48, 0x34, 0x7D, 0x0D, 0xFE, 0x24, 0xF2, 0x16, 0x1A, 0x55, 0x4B, 0x9E, + 0x95, 0x33, 0x10, 0x27, 0xA0, 0x48, 0x76, 0x62, 0x1B, 0xB2, 0x47, 0x5A, 0x54, 0x46, 0x3B, 0x5A, 0x5D, 0x56, 0x97, 0xEC, 0x61, 0xFE, 0xCE, 0x7E, + 0xAD, 0xFC, 0x7B, 0xCD, 0x67, 0xEE, 0xBE, 0x8F, 0x69, 0x5C, 0x21, 0x4D, 0x6E, 0xB4, 0xC1, 0x14, 0x41, 0x58, 0x33, 0xFD, 0x59, 0xA7, 0x71, 0xF7, + 0x95, 0xD1, 0x98, 0x6C, 0x5B, 0x2F, 0xF2, 0x64, 0x07, 0x8F, 0x54, 0x9D, 0x63, 0x30, 0x75, 0x1C, 0xC5, 0x59, 0x9C, 0x70, 0xBA, 0x18, 0x5B, 0x7A, + 0xB4, 0x73, 0x37, 0x62, 0xF9, 0x81, 0x59, 0x1C, 0x11, 0xFB, 0xA6, 0xAD, 0x13, 0x43, 0x0E, 0x98, 0xB3, 0x1C, 0x91, 0x32, 0x3B, 0x39, 0x7F, 0xC8, + 0x18, 0xEC, 0xF8, 0xF7, 0xB6, 0x85, 0x86, 0x40, 0x7A, 0x75, 0xCA, 0x33, 0x41, 0x55, 0xBD, 0x3D, 0xE1, 0x90, 0x09, 0x70, 0x69, 0xF3, 0x1B, 0x36, + 0xE5, 0xAC, 0x3A, 0x91, 0x99, 0xC9, 0x03, 0x77, 0x8D, 0x8D, 0x5D, 0xEC, 0x9A, 0xAE, 0x1C, 0xF8, 0xB7, 0xD7, 0xEC, 0xEB, 0xF2, 0x56, 0xA8, 0xB3, + 0x18, 0xEE, 0x76, 0x2A, 0x94, 0x0C, 0xCF, 0xC9, 0xC3, 0x33, 0x2C, 0x4C, 0x7B, 0x69, 0x50, 0xF0, 0x36, 0x9D, 0x0C, 0xC5, 0xEC, 0xFF, 0x6B, 0x71, + 0x26, 0xCE, 0x1E, 0xBB, 0xE2, 0x87, 0xA7, 0x3D, 0x91, 0x11, 0xF9, 0x59, 0xC9, 0x17, 0x0D, 0xB4, 0xAC, 0xAD, 0x8C, 0x60, 0x18, 0x14, 0x5C, 0x82, + 0x88, 0xB9, 0xFB, 0xCC, 0xE7, 0x78, 0xBE, 0x43, 0xCE, 0xBA, 0xFE, 0x6A, 0xE6, 0x8B, 0x1D, 0x23, 0x7E, 0x55, 0x22, 0x2E, 0x2F, 0xE4, 0x60, 0x03, + 0x80, 0xF6, 0x4D, 0xE7, 0xAD, 0x58, 0x6E, 0x5E, 0x38, 0x9D, 0x1D, 0x48, 0x6E, 0x65, 0x5D, 0x1B, 0x5B, 0x11, 0xDB, 0x19, 0x3C, 0x30, 0x32, 0x96, + 0xCE, 0x62, 0x24, 0xAF, 0x59, 0xA4, 0x25, 0xB1, 0xA5, 0x61, 0xC3, 0x1A, 0xC6, 0x75, 0xC3, 0xB8, 0x1D, 0x11, 0x66, 0x5A, 0xDB, 0x2C, 0x04, 0xAB, + 0xF4, 0xB1, 0x68, 0x84, 0xC3, 0xD9, 0x87, 0x30, 0xBF, 0xBB, 0xE3, 0x26, 0x56, 0x3F, 0x0F, 0xB6, 0xE0, 0x61, 0x8C, 0xB9, 0x59, 0xDE, 0xFB, 0xA2, + 0x11, 0x57, 0x91, 0x59, 0x69, 0x7E, 0x26, 0xBB, 0x8E, 0x4B, 0x3E, 0xAC, 0x77, 0xD1, 0x84, 0x79, 0x9A, 0x8C, 0x1D, 0xC1, 0x67, 0x73, 0xBD, 0xCE, + 0x7C, 0x08, 0x4F, 0x87, 0x43, 0xDB, 0xC9, 0xAE, 0xFD, 0xC6, 0x4F, 0xBB, 0x3A, 0x11, 0x06, 0x87, 0x7B, 0x93, 0x75, 0x6A, 0xE7, 0x90, 0x0B, 0x80, + 0x83, 0x77, 0x27, 0x0B, 0x65, 0x9F, 0x74, 0x79, 0xA3, 0xA4, 0x22, 0x63, 0x8D, 0xBA, 0x24, 0xE1, 0xDE, 0xFD, 0x55, 0x8B, 0x9A, 0x0E, 0xD2, 0x3F, + 0x1C, 0xE5, 0x54, 0xD7, 0x67, 0xFD, 0x43, 0x89, 0x87, 0xAA, 0x17, 0x98, 0x87, 0xB4, 0xE2, 0x68, 0x9F, 0x8E, 0xA9, 0x11, 0x82, 0x9E, 0xDA, 0x8F, + 0x0D, 0x29, 0x45, 0xD6, 0x62, 0xE9, 0x2F, 0x2C, 0x04, 0xA8, 0x9B, 0x93, 0xA3, 0xB7, 0xB5, 0x92, 0xBB, 0x70, 0xC1, 0x9C, 0x5A, 0x14, 0x9A, 0x80, + 0xEA, 0x53, 0xEB, 0xAB, 0xF2, 0xDE, 0xEC, 0x25, 0x89, 0xD0, 0xBE, 0x15, 0xDB, 0x81, 0x6B, 0xD5, 0x95, 0x05, 0xC0, 0xC6, 0x5D, 0x1B, 0x98, 0xD8, + 0xB8, 0x8B, 0xE8, 0x32, 0xF8, 0xB3, 0xE4, 0x5B, 0xB3, 0x8B, 0x44, 0xEF, 0x69, 0xD9, 0x35, 0xD1, 0x3D, 0x74, 0xE1, 0x0A, 0x73, 0x80, 0xAE, 0x84, + 0x9B, 0x50, 0xBD, 0xBF, 0x19, 0x93, 0x97, 0xD9, 0x0D, 0x7A, 0xCC, 0x82, 0xD2, 0xA8, 0x11, 0x8B, 0x79, 0xA8, 0x4A, 0x53, 0x20, 0xE4, 0x03, 0xDE, + 0xD5, 0x47, 0x1F, 0x76, 0x4B, 0x78, 0x93, 0xAE, 0xB5, 0xD4, 0x39, 0xC4, 0x5F, 0x70, 0xA3, 0x31, 0x50, 0x95, 0x95, 0x34, 0x02, 0xE1, 0xE0, 0xB9, + 0xA8, 0xDB, 0x8F, 0xBC, 0xF3, 0xD6, 0x70, 0x49, 0xAC, 0x96, 0x0A, 0x4A, 0x04, 0xC2, 0x9A, 0xDB, 0xA7, 0x7F, 0x32, 0x01, 0x84, 0x6C, 0x64, 0x97, + 0x5E, 0x76, 0x7D, 0x63, 0x52, 0x81, 0xFE, 0x4A, 0x1E, 0xB7, 0x1A, 0xEB, 0xA4, 0x7A, 0x57, 0x4D, 0xF5, 0x5D, 0xDC, 0xB1, 0xFF, 0xB6, 0x17, 0x8B, + 0x74, 0xF9, 0x08, 0x6F, 0xBB, 0xEC, 0x9F, 0xB9, 0xC3, 0x6C, 0x0E, 0x8F, 0x7E, 0x9F, 0x50, 0xB1, 0xCB, 0xC5, 0xEB, 0x3B, 0x09, 0xBB, 0x2D, 0xB3, + 0xA6, 0x30, 0x64, 0xD9, 0xFC, 0xEE, 0x33, 0x86, 0xCE, 0xF0, 0xF9, 0xEB, 0x51, 0x1D, 0xB1, 0xC5, 0x2A, 0x49, 0x77, 0x46, 0xD9, 0x02, 0x1D, 0xA3, + 0x40, 0xC5, 0x41, 0x04, 0x9B, 0x41, 0xB5, 0xAD, 0x9F, 0xCF, 0x75, 0xD7, 0xD9, 0x21, 0x59, 0xFE, 0xD5, 0x80, 0xCC, 0xB6, 0x8E, 0xB9, 0x2E, 0x57, + 0xB1, 0x1B, 0x17, 0x09, 0x80, 0x2D, 0x10, 0x1A, 0x92, 0xB3, 0x87, 0x6F, 0xEB, 0x24, 0xE8, 0x53, 0x7B, 0x4E, 0xF1, 0x85, 0x30, 0xFD, 0x3C, 0x7D, + 0x08, 0xE0, 0x90, 0x61, 0xF8, 0x12, 0xD0, 0xEC, 0x66, 0x0F, 0x02, 0xDB, 0xE6, 0xA5, 0x0D, 0x22, 0xEB, 0x6B, 0x63, 0xCE, 0xBE, 0x12, 0x8F, 0xEE, + 0xE0, 0x65, 0xFC, 0x20, 0xED, 0x19, 0x45, 0x4E, 0xD5, 0x3A, 0xE9, 0x6F, 0xF4, 0x92, 0xC8, 0xA1, 0x3B, 0x75, 0xD3, 0x6A, 0x6F, 0xCA, 0x6B, 0x61, + 0xCC, 0xFC, 0x6F, 0xFF, 0x7D, 0x7A, 0x79, 0xCE, 0x5B, 0x81, 0x3B, 0x03, 0x89, 0x88, 0xE7, 0x3E, 0xC4, 0x3C, 0xA2, 0xCC, 0xC9, 0x94, 0x0D, 0x8A, + 0x8D, 0x39, 0xA3, 0xCB, 0xFE, 0x10, 0x21, 0x15, 0x30, 0x8C, 0xC2, 0x47, 0xD7, 0x6E, 0x22, 0xB8, 0xDE, 0xA7, 0x3F, 0x5A, 0x83, 0x8E, 0xEC, 0xBA, + 0x08, 0x59, 0xA5, 0x3B, 0xD1, 0x3F, 0x33, 0x44, 0x4E, 0xE7, 0xBB, 0x0D, 0x60, 0xC7, 0xD6, 0xA1, 0x55, 0x18, 0x18, 0xDA, 0x44, 0x74, 0x92, 0xE7, + 0xFA, 0x12, 0x53, 0xD0, 0xC6, 0xC6, 0xA5, 0xA9, 0xC6, 0x31, 0xEC, 0xAC, 0x82, 0x5C, 0x54, 0x1E, 0x66, 0x57, 0x04, 0x2E, 0x6B, 0xDF, 0x20, 0xF7, + 0x59, 0x9D, 0x2A, 0xA9, 0xBA, 0xCB, 0xB6, 0xC8, 0x27, 0x17, 0xBC, 0xA6, 0xA9, 0xC7, 0x79, 0xA3, 0x48, 0xFB, 0x88, 0xD5, 0xB4, 0x2F, 0xE3, 0x6E, + 0x84, 0xB4, 0x84, 0xFB, 0xA7, 0xD5, 0xF7, 0xC6, 0xF2, 0x34, 0x3C, 0x3F, 0x89, 0x16, 0x10, 0x76, 0x44, 0x22, 0x01, 0x88, 0x9B, 0x09, 0xD3, 0x0C, + 0x33, 0x9B, 0x29, 0xFE, 0x26, 0x3F, 0xD3, 0xD5, 0x45, 0x67, 0x32, 0x6B, 0x4E, 0x51, 0x1A, 0x99, 0x6D, 0x92, 0xAC, 0x35, 0x92, 0x75, 0x03, 0x6B, + 0xCC, 0xBD, 0x9D, 0x24, 0xAE, 0xB5, 0x35, 0x12, 0x7F, 0x83, 0xAA, 0x72, 0xC0, 0x6D, 0x23, 0x1F, 0xC8, 0xCB, 0x58, 0x28, 0xCF, 0xD9, 0x90, 0xF8, + 0x21, 0x06, 0x9C, 0x50, 0xE5, 0x22, 0xD6, 0xF0, 0x7C, 0x93, 0x8B, 0x9B, 0x12, 0x47, 0x69, 0x71, 0xE3, 0xF5, 0x7A, 0xE5, 0xCB, 0x41, 0x38, 0x44, + 0x8F, 0xA7, 0x41, 0xD5, 0x64, 0x96, 0xB3, 0x0B, 0xA9, 0xB6, 0xCD, 0x75, 0xC5, 0x54, 0x34, 0xFA, 0x62, 0x82, 0x2B, 0x5A, 0x77, 0xF4, 0x30, 0x43, + 0x0F, 0x65, 0x44, 0xC4, 0x25, 0x1C, 0x6F, 0x09, 0xF5, 0x33, 0x11, 0xDD, 0xC3, 0xC2, 0xB4, 0xAC, 0x8D, 0x72, 0x7E, 0x1A, 0x4F, 0x06, 0x9A, 0x67, + 0xA3, 0x18, 0x28, 0x8A, 0xF7, 0xBA, 0x56, 0xF8, 0xCA, 0xB6, 0xE2, 0xD0, 0x95, 0xD5, 0x88, 0x48, 0x68, 0xA6, 0xF1, 0x72, 0x77, 0x81, 0x65, 0x32, + 0xEB, 0x5A, 0x90, 0x29, 0xF7, 0xDF, 0x3C, 0x33, 0xA2, 0xFD, 0x11, 0x60, 0x8D, 0x38, 0xDB, 0xDD, 0x12, 0x63, 0xA4, 0x36, 0xAA, 0x99, 0xE6, 0x09, + 0x6F, 0xDC, 0xB0, 0x4B, 0x39, 0x22, 0x2C, 0x1A, 0x39, 0x70, 0x3D, 0x27, 0x7E, 0xDC, 0x0E, 0xE3, 0x33, 0x62, 0xF0, 0x30, 0x13, 0xCB, 0x52, 0xB7, + 0xF6, 0xD8, 0x1C, 0xE4, 0xD5, 0xD1, 0x6F, 0x19, 0x18, 0x72, 0xD5, 0xF3, 0x2A, 0x80, 0xC1, 0x9A, 0xC3, 0x77, 0x71, 0x78, 0xE5, 0x38, 0xBA, 0x90, + 0x79, 0x42, 0xDD, 0xBA, 0x76, 0x17, 0x07, 0x2D, 0x30, 0x6E, 0xE5, 0xE4, 0x25, 0x9D, 0xDE, 0xB6, 0x45, 0x0F, 0x33, 0xD0, 0x14, 0xD7, 0x6F, 0x27, + 0xEC, 0x54, 0x34, 0xE3, 0xB8, 0x8B, 0xAF, 0x23, 0xDE, 0xDE, 0x1D, 0x6F, 0xC7, 0x57, 0x74, 0xB3, 0xD4, 0x43, 0x4C, 0x21, 0xE2, 0x8E, 0xDF, 0x42, + 0x3D, 0xDD, 0xF1, 0xA5, 0x4D, 0x14, 0xBC, 0x91, 0x48, 0xE6, 0xC2, 0x48, 0xF2, 0x99, 0x2A, 0x6E, 0x6E, 0x87, 0xCB, 0xDA, 0xEC, 0xEB, 0xAD, 0xD8, + 0x69, 0xBB, 0xBA, 0xBF, 0xEA, 0xD6, 0xE6, 0xCC, 0xE1, 0x22, 0x06, 0x7C, 0x7F, 0x74, 0x18, 0x23, 0xF5, 0xBC, 0x90, 0x06, 0xEE, 0x35, 0xEF, 0x85, + 0x93, 0x31, 0x30, 0x44, 0x3C, 0x8C, 0xC5, 0x74, 0x88, 0x35, 0x7C, 0x48, 0xB7, 0x5F, 0x7C, 0x0D, 0x20, 0x0F, 0x6B, 0x6C, 0x4D, 0xC5, 0xEF, 0x10, + 0x1B, 0x21, 0x72, 0x45, 0x90, 0xF3, 0x51, 0xED, 0x3D, 0x8E, 0x08, 0x70, 0xA0, 0x0B, 0xB0, 0x81, 0x41, 0xA0, 0x59, 0xAE, 0x76, 0x06, 0x0D, 0x11, + 0x43, 0x6F, 0x1D, 0x00, 0xD5, 0x93, 0xB2, 0x15, 0x82, 0x2A, 0x7C, 0x6E, 0x7B, 0x79, 0x99, 0x6B, 0xF3, 0x1D, 0x27, 0x3E, 0x5D, 0xCB, 0x8E, 0x4A, + 0x07, 0xF5, 0x2C, 0x17, 0xF3, 0x4C, 0x1D, 0x66, 0xA9, 0x8D, 0x0C, 0xE6, 0x7C, 0x74, 0x16, 0xE1, 0x89, 0xF8, 0x83, 0xAF, 0x1A, 0x8B, 0xC5, 0x0F, + 0xE7, 0xA6, 0xA6, 0xD6, 0xE4, 0xF6, 0x98, 0xDF, 0xED, 0xE9, 0x38, 0x24, 0x11, 0xF4, 0x47, 0x4D, 0x8C, 0xB0, 0xCE, 0x6B, 0x86, 0x1C, 0xE8, 0xC6, + 0x48, 0x09, 0xD2, 0xDA, 0xAA, 0xB1, 0xF1, 0xD5, 0x31, 0xDE, 0x50, 0x21, 0xB5, 0xED, 0x01, 0x11, 0xED, 0x61, 0x51, 0xD0, 0x30, 0xFC, 0x71, 0x3B, + 0x5A, 0xAC, 0x68, 0x2C, 0xC7, 0xC4, 0x47, 0xD5, 0xC6, 0x4C, 0x49, 0x4E, 0x73, 0x91, 0xE4, 0xAC, 0x99, 0x79, 0xEC, 0xAD, 0x55, 0x93, 0x8A, 0xE1, + 0x14, 0x9B, 0xFE, 0x4B, 0x22, 0xA4, 0x73, 0x5F, 0xCF, 0x10, 0xBB, 0x9F, 0x29, 0x24, 0x66, 0xC7, 0xE9, 0x1B, 0x5F, 0x54, 0x24, 0x43, 0x09, 0xFA, + 0xDF, 0x6F, 0xBB, 0x9C, 0x33, 0x3C, 0xF2, 0xF3, 0xF3, 0xFB, 0xDF, 0x2A, 0xA5, 0x25, 0x63, 0x1B, 0x5B, 0x8A, 0x9F, 0x6D, 0x9A, 0xCB, 0x57, 0xCF, + 0xC9, 0xC7, 0x8D, 0x0E, 0xD3, 0xA2, 0xDA, 0x0C, 0x31, 0xFF, 0xE5, 0xB5, 0x17, 0x97, 0x55, 0x3F, 0xC7, 0x4F, 0xFC, 0x2E, 0x3B, 0x6B, 0xC6, 0xA6, + 0x6D, 0xF0, 0x1B, 0xEE, 0x9D, 0x5F, 0xA4, 0x03, 0x7C, 0xBA, 0x56, 0xA4, 0x99, 0x4B, 0x43, 0xC6, 0xC4, 0xFD, 0x39, 0x44, 0x1C, 0x05, 0x06, 0x71, + 0xDB, 0x3C, 0xCC, 0x4E, 0x9F, 0xB3, 0xF8, 0xFC, 0xD1, 0xE2, 0x5B, 0x21, 0x04, 0xFF, 0x12, 0x2E, 0xB6, 0x4C, 0xA3, 0x98, 0xE3, 0xDC, 0xB9, 0xAC, + 0x5B, 0x09, 0xBC, 0xBF, 0xF3, 0x85, 0x0A, 0xE0, 0x58, 0x98, 0xC3, 0xB9, 0x1F, 0x55, 0xFC, 0x31, 0x44, 0x86, 0x75, 0x0C, 0x19, 0x98, 0x0C, 0x18, + 0x15, 0x30, 0xDE, 0x14, 0x24, 0xCF, 0x47, 0xD2, 0x5C, 0x7F, 0xA0, 0xDB, 0xCA, 0x8E, 0x46, 0x4D, 0x4D, 0x18, 0xF9, 0x99, 0xA0, 0x33, 0xCB, 0x48, + 0x19, 0x14, 0x6E, 0xA9, 0x27, 0x09, 0x78, 0x1E, 0x3C, 0xDF, 0x10, 0x1B, 0xEA, 0x3E, 0x87, 0x94, 0x68, 0xB6, 0xB7, 0x3A, 0x4B, 0xEB, 0xBE, 0xC3, + 0x4A, 0x12, 0x58, 0xD2, 0x66, 0x66, 0xA7, 0x04, 0xD6, 0x41, 0xC3, 0x34, 0xC3, 0x83, 0x36, 0x7A, 0x5F, 0xEE, 0x6D, 0x1B, 0x73, 0x63, 0x47, 0x0D, + 0xA3, 0xE2, 0x46, 0x2B, 0xCD, 0x04, 0x82, 0x9D, 0xEE, 0xC3, 0x59, 0x8C, 0x2D, 0x4D, 0xBD, 0x8F, 0x02, 0xDD, 0x58, 0xAB, 0x7D, 0x6C, 0xD8, 0x93, + 0xF8, 0x3F, 0xE7, 0x30, 0x91, 0xB2, 0x0C, 0xC2, 0xDB, 0xBC, 0x49, 0xBC, 0x3D, 0x35, 0xC5, 0xCE, 0xA4, 0x26, 0x64, 0x0E, 0x18, 0x7A, 0xFC, 0xDB, + 0x23, 0x96, 0x3C, 0x5D, 0xC5, 0x58, 0xA8, 0x87, 0x5E, 0xEE, 0x28, 0xC9, 0xCF, 0xBB, 0x25, 0x0D, 0xD9, 0x77, 0x95, 0x26, 0x6D, 0x5B, 0xFF, 0x45, + 0x25, 0xC8, 0x4B, 0xD4, 0x60, 0x12, 0xAB, 0xC6, 0x68, 0x0B, 0xC7, 0x7D, 0xB5, 0xCC, 0xA0, 0x87, 0xC9, 0x93, 0xE7, 0xDD, 0x82, 0x37, 0xBE, 0xCD, + 0x59, 0x3E, 0xFE, 0xDF, 0xF7, 0x66, 0x8F, 0x8B, 0x58, 0x9C, 0x4A, 0xA6, 0x6D, 0x76, 0xDF, 0xC4, 0xC8, 0x0E, 0x88, 0x87, 0xD7, 0x23, 0xE0, 0x17, + 0x0D, 0xBB, 0x91, 0x16, 0x33, 0x6E, 0x1D, 0x38, 0xB9, 0xB5, 0xFC, 0xB3, 0x01, 0xF8, 0x6C, 0xC6, 0x2A, 0x02, 0xE0, 0xDC, 0xCE, 0xD8, 0x88, 0xCC, + 0xA4, 0xB8, 0xED, 0xCD, 0x3D, 0xD4, 0x5B, 0xBE, 0xD4, 0x48, 0xCC, 0x67, 0x6B, 0x7A, 0xEC, 0x1D, 0xCF, 0x0E, 0x63, 0xCA, 0x70, 0x8B, 0xB1, 0xB7, + 0xB5, 0x0F, 0x9F, 0xEF, 0x75, 0xC2, 0xBC, 0x23, 0xE3, 0x4B, 0xEB, 0x18, 0x66, 0x5D, 0x3E, 0x82, 0x42, 0x1F, 0xEF, 0xF9, 0x20, 0x6A, 0x3C, 0xCD, + 0x71, 0xFF, 0xE8, 0x8E, 0x15, 0x3B, 0xB7, 0xB7, 0x26, 0x0D, 0xC2, 0xFD, 0x3F, 0x06, 0x4E, 0xC9, 0x12, 0x2E, 0xCC, 0xD1, 0x79, 0xBF, 0xAC, 0x6C, + 0x3C, 0x33, 0xCF, 0x73, 0x3C, 0x66, 0xEC, 0x5C, 0x48, 0x9B, 0x0E, 0x2F, 0x67, 0xC0, 0x6A, 0xA5, 0x4E, 0x5F, 0x36, 0x92, 0x34, 0x69, 0x01, 0x1F, + 0xBA, 0x5A, 0x8D, 0xCA, 0x23, 0x02, 0x06, 0xBB, 0xBB, 0xCA, 0x88, 0x27, 0x77, 0x83, 0x0F, 0x74, 0x7F, 0x4F, 0x3E, 0x68, 0xAB, 0xB2, 0xF1, 0xB4, + 0xE8, 0xCB, 0x59, 0x48, 0x9A, 0x16, 0x32, 0xE4, 0xF7, 0x90, 0x86, 0x24, 0x33, 0xAE, 0x04, 0x5C, 0xE4, 0x32, 0x0C, 0xEC, 0x41, 0xAD, 0x67, 0xF9, + 0xB2, 0x6F, 0x8A, 0x6F, 0xA9, 0x6D, 0xEB, 0x39, 0xFF, 0x09, 0xE6, 0xD5, 0x98, 0x6B, 0x30, 0xD0, 0x9D, 0xFA, 0x52, 0xD8, 0x94, 0xEB, 0xEA, 0xDF, + 0xA4, 0xB9, 0xFB, 0x5E, 0x3A, 0xFE, 0xFD, 0xB4, 0x43, 0x4E, 0x2F, 0x7F, 0xEB, 0xD8, 0x8B, 0x18, 0xB1, 0xF6, 0x71, 0xF1, 0x61, 0x83, 0xD7, 0x87, + 0x6F, 0x17, 0x21, 0x99, 0x6E, 0x4A, 0xD8, 0x1D, 0x06, 0x55, 0xB8, 0xAE, 0x40, 0x56, 0x1E, 0xDD, 0x43, 0x1D, 0xB6, 0xF1, 0xC6, 0xED, 0x61, 0x9D, + 0x7A, 0x16, 0xF6, 0x67, 0x88, 0x41, 0x3C, 0xC4, 0xCB, 0x61, 0x55, 0x8E, 0xF0, 0x4F, 0x07, 0x36, 0x13, 0x5C, 0xE4, 0x21, 0xD8, 0xA2, 0xDE, 0x88, + 0x52, 0x95, 0xCF, 0x00, 0xF7, 0x29, 0x34, 0x5A, 0x4E, 0xF9, 0x75, 0xED, 0x97, 0x19, 0xB6, 0xDE, 0xFB, 0x88, 0xE3, 0x2A, 0xC2, 0x22, 0xC2, 0x25, + 0x24, 0x56, 0x10, 0x17, 0x10, 0x2E, 0x23, 0x56, 0xF4, 0x05, 0x11, 0x3E, 0xAF, 0x22, 0xB3, 0x84, 0x78, 0x81, 0x74, 0x1D, 0xE9, 0xAA, 0x40, 0x6C, + 0x9C, 0x2C, 0x05, 0x9A, 0x61, 0x41, 0x65, 0xFB, 0x10, 0x73, 0x4D, 0x95, 0x5D, 0x83, 0xEF, 0xA4, 0x54, 0xA3, 0x71, 0x73, 0xA8, 0x79, 0xFB, 0x40, + 0xA4, 0x6D, 0x16, 0xD1, 0xB3, 0xE2, 0x82, 0xBA, 0x16, 0x5F, 0x94, 0xC8, 0x8D, 0xA1, 0x11, 0xD4, 0x89, 0xCE, 0xB9, 0x65, 0x9E, 0x57, 0x46, 0xDA, + 0xBA, 0x15, 0x1D, 0xD8, 0x18, 0x52, 0xF0, 0x9E, 0x06, 0x02, 0x1C, 0x0F, 0x64, 0x85, 0x1F, 0x59, 0x09, 0xD2, 0xDE, 0x3D, 0x2D, 0x4E, 0x41, 0x28, + 0xBE, 0x27, 0x72, 0x35, 0x14, 0x1B, 0x32, 0xA0, 0x5C, 0x37, 0x2F, 0x30, 0x1E, 0x1C, 0x99, 0xE9, 0x2B, 0x2D, 0x05, 0x6D, 0x5D, 0x6E, 0xF8, 0xE4, + 0xB6, 0xF6, 0x04, 0xE5, 0x75, 0xA5, 0xA5, 0xC8, 0xB6, 0xC4, 0xF6, 0xC9, 0xFB, 0x03, 0x12, 0x27, 0x6B, 0x41, 0x6A, 0x58, 0x96, 0x91, 0x35, 0x01, + 0xA7, 0x1D, 0x28, 0x1D, 0x9B, 0xB6, 0x44, 0x22, 0x54, 0xEA, 0x7D, 0x0A, 0x8B, 0x3C, 0x03, 0x64, 0x99, 0x33, 0x0B, 0x83, 0x12, 0xB3, 0x93, 0xA7, + 0x35, 0x2C, 0x5D, 0xA3, 0xB2, 0x83, 0x13, 0x6A, 0xCF, 0x19, 0xB0, 0x62, 0x38, 0x23, 0xA6, 0x29, 0x9D, 0x2A, 0x8B, 0x59, 0xAE, 0x7D, 0x33, 0xC2, + 0x11, 0xFA, 0x56, 0x1D, 0xEA, 0x1A, 0x1C, 0xB6, 0xA0, 0x46, 0x83, 0x09, 0x7E, 0x2C, 0xB7, 0x2A, 0xE1, 0xE1, 0x31, 0x47, 0x7F, 0xF9, 0x52, 0x70, + 0x3C, 0xE8, 0x00, 0x0B, 0x91, 0xDA, 0xB9, 0xAD, 0x13, 0x5B, 0xED, 0x5C, 0x10, 0xDD, 0x48, 0xB3, 0x49, 0x71, 0x6A, 0x23, 0x6D, 0x58, 0xD8, 0xEB, + 0x75, 0x9C, 0x0A, 0x3E, 0x30, 0x53, 0xCE, 0xC9, 0xA1, 0x99, 0x5C, 0x87, 0x0E, 0x4D, 0x6D, 0x83, 0x99, 0x84, 0xA5, 0x3D, 0x00, 0x5C, 0xE5, 0x43, + 0xBE, 0x99, 0x37, 0x01, 0xE9, 0x59, 0xA6, 0x35, 0x5B, 0xEB, 0x6E, 0xB7, 0x19, 0x49, 0xA7, 0x33, 0x59, 0xB1, 0x41, 0x5F, 0x43, 0xBB, 0x65, 0xFA, + 0xE1, 0xAE, 0xFC, 0x20, 0x8D, 0x40, 0x3C, 0xC3, 0x1F, 0xB8, 0x04, 0x7B, 0xF3, 0x20, 0x31, 0xA2, 0x80, 0x85, 0x6F, 0x57, 0xD8, 0x6D, 0xE6, 0x7D, + 0x88, 0xBA, 0xFA, 0x66, 0x82, 0x79, 0xEB, 0x99, 0x26, 0xB0, 0x0A, 0x6A, 0x43, 0x9D, 0xBE, 0x39, 0x20, 0xDA, 0xB1, 0x75, 0xBB, 0x55, 0x75, 0xC9, + 0x1D, 0x48, 0x42, 0xB7, 0x9A, 0xC8, 0x04, 0x7F, 0x6A, 0xE9, 0x3D, 0xB0, 0xCC, 0x1C, 0x9D, 0xD0, 0x92, 0x73, 0xF9, 0x06, 0x4C, 0x1D, 0x9B, 0x80, + 0x8E, 0x61, 0xBB, 0x3A, 0xC6, 0xA7, 0x52, 0x76, 0x85, 0xFD, 0xA6, 0xDC, 0x2D, 0x63, 0xAF, 0x36, 0x73, 0x0E, 0x26, 0xFF, 0x0F, 0x54, 0x8E, 0xA3, + 0xD0, 0x9D, 0x2B, 0x78, 0x95, 0x8A, 0x34, 0x1D, 0x9B, 0xA8, 0xD9, 0x00, 0x13, 0x33, 0xE5, 0x17, 0x39, 0xD3, 0xA0, 0x04, 0xF7, 0x66, 0x38, 0x47, + 0x65, 0x46, 0x22, 0x17, 0x0C, 0x50, 0x00, 0x8B, 0x63, 0xB4, 0x18, 0x96, 0x01, 0x8A, 0x01, 0x95, 0x01, 0x32, 0xCE, 0x21, 0xCA, 0x42, 0xC1, 0x18, + 0x66, 0xDD, 0x60, 0xFC, 0x10, 0xDE, 0xC4, 0x1A, 0x1C, 0xF5, 0x80, 0x96, 0xE1, 0x2A, 0x13, 0x96, 0x11, 0x40, 0x87, 0x00, 0x0C, 0xF0, 0x22, 0x4E, + 0x9A, 0x12, 0x40, 0x58, 0x02, 0xA6, 0x82, 0x0F, 0xDE, 0xB7, 0x43, 0x04, 0x93, 0x80, 0xE4, 0x99, 0x8C, 0x85, 0xFB, 0xA3, 0x6D, 0xC2, 0x08, 0x38, + 0x20, 0xA3, 0x0B, 0x50, 0x3C, 0x40, 0x7A, 0xAD, 0x3A, 0xBB, 0x81, 0x80, 0xA2, 0x42, 0xE3, 0x8C, 0x25, 0x0A, 0xCA, 0xB6, 0xCE, 0x42, 0x01, 0x15, + 0xD4, 0x96, 0xB5, 0xC0, 0x06, 0x54, 0x85, 0xBF, 0xAC, 0x0E, 0x40, 0xA0, 0xBA, 0x28, 0xB3, 0xCA, 0x8E, 0x40, 0xCD, 0x58, 0xCD, 0xBA, 0x01, 0x88, + 0xE9, 0xF7, 0x25, 0x6B, 0xB0, 0x12, 0xD3, 0x91, 0xF5, 0x9C, 0xC9, 0x04, 0x4D, 0x7B, 0x06, 0x33, 0xCA, 0xF6, 0xC3, 0xCE, 0x4B, 0x26, 0xA4, 0x4F, + 0x57, 0xF2, 0x3D, 0x7E, 0x90, 0x27, 0x3D, 0xA1, 0xE0, 0x86, 0xDC, 0xDD, 0x45, 0x52, 0x77, 0xE8, 0xF1, 0x4A, 0x51, 0x6A, 0xC8, 0xAD, 0x5E, 0xA5, + 0xD4, 0xDB, 0xE3, 0x55, 0xDF, 0xE0, 0xBD, 0x5D, 0x1E, 0x77, 0x5C, 0x5E, 0xB7, 0x0A, 0xB8, 0xC4, 0x46, 0x2F, 0x30, 0x1B, 0x8D, 0x92, 0x50, 0xA3, + 0x65, 0x29, 0x2C, 0x87, 0x30, 0x62, 0xD0, 0x45, 0xD0, 0x3D, 0xD0, 0x63, 0xFB, 0xEB, 0x0C, 0x8D, 0xA0, 0x91, 0x4E, 0xB8, 0x5A, 0xD5, 0x6A, 0x61, + 0x03, 0x2D, 0x55, 0x6E, 0x09, 0xDB, 0x2E, 0x53, 0x05, 0xC8, 0x52, 0x42, 0x02, 0xA2, 0x30, 0xE8, 0x69, 0xB0, 0xA0, 0x94, 0xC1, 0x0B, 0x12, 0xCA, + 0x04, 0xD6, 0x53, 0x1B, 0x1A, 0x43, 0xDA, 0xD2, 0x05, 0xC0, 0xDC, 0xC2, 0xDD, 0x87, 0x0A, 0x97, 0x3A, 0x14, 0x1E, 0x5B, 0x38, 0xA5, 0xCE, 0x36, + 0x9D, 0xCE, 0x4D, 0xF8, 0x02, 0x80, 0x8B, 0x10, 0x09, 0x3D, 0x0D, 0x22, 0xD8, 0xF4, 0x80, 0x20, 0xA1, 0xC3, 0x03, 0xA4, 0x21, 0x4C, 0x24, 0x56, + 0x2C, 0x71, 0x00, 0x55, 0x6A, 0xE1, 0xC1, 0x01, 0x0B, 0xD7, 0xA4, 0x1E, 0x65, 0x0D, 0xE6, 0xBE, 0x0C, 0x16, 0xE3, 0x16, 0x0C, 0x19, 0x42, 0x52, + 0x72, 0x78, 0x94, 0x29, 0x63, 0x94, 0x85, 0x53, 0x81, 0x94, 0x04, 0x0A, 0x72, 0xA6, 0x14, 0x75, 0x35, 0x10, 0x25, 0xF9, 0x04, 0x00, 0xB0, 0x0C, + 0xAD, 0x20, 0x45, 0xA0, 0x54, 0x73, 0xC0, 0x76, 0x14, 0x53, 0x65, 0x31, 0x70, 0x9F, 0x0B, 0xA8, 0xB8, 0x21, 0x80, 0xA9, 0x45, 0x68, 0xC7, 0x51, + 0x50, 0x14, 0x9C, 0xC3, 0x0D, 0x61, 0x8F, 0xE4, 0x99, 0xE2, 0xE7, 0x40, 0x95, 0x6B, 0x4F, 0xD3, 0x82, 0xDC, 0x31, 0x9E, 0xB1, 0xD5, 0x4E, 0x81, + 0x37, 0x01, 0x64, 0x15, 0x01, 0x30, 0x0C, 0x82, 0xF9, 0x72, 0x00, 0xF0, 0xC2, 0xD4, 0x31, 0x42, 0x98, 0xD3, 0xD6, 0x8A, 0xB3, 0x9A, 0xE4, 0x06, + 0xF0, 0xD6, 0x46, 0x36, 0x48, 0xAD, 0x18, 0xA4, 0xE6, 0x07, 0x17, 0xCD, 0xA4, 0x0F, 0x2A, 0x3A, 0x70, 0xA4, 0x34, 0xD0, 0x4C, 0x48, 0xEA, 0xD2, + 0xC6, 0xC3, 0x00, 0x4F, 0x42, 0x6C, 0xA9, 0x59, 0x97, 0xDC, 0xFD, 0xD0, 0xDD, 0xD0, 0xD5, 0x90, 0xEE, 0x44, 0xC8, 0x75, 0x5F, 0x5B, 0x17, 0x17, + 0x3E, 0x69, 0x62, 0xFE, 0x70, 0x1E, 0xFC, 0x48, 0x7D, 0xA6, 0xBB, 0x43, 0x1E, 0x60, 0x82, 0x2C, 0xB8, 0x13, 0x00, 0x89, 0x23, 0x98, 0x3A, 0x56, + 0x28, 0xB3, 0x36, 0xD5, 0x66, 0x80, 0xD8, 0xE4, 0x2F, 0x72, 0x9D, 0x17, 0xDC, 0x7D, 0x82, 0xAF, 0x31, 0x27, 0x01, 0xC0, 0x4A, 0xA4, 0x2B, 0x59, + 0x0D, 0x80, 0x50, 0x32, 0x27, 0x19, 0xD2, 0x6D, 0x12, 0x7C, 0xE0, 0x66, 0xAA, 0xD0, 0x74, 0x7D, 0x5D, 0x7B, 0x31, 0x34, 0x52, 0x43, 0x11, 0x64, + 0x71, 0x25, 0x68, 0xE4, 0x8F, 0x46, 0x80, 0x03, 0x88, 0x57, 0xA2, 0x14, 0x94, 0x5F, 0x3F, 0x09, 0x5D, 0x17, 0xC4, 0xC8, 0x20, 0xAB, 0xD1, 0x74, + 0x55, 0xF5, 0xF5, 0xDD, 0xA7, 0xAE, 0xCF, 0x1F, 0xCE, 0x20, 0x86, 0x4E, 0x29, 0x95, 0x5B, 0x9B, 0x84, 0x1F, 0xB1, 0x4C, 0xF7, 0xF6, 0x99, 0xF9, + 0x46, 0x79, 0xDC, 0x1B, 0xAE, 0x24, 0xCC, 0xA9, 0x80, 0xD2, 0x11, 0x94, 0x85, 0x0E, 0xA0, 0x03, 0x0A, 0x6B, 0x53, 0x27, 0xC9, 0x12, 0xE1, 0x76, + 0xAA, 0xE5, 0x0B, 0x90, 0x77, 0x16, 0x82, 0xC0, 0x13, 0x05, 0xB2, 0xC6, 0xDB, 0xF5, 0x9B, 0x38, 0x8B, 0x6E, 0x66, 0x2F, 0xB8, 0x47, 0x6C, 0xE9, + 0x6D, 0x13, 0xAA, 0x2C, 0x74, 0x99, 0xB6, 0xA0, 0x1C, 0x7C, 0x9D, 0xCC, 0x24, 0x62, 0x30, 0x35, 0x19, 0x34, 0xB1, 0xBD, 0x68, 0xDD, 0x0A, 0x5D, + 0x0A, 0xDD, 0xEE, 0xD8, 0xAC, 0x9B, 0xDA, 0x23, 0xAD, 0xCA, 0xAA, 0xE9, 0xC2, 0xE7, 0x81, 0xB3, 0xF1, 0x37, 0xAA, 0x4A, 0x0D, 0xFF, 0x48, 0x64, + 0xBA, 0x58, 0x5D, 0x27, 0xC8, 0x30, 0x61, 0x24, 0x40, 0xD0, 0x49, 0x91, 0x73, 0x89, 0x67, 0xD3, 0xD8, 0xC1, 0x00, 0x87, 0xA6, 0x6E, 0x66, 0xD4, + 0x34, 0x9F, 0xF9, 0x7B, 0xDE, 0xA2, 0xAD, 0xEE, 0x9A, 0x8E, 0xA7, 0xEA, 0x7B, 0x0C, 0xC2, 0x9C, 0x18, 0x87, 0xF1, 0x05, 0x72, 0x9F, 0x14, 0xD8, + 0xFA, 0x75, 0x59, 0x09, 0xE9, 0xD8, 0x09, 0x48, 0xFA, 0x39, 0x29, 0x6E, 0x42, 0x1E, 0x2E, 0xA1, 0xC1, 0x15, 0x4F, 0x14, 0xCE, 0x51, 0x9E, 0x6E, + 0x57, 0xB7, 0x43, 0x97, 0x43, 0xB7, 0x29, 0xAF, 0xCB, 0x87, 0x07, 0x3C, 0x68, 0xE0, 0x65, 0x55, 0xC5, 0x28, 0xF6, 0xB3, 0x2E, 0x3E, 0x36, 0xB8, + 0x64, 0xE1, 0x95, 0x8D, 0xD8, 0xFB, 0x61, 0x77, 0xF6, 0xAB, 0x75, 0xC6, 0x0B, 0x08, 0xF5, 0x44, 0x67, 0xA7, 0x09, 0xA7, 0x2D, 0x5D, 0x4F, 0x84, + 0x94, 0x28, 0x01, 0xE6, 0xC2, 0xF5, 0x94, 0x91, 0x34, 0x26, 0x50, 0xA5, 0xEF, 0x8A, 0x04, 0x04, 0x50, 0x2D, 0x4A, 0x16, 0x5A, 0x5A, 0xAE, 0x35, + 0x93, 0xA4, 0x5E, 0x5A, 0x68, 0x30, 0xD1, 0xE9, 0x4B, 0x32, 0x32, 0xE5, 0x97, 0x62, 0x32, 0xC7, 0x92, 0x73, 0x5E, 0x17, 0x3C, 0x88, 0x97, 0xB3, + 0xA4, 0x00, 0x7C, 0xF4, 0xCB, 0xA8, 0x13, 0x5A, 0xD1, 0x2C, 0x3C, 0xA1, 0xB8, 0x03, 0x42, 0x73, 0x98, 0x40, 0x09, 0x3C, 0xF8, 0x6C, 0x90, 0xE5, + 0x79, 0x01, 0x44, 0xA7, 0x07, 0x17, 0x9C, 0x27, 0x5E, 0x6C, 0x8A, 0x81, 0xD0, 0xAC, 0xD1, 0x23, 0xF3, 0xED, 0x45, 0x12, 0xBC, 0x8F, 0x59, 0xD8, + 0xE3, 0x12, 0x92, 0x0E, 0xC9, 0xE6, 0x10, 0x4B, 0x54, 0xC5, 0x4A, 0x2A, 0xA0, 0x47, 0xBA, 0x84, 0x1E, 0x89, 0x71, 0xA5, 0xE4, 0xB9, 0x32, 0x19, + 0x24, 0x6A, 0x64, 0xC1, 0x68, 0x91, 0x0A, 0xAF, 0x92, 0x1D, 0x60, 0x23, 0x4D, 0xCC, 0x40, 0x9A, 0xD1, 0x3C, 0xD2, 0x20, 0x72, 0xE4, 0x51, 0x44, + 0xE4, 0x2F, 0xCA, 0xAC, 0x28, 0xD5, 0xF8, 0x58, 0xC4, 0x38, 0x0A, 0xB6, 0x78, 0x2A, 0xA5, 0x38, 0x65, 0x6A, 0x08, 0x17, 0xB0, 0x21, 0xDE, 0xB0, + 0xC4, 0x1D, 0x5B, 0xC8, 0x90, 0x1B, 0xE2, 0x03, 0xC0, 0xC3, 0xA8, 0x40, 0x43, 0x11, 0x95, 0x41, 0xC2, 0x2C, 0x0B, 0x59, 0xDC, 0x84, 0x38, 0x9A, + 0x0C, 0xCA, 0x21, 0x11, 0xEC, 0xBB, 0xBC, 0x13, 0x9D, 0x84, 0x82, 0x01, 0xC2, 0xC4, 0xF6, 0x0F, 0xCB, 0x8F, 0x9F, 0x2D, 0x90, 0xDF, 0x8D, 0x84, + 0xBE, 0xA0, 0x09, 0x3F, 0x10, 0x00, 0xF1, 0x31, 0x85, 0xF7, 0x34, 0x4C, 0xD0, 0x0B, 0xD1, 0x94, 0x07, 0x36, 0x02, 0x0F, 0x8D, 0xC4, 0xDD, 0x8D, + 0x34, 0x3B, 0x3B, 0xB5, 0xBA, 0xC1, 0xBA, 0xB2, 0xA3, 0x9D, 0x8F, 0x49, 0x18, 0x74, 0x68, 0x73, 0x0F, 0xD6, 0x3B, 0x1E, 0xAF, 0x78, 0x73, 0xB5, + 0x44, 0xE6, 0x6A, 0x1C, 0xE5, 0x80, 0x4A, 0xE3, 0x8E, 0xCE, 0x70, 0x4E, 0x59, 0x76, 0x58, 0x69, 0xD1, 0x51, 0x22, 0x07, 0x0B, 0x9C, 0xAC, 0xB7, + 0x8F, 0xC3, 0x96, 0xBD, 0x51, 0xE7, 0x26, 0x98, 0x63, 0x13, 0x41, 0xC2, 0x67, 0x26, 0xF5, 0xFC, 0xEF, 0x8B, 0x50, 0x32, 0xC4, 0x63, 0x02, 0x4B, + 0x2C, 0x84, 0xE8, 0xAB, 0x30, 0x05, 0x96, 0x02, 0x9A, 0x91, 0x18, 0x9A, 0xAC, 0xD3, 0x1A, 0xB6, 0x1B, 0xCE, 0xB2, 0x01, 0x70, 0x30, 0x7A, 0xEA, + 0x0F, 0xCA, 0xC6, 0x77, 0x47, 0x74, 0xB5, 0xBA, 0x20, 0xBA, 0x50, 0xDD, 0x08, 0x83, 0x10, 0x04, 0x8C, 0x7E, 0x3F, 0x47, 0x18, 0x61, 0xD1, 0x74, + 0xC4, 0xC8, 0x39, 0xF3, 0x87, 0x28, 0xC7, 0x7F, 0xC0, 0xB9, 0x3F, 0x4B, 0x42, 0x3F, 0x1B, 0xC2, 0xF0, 0x91, 0x11, 0xE0, 0x83, 0xAB, 0xC0, 0x87, + 0xC8, 0xC5, 0xF7, 0xF3, 0xB9, 0xC6, 0xD7, 0x73, 0x25, 0x8F, 0x8F, 0x27, 0x0C, 0xDB, 0x8F, 0x81, 0xBD, 0x9F, 0xA7, 0xC8, 0x1F, 0xC5, 0x20, 0xA3, + 0x9A, 0xC6, 0x95, 0x93, 0x4F, 0x21, 0x12, 0x5D, 0x11, 0xDD, 0xAB, 0xAE, 0x83, 0x6E, 0x25, 0x2E, 0x5D, 0x82, 0xE6, 0x0B, 0x47, 0x0E, 0x44, 0xB6, + 0x86, 0x72, 0x94, 0x5D, 0x97, 0x51, 0xD8, 0x52, 0xE0, 0xA9, 0x0E, 0x06, 0x0E, 0xEB, 0x36, 0xD8, 0xAD, 0x03, 0x82, 0x03, 0x7B, 0x25, 0xD8, 0xB2, + 0x07, 0x96, 0x9B, 0x74, 0xCB, 0x32, 0x12, 0xBB, 0x49, 0xD9, 0x89, 0x5D, 0x5B, 0x06, 0x63, 0x53, 0xF0, 0x29, 0x73, 0xF8, 0xB1, 0x23, 0x94, 0x25, + 0xD8, 0x67, 0x40, 0x60, 0xB7, 0x70, 0x9F, 0x00, 0x6E, 0xEA, 0x23, 0xC0, 0x40, 0xCA, 0x11, 0xE8, 0xD6, 0xAE, 0x94, 0x18, 0xB1, 0x48, 0xCD, 0xE4, + 0x74, 0x10, 0x93, 0x3A, 0x85, 0xA4, 0xF0, 0xAC, 0x82, 0x77, 0x73, 0x2F, 0x2E, 0xCE, 0x0F, 0xE0, 0x31, 0xFF, 0x5B, 0x23, 0xC0, 0x1D, 0xCA, 0x70, + 0xE1, 0xAB, 0x86, 0x5F, 0x8D, 0xD7, 0x06, 0xF9, 0x87, 0x4A, 0xD9, 0x65, 0x95, 0xE7, 0x0B, 0xBE, 0x80, 0x49, 0x87, 0xB4, 0x59, 0x0F, 0x0F, 0x08, + 0x8A, 0x21, 0xEA, 0xD1, 0x5F, 0x4F, 0x11, 0x71, 0xE6, 0x23, 0x6A, 0x51, 0x74, 0x34, 0x11, 0x96, 0xE6, 0xD7, 0xD4, 0x45, 0x5F, 0x41, 0x2D, 0xF5, + 0xA7, 0x6A, 0x05, 0xB9, 0x11, 0x3E, 0x95, 0x53, 0xE1, 0x61, 0xB9, 0x18, 0xEE, 0x96, 0xDF, 0xC0, 0x03, 0xF3, 0x1B, 0xC7, 0xF1, 0x91, 0xE0, 0x82, + 0x7F, 0xB0, 0xBE, 0xFC, 0x98, 0xF5, 0x93, 0xDF, 0x5A, 0x3B, 0xD9, 0x7E, 0xAB, 0xDB, 0x1A, 0xE8, 0x87, 0xEB, 0x7F, 0x9B, 0xDB, 0xB8, 0x78, 0x38, + 0x0F, 0xC2, 0x9B, 0xF2, 0x49, 0xF3, 0xA4, 0xF9, 0x6F, 0xAD, 0x44, 0x4E, 0x87, 0x81, 0xD1, 0x04, 0xA9, 0x0C, 0xBE, 0x1F, 0x69, 0x4B, 0xFE, 0x24, + 0xD4, 0x22, 0x29, 0x52, 0xB9, 0xE4, 0x7A, 0x01, 0xBA, 0x61, 0x80, 0xDC, 0x41, 0x77, 0x90, 0x2B, 0x11, 0x60, 0x3F, 0xD9, 0xF9, 0x4A, 0xB8, 0x4B, + 0x1F, 0x2E, 0xB4, 0xF8, 0x27, 0xE6, 0x7E, 0x0D, 0x21, 0x3C, 0xF2, 0x44, 0xC8, 0x44, 0xD4, 0xCF, 0x01, 0x31, 0xF9, 0x82, 0x2B, 0x57, 0x32, 0x66, + 0x09, 0x78, 0x68, 0x50, 0xAC, 0xFF, 0x68, 0xDB, 0x9F, 0x82, 0xC2, 0x06, 0x90, 0xA8, 0x23, 0x95, 0x72, 0x4C, 0x12, 0xD3, 0xA2, 0x3D, 0x76, 0x13, + 0x9F, 0x0F, 0xC1, 0x8E, 0xF0, 0x43, 0xD8, 0x22, 0xBE, 0x84, 0x2E, 0x21, 0xD7, 0xEA, 0x5A, 0x39, 0x5A, 0x47, 0xCB, 0xCB, 0xBD, 0x9C, 0x33, 0x76, + 0xC6, 0xBC, 0xCE, 0x1E, 0xCD, 0x1B, 0x6D, 0xF3, 0x57, 0x62, 0x93, 0x7E, 0x2C, 0x76, 0xEC, 0xA7, 0x50, 0x63, 0x73, 0xB0, 0xF9, 0x0A, 0x6C, 0xA3, + 0x7F, 0x76, 0xD3, 0xDD, 0x6E, 0xF2, 0xA3, 0x7E, 0x94, 0x6F, 0xE8, 0x43, 0xEE, 0x45, 0x1D, 0x78, 0x04, 0x7B, 0xA6, 0xC7, 0xCD, 0x84, 0xEE, 0x96, + 0x78, 0x0D, 0xC3, 0x99, 0x0E, 0x01, 0x23, 0x54, 0x82, 0xCA, 0xB8, 0x22, 0x49, 0x56, 0xF3, 0x96, 0x34, 0x06, 0x12, 0x20, 0xF1, 0xEA, 0x84, 0x10, + 0x25, 0x20, 0xCA, 0x12, 0x11, 0x09, 0x44, 0x84, 0x44, 0x82, 0x48, 0x0A, 0x52, 0x52, 0x4E, 0x2A, 0x1D, 0xD4, 0xB9, 0xC7, 0x11, 0xFF, 0xB5, 0x9F, + 0xBE, 0x2F, 0x55, 0x7B, 0x88, 0xF9, 0x2E, 0xEA, 0xE9, 0xDE, 0x11, 0x7E, 0x59, 0x52, 0x57, 0xE5, 0x66, 0x03, 0x31, 0x62, 0x31, 0x34, 0x87, 0xFF, + 0x28, 0x1E, 0x8F, 0x86, 0x86, 0x12, 0x3B, 0x77, 0xD6, 0xA0, 0xEB, 0x68, 0x88, 0x86, 0x41, 0x83, 0x5F, 0x8C, 0x34, 0x54, 0x69, 0x32, 0x79, 0xFE, + 0x5B, 0x0A, 0x74, 0x68, 0xA8, 0x76, 0x2B, 0x4C, 0x48, 0x84, 0xB1, 0x09, 0x82, 0x32, 0xDC, 0x93, 0x5D, 0x7B, 0xB1, 0xA4, 0xAE, 0x8D, 0xC1, 0xE4, + 0x59, 0x7C, 0xA6, 0x9A, 0x01, 0x90, 0x05, 0x85, 0xD8, 0xD9, 0xB1, 0x1E, 0x04, 0x23, 0x23, 0x58, 0xA7, 0xDD, 0xAB, 0x1D, 0xE8, 0x48, 0x4C, 0x29, + 0x77, 0x16, 0x14, 0x1B, 0xCD, 0x8B, 0xD7, 0x94, 0xAA, 0x1D, 0xC5, 0x7C, 0xDF, 0x9F, 0xB8, 0x7D, 0xD5, 0xC6, 0xEB, 0xB3, 0xA9, 0x57, 0xD9, 0x87, + 0x8D, 0x55, 0x66, 0xCE, 0xEE, 0x28, 0xCB, 0x52, 0xE6, 0xD9, 0xCE, 0x26, 0x96, 0x7A, 0xA7, 0x30, 0x59, 0xAF, 0x2E, 0x87, 0xAB, 0x21, 0xDB, 0xA6, + 0x2D, 0xB4, 0x15, 0xE3, 0xC2, 0xF8, 0x42, 0xEA, 0x90, 0x54, 0x8F, 0x52, 0xC5, 0x12, 0xB3, 0xBD, 0x03, 0x97, 0xD1, 0x07, 0x3A, 0xEB, 0x73, 0xA6, + 0xDC, 0x4C, 0xC9, 0x4C, 0x17, 0xA4, 0x7E, 0x6D, 0x68, 0x81, 0x8E, 0x8E, 0x9E, 0x10, 0xE6, 0x26, 0x27, 0x55, 0x08, 0xB7, 0xC6, 0x69, 0x0D, 0xCB, + 0xD0, 0xFA, 0x98, 0x67, 0x63, 0xF8, 0xDE, 0x7B, 0xD5, 0x98, 0xE2, 0xBF, 0xFE, 0xC3, 0xB5, 0xBD, 0x6A, 0xA7, 0x57, 0x7B, 0x99, 0xBA, 0x85, 0x56, + 0xE9, 0x64, 0xC9, 0xC8, 0x62, 0x85, 0xDB, 0xC9, 0x51, 0x3C, 0x70, 0xDF, 0xF7, 0x35, 0xB1, 0xBD, 0x44, 0xB2, 0x0D, 0x5C, 0xB8, 0x70, 0x40, 0xAA, + 0x0D, 0x0D, 0xF2, 0x5C, 0xCA, 0x93, 0x06, 0xF6, 0xFB, 0xEC, 0x02, 0x32, 0x8C, 0x6F, 0x69, 0x29, 0x9A, 0xA4, 0x6B, 0xB2, 0xFA, 0x93, 0x0F, 0x6D, + 0x69, 0x8F, 0x14, 0xAE, 0x0E, 0xCF, 0x70, 0xD3, 0x58, 0x2A, 0xA2, 0x0D, 0x4A, 0x70, 0x6B, 0x07, 0xA7, 0xCC, 0x4A, 0x86, 0x37, 0xF2, 0x26, 0x0D, + 0xC4, 0xCF, 0x64, 0xB4, 0x8B, 0x23, 0xCA, 0xAA, 0xA9, 0xD0, 0xAD, 0x9A, 0x0B, 0x39, 0x82, 0xCC, 0x46, 0xC5, 0xD0, 0x58, 0xCB, 0xE3, 0x4C, 0xDD, + 0xE2, 0x00, 0xEA, 0x38, 0x2F, 0x77, 0x35, 0x8B, 0xEE, 0x19, 0xF4, 0x4F, 0x78, 0x09, 0x5F, 0x47, 0x7A, 0xED, 0x61, 0xE2, 0x3B, 0x90, 0x5E, 0x0F, + 0x7F, 0x94, 0xC1, 0xCC, 0xAD, 0xD3, 0x03, 0x44, 0x1F, 0xD8, 0x8A, 0x95, 0xF3, 0x32, 0xED, 0xEE, 0x91, 0x43, 0x3A, 0xFE, 0x79, 0x07, 0xB3, 0x93, + 0x3C, 0x12, 0x98, 0x56, 0x30, 0x9A, 0xC2, 0xEC, 0x16, 0xF7, 0x09, 0x48, 0xAE, 0x4F, 0xA3, 0x46, 0x35, 0xC5, 0x7D, 0xE7, 0xD5, 0xAF, 0x6B, 0x90, + 0x71, 0x12, 0x35, 0x16, 0x10, 0x1B, 0xA2, 0x03, 0x5B, 0xDC, 0x39, 0x9D, 0x0E, 0x4E, 0xA7, 0x13, 0xDB, 0xA2, 0x2D, 0xDA, 0x18, 0x77, 0xA9, 0x4B, + 0xB4, 0xCD, 0x79, 0x1A, 0x54, 0x98, 0x99, 0xF5, 0x85, 0x40, 0xEC, 0x0F, 0xCA, 0x60, 0x71, 0x13, 0x42, 0xEF, 0x02, 0x92, 0x85, 0x23, 0x91, 0x27, + 0x0C, 0x1C, 0xBF, 0x36, 0xA1, 0x74, 0x93, 0xA5, 0x8D, 0xCD, 0x5B, 0xB0, 0xEF, 0x5B, 0x7F, 0x9A, 0x6F, 0xA2, 0xF0, 0xDC, 0x5B, 0x1C, 0x20, 0xE7, + 0xCE, 0x67, 0x16, 0x02, 0xD7, 0xC1, 0x13, 0x66, 0xF2, 0xFD, 0x93, 0x65, 0x5D, 0xA7, 0xE1, 0x6B, 0x3D, 0x27, 0x50, 0x0B, 0xDB, 0x16, 0x1A, 0x5D, + 0x7F, 0xD4, 0x27, 0xD6, 0xBF, 0xBD, 0x5F, 0xD8, 0xEC, 0x73, 0xC7, 0x7D, 0x73, 0xD6, 0x69, 0xF3, 0x94, 0x1F, 0xAC, 0x9A, 0x05, 0xE4, 0x53, 0xAC, + 0x89, 0x72, 0x8E, 0xA2, 0x97, 0xD3, 0x85, 0xF9, 0xB4, 0xFB, 0xBA, 0x08, 0x43, 0x04, 0x1B, 0x79, 0xE6, 0xF9, 0x72, 0xC5, 0xDD, 0x5C, 0xBE, 0x5B, + 0x30, 0x4A, 0xE2, 0x70, 0xC7, 0x60, 0xF4, 0x49, 0x54, 0xEF, 0xD1, 0x7C, 0x06, 0x36, 0x30, 0x81, 0xC4, 0x1A, 0x5D, 0x2E, 0x46, 0xC5, 0x05, 0x74, + 0xC5, 0x4C, 0x9E, 0xEE, 0x22, 0x02, 0xB9, 0x33, 0x13, 0x25, 0xB3, 0x1B, 0xCB, 0xCA, 0xE5, 0xF5, 0x5C, 0x13, 0x66, 0x4D, 0xED, 0x33, 0x79, 0x1E, + 0xD5, 0x23, 0x14, 0x36, 0x00, 0xA6, 0xDD, 0x5C, 0x8A, 0xD2, 0x94, 0x9F, 0x81, 0xE9, 0x7C, 0xD9, 0x79, 0x04, 0x88, 0x58, 0x66, 0x6C, 0x4A, 0xE7, + 0x45, 0x3F, 0x6C, 0x2F, 0xAA, 0x79, 0xE0, 0x3E, 0x04, 0x37, 0xF8, 0xCB, 0x68, 0xB5, 0x41, 0x9F, 0x5C, 0x27, 0x8E, 0x39, 0x99, 0x48, 0x19, 0xFB, + 0x4D, 0x0B, 0x28, 0x87, 0x64, 0x7D, 0x20, 0xBB, 0x3D, 0xF1, 0xC9, 0x76, 0x80, 0x77, 0xAC, 0xE1, 0xC6, 0xAA, 0x5F, 0x44, 0x5E, 0x16, 0xC6, 0x4F, + 0x51, 0x26, 0xB4, 0x56, 0x66, 0xC7, 0x6D, 0xA8, 0x23, 0x37, 0xCB, 0x3C, 0xAC, 0x3C, 0x55, 0x09, 0x6A, 0x60, 0x8C, 0xDA, 0xC6, 0x83, 0xC7, 0xBD, + 0x6B, 0x1D, 0x86, 0xD7, 0xCA, 0x22, 0x3D, 0xA6, 0xBB, 0xF9, 0xBC, 0xC1, 0x1B, 0x54, 0x14, 0xE7, 0x35, 0xAE, 0x6E, 0xAF, 0x68, 0xB4, 0xEB, 0x84, + 0xDA, 0x3D, 0x2E, 0x52, 0xE8, 0xF3, 0x2D, 0xD4, 0x7F, 0x0F, 0x39, 0x8B, 0xCC, 0xF4, 0xDD, 0x5B, 0x4E, 0x17, 0xDE, 0x63, 0xDE, 0xE8, 0xB6, 0xA3, + 0x2E, 0xE3, 0x68, 0x01, 0xB4, 0x41, 0x23, 0x3C, 0x31, 0x2A, 0xCF, 0xB3, 0x43, 0xF7, 0x25, 0x54, 0xDC, 0x12, 0x63, 0x51, 0x97, 0xEB, 0xFE, 0x67, + 0xC4, 0x77, 0xE5, 0xB4, 0x22, 0xA3, 0x1B, 0x30, 0x08, 0xDD, 0x83, 0x19, 0x5F, 0x3A, 0x5D, 0xC9, 0x4D, 0x12, 0xAE, 0x1A, 0x85, 0x87, 0xE9, 0x93, + 0xB0, 0x35, 0x47, 0x6E, 0xEC, 0x57, 0x62, 0x7D, 0x5F, 0xA6, 0x7A, 0x64, 0x82, 0x14, 0x64, 0x7A, 0x18, 0x58, 0x11, 0xA3, 0x03, 0x31, 0xFD, 0x40, + 0x93, 0x0C, 0x8D, 0xC0, 0x13, 0x8B, 0x7C, 0x73, 0x34, 0x13, 0xA2, 0x65, 0xE7, 0x21, 0xCE, 0x85, 0x03, 0xD2, 0xCE, 0xD4, 0xB8, 0xCD, 0x8D, 0xC1, + 0x7A, 0xF6, 0xC8, 0xC6, 0x9B, 0xB2, 0x77, 0x2D, 0x7E, 0x48, 0xD0, 0xC5, 0x86, 0x46, 0xFA, 0x2B, 0xC6, 0xBA, 0x5D, 0xEA, 0x00, 0xB6, 0x83, 0x0E, + 0xAC, 0xC5, 0xDB, 0x09, 0x25, 0xF9, 0xA5, 0xF9, 0x7C, 0x70, 0x76, 0xF2, 0xBB, 0x0C, 0x70, 0xD9, 0xB5, 0x3F, 0x61, 0x42, 0x7B, 0x7B, 0xEC, 0x4D, + 0x85, 0x34, 0xEE, 0x48, 0x46, 0x45, 0xB4, 0x5B, 0xE6, 0xD1, 0x0A, 0xB5, 0x25, 0x3F, 0x91, 0x9E, 0x46, 0xE8, 0xAA, 0x25, 0x6F, 0x4B, 0x50, 0x49, + 0x5D, 0x6D, 0xB1, 0x67, 0x5B, 0xC1, 0xD2, 0x7A, 0x4C, 0x92, 0x17, 0xB1, 0xAD, 0x86, 0x5F, 0xE1, 0xA4, 0x4C, 0x47, 0x44, 0x7A, 0x0D, 0xD7, 0x8F, + 0x2D, 0x5E, 0x9A, 0x3E, 0x6D, 0x65, 0x5C, 0x2D, 0xCE, 0xAA, 0xD1, 0xF5, 0x89, 0x8D, 0xE8, 0x27, 0x6F, 0xCF, 0xDA, 0x8C, 0xB7, 0x8E, 0x70, 0x17, + 0xA4, 0x1E, 0x00, 0x16, 0x72, 0xB1, 0x39, 0x50, 0xAC, 0x29, 0x74, 0x09, 0x00, 0x3C, 0x02, 0x5E, 0x63, 0x02, 0x60, 0x82, 0xEC, 0xA9, 0x98, 0x18, + 0x8B, 0x6B, 0x3F, 0x1B, 0xA1, 0xFA, 0x50, 0x58, 0x34, 0x1C, 0x77, 0xF1, 0x64, 0x77, 0xDF, 0x81, 0x03, 0x64, 0x40, 0xFC, 0xAA, 0x23, 0xF2, 0x3D, + 0xB0, 0x96, 0x31, 0xEE, 0x13, 0x46, 0x4B, 0x63, 0x34, 0x8A, 0xC4, 0x50, 0x16, 0x91, 0x49, 0x01, 0xA9, 0x00, 0xA8, 0x00, 0xA7, 0x00, 0x6D, 0xEB, + 0xA6, 0x6E, 0xF6, 0x8D, 0x12, 0xDA, 0x42, 0xFA, 0xA6, 0x33, 0x69, 0xA1, 0x36, 0xC4, 0x99, 0x5A, 0x13, 0x3B, 0xB8, 0x6A, 0x0D, 0x03, 0xD8, 0x42, + 0x5F, 0xE0, 0xAF, 0x5E, 0xC1, 0x18, 0x36, 0x83, 0x82, 0x2D, 0x0B, 0xED, 0xB1, 0x6E, 0xD2, 0x4D, 0xB6, 0x51, 0x93, 0x5E, 0xF8, 0x8B, 0x94, 0xC3, + 0x73, 0x24, 0x22, 0x33, 0x89, 0xE4, 0x1E, 0x4F, 0x12, 0x94, 0xA6, 0xAB, 0x04, 0x1D, 0xCA, 0x5C, 0x5C, 0x4D, 0xC8, 0xDB, 0x80, 0x70, 0x86, 0xD0, + 0x55, 0x51, 0x23, 0xFF, 0x30, 0x20, 0xF9, 0xAB, 0x24, 0xC1, 0xE6, 0xD0, 0x2C, 0x51, 0xA1, 0xFA, 0x04, 0xDD, 0x9B, 0xD0, 0x13, 0x5F, 0xD6, 0x92, + 0x27, 0x18, 0x85, 0xB4, 0xC1, 0x37, 0x64, 0x13, 0x76, 0x22, 0x85, 0x2C, 0x46, 0xB2, 0xE9, 0x1D, 0x39, 0x46, 0xDF, 0x2E, 0xA7, 0x78, 0xEE, 0x48, + 0x1F, 0x7D, 0x94, 0xDE, 0x3D, 0x80, 0x4F, 0x17, 0x60, 0xFD, 0x8E, 0xF1, 0xA4, 0x17, 0x16, 0x03, 0xB3, 0xA4, 0x07, 0xFE, 0x20, 0x61, 0x70, 0x50, + 0x1A, 0xE1, 0x23, 0x72, 0x4C, 0xB3, 0x48, 0x24, 0x9A, 0x76, 0x2D, 0xDA, 0xF6, 0x38, 0x75, 0xF3, 0x45, 0xC8, 0x2E, 0x4E, 0x40, 0x05, 0x0E, 0x79, + 0x0B, 0x69, 0x46, 0xEA, 0xBC, 0x49, 0xAA, 0x17, 0x4C, 0x06, 0x0D, 0x62, 0x86, 0xE8, 0xB1, 0x19, 0xA3, 0x45, 0xC4, 0x11, 0x2B, 0x23, 0x92, 0x6D, + 0x92, 0x28, 0x25, 0x4D, 0x4A, 0x9A, 0xDC, 0x95, 0x96, 0x2F, 0x33, 0x92, 0x4A, 0xB1, 0x23, 0x4A, 0x78, 0xA7, 0x22, 0x90, 0xE8, 0x2A, 0x33, 0x53, + 0xD3, 0xB6, 0x33, 0x38, 0x6B, 0x74, 0x60, 0x3A, 0xD1, 0x51, 0xC4, 0xBF, 0x4F, 0x0C, 0xC6, 0x08, 0x2D, 0x94, 0x6A, 0x87, 0xFD, 0xA9, 0x8B, 0x05, + 0xEA, 0xAF, 0xB9, 0x18, 0xD8, 0x62, 0x3C, 0xA4, 0x89, 0x70, 0x95, 0xB6, 0xC2, 0x6A, 0x7A, 0x0D, 0x5F, 0xD9, 0x40, 0x0C, 0xB7, 0x6C, 0x74, 0x6E, + 0x05, 0xA9, 0xA5, 0xAD, 0xD3, 0x3A, 0xAA, 0xBD, 0xAB, 0xD2, 0x5D, 0x2D, 0x85, 0x50, 0xD5, 0x1C, 0xAC, 0x58, 0xAB, 0xB7, 0x18, 0x45, 0xA7, 0xE0, + 0x1B, 0x8D, 0x83, 0x9D, 0x34, 0x1B, 0xE7, 0xD8, 0x31, 0xFC, 0x64, 0xA1, 0xE8, 0xDB, 0x92, 0x51, 0x3C, 0x9B, 0x47, 0x1F, 0xED, 0x50, 0xEF, 0x16, + 0x4F, 0x87, 0x9D, 0xA5, 0x78, 0x71, 0x59, 0x1F, 0x1A, 0x04, 0x07, 0x7B, 0x8C, 0x8F, 0x34, 0x12, 0x8E, 0xB1, 0x32, 0x34, 0x6D, 0x93, 0x68, 0x98, + 0x0E, 0xC4, 0x3C, 0x04, 0xAB, 0x21, 0x6E, 0xD8, 0xB0, 0xD8, 0x62, 0x7F, 0x44, 0x20, 0xDB, 0x62, 0x4E, 0x59, 0x20, 0x33, 0x48, 0x4F, 0x99, 0x54, + 0x1A, 0xCD, 0x4C, 0xD3, 0x7D, 0xA6, 0x9F, 0x96, 0x34, 0x27, 0xF5, 0x9F, 0x68, 0xAA, 0x29, 0xC5, 0x4A, 0x7B, 0x2A, 0xFE, 0xF8, 0x46, 0x88, 0x12, + 0xB6, 0x2B, 0x7A, 0xAD, 0x59, 0x3C, 0x5B, 0xAF, 0x69, 0xA2, 0xCF, 0x66, 0x8D, 0x5E, 0x9B, 0x4C, 0x1A, 0xCC, 0x0C, 0xD3, 0x74, 0x66, 0x9D, 0x16, + 0xC6, 0x45, 0x6D, 0x27, 0xDE, 0x59, 0x46, 0xB1, 0xD1, 0x86, 0x8A, 0xA2, 0x56, 0x63, 0x6F, 0x7F, 0x91, 0x6B, 0x7B, 0xD3, 0xD7, 0x5C, 0x33, 0xB6, + 0xD8, 0x7C, 0xD1, 0x44, 0x66, 0x91, 0xB6, 0x32, 0xAF, 0xB4, 0x91, 0x08, 0xD7, 0x58, 0x62, 0x96, 0x65, 0x13, 0xDB, 0xAC, 0xA0, 0x38, 0x68, 0xEB, + 0xE2, 0xA5, 0x25, 0xAB, 0x8A, 0x3E, 0xAC, 0xF6, 0xD2, 0xDC, 0x3A, 0x83, 0xC5, 0xEA, 0x2D, 0x40, 0x6F, 0xA5, 0x98, 0x2A, 0x1A, 0xC7, 0xCC, 0xD1, + 0x6C, 0xF3, 0x49, 0xEB, 0x88, 0x3B, 0x16, 0x4A, 0x8C, 0xB2, 0x64, 0x62, 0x99, 0xCD, 0x13, 0xF5, 0xEC, 0x30, 0x42, 0x5A, 0x3D, 0x33, 0xA4, 0x7E, + 0xB4, 0xB4, 0x9F, 0x07, 0xA9, 0x5F, 0x87, 0xF0, 0x3F, 0x33, 0xB3, 0xFB, 0xCD, 0xE4, 0x5F, 0x26, 0xF7, 0x93, 0x05, 0xFF, 0x31, 0x1A, 0xBF, 0x98, + 0xDD, 0x2F, 0x26, 0xFC, 0x81, 0x25, 0xFE, 0x30, 0xFE, 0x59, 0x08, 0x7F, 0x15, 0xC3, 0x2E, 0xFE, 0x47, 0x84, 0xF0, 0xC0, 0xE7, 0xE7, 0x30, 0xFC, + 0x33, 0x58, 0x10, 0xFE, 0x14, 0xF6, 0x5F, 0xB8, 0x5F, 0x02, 0xDC, 0xFF, 0x60, 0xED, 0x6F, 0x10, 0xF6, 0x33, 0xD8, 0x3F, 0x6B, 0xFE, 0x58, 0xC1, + 0xDF, 0xF7, 0xE9, 0xF7, 0xF5, 0xEF, 0xDB, 0xBF, 0x37, 0xFC, 0x7B, 0xFC, 0xF7, 0xF6, 0x57, 0x00, 0xF7, 0x27, 0x40, 0x20, 0xF7, 0x13, 0xE0, 0x5F, + 0xC0, 0xF0, 0xA7, 0x6A, 0xF0, 0x03, 0x40, 0x14, 0x9C, 0x9B, 0xB1, 0x4A, 0xE2, 0x92, 0xDD, 0x12, 0xB9, 0xEC, 0x92, 0x39, 0x97, 0xCB, 0xEC, 0xD2, + 0x73, 0xC6, 0x69, 0xBA, 0x79, 0xA8, 0x37, 0x4D, 0x4E, 0x3D, 0x0B, 0x4C, 0x3E, 0x06, 0xBA, 0x53, 0xF4, 0xB4, 0x01, 0x81, 0x65, 0xA8, 0x61, 0x10, + 0xB5, 0xA9, 0x57, 0x61, 0x67, 0x0D, 0x21, 0x9B, 0x82, 0x72, 0x0A, 0x92, 0xB4, 0x01, 0x32, 0x18, 0x44, 0xD8, 0x21, 0x45, 0x74, 0x51, 0x19, 0x05, + 0x35, 0xEA, 0x1F, 0x63, 0x16, 0xF3, 0xA7, 0x08, 0x50, 0x45, 0x6F, 0xD4, 0xBC, 0x8B, 0xA7, 0x26, 0xCC, 0x66, 0x0A, 0x4E, 0x9B, 0xD7, 0x5C, 0x86, + 0xE9, 0xFA, 0x3E, 0xA5, 0x3B, 0xF2, 0x7F, 0x9E, 0xF6, 0xAE, 0x5C, 0x08, 0x3C, 0x55, 0xF9, 0x29, 0x1D, 0xE7, 0x9C, 0x78, 0x6A, 0x0F, 0xA3, 0x33, + 0xE6, 0xB7, 0xB2, 0x66, 0xE0, 0xB0, 0xBB, 0x31, 0xC0, 0x17, 0xCF, 0x2F, 0x9C, 0x4E, 0x28, 0xC6, 0xDA, 0x8F, 0x49, 0x19, 0x20, 0xBA, 0xA7, 0x52, + 0x56, 0x46, 0xC6, 0xD4, 0xF4, 0xB6, 0x83, 0xF4, 0x47, 0x82, 0xC5, 0xF9, 0x7A, 0xAF, 0xB0, 0x60, 0xED, 0xEF, 0xED, 0xBD, 0x3F, 0xBF, 0xCE, 0xFE, + 0x32, 0x66, 0x63, 0x82, 0xFA, 0xE8, 0x1D, 0xB0, 0xCE, 0x18, 0x27, 0x78, 0x68, 0x3B, 0xC6, 0x14, 0x93, 0xC5, 0x33, 0x0F, 0x33, 0x15, 0x9B, 0xB0, + 0x90, 0x7F, 0x6D, 0xCE, 0xC4, 0x59, 0xCF, 0x6C, 0x43, 0x64, 0x68, 0x6A, 0xD4, 0x9B, 0x87, 0x05, 0x57, 0x6C, 0x4C, 0x9A, 0xAE, 0x0D, 0xD2, 0xBC, + 0xF7, 0x64, 0x4C, 0x58, 0x12, 0x93, 0xE0, 0xC8, 0xA4, 0x1C, 0xFB, 0x32, 0xB2, 0x46, 0x13, 0x3A, 0xFA, 0x5C, 0x4D, 0x86, 0x7B, 0x65, 0xCC, 0xDE, + 0x29, 0x01, 0x1D, 0x73, 0xE1, 0x61, 0x5D, 0xD6, 0x95, 0x34, 0x07, 0xC6, 0x01, 0x12, 0x46, 0x32, 0x09, 0xF9, 0x01, 0x7B, 0xC2, 0x2A, 0x83, 0x90, + 0x3A, 0xE0, 0xEE, 0x95, 0xD1, 0x66, 0x9D, 0xFC, 0x6C, 0x2B, 0x41, 0xA2, 0xB7, 0x27, 0x44, 0x9E, 0x80, 0xC4, 0x86, 0xAE, 0x4B, 0x09, 0xD0, 0x7C, + 0x9E, 0xA7, 0x99, 0x49, 0x2B, 0x93, 0x0B, 0xB2, 0x1A, 0x33, 0xF4, 0x13, 0x60, 0x98, 0x0C, 0xE2, 0xBA, 0x97, 0xA6, 0x21, 0x49, 0x39, 0x4B, 0x1C, + 0x20, 0x00, 0x5A, 0x47, 0x8C, 0x0D, 0x3B, 0x60, 0xEE, 0x68, 0x18, 0x03, 0xD5, 0x60, 0x95, 0xE4, 0xAE, 0xB4, 0x18, 0x15, 0x81, 0xE0, 0xA5, 0xE3, + 0x16, 0x64, 0x2D, 0x24, 0xA4, 0xE0, 0xC3, 0x88, 0xB4, 0x68, 0x5C, 0x9F, 0xF5, 0x88, 0x80, 0x89, 0x8B, 0x57, 0x98, 0x77, 0x1B, 0xEB, 0x57, 0xEF, + 0x33, 0x6A, 0x58, 0x58, 0x51, 0xEC, 0xE6, 0x4E, 0x50, 0xB7, 0x03, 0xBA, 0x6A, 0xBF, 0xCF, 0xA4, 0x4C, 0x01, 0xB2, 0x00, 0xBF, 0x00, 0xC9, 0x00, + 0xC5, 0xF5, 0xC1, 0xD6, 0x6A, 0xC5, 0x5B, 0x67, 0xC0, 0x95, 0x81, 0x6E, 0x5D, 0x20, 0x5B, 0x11, 0xD8, 0xD6, 0x03, 0xB4, 0xD5, 0x80, 0x6F, 0x25, + 0x20, 0x5C, 0xC9, 0xDC, 0x4A, 0x55, 0x5C, 0xA7, 0xC4, 0x56, 0xA9, 0xE1, 0x2A, 0x55, 0xAE, 0x00, 0x84, 0x2B, 0x80, 0xDD, 0xAA, 0xE4, 0x8F, 0xF2, + 0xBD, 0xA8, 0xF2, 0x41, 0x09, 0xBF, 0xD3, 0xEC, 0x37, 0x99, 0x9F, 0x09, 0xF7, 0x97, 0x8E, 0x6F, 0xC9, 0xF7, 0x94, 0x68, 0xFF, 0x48, 0xF8, 0x8E, + 0x7E, 0x62, 0xEE, 0x17, 0x99, 0x9F, 0xC8, 0xF6, 0x86, 0xAE, 0x9E, 0x50, 0xF0, 0x07, 0xE5, 0x7E, 0x10, 0xF9, 0x81, 0x82, 0x0F, 0xC8, 0xF8, 0x7F, + 0x6C, 0xCF, 0xE7, 0xF7, 0x7B, 0x88, 0xBF, 0xA7, 0xF7, 0xA7, 0xED, 0xEB, 0x10, 0x3F, 0x28, 0xF6, 0x73, 0xE2, 0x0C, 0x1F, 0x08, 0xFC, 0x36, 0xE7, + 0xB3, 0xF9, 0xD7, 0x90, 0x9F, 0x66, 0xF7, 0x62, 0xE5, 0x87, 0x6D, 0x3D, 0x19, 0xE3, 0x8F, 0xB9, 0xFD, 0xCF, 0xF7, 0x61, 0x7A, 0xCF, 0x65, 0xF7, + 0x5C, 0x66, 0xBF, 0x25, 0xF8, 0x5B, 0xCA, 0xCF, 0x52, 0x7B, 0x2B, 0xBB, 0x9F, 0x62, 0xBE, 0x94, 0xE3, 0x77, 0x05, 0xBF, 0x2B, 0xF7, 0xE6, 0xF1, + 0xB9, 0x6E, 0xCF, 0xA4, 0xF6, 0x47, 0x88, 0x9C, 0xFF, 0x23, 0xFA, 0x47, 0x6B, 0x15, 0xDE, 0xD6, 0x3E, 0x62, 0x6B, 0x1F, 0xDD, 0xBA, 0x27, 0x0F, + 0xAD, 0xB8, 0x9E, 0xBC, 0xF5, 0x24, 0xD7, 0x3B, 0xC6, 0xB5, 0x0E, 0x6E, 0x0D, 0x02, 0x57, 0x39, 0xE5, 0x1A, 0xA7, 0x5C, 0xE1, 0x6C, 0xAD, 0x70, + 0xAE, 0x56, 0xA0, 0xB9, 0xB2, 0x09, 0xAE, 0x6B, 0x86, 0x6B, 0x9A, 0xDA, 0x8A, 0x66, 0x6C, 0x0D, 0x03, 0xAE, 0x61, 0xB2, 0x15, 0xAC, 0xB7, 0x82, + 0xDD, 0xD6, 0xAF, 0xAD, 0xF5, 0xEB, 0x6A, 0x15, 0xE3, 0x5B, 0xC3, 0xBC, 0x7E, 0x79, 0xED, 0x72, 0x5B, 0xB9, 0x9C, 0x6B, 0x95, 0xDF, 0x6A, 0xF6, + 0x56, 0x27, 0xB6, 0x95, 0x8B, 0x66, 0x5C, 0x9B, 0xF4, 0xD6, 0x26, 0xAF, 0x4A, 0xCC, 0x35, 0x89, 0x71, 0x3D, 0x72, 0x5B, 0x8B, 0x94, 0xEB, 0x10, + 0xE0, 0x1A, 0x44, 0xB6, 0x02, 0x19, 0xAE, 0x3E, 0x6A, 0x6B, 0x8F, 0xD9, 0xCA, 0xE3, 0x75, 0x07, 0x71, 0xD5, 0x71, 0xAE, 0x39, 0x80, 0xEB, 0x8D, + 0xAB, 0xB5, 0x06, 0xF1, 0x5C, 0xB3, 0x74, 0x6B, 0x16, 0x6D, 0xA5, 0x71, 0x5C, 0x63, 0x08, 0xD7, 0x18, 0xE6, 0x8A, 0x93, 0xAD, 0x2F, 0x7E, 0xAB, + 0x8B, 0xE1, 0xCA, 0x02, 0xB8, 0xA6, 0x90, 0xAD, 0x58, 0xE6, 0x5A, 0x62, 0x6B, 0x05, 0x51, 0xAE, 0x1B, 0x6E, 0x6B, 0x49, 0x5C, 0x4B, 0xDD, 0x9A, + 0x41, 0xB7, 0xD2, 0x78, 0x2B, 0x85, 0xDC, 0x1A, 0x21, 0x44, 0x78, 0x6F, 0x10, 0xDB, 0xFB, 0x83, 0x7C, 0x7B, 0xFC, 0xDE, 0x1D, 0xE7, 0xAB, 0x75, + 0x83, 0xF8, 0xDA, 0xF0, 0xBD, 0x59, 0xE6, 0x0B, 0xA3, 0xF7, 0xB6, 0xB0, 0xBD, 0x2B, 0xCC, 0xF7, 0x46, 0xBE, 0x27, 0x8C, 0xAF, 0x8D, 0xF7, 0x9A, + 0x98, 0xBD, 0x22, 0x82, 0xAF, 0x87, 0xDC, 0xAB, 0x81, 0x7C, 0x31, 0x5C, 0xB8, 0xBD, 0x34, 0x0A, 0x13, 0x74, 0xAF, 0x84, 0xF2, 0x85, 0x00, 0xE4, + 0xE9, 0xDE, 0x07, 0x0F, 0x66, 0x63, 0xC4, 0xA0, 0x6F, 0x67, 0x65, 0x35, 0x1B, 0xAB, 0x0A, 0x56, 0xED, 0xAA, 0xAA, 0x66, 0x63, 0xC4, 0xA0, 0x6F, + 0x97, 0x7B, 0x1D, 0xD4, 0x5E, 0x07, 0xB3, 0xB7, 0xC1, 0xD8, 0xDB, 0xE0, 0x7C, 0x19, 0x98, 0x6F, 0x02, 0xDB, 0x7B, 0x40, 0xF6, 0xCA, 0xCA, 0xB7, + 0x00, 0xF9, 0x0E, 0x38, 0x5F, 0x01, 0xC3, 0x77, 0xAA, 0xF6, 0x06, 0xC8, 0xBD, 0x52, 0xE7, 0xAB, 0x5B, 0xEF, 0xBF, 0x75, 0x94, 0xD6, 0x2A, 0x0A, + 0xB8, 0x8A, 0xDA, 0xAD, 0x9F, 0x7A, 0xAB, 0xA7, 0x72, 0xED, 0x34, 0x5C, 0x39, 0xE1, 0xD6, 0x4C, 0xE7, 0x8A, 0xE9, 0x92, 0x25, 0xDE, 0x6A, 0xA9, + 0x5C, 0x27, 0xF9, 0x56, 0x49, 0xAF, 0x8F, 0x70, 0xEB, 0xA3, 0xD9, 0xDA, 0x68, 0xB6, 0x32, 0xDA, 0xAD, 0x8B, 0x8E, 0xEB, 0x22, 0xB1, 0x15, 0x91, + 0x71, 0x35, 0x54, 0x5C, 0x87, 0xC2, 0xB5, 0xD0, 0x6C, 0x15, 0x64, 0xAE, 0x81, 0x8C, 0x2B, 0xA0, 0xDF, 0x01, 0xA0, 0x2A, 0x51, 0xE1, 0x49, 0x43, + 0xC5, 0x5B, 0xD2, 0x23, 0x87, 0xD5, 0x01, 0x82, 0x81, 0xA7, 0xFA, 0x18, 0x29, 0x50, 0x1D, 0x33, 0x58, 0x9C, 0x08, 0xC1, 0xE1, 0x82, 0xC4, 0x05, + 0xAB, 0x9F, 0x22, 0x39, 0x41, 0x2A, 0x74, 0xB6, 0xF1, 0x42, 0x85, 0x0B, 0x88, 0x0C, 0x14, 0x21, 0x68, 0x01, 0x04, 0x68, 0x52, 0x44, 0xE7, 0x4B, + 0x8A, 0xCE, 0x05, 0x07, 0x29, 0x2D, 0xF2, 0x31, 0xE3, 0xF5, 0xC4, 0x88, 0x56, 0x0C, 0xAC, 0x0F, 0x15, 0x18, 0x3C, 0x00, 0xAA, 0x4F, 0x94, 0x86, + 0x7A, 0xDE, 0x80, 0x79, 0x75, 0x1D, 0xE1, 0x91, 0xA5, 0x62, 0x84, 0x05, 0x07, 0xBF, 0x06, 0x46, 0x1D, 0x8B, 0x87, 0xF4, 0xC0, 0x39, 0xE3, 0x15, + 0x25, 0xC9, 0x33, 0x5E, 0x53, 0xA8, 0x84, 0x57, 0x05, 0xAF, 0x53, 0x7F, 0xA8, 0x4B, 0x8D, 0xFE, 0xC8, 0x79, 0x1F, 0x15, 0xAE, 0xB5, 0xC6, 0x2A, + 0x4F, 0x30, 0x01, 0x72, 0xD7, 0x4F, 0x51, 0x0F, 0xAE, 0x68, 0xE7, 0x57, 0xBE, 0x73, 0x64, 0xBF, 0xD7, 0x8D, 0xF9, 0xAE, 0x91, 0x1D, 0x73, 0xAF, + 0x9A, 0xD9, 0x9B, 0xA6, 0xF8, 0x43, 0x43, 0x9E, 0x62, 0x9F, 0xA1, 0x09, 0xC3, 0x48, 0xDD, 0x6B, 0x46, 0x16, 0x7C, 0xCB, 0xD8, 0x6E, 0x2F, 0x18, + 0x39, 0x7C, 0xC9, 0x6C, 0xBD, 0x63, 0x6A, 0xEF, 0xEF, 0xEB, 0xF8, 0x82, 0x11, 0xBE, 0x5E, 0xC8, 0xD7, 0xE7, 0x7B, 0xB5, 0x0C, 0x5F, 0xAF, 0xDE, + 0xDB, 0xBB, 0x22, 0x03, 0x5A, 0x29, 0x5F, 0x2B, 0xB2, 0x97, 0xCA, 0xEE, 0x95, 0x02, 0xE5, 0x7C, 0xBB, 0x4C, 0xDC, 0xEB, 0xA4, 0x89, 0xD8, 0xCB, + 0xC4, 0x7C, 0x97, 0x20, 0xE9, 0xBD, 0x46, 0x64, 0x6F, 0x80, 0xB3, 0xA8, 0x61, 0x9C, 0x49, 0xA4, 0xA2, 0x14, 0x24, 0xE5, 0xA4, 0xD2, 0x18, 0xF1, + 0x9E, 0x48, 0x5A, 0x52, 0x50, 0x48, 0x07, 0xD0, 0xA5, 0x35, 0x64, 0xB6, 0x0C, 0x22, 0xDC, 0xCD, 0x36, 0xEB, 0xE3, 0x59, 0xB1, 0xED, 0x53, 0x2A, + 0x8E, 0x70, 0x0B, 0x8E, 0x1C, 0x52, 0x82, 0x54, 0x85, 0xC2, 0x76, 0x3E, 0xA2, 0x68, 0x5F, 0xF2, 0xCF, 0x47, 0xAE, 0x61, 0x2D, 0xDB, 0x95, 0xBD, + 0x18, 0xCD, 0x5D, 0x4A, 0x7A, 0x7C, 0xF9, 0xCA, 0x7E, 0xA0, 0xA8, 0xD2, 0x0B, 0xDB, 0xC8, 0x96, 0x18, 0x25, 0xB0, 0x07, 0x17, 0x0B, 0xAD, 0x6C, + 0x47, 0x5E, 0x08, 0xE0, 0x5C, 0xE9, 0x4A, 0xD6, 0x05, 0x67, 0x9C, 0xE6, 0xE0, 0x81, 0x9D, 0x41, 0xB3, 0xE7, 0x01, 0x17, 0xBC, 0xF3, 0x33, 0xD0, + 0x39, 0x93, 0x42, 0xD5, 0x0F, 0x06, 0xD3, 0x61, 0x18, 0x36, 0x8C, 0x4A, 0x0D, 0x70, 0x51, 0xC4, 0x69, 0x0C, 0x30, 0x23, 0x15, 0xD0, 0x55, 0xB4, + 0x2E, 0x38, 0xD2, 0xBF, 0xFD, 0x85, 0x4A, 0x90, 0x8A, 0xB4, 0x5F, 0xDF, 0x6A, 0xB5, 0xDB, 0xA9, 0xCE, 0xB2, 0x90, 0xEA, 0x0D, 0x34, 0x08, 0x00, + 0x34, 0x0E, 0x08, 0x08, 0x00, 0x00, 0x1A, 0x2A, 0x08, 0x4F, 0x5F, 0x72, 0x84, 0x96, 0x08, 0xB5, 0xC4, 0xD7, 0xF4, 0x09, 0x09, 0x00, 0x00, 0x21, + 0x3C, 0x56, 0x6C, 0x86, 0x9E, 0xB3, 0xC2, 0xD2, 0xE2, 0xF0, 0xFF, 0x1B, 0x0A, 0x00, 0x00, 0x37, 0x47, 0x5A, 0x69, 0x76, 0x8A, 0x9D, 0xB3, 0xC2, + 0xD2, 0xE1, 0xF1, 0x04, 0x0B, 0x00, 0x00, 0x16, 0x27, 0x37, 0x49, 0x58, 0x6B, 0x7F, 0x90, 0xA0, 0xB2, 0xC5, 0xD6, 0xE9, 0xF8, 0x09, 0x0C, 0x00, + 0x00, 0x19, 0x26, 0x36, 0x52, 0x6E, 0x8D, 0x9A, 0xAA, 0xB9, 0xCD, 0xE0, 0xF0, 0x07, 0x0D, 0x00, 0x00, 0x1D, 0x30, 0x44, 0x58, 0x6D, 0x81, 0x96, + 0xA5, 0xB4, 0xC5, 0xD8, 0xE8, 0xFD, 0x0E, 0x0E, 0x00, 0x00, 0x1F, 0x35, 0x47, 0x5C, 0x6D, 0x7B, 0x91, 0xA2, 0xB3, 0xC4, 0xD6, 0xE9, 0xFF, 0x13, + 0x0F, 0x00, 0x00, 0x21, 0x35, 0x45, 0x55, 0x65, 0x77, 0x86, 0x99, 0xAA, 0xBA, 0xCE, 0xDF, 0xF0, 0x0A, 0x10, 0x31, 0x44, 0x56, 0x69, 0x7F, 0x90, + 0xA1, 0x10, 0xC7, 0xD1, 0xDD, 0xE8, 0xF4, 0xFF, 0x0B, 0x11, 0x00, 0x00, 0x19, 0x28, 0x34, 0x41, 0x4E, 0x58, 0x65, 0x72, 0x7E, 0x8B, 0x97, 0xA5, + 0xB0, 0xC0, 0xCF, 0xDE, 0xEB, 0xF6, 0x04, 0x12, 0x00, 0x00, 0x0F, 0x19, 0x24, 0x32, 0x41, 0x4B, 0x57, 0x63, 0x74, 0x83, 0x8D, 0x9A, 0xA8, 0xB5, + 0xC3, 0xD2, 0xDD, 0xEC, 0xF9, 0x06, 0x13, 0x00, 0x00, 0x15, 0x23, 0x31, 0x3E, 0x4F, 0x61, 0x6E, 0x7A, 0x85, 0x90, 0x9D, 0xAB, 0xB7, 0xC3, 0xD0, + 0xE2, 0xF3, 0xFD, 0x07, 0x14, 0x00, 0x00, 0x17, 0x26, 0x35, 0x40, 0x4E, 0x5D, 0x80, 0xB3, 0xA4, 0x20, 0xBA, 0x35, 0xF0, 0xD9, 0x0C, 0x00, 0x3A, + 0x8F, 0xFF, 0x3C, 0x42, 0x01, 0x64, 0x1C, 0x30, 0x37, 0xF2, 0xE6, 0x18, 0x0A, 0x0D, 0xE3, 0x19, 0x00, 0xA2, 0x03, 0x58, 0x2B, 0x03, 0xFC, 0x68, + 0x00, 0xEA, 0x7C, 0xE0, 0x1C, 0x36, 0x10, 0x88, 0x5C, 0x6B, 0x00, 0x1A, 0xAF, 0xA0, 0x08, 0x93, 0xAE, 0x00, 0x6D, 0x4D, 0x5E, 0xD0, 0x45, 0x5B, + 0xF3, 0xAD, 0xE3, 0x2D, 0x22, 0x5C, 0xD9, 0x45, 0xBB, 0xFD, 0xC2, 0x7B, 0x7D, 0x76, 0x84, 0x12, 0x0A, 0x24, 0x44, 0xB4, 0x63, 0xDD, 0x6E, 0xFA, + 0xD4, 0x46, 0xAE, 0x34, 0x79, 0x25, 0x0A, 0x18, 0x1B, 0xD9, 0x32, 0x05, 0xD8, 0x01, 0xCC, 0x01, 0xD4, 0x01, 0x77, 0xDF, 0x90, 0xF9, 0x86, 0x9B, + 0x7A, 0x39, 0x71, 0xFE, 0xC4, 0x5D, 0x02, 0xCC, 0x3E, 0x94, 0x84, 0x5F, 0xDD, 0xDE, 0x9B, 0x7B, 0x57, 0x49, 0x8F, 0xDC, 0x49, 0xB6, 0xB9, 0xD3, + 0xCE, 0xB3, 0xC6, 0x9E, 0xA4, 0x6E, 0x7D, 0xD1, 0x56, 0x6C, 0xA2, 0x92, 0x68, 0xA3, 0x07, 0x6D, 0x41, 0x5B, 0x48, 0x75, 0x00, 0x10, 0xDB, 0xC7, + 0x1D, 0xF0, 0x98, 0xB3, 0xCD, 0x69, 0x62, 0x17, 0xB3, 0xC9, 0xD0, 0x11, 0x47, 0x60, 0x17, 0xC0, 0x46, 0x41, 0x6D, 0xA8, 0xFD, 0xAA, 0xAA, 0x4B, + 0x40, 0x50, 0xD7, 0xAC, 0x25, 0xB4, 0xE8, 0xCF, 0xA3, 0xD2, 0xD7, 0x18, 0xE4, 0x02, 0xFD, 0x07, 0x74, 0x09, 0x2D, 0xB2, 0xFC, 0x7F, 0x2F, 0x96, + 0x81, 0x06, 0x7F, 0xDE, 0x4C, 0x2E, 0xA5, 0x46, 0xD2, 0xE7, 0x74, 0x09, 0x5A, 0x17, 0xB9, 0x51, 0x73, 0x06, 0x92, 0x71, 0x11, 0x5D, 0x78, 0xF6, + 0xBB, 0x51, 0x56, 0x1B, 0x41, 0xEE, 0x42, 0x10, 0xAE, 0xCA, 0x4A, 0xFD, 0x55, 0x45, 0x82, 0x34, 0xDF, 0x90, 0x59, 0x94, 0x62, 0xC4, 0xC7, 0x0D, + 0x19, 0x69, 0x22, 0xC4, 0x2E, 0x84, 0x79, 0x71, 0x15, 0xF8, 0x5E, 0x95, 0x7E, 0x01, 0xCF, 0xB4, 0x65, 0x64, 0x17, 0xC4, 0x41, 0xBD, 0xB8, 0x15, + 0x64, 0x64, 0x2E, 0x31, 0x15, 0xD3, 0xBF, 0x05, 0xD0, 0x09, 0xE7, 0xCC, 0xE2, 0xA1, 0x20, 0x9F, 0xDC, 0x0A, 0x33, 0x0B, 0x5C, 0x60, 0xEB, 0xAF, + 0x9D, 0x12, 0xD2, 0xA4, 0x24, 0xB3, 0x05, 0x4A, 0x20, 0x9E, 0xD9, 0xAD, 0x8D, 0x2D, 0xED, 0x84, 0x19, 0x08, 0x31, 0x32, 0x85, 0xAF, 0x03, 0x5E, + 0x29, 0x6A, 0x52, 0xD1, 0x9F, 0x1D, 0x2A, 0xD4, 0xB9, 0x39, 0x07, 0x4E, 0x9B, 0x49, 0x47, 0x74, 0x12, 0xC0, 0x3C, 0xB8, 0xB5, 0x11, 0x17, 0x1C, + 0x5C, 0xD9, 0x5A, 0x6C, 0x75, 0x89, 0xE8, 0xA7, 0xAA, 0x03, 0x75, 0x72, 0xD2, 0xC1, 0xA4, 0x84, 0xCC, 0x62, 0x58, 0x84, 0x8F, 0xEE, 0xC5, 0x59, + 0x87, 0xAF, 0x02, 0x5C, 0xA9, 0x7F, 0xCA, 0xE8, 0x8F, 0x26, 0xE5, 0x23, 0x96, 0x26, 0x41, 0x74, 0xCC, 0x95, 0xD1, 0xC6, 0x26, 0x2C, 0x08, 0x67, + 0xB1, 0x43, 0x7B, 0xE6, 0xA8, 0x69, 0x44, 0x27, 0x01, 0xA2, 0x37, 0x57, 0x36, 0xD3, 0x10, 0x61, 0xAC, 0xBD, 0x3E, 0x4F, 0x25, 0xA4, 0x16, 0xC3, + 0xF3, 0x1E, 0x8D, 0x15, 0x65, 0xE4, 0x07, 0xE3, 0x2D, 0xF5, 0xB7, 0x4A, 0x05, 0xE1, 0xC1, 0xA4, 0x84, 0x6C, 0xC4, 0x72, 0xA8, 0xE4, 0xFC, 0x87, + 0x37, 0xF7, 0xA6, 0x82, 0xC4, 0x58, 0x58, 0x03, 0x02, 0xE0, 0x6D, 0x54, 0x00, 0x00, 0x80, 0xD2, 0x98, 0x6D, 0xCA, 0x30, 0x5E, 0x81, 0x42, 0x78, + 0x06, 0xC2, 0x23, 0xEF, 0xAE, 0x4E, 0x6E, 0xC6, 0x9B, 0x89, 0x0C, 0x5D, 0xE3, 0xED, 0x2F, 0x35, 0x25, 0xB4, 0x29, 0xD9, 0x48, 0xE5, 0x70, 0x09, + 0xE1, 0xE0, 0x39, 0xC8, 0x5E, 0x8D, 0xB6, 0x13, 0x66, 0x64, 0x13, 0x10, 0x70, 0xAB, 0x7F, 0x14, 0x54, 0x0F, 0xE5, 0x98, 0x2C, 0x86, 0x81, 0x77, + 0x65, 0xB4, 0x31, 0x09, 0x03, 0xAA, 0x7E, 0x28, 0x6A, 0xA0, 0x4C, 0x34, 0x8D, 0x53, 0x06, 0xF3, 0x62, 0xA0, 0xD8, 0x20, 0x81, 0xC0, 0x96, 0xE9, + 0x7F, 0xAA, 0x39, 0xE3, 0x94, 0xF1, 0x52, 0x85, 0x10, 0x30, 0x87, 0x99, 0x4D, 0x04, 0x18, 0x83, 0x2D, 0xAE, 0x35, 0xE9, 0x77, 0xAA, 0xF7, 0x60, + 0xAE, 0x69, 0xAC, 0x52, 0x78, 0xDE, 0x41, 0xE7, 0x96, 0x16, 0x44, 0xC2, 0x43, 0x6E, 0x84, 0xEB, 0xD6, 0xBA, 0x6D, 0x16, 0x6C, 0xF2, 0xCD, 0x35, + 0x60, 0x25, 0x48, 0xD5, 0xA4, 0x27, 0x8C, 0x14, 0x2E, 0xDA, 0x6C, 0xE2, 0xBA, 0xA4, 0x6D, 0xAE, 0x72, 0x85, 0x78, 0xBE, 0xB9, 0x53, 0xBE, 0xD7, + 0x65, 0xC9, 0xE3, 0x2C, 0xDE, 0xD3, 0xAE, 0xD0, 0xC4, 0xAE, 0xC8, 0x08, 0x6C, 0x73, 0xD3, 0xE5, 0xAF, 0x52, 0x57, 0x4F, 0x55, 0x11, 0x57, 0x3F, + 0x7A, 0x7A, 0xA5, 0x4D, 0xDE, 0xBB, 0x8B, 0x7E, 0x01, 0x33, 0xD6, 0x1B, 0xB8, 0x7C, 0xCE, 0x9B, 0x80, 0x0B, 0xF9, 0xC0, 0x7A, 0xD4, 0x17, 0x79, + 0x2D, 0xEE, 0xC8, 0x06, 0x56, 0x13, 0xFB, 0x86, 0x13, 0x58, 0x09, 0x6E, 0x6D, 0x73, 0xD3, 0x0E, 0x30, 0x92, 0x7D, 0xA8, 0xBB, 0xEF, 0xB1, 0x15, + 0xBF, 0x9C, 0x92, 0x5F, 0x33, 0x50, 0xEE, 0x15, 0xBF, 0x89, 0x49, 0x6C, 0xF3, 0xD5, 0x4C, 0xEF, 0x8B, 0xB7, 0xE4, 0xC6, 0xED, 0xEB, 0x82, 0x89, + 0x0B, 0xD9, 0x17, 0x84, 0x53, 0xFD, 0xF5, 0xED, 0xA2, 0xFA, 0xF8, 0x8E, 0x23, 0xC3, 0xDB, 0xC1, 0xAF, 0x76, 0xC5, 0xB7, 0xFA, 0xA5, 0x22, 0xA5, + 0x3F, 0x48, 0x09, 0x50, 0xED, 0xD4, 0xA7, 0x3E, 0xDB, 0xF3, 0x34, 0xC8, 0xF9, 0x84, 0xC4, 0x73, 0x36, 0x3B, 0xF7, 0xCB, 0xF4, 0xCA, 0x39, 0xE0, + 0x65, 0x4D, 0xF4, 0xC6, 0xDB, 0x26, 0x4A, 0x25, 0x40, 0xCD, 0xAB, 0x92, 0x5E, 0x33, 0x57, 0x6E, 0xEF, 0xA0, 0x57, 0x10, 0xC7, 0xD9, 0xCE, 0xFA, + 0xA0, 0x86, 0x57, 0xCE, 0x7A, 0x66, 0x03, 0xA2, 0x41, 0xED, 0x63, 0x14, 0xD6, 0x3C, 0x67, 0xA7, 0x9A, 0x11, 0x28, 0xF3, 0x86, 0x00, 0xF3, 0x7A, + 0x6D, 0x79, 0xC7, 0xD8, 0x72, 0xF8, 0x74, 0xDF, 0xAB, 0xB6, 0x3B, 0x65, 0x64, 0x63, 0x35, 0xB7, 0x5E, 0xAA, 0x6B, 0xD9, 0x9B, 0x64, 0x9B, 0xF3, + 0x58, 0x6D, 0x7E, 0xCD, 0xD9, 0x74, 0xDB, 0x88, 0xB0, 0x4F, 0xB4, 0xC9, 0x5D, 0x74, 0xD0, 0x83, 0x56, 0x82, 0x75, 0x77, 0xDF, 0x99, 0x95, 0x19, + 0x98, 0xFD, 0xA7, 0x4C, 0x2B, 0xB1, 0xAD, 0x48, 0x85, 0x06, 0xFF, 0xD0, 0xAA, 0xDE, 0xDE, 0x4F, 0x3A, 0x01, 0xBF, 0xCA, 0x52, 0xAD, 0x61, 0x9F, + 0x83, 0x01, 0x8E, 0x05, 0xF5, 0x11, 0x55, 0x2B, 0xEA, 0x52, 0xDC, 0x73, 0xF0, 0x7F, 0x6C, 0xC5, 0xCB, 0xEE, 0x1B, 0x29, 0xE2, 0x1F, 0xBB, 0x5F, + 0xBA, 0x8C, 0x5C, 0x26, 0x51, 0xB2, 0x64, 0x1E, 0x47, 0x6A, 0x2F, 0xDB, 0xE4, 0x6E, 0xDB, 0xCD, 0x25, 0x5A, 0xEB, 0x86, 0x08, 0xCB, 0x52, 0x7A, + 0xE8, 0x8E, 0x5D, 0x2C, 0xD6, 0x25, 0x2B, 0x8D, 0xD1, 0x66, 0x75, 0xC5, 0x58, 0x4A, 0xF0, 0x94, 0xA1, 0x55, 0xF7, 0x9E, 0x2A, 0xD2, 0x8D, 0x76, + 0x01, 0x74, 0x6B, 0x6B, 0x19, 0x21, 0xEC, 0x58, 0x20, 0xAE, 0x1F, 0x2C, 0x5A, 0x27, 0x37, 0x0F, 0x9A, 0xBB, 0x2F, 0xFA, 0x23, 0x9E, 0xA3, 0x50, + 0x39, 0x78, 0xE2, 0x64, 0x66, 0xB2, 0x44, 0x44, 0x09, 0xD5, 0x7C, 0x3D, 0x5B, 0x31, 0x5A, 0x88, 0x67, 0xB4, 0x78, 0x37, 0x2D, 0x64, 0x83, 0x4B, + 0xA7, 0x05, 0xC7, 0x11, 0x85, 0x99, 0xC1, 0x8D, 0x01, 0xC2, 0x3E, 0x17, 0x37, 0x41, 0x95, 0xAD, 0xC8, 0xD5, 0x3E, 0x6D, 0xB9, 0xD2, 0x9B, 0x6B, + 0xE7, 0xCE, 0x14, 0x73, 0x83, 0xC1, 0x0E, 0x5D, 0x0A, 0x17, 0xCA, 0xED, 0xE4, 0x2F, 0x55, 0x99, 0x87, 0x93, 0xA3, 0x75, 0x19, 0x46, 0x2F, 0x51, + 0x55, 0xC1, 0x64, 0xA1, 0x0D, 0x9B, 0x68, 0x15, 0x2E, 0x1D, 0x12, 0xFE, 0x8F, 0x11, 0xEC, 0x02, 0x22, 0x56, 0xEA, 0x90, 0xEB, 0x9C, 0x20, 0x58, + 0x26, 0xC0, 0x6B, 0xE3, 0xDF, 0x3B, 0xF4, 0x61, 0xE7, 0xF6, 0xAE, 0xCF, 0xD3, 0xC2, 0x71, 0x48, 0xBB, 0xA9, 0x17, 0x35, 0xB4, 0xE4, 0xAC, 0x28, + 0x6C, 0x45, 0x28, 0x81, 0xB3, 0x67, 0x14, 0xB3, 0x3A, 0x5D, 0xF6, 0xC5, 0x10, 0xCF, 0x09, 0x1E, 0xEA, 0x41, 0x63, 0x87, 0x20, 0x56, 0x7B, 0x91, + 0x3F, 0xA5, 0xC2, 0x67, 0x80, 0xD5, 0x95, 0x9D, 0x5E, 0x5A, 0x11, 0xEA, 0xF4, 0xAB, 0xEC, 0x43, 0x8D, 0xD1, 0x2A, 0x9A, 0xE2, 0x3B, 0xA7, 0x6D, + 0x9E, 0xCC, 0x3A, 0x43, 0x04, 0x7E, 0x62, 0x16, 0xDA, 0x49, 0xC4, 0xCF, 0xDA, 0x4E, 0xB4, 0x33, 0x05, 0x66, 0xFD, 0xE8, 0xDB, 0x72, 0x6D, 0x8F, + 0xB7, 0x25, 0xBB, 0x0B, 0x10, 0xF5, 0xB9, 0xA7, 0x3C, 0x33, 0xD2, 0x2D, 0xD5, 0xE6, 0x6F, 0x84, 0x5E, 0x64, 0x35, 0x49, 0x7C, 0xED, 0x9A, 0x26, + 0x40, 0x09, 0x4D, 0x6B, 0x35, 0x41, 0x22, 0x8B, 0x6C, 0x6B, 0x39, 0x96, 0xC5, 0x01, 0xB3, 0x6A, 0x51, 0xDA, 0x85, 0x28, 0x8D, 0x54, 0xF9, 0x05, + 0x36, 0xB9, 0x2A, 0x4B, 0x2B, 0x55, 0x90, 0xF5, 0x1C, 0x17, 0xAA, 0x63, 0x9B, 0x21, 0xC7, 0x62, 0xB6, 0xE9, 0xA3, 0x6D, 0xB3, 0x13, 0x83, 0xF1, + 0x11, 0x2C, 0x4C, 0x4A, 0x45, 0xB6, 0xE4, 0xF3, 0x38, 0x50, 0x9C, 0xBE, 0xBB, 0xFB, 0x58, 0xD8, 0xF7, 0x30, 0x1E, 0x73, 0x30, 0xE6, 0xF2, 0x8E, + 0xB9, 0xF5, 0xE2, 0xB8, 0x69, 0xBC, 0xE4, 0x07, 0xAB, 0xB3, 0x26, 0x3C, 0x9B, 0xB7, 0xDA, 0x46, 0x9A, 0x67, 0x02, 0x34, 0xB5, 0x5F, 0xE4, 0xD3, + 0x05, 0x99, 0x3A, 0xF2, 0xF1, 0xC9, 0xE1, 0xCB, 0x91, 0x30, 0xFE, 0x8C, 0xCB, 0xD3, 0x4A, 0x4B, 0x5D, 0xC6, 0xF2, 0x2F, 0x56, 0x6A, 0x3F, 0xAC, + 0xF3, 0x61, 0xE0, 0x97, 0xFC, 0xC0, 0xEA, 0x21, 0x4E, 0x63, 0xF9, 0xC1, 0xD9, 0xE6, 0x33, 0x2C, 0x33, 0x68, 0xF4, 0x61, 0x58, 0x5F, 0x59, 0xF3, + 0xB7, 0x6C, 0x73, 0x95, 0x0E, 0x0B, 0x8B, 0x15, 0xE0, 0x28, 0xEE, 0x85, 0x6C, 0xC5, 0xAA, 0x9B, 0x20, 0x6A, 0x87, 0x3F, 0x4E, 0x80, 0x7C, 0xAA, + 0x51, 0x3D, 0x4C, 0x49, 0xD2, 0xE2, 0x3B, 0x4A, 0x6F, 0xA8, 0x1D, 0x3E, 0x99, 0x9E, 0x76, 0x39, 0xA3, 0xB4, 0xA1, 0xCC, 0x54, 0x72, 0x4C, 0x52, + 0x34, 0x8C, 0x91, 0x10, 0xC7, 0xA4, 0x08, 0x5E, 0x8E, 0x24, 0x17, 0xCF, 0xA9, 0x68, 0x64, 0x99, 0xF8, 0x43, 0xF4, 0xB4, 0xC8, 0x94, 0xF7, 0x38, + 0x7C, 0x99, 0xA1, 0xF4, 0x42, 0x93, 0x29, 0x55, 0xE1, 0xDF, 0x08, 0xA3, 0x4A, 0x46, 0xFE, 0x23, 0xD2, 0x8B, 0x88, 0x78, 0xC8, 0x14, 0x2E, 0xC8, + 0xD5, 0x00, 0x87, 0x8A, 0xFE, 0xDE, 0xD6, 0x27, 0xDE, 0x73, 0x03, 0x64, 0x94, 0xC2, 0x05, 0x52, 0x21, 0x0B, 0x22, 0xB2, 0x35, 0x71, 0x9A, 0xB4, + 0x2E, 0x4E, 0x8C, 0x46, 0x94, 0xE4, 0x65, 0x48, 0xCB, 0x2D, 0xD8, 0x8A, 0x48, 0x62, 0xC2, 0xC4, 0x5F, 0xE2, 0xAE, 0xBB, 0x6F, 0x8C, 0xC8, 0x02, + 0xF8, 0x31, 0xFB, 0x27, 0xAC, 0x0E, 0x31, 0x74, 0xD3, 0x36, 0x57, 0x1B, 0xCF, 0x26, 0x9C, 0xE6, 0xAA, 0xA6, 0x12, 0x8D, 0x75, 0x2F, 0x32, 0x31, + 0x8C, 0x0E, 0x46, 0x1E, 0xB7, 0x89, 0xB9, 0x99, 0x3E, 0x1E, 0xCD, 0xDF, 0xA9, 0x73, 0x3A, 0xB7, 0x93, 0xF9, 0x39, 0xC7, 0x94, 0xF3, 0xC3, 0xA9, + 0xAB, 0x97, 0xB7, 0x7C, 0xE5, 0xDF, 0x9C, 0xF2, 0x6E, 0xDE, 0x66, 0xCD, 0xD5, 0xA4, 0xF9, 0xA4, 0xE4, 0x13, 0x6F, 0xE6, 0x50, 0x1E, 0xF9, 0x32, + 0x87, 0x3C, 0x99, 0x8F, 0xB9, 0x98, 0x3F, 0x3E, 0xCC, 0xC1, 0xFC, 0xCB, 0x97, 0xDC, 0xF1, 0x6C, 0xDE, 0x78, 0xC6, 0x7B, 0x79, 0x97, 0x73, 0xB9, + 0x90, 0x2F, 0x7E, 0xCB, 0xB5, 0x5C, 0xF1, 0x59, 0xB0, 0x3C, 0xF1, 0x57, 0xAC, 0xDC, 0x51, 0xCC, 0xAB, 0x4C, 0x41, 0xFC, 0xE4, 0xA5, 0xFC, 0xF0, + 0x51, 0x0E, 0xE5, 0x86, 0x7F, 0x52, 0x5F, 0xEF, 0xE4, 0x4D, 0xCE, 0xE4, 0x4B, 0x5E, 0xA8, 0xE4, 0x49, 0x4E, 0x78, 0x24, 0x3F, 0x32, 0x78, 0x23, + 0x2F, 0xF2, 0x78, 0xC9, 0x13, 0x39, 0x95, 0xA3, 0x2F, 0xF8, 0xF3, 0x87, 0x5C, 0xC8, 0x03, 0xEF, 0xE5, 0x41, 0x0E, 0xE4, 0xC7, 0x01, 0xEF, 0xE3, + 0xEF, 0x3C, 0xAA, 0xF7, 0x7B, 0xDF, 0x1D, 0xF9, 0xBE, 0xA3, 0x5E, 0xF0, 0xBD, 0xEB, 0xD5, 0x1B, 0xAE, 0xE3, 0x79, 0x4F, 0x70, 0x3C, 0x1C, 0x77, + 0x76, 0x36, 0x5E, 0xF7, 0x1A, 0x74, 0x73, 0x72, 0x8F, 0x9B, 0x71, 0xBB, 0x47, 0xC9, 0x78, 0x8C, 0xC3, 0xF8, 0xDB, 0x73, 0xDC, 0xED, 0xC5, 0xE1, + 0x5C, 0xBC, 0xED, 0x2D, 0x9E, 0xE1, 0x2C, 0xBE, 0xE2, 0x6C, 0x5F, 0xBB, 0x8A, 0xAB, 0x3D, 0xED, 0x29, 0x50, 0x94, 0x7F, 0xE3, 0x68, 0x3F, 0xF1, + 0xB3, 0x9B, 0x78, 0x89, 0x9B, 0x9D, 0xC4, 0x47, 0xDC, 0xFA, 0xB2, 0x93, 0x5D, 0x44, 0x88, 0x83, 0xF8, 0x87, 0x97, 0x3D, 0xBC, 0xC3, 0x39, 0x80, + 0x7D, 0xEC, 0x1B, 0xAE, 0xE1, 0x52, 0x17, 0x7B, 0x86, 0x63, 0x20, 0xFF, 0xC2, 0x2D, 0xBC, 0xC2, 0x29, 0x3C, 0xEC, 0x60, 0x5F, 0xF7, 0xBA, 0x84, + 0x77, 0x3D, 0xC2, 0x21, 0x3C, 0xB8, 0x83, 0xB3, 0xBD, 0xC1, 0x19, 0x7C, 0xC2, 0xB9, 0x6E, 0xF7, 0x05, 0x57, 0xF0, 0x04, 0x08, 0x7E, 0xE0, 0x06, + 0x5E, 0xE0, 0x04, 0x06, 0xBC, 0x2D, 0x2A, 0xEB, 0xE3, 0x63, 0x89, 0xC3, 0x5F, 0xEF, 0xAD, 0xDE, 0xE5, 0xFE, 0x66, 0xF1, 0xAD, 0xF6, 0xD9, 0x53, + 0x7D, 0xCA, 0xFA, 0x00, 0x97, 0x7A, 0x14, 0x54, 0xF9, 0xE5, 0xA6, 0x33, 0x9D, 0xAA, 0x34, 0x45, 0x8A, 0x3E, 0xFA, 0x22, 0xE9, 0xA3, 0x47, 0x44, + 0x37, 0x02, 0x70, 0xA8, 0xD1, 0x8F, 0x92, 0xEA, 0x27, 0xFD, 0xD0, 0x3F, 0x3D, 0x7D, 0x3A, 0x37, 0x57, 0xC9, 0xEE, 0x10, 0x6C, 0xB3, 0x53, 0x95, + 0xAD, 0xAB, 0x06, 0x77, 0xE6, 0x16, 0xD1, 0xBB, 0xC5, 0xED, 0x92, 0x95, 0xD2, 0x5B, 0xBD, 0x2D, 0xA4, 0xAD, 0x22, 0x26, 0x0E, 0xE7, 0xFC, 0xC3, + 0x43, 0x3D, 0xB2, 0xC3, 0x14, 0x85, 0x95, 0xA8, 0x93, 0xF3, 0x56, 0x66, 0x52, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xD2, 0x1C, 0x23, 0x49, 0x1B, + 0x08, 0x44, 0x19, 0x32, 0x04, 0x51, 0x2C, 0xE9, 0x03, 0x66, 0x50, 0xC6, 0x25, 0x90, 0x49, 0x52, 0x92, 0x94, 0x7F, 0xA5, 0xD2, 0x6E, 0x67, 0xC3, + 0x24, 0x3D, 0xD7, 0x57, 0xF5, 0x1C, 0xDA, 0x99, 0xFD, 0x48, 0xFF, 0xC3, 0xF2, 0x83, 0x25, 0x2A, 0x5B, 0xE9, 0xAF, 0x78, 0x5F, 0x57, 0xEC, 0x2E, + 0xDC, 0x9A, 0xCD, 0x4D, 0xA2, 0xBC, 0xEE, 0x86, 0xBB, 0xFB, 0x84, 0x16, 0x5C, 0xEB, 0x63, 0xBA, 0x17, 0x54, 0x1C, 0xAE, 0x74, 0xF4, 0xDE, 0xE6, + 0x15, 0x19, 0x8D, 0x68, 0x12, 0xD1, 0xC1, 0x28, 0xA0, 0xF0, 0xBB, 0x91, 0x4A, 0xAF, 0x5B, 0xC4, 0xCC, 0x22, 0xA1, 0x43, 0x2D, 0x95, 0xD2, 0x78, + 0x4D, 0x6E, 0xED, 0xA1, 0x08, 0xB9, 0x83, 0x7D, 0x7B, 0x9E, 0x49, 0x77, 0x32, 0x31, 0x9A, 0x5B, 0xEF, 0x32, 0xA4, 0xC5, 0x57, 0x45, 0x3F, 0x00, + 0xA5, 0xBB, 0x5C, 0x8D, 0xFF, 0xD1, 0xF8, 0x3A, 0xBD, 0x55, 0x0E, 0x62, 0x87, 0x3B, 0x5B, 0x5D, 0x37, 0xBD, 0x42, 0x2E, 0x4F, 0x38, 0x3B, 0xD7, + 0x11, 0x4D, 0xA8, 0x08, 0x42, 0x8B, 0x36, 0x9C, 0xEB, 0xD2, 0xDB, 0x20, 0x11, 0x5F, 0x87, 0x3C, 0x53, 0x70, 0x59, 0xA2, 0x7B, 0x65, 0xDD, 0x07, + 0xE7, 0x72, 0xC2, 0x9D, 0x45, 0x3E, 0xC6, 0xD4, 0xE9, 0xEF, 0x43, 0xB2, 0x05, 0xDF, 0x4C, 0x96, 0x1A, 0x50, 0xC0, 0x99, 0xFE, 0x5E, 0x2E, 0x8D, + 0x3F, 0x5C, 0x7B, 0xA7, 0x23, 0x2D, 0xA4, 0x9F, 0x08, 0xCC, 0x77, 0x65, 0xFE, 0xE3, 0x40, 0xCD, 0xFE, 0xAE, 0x92, 0xC3, 0xBD, 0x7C, 0xE7, 0x60, + 0x4C, 0xDC, 0x56, 0xCC, 0x7A, 0x90, 0xA6, 0xCC, 0xB8, 0xA2, 0xCA, 0x63, 0xB9, 0xCE, 0x8E, 0xB0, 0x0A, 0x78, 0x7C, 0x20, 0xF4, 0xFE, 0x55, 0x7C, + 0xFF, 0xED, 0x97, 0xF0, 0x8F, 0x79, 0xFE, 0xFF, 0x9F, 0x2A, 0x7B, 0x89, 0x7B, 0xCA, 0xAD, 0x66, 0x8E, 0x74, 0x67, 0x4D, 0xE5, 0x0D, 0xD4, 0x13, + 0x1C, 0x53, 0x70, 0xF6, 0xB5, 0xF9, 0xF6, 0x1C, 0x5F, 0x17, 0x9F, 0x89, 0x2A, 0x9A, 0xE5, 0x2D, 0xA0, 0x9E, 0x9D, 0x55, 0xBC, 0x95, 0xC5, 0x7A, + 0x72, 0x6C, 0x3F, 0x2D, 0xF5, 0x05, 0xAD, 0x73, 0xD4, 0x07, 0x11, 0x1B, 0x0A, 0xA8, 0xFA, 0x18, 0x0B, 0x35, 0xFA, 0x1E, 0x35, 0x6C, 0xB4, 0x29, + 0x43, 0x70, 0xDF, 0xAC, 0x64, 0xE6, 0xD3, 0x1C, 0xF9, 0xBA, 0x68, 0xC2, 0xD3, 0xB7, 0x71, 0xF1, 0xDB, 0xE0, 0x5A, 0x4E, 0x2F, 0x90, 0xE7, 0xF3, + 0xCA, 0xB2, 0x2E, 0x86, 0x05, 0xE8, 0xBD, 0x2A, 0xE2, 0x68, 0xBF, 0x54, 0xB5, 0x25, 0x5E, 0x5B, 0x0C, 0xCB, 0x7B, 0xA0, 0xCF, 0xB2, 0xCB, 0x98, + 0x5C, 0xB3, 0xE8, 0x15, 0xF3, 0x28, 0xA9, 0xC0, 0x9D, 0xD4, 0x2C, 0x7F, 0xFF, 0x4E, 0x37, 0xF7, 0x82, 0x8B, 0x51, 0x6D, 0x7B, 0xC0, 0x45, 0xF6, + 0x3B, 0xFA, 0x8F, 0xA7, 0xBE, 0x23, 0x62, 0x2A, 0x1A, 0x74, 0x28, 0x60, 0x60, 0x47, 0x10, 0x38, 0x9E, 0xDF, 0xC7, 0x90, 0x1F, 0x79, 0xAF, 0xEA, + 0x65, 0xC6, 0x26, 0xD2, 0x8C, 0xB2, 0x3E, 0x23, 0x6C, 0x4D, 0x57, 0xD5, 0xC1, 0x4B, 0x1E, 0xE2, 0xDC, 0x5B, 0xBF, 0xFE, 0x2D, 0x3E, 0x38, 0xB6, + 0x0A, 0x57, 0x9B, 0xFA, 0x9C, 0xDC, 0x82, 0x51, 0x37, 0x67, 0x8E, 0x93, 0xF3, 0xB4, 0x1F, 0xE6, 0xFA, 0x4D, 0x95, 0x83, 0xE5, 0x32, 0xB3, 0x52, + 0x84, 0xF8, 0x73, 0x2E, 0xB7, 0x85, 0x9D, 0x6F, 0x51, 0x90, 0x09, 0xC0, 0x8F, 0xF5, 0xBC, 0x3E, 0xBC, 0x2C, 0x46, 0x9E, 0x43, 0x9C, 0x52, 0x13, + 0xDC, 0x1E, 0x8A, 0xE9, 0x27, 0xB8, 0x6F, 0x5B, 0x0F, 0xF7, 0x36, 0xDB, 0xC6, 0x64, 0xAA, 0xF4, 0x13, 0xF5, 0x38, 0x39, 0xC9, 0xF7, 0xA1, 0x2D, + 0xAC, 0x99, 0x14, 0x39, 0x33, 0x5E, 0x54, 0x91, 0x03, 0x5B, 0xB7, 0x59, 0x7F, 0xDE, 0x37, 0xFE, 0xB6, 0x2D, 0x8E, 0xCA, 0x77, 0x09, 0xE7, 0x88, + 0x2F, 0x75, 0xFB, 0xEE, 0x0F, 0x11, 0x26, 0xFF, 0x35, 0x75, 0xEE, 0xC7, 0x4F, 0x23, 0xBB, 0xD3, 0x69, 0xBA, 0x37, 0x65, 0x4B, 0x41, 0x6B, 0x17, + 0xCD, 0x1C, 0x15, 0x55, 0xC1, 0x69, 0xFB, 0xF9, 0xBD, 0x9A, 0x5C, 0x4E, 0x45, 0xB0, 0x86, 0x36, 0xF1, 0xBF, 0x22, 0xE0, 0x7B, 0xCC, 0x02, 0x93, + 0xFB, 0xFB, 0x10, 0x4F, 0xDB, 0x7F, 0x4B, 0xCB, 0x1D, 0xE7, 0x0E, 0xE3, 0xFA, 0xDC, 0x80, 0xCA, 0x2D, 0x0E, 0x3F, 0x5E, 0x4E, 0xE6, 0x89, 0x7E, + 0x9F, 0xCD, 0x7D, 0xF0, 0xB8, 0x80, 0xBA, 0xAB, 0x6C, 0x30, 0xCE, 0xEE, 0x4F, 0xBA, 0xB3, 0x2A, 0xE4, 0x95, 0x32, 0x2A, 0x2E, 0xE6, 0x49, 0x55, + 0xA9, 0x49, 0x0C, 0xEB, 0x97, 0x41, 0x59, 0x4B, 0x7B, 0xC2, 0x17, 0x3A, 0x3D, 0x1A, 0x78, 0xCD, 0xD3, 0xD2, 0x69, 0xAB, 0xF7, 0x85, 0x14, 0x3C, + 0x91, 0xC3, 0x9A, 0x63, 0x89, 0xBF, 0x87, 0x3C, 0xE7, 0xAE, 0xE0, 0xB7, 0x92, 0x72, 0x6F, 0x24, 0xC3, 0x2B, 0x6D, 0x72, 0xD5, 0xE9, 0x43, 0x13, + 0xB8, 0x3D, 0xDE, 0x35, 0xC2, 0xD6, 0xBC, 0x9A, 0xF9, 0xC9, 0xCF, 0x65, 0xC9, 0x75, 0x17, 0xEA, 0x9B, 0xB6, 0x61, 0xCF, 0x95, 0x7A, 0x0B, 0xC1, + 0x9C, 0x14, 0x3A, 0x72, 0x05, 0x4F, 0x70, 0x9F, 0x90, 0xAF, 0x9D, 0xE8, 0xD3, 0x57, 0x7E, 0xC6, 0x1B, 0x47, 0x22, 0x33, 0x32, 0x49, 0x6E, 0xD7, + 0x7A, 0x3F, 0xA0, 0x31, 0xB8, 0xEE, 0x71, 0x18, 0xF4, 0xA0, 0xF6, 0x13, 0x9C, 0x4B, 0x6B, 0x7C, 0x25, 0xC8, 0x93, 0x39, 0x3F, 0xFC, 0x32, 0x50, + 0x5F, 0x40, 0x83, 0xBB, 0x83, 0x1D, 0xF8, 0x1B, 0x85, 0x5C, 0xB6, 0xE9, 0x23, 0x95, 0x6B, 0xB1, 0xE6, 0x5B, 0x54, 0x79, 0x3E, 0x9D, 0x1E, 0x89, + 0x30, 0x81, 0xA8, 0xCC, 0xBE, 0x76, 0x5D, 0xFF, 0x69, 0x1F, 0xC7, 0x2B, 0x64, 0x97, 0xA6, 0x58, 0xF2, 0x7E, 0x73, 0xDE, 0x6B, 0x27, 0x61, 0x1B, + 0x9E, 0x3E, 0x29, 0x72, 0xE7, 0xA6, 0xA0, 0x12, 0xD6, 0x4E, 0x86, 0x25, 0x99, 0xD8, 0x97, 0x1D, 0x03, 0x1D, 0xF9, 0x41, 0x67, 0x93, 0x75, 0x80, + 0x21, 0x38, 0xD0, 0x90, 0xEB, 0x8C, 0xA7, 0xE0, 0x5F, 0x33, 0x53, 0x1D, 0x38, 0xBB, 0x94, 0x92, 0x97, 0xA2, 0x78, 0xED, 0x81, 0x90, 0xAF, 0x31, + 0x34, 0x63, 0x00, 0x3B, 0x96, 0xA6, 0xF2, 0x02, 0xE1, 0xB8, 0xC7, 0x91, 0x2E, 0xFA, 0xFA, 0xB6, 0xFA, 0xE6, 0x77, 0xCE, 0xAD, 0xF9, 0xEB, 0x74, + 0xFB, 0xF1, 0x03, 0x3C, 0x81, 0x89, 0x7A, 0x9D, 0x99, 0x0D, 0xBE, 0x2C, 0x77, 0x30, 0x9F, 0x37, 0x8C, 0xF9, 0xBB, 0x0A, 0x6F, 0x3B, 0xCB, 0xF7, + 0xF5, 0x9A, 0x63, 0x66, 0x6B, 0x8B, 0x9E, 0x76, 0x4E, 0x49, 0x17, 0x35, 0xC1, 0xEF, 0xCB, 0xBB, 0xFC, 0x7E, 0x6C, 0xCD, 0x9E, 0x0C, 0x8F, 0x63, + 0x7F, 0xCD, 0xA3, 0x93, 0xD7, 0x7B, 0xFA, 0xAF, 0x04, 0xB5, 0xAD, 0xEC, 0x89, 0x26, 0x0C, 0xFF, 0xAC, 0x61, 0xE1, 0x54, 0x8C, 0x2A, 0xD9, 0x02, + 0x3C, 0xE7, 0xA7, 0xE0, 0xE3, 0x38, 0xF7, 0x5F, 0xF6, 0xC0, 0x24, 0xFF, 0x9B, 0xB8, 0x75, 0x46, 0xB9, 0x8D, 0x95, 0x93, 0xE7, 0xF2, 0x08, 0xE2, + 0x0C, 0x71, 0x33, 0x49, 0x92, 0xD5, 0x7F, 0xD2, 0x3E, 0xFA, 0xAF, 0xF9, 0x61, 0x68, 0x4A, 0x54, 0x08, 0xBD, 0x2D, 0x16, 0xBF, 0x15, 0xFD, 0x2A, + 0x86, 0x2B, 0x5C, 0x5C, 0x50, 0x02, 0x5E, 0x8A, 0x39, 0x56, 0xEC, 0xAF, 0x73, 0x71, 0xE6, 0xFF, 0x70, 0x56, 0x8C, 0x79, 0xAB, 0x0C, 0x88, 0xA3, + 0xB5, 0x4E, 0xD8, 0x8A, 0xE3, 0x90, 0x97, 0x4E, 0x04, 0xA8, 0x07, 0x73, 0x7E, 0x58, 0x5F, 0xCB, 0x27, 0x32, 0x7E, 0x5D, 0xBB, 0x06, 0xF5, 0x42, + 0x52, 0x6D, 0xE3, 0xC4, 0xFF, 0xFA, 0xCF, 0x00, 0x2A, 0xF7, 0x8F, 0x3F, 0xF0, 0x9F, 0x1C, 0x7F, 0x5A, 0x40, 0x70, 0xBA, 0x0D, 0xE5, 0x87, 0x1C, + 0x17, 0x5F, 0xEA, 0x93, 0x7F, 0x04, 0x88, 0xB0, 0xBC, 0x39, 0xF0, 0xBB, 0xCE, 0x67, 0x00, 0x4A, 0x6E, 0x54, 0xB7, 0xBD, 0xCE, 0xE7, 0x82, 0xE5, + 0xAA, 0x29, 0xD3, 0x61, 0x5D, 0x0A, 0xFA, 0xEC, 0x77, 0xC5, 0x96, 0xF6, 0x74, 0x50, 0xB7, 0xE3, 0xA9, 0xBE, 0x8B, 0xEB, 0xCC, 0x9C, 0xB2, 0xE1, + 0xCF, 0xF3, 0xBD, 0x04, 0xFB, 0x16, 0xE6, 0x86, 0xDE, 0x5C, 0xEA, 0x5F, 0xFE, 0xC7, 0xCA, 0x77, 0xB0, 0x32, 0x34, 0xD8, 0x2F, 0xCB, 0xB3, 0x4F, + 0x74, 0x66, 0x00, 0x36, 0xF4, 0x7D, 0x08, 0x04, 0x7F, 0x24, 0x2C, 0x14, 0x28, 0x32, 0xB9, 0xA7, 0xAC, 0x21, 0x5C, 0x75, 0x8A, 0x6C, 0x5E, 0x62, + 0xB9, 0xA6, 0x0F, 0xB0, 0xBB, 0x35, 0x6E, 0x60, 0x18, 0x7B, 0xA2, 0xFD, 0x5E, 0x62, 0xCA, 0x87, 0xEB, 0x84, 0xB6, 0xF9, 0xEE, 0xDF, 0x05, 0x9E, + 0xB2, 0xAB, 0x70, 0xD8, 0xD6, 0x8D, 0x5C, 0xC7, 0x4C, 0x34, 0x17, 0xC8, 0x6E, 0x78, 0xBC, 0x97, 0xBA, 0x93, 0xAF, 0x25, 0xC6, 0xB5, 0xF0, 0xC6, + 0x54, 0x8C, 0x5B, 0x30, 0x9E, 0xE4, 0x3F, 0x11, 0xFE, 0xA2, 0xE3, 0x5C, 0x99, 0x27, 0x95, 0xB6, 0xB7, 0x30, 0xD1, 0x51, 0xB8, 0xB8, 0x80, 0x2E, + 0x13, 0x05, 0x8C, 0x54, 0x2D, 0x3B, 0x24, 0x7A, 0xC9, 0x0D, 0xFC, 0xBC, 0x02, 0x1B, 0xC0, 0x57, 0xFA, 0x0D, 0xAF, 0x2E, 0x62, 0xBB, 0x5D, 0xF8, + 0xA3, 0xF9, 0x02, 0x16, 0x7C, 0x31, 0x45, 0x56, 0xD4, 0xD4, 0x62, 0x77, 0x75, 0xF8, 0x37, 0x29, 0xD9, 0xF9, 0x74, 0xB2, 0x68, 0x75, 0x08, 0x19, + 0x6E, 0x66, 0x11, 0xFC, 0xBE, 0xEA, 0xC7, 0xE1, 0x62, 0xDF, 0x9C, 0xA4, 0x92, 0x5C, 0x38, 0x16, 0x1A, 0xF9, 0xBE, 0xAE, 0xE7, 0xD0, 0x67, 0xC7, + 0xFD, 0x16, 0xCE, 0x14, 0x8D, 0x57, 0xB2, 0xE9, 0xA0, 0xD1, 0x0F, 0x1F, 0x20, 0x7B, 0x07, 0x72, 0x21, 0xE5, 0x31, 0x4A, 0xDA, 0x2E, 0xC3, 0x57, + 0x8D, 0x40, 0xD4, 0xB0, 0x83, 0xA9, 0x1F, 0xBC, 0xB2, 0xEB, 0x91, 0x20, 0x92, 0xE3, 0xDF, 0x6D, 0xA5, 0xB4, 0x2D, 0x48, 0x80, 0x5F, 0x04, 0x36, + 0x80, 0x7E, 0x02, 0x83, 0xDB, 0x00, 0x36, 0x88, 0xEE, 0x00, 0x98, 0xE5, 0x01, 0x6F, 0x88, 0xCC, 0x12, 0xB9, 0x01, 0x05, 0x6F, 0x88, 0xCC, 0x12, + 0xB9, 0xD9, 0x40, 0x3F, 0x88, 0xEE, 0x00, 0x98, 0x25, 0x72, 0x03, 0xC0, 0x97, 0x00, 0xF1, 0x05, 0xF0, 0x0B, 0xE0, 0x17, 0x81, 0x0D, 0xA0, 0x9F, + 0xC0, 0xE0, 0x36, 0x80, 0x0D, 0xA2, 0x3B, 0x00, 0x86, 0x37, 0x90, 0x1F, 0x00, 0xB3, 0x44, 0x6E, 0x80, 0x86, 0x2F, 0xE4, 0x5A, 0x84, 0x94, 0x99, + 0x4B, 0x20, 0x24, 0x19, 0xC2, 0x64, 0x25, 0x10, 0x6E, 0x23, 0xB4, 0xD3, 0xA4, 0xB4, 0x89, 0x4A, 0x02, 0xDC, 0x46, 0x28, 0x09, 0x44, 0x7B, 0x6A, + 0x73, 0xD3, 0x00, 0xBE, 0x09, 0x68, 0x02, 0xF9, 0x0C, 0x6C, 0xBC, 0x05, 0x7C, 0x13, 0xD0, 0x04, 0xF2, 0x19, 0x00, 0x6D, 0x0B, 0xF8, 0x04, 0xF2, + 0x19, 0x02, 0x7C, 0x03, 0xF9, 0x0C, 0xA0, 0xC1, 0x0D, 0x6C, 0x07, 0xD0, 0x28, 0xB2, 0x13, 0xA0, 0x78, 0x05, 0xD9, 0x28, 0xF2, 0x2B, 0x41, 0x38, + 0x34, 0x54, 0x00, 0x1A, 0x68, 0xA8, 0x13, 0x49, 0xE0, 0x98, 0x36, 0x1D, 0xD4, 0xE8, 0x41, 0x21, 0xC6, 0x18, 0x26, 0x88, 0x51, 0x43, 0x18, 0xCD, + 0x21, 0xC0, 0x09, 0xC9, 0x30, 0xC4, 0x18, 0xC3, 0x0E, 0x1C, 0xE3, 0x64, 0xB1, 0x11, 0x29, 0x45, 0x7E, 0x4B, 0x72, 0xCB, 0x6E, 0x49, 0xF6, 0x4F, + 0x7B, 0x9F, 0x6E, 0x3C, 0x0C, 0xFB, 0xEF, 0x66, 0xA8, 0x91, 0xC8, 0xEC, 0xBF, 0xDB, 0xEC, 0x7B, 0x64, 0xB9, 0x3C, 0x07, 0x44, 0x37, 0x32, 0xAA, + 0xEB, 0x1A, 0x43, 0xAF, 0x8C, 0xAE, 0xAB, 0x38, 0xA5, 0x58, 0x01, 0x10, 0x01, 0x1C, 0x01, 0xCE, 0x79, 0x88, 0x47, 0x23, 0x86, 0x0D, 0x33, 0xF9, + 0xD8, 0x4D, 0x8E, 0xD1, 0xDD, 0xFC, 0xF8, 0xB4, 0xDE, 0x5F, 0x8C, 0xB1, 0x47, 0x33, 0x16, 0x23, 0x6C, 0xB7, 0xDC, 0xC4, 0x93, 0x45, 0x8A, 0x5E, + 0x55, 0x0C, 0x29, 0xEA, 0xF1, 0xA7, 0xF2, 0xC9, 0x42, 0x02, 0x53, 0x0E, 0x55, 0x3A, 0x26, 0x18, 0x10, 0x8B, 0x65, 0x5F, 0x6C, 0xA0, 0x44, 0xBC, + 0x58, 0x93, 0x1A, 0x2A, 0x43, 0x5B, 0xD0, 0x91, 0xCD, 0x68, 0x53, 0x11, 0x8D, 0xA1, 0x50, 0x39, 0x14, 0xC6, 0xBE, 0x58, 0x09, 0x56, 0x65, 0x7B, + 0xAB, 0xA5, 0x76, 0x5A, 0x5E, 0x1D, 0x56, 0xDA, 0x1C, 0x16, 0x87, 0xBD, 0x61, 0x6D, 0xD8, 0x1A, 0x74, 0x89, 0x0D, 0xD1, 0x24, 0x94, 0x09, 0x14, + 0x68, 0x38, 0xD9, 0x1A, 0x29, 0x98, 0x45, 0x09, 0xF1, 0x6C, 0x87, 0xC6, 0x72, 0x76, 0xC6, 0x6E, 0xD6, 0x64, 0x35, 0x25, 0x22, 0x99, 0xC5, 0x6C, + 0xC8, 0x82, 0xEC, 0xC7, 0xD2, 0xB0, 0x97, 0xF5, 0x58, 0x91, 0xB5, 0xEC, 0x0C, 0x7B, 0x12, 0xC3, 0x0B, 0xEB, 0x82, 0xD6, 0xD0, 0xA9, 0x4A, 0x28, + 0x54, 0x23, 0x54, 0xC6, 0xCA, 0xB0, 0x30, 0x2C, 0x0C, 0xFA, 0x84, 0x52, 0x2A, 0x69, 0x0F, 0xDB, 0x82, 0xC2, 0x7D, 0x01, 0x81, 0x2D, 0xE9, 0x68, + 0x13, 0x43, 0xA8, 0x8B, 0x95, 0x31, 0xC4, 0xB2, 0xE0, 0x84, 0x0A, 0xB1, 0x2B, 0x1C, 0x51, 0xC4, 0x66, 0xF4, 0xC6, 0x05, 0xAB, 0x02, 0xC7, 0xA2, + 0xB0, 0x27, 0xAC, 0x09, 0x5B, 0x42, 0x0A, 0x31, 0x48, 0xD8, 0x11, 0x3A, 0x44, 0xD8, 0x10, 0x96, 0x03, 0x84, 0xFD, 0x60, 0x3D, 0xE0, 0x80, 0xA1, + 0x48, 0xEC, 0x06, 0xCB, 0xC1, 0x6A, 0x90, 0xC1, 0x62, 0xB0, 0x0B, 0x70, 0xAC, 0x05, 0x14, 0x6C, 0x05, 0x3B, 0x81, 0x04, 0x11, 0x40, 0xB0, 0x0F, + 0x38, 0xB0, 0x29, 0x6C, 0x03, 0xCB, 0x40, 0x07, 0x0B, 0x63, 0x39, 0xF6, 0x82, 0x04, 0x16, 0x81, 0x5D, 0xE0, 0x80, 0x7D, 0xE1, 0x62, 0x0D, 0xD8, + 0x02, 0x96, 0x80, 0x1D, 0x60, 0x05, 0xD8, 0x00, 0x76, 0x57, 0xB7, 0x50, 0x2D, 0x34, 0x0B, 0xC5, 0x42, 0xAF, 0x50, 0x2B, 0xB4, 0x0A, 0x2A, 0x74, + 0x0A, 0x95, 0x42, 0x6F, 0xE8, 0x8D, 0x7D, 0x40, 0x01, 0xD0, 0x28, 0x14, 0xB4, 0x0A, 0x2C, 0x07, 0xEA, 0x42, 0x31, 0x3B, 0x83, 0xEE, 0xA0, 0x40, + 0xFC, 0xA0, 0x3C, 0xA8, 0x0B, 0xEA, 0x83, 0x66, 0x1A, 0x84, 0x86, 0xA8, 0x12, 0x0A, 0x85, 0xC6, 0x50, 0x1E, 0x0A, 0xD0, 0x1B, 0x3E, 0x01, 0x2F, + 0xFD, 0xA1, 0x84, 0x1D, 0x7A, 0x7D, 0xB5, 0xF4, 0x51, 0xA4, 0x2F, 0x74, 0x3D, 0xFE, 0xF8, 0xC9, 0x3E, 0xDF, 0xCB, 0x9E, 0x2B, 0xCE, 0x2D, 0xA3, + 0x64, 0x84, 0xF3, 0x33, 0x92, 0x1B, 0x35, 0xAC, 0xB8, 0x9A, 0xFE, 0x56, 0xBB, 0x74, 0x46, 0x31, 0x7C, 0x93, 0x7A, 0x0A, 0x41, 0x59, 0x5B, 0x95, + 0xC3, 0x09, 0xE3, 0x4B, 0xF4, 0xB7, 0x94, 0x65, 0x74, 0x14, 0x89, 0xFF, 0x7D, 0xA7, 0xA3, 0x47, 0x8E, 0xB5, 0xEB, 0x09, 0x6A, 0xF4, 0x90, 0xBC, + 0xB1, 0xC7, 0xC5, 0xD7, 0x5F, 0x2E, 0xDF, 0x3B, 0xF5, 0x66, 0x9C, 0x2D, 0x9E, 0x60, 0x93, 0x9A, 0x1E, 0x9F, 0x25, 0x23, 0xD2, 0x63, 0xF9, 0x16, + 0x63, 0xA4, 0xD1, 0x57, 0xAF, 0x35, 0x9F, 0x77, 0x13, 0x89, 0x4B, 0xB2, 0x91, 0xE9, 0x2B, 0x58, 0x71, 0xC8, 0x4D, 0xAA, 0xC7, 0x9E, 0x29, 0x28, + 0xF9, 0x12, 0x1B, 0xFA, 0xBF, 0x96, 0xAF, 0xAD, 0xE7, 0x0C, 0xA7, 0xE5, 0x92, 0x9D, 0x6B, 0x8B, 0xE1, 0x63, 0x8B, 0x5E, 0xFD, 0xAD, 0x7A, 0x9E, + 0xE2, 0x6F, 0x7A, 0x1E, 0xE4, 0x70, 0xCA, 0xCB, 0x3D, 0x1E, 0xE9, 0xB9, 0x13, 0xFA, 0x4D, 0xC7, 0x73, 0xDE, 0x9A, 0xCF, 0x73, 0x86, 0x94, 0xDF, + 0xA8, 0x2B, 0xF3, 0xD7, 0x98, 0x4F, 0x1B, 0x0F, 0x3D, 0x7C, 0xB3, 0xB1, 0xF5, 0x9A, 0x09, 0x3B, 0xCA, 0x09, 0x72, 0xAC, 0xB9, 0x38, 0x7A, 0x8B, + 0x3C, 0xCD, 0xEA, 0xF1, 0xC4, 0xBE, 0xA4, 0xE1, 0xE4, 0xF1, 0x2D, 0x2E, 0x69, 0xF1, 0xB9, 0x63, 0xCB, 0xB1, 0xF9, 0x12, 0x72, 0x23, 0x01, 0x61, + 0x4C, 0x32, 0xAD, 0xD8, 0xEF, 0x71, 0xFB, 0x91, 0x4C, 0xBF, 0x87, 0x3F, 0x31, 0x46, 0xF4, 0xB2, 0x1B, 0x86, 0x4C, 0x67, 0x8B, 0xE4, 0x40, 0xE6, + 0xBB, 0x9C, 0x3F, 0xF9, 0x07, 0x63, 0x76, 0xDC, 0x91, 0x62, 0x4B, 0x10, 0xF2, 0xC5, 0x1F, 0x19, 0xBC, 0xF8, 0xBD, 0x9C, 0x4D, 0x4D, 0x1C, 0x1F, + 0x3A, 0x5F, 0xE6, 0x84, 0xCD, 0xCF, 0x0C, 0xDF, 0x61, 0xF8, 0x26, 0x8E, 0x39, 0x53, 0x43, 0xCD, 0x15, 0x78, 0xF2, 0x31, 0xE3, 0x47, 0xD6, 0x92, + 0x7A, 0x97, 0x48, 0x5E, 0x5C, 0xA3, 0x41, 0xFE, 0x5A, 0x7A, 0x4B, 0x81, 0x8E, 0x32, 0x51, 0x5E, 0xC2, 0xF7, 0xCC, 0x8F, 0x7B, 0xDA, 0xCD, 0xC6, + 0x20, 0xAB, 0x3D, 0x50, 0x92, 0x2A, 0x2E, 0x92, 0x8C, 0x7D, 0xF3, 0x38, 0x35, 0x4B, 0xA4, 0x74, 0x92, 0xF8, 0x32, 0xD9, 0xF1, 0x8B, 0x7A, 0x08, + 0xF2, 0x56, 0x65, 0xF0, 0x29, 0x37, 0x5F, 0x7A, 0xC7, 0x1A, 0xBA, 0x16, 0xE1, 0x4E, 0xFC, 0x87, 0x1E, 0x72, 0xBA, 0x8F, 0x56, 0xAB, 0x38, 0xD5, + 0xB2, 0xDD, 0x13, 0x91, 0x9E, 0x5F, 0x2F, 0x33, 0xB1, 0xBC, 0x9E, 0xCD, 0x35, 0x0A, 0x65, 0x91, 0xFE, 0x39, 0x83, 0x3A, 0x92, 0xCA, 0x4B, 0x1D, + 0x93, 0x3B, 0x6C, 0xF8, 0xFB, 0xC9, 0xA1, 0x5A, 0x6F, 0x4A, 0xE8, 0xCF, 0xC2, 0x38, 0xFE, 0x99, 0x31, 0xE7, 0x86, 0x3B, 0x7D, 0x69, 0xEC, 0xA6, + 0x7C, 0xA9, 0x49, 0x6E, 0x0F, 0xE4, 0x9B, 0xAF, 0x21, 0x89, 0x9A, 0x37, 0x92, 0xA3, 0xE3, 0x86, 0xDF, 0x95, 0x87, 0xB2, 0x86, 0x92, 0xD2, 0x3C, + 0xE5, 0x36, 0xAE, 0xAA, 0x9D, 0xE4, 0xD1, 0xC3, 0xD7, 0x38, 0x9C, 0x4F, 0xDF, 0x35, 0x90, 0x23, 0xC1, 0x16, 0x45, 0xEB, 0x31, 0xE6, 0x23, 0xE6, + 0x7C, 0x7A, 0x23, 0x22, 0x35, 0xE5, 0x32, 0xBB, 0xA8, 0x49, 0x32, 0xB9, 0xDF, 0xC8, 0x74, 0xBC, 0x72, 0x79, 0x68, 0x52, 0x91, 0x7A, 0xCE, 0xA1, + 0x46, 0xC9, 0xA4, 0x5F, 0x24, 0xE7, 0xDA, 0x03, 0x5B, 0x36, 0xC7, 0x62, 0x8D, 0x8D, 0x7F, 0x24, 0xD1, 0xAB, 0x27, 0xF2, 0xF1, 0x31, 0xD8, 0x21, + 0x1B, 0xAC, 0x92, 0x79, 0x9C, 0xAD, 0x70, 0x86, 0xB5, 0x6C, 0xD0, 0x7C, 0xD7, 0x15, 0x4F, 0xCC, 0x05, 0xA7, 0x47, 0x8A, 0x3F, 0x71, 0x93, 0xD5, + 0x63, 0x28, 0x76, 0x98, 0x76, 0x9C, 0x71, 0x8A, 0xEB, 0x8D, 0x14, 0x52, 0xC5, 0x07, 0xDF, 0x35, 0xA8, 0xDF, 0x84, 0x0E, 0xF2, 0x1E, 0xAB, 0x40, + 0x9E, 0x63, 0x01, 0x2E, 0xBE, 0xEE, 0x49, 0xA3, 0x39, 0x29, 0x9D, 0x8D, 0x6B, 0x8D, 0xE8, 0x33, 0x92, 0x8B, 0x64, 0x4A, 0xA6, 0xCF, 0x38, 0x6A, + 0x82, 0x3C, 0x17, 0xF9, 0x94, 0x91, 0x3E, 0x3A, 0xF4, 0xA8, 0x9C, 0x3D, 0x17, 0xC7, 0xD0, 0x3D, 0x7E, 0x19, 0x49, 0xF2, 0x37, 0xE6, 0xFA, 0x5C, + 0x59, 0x9B, 0x54, 0xAC, 0xD1, 0x8C, 0x3C, 0x6C, 0x0E, 0xE9, 0x0A, 0x36, 0x28, 0x83, 0x17, 0xAE, 0xA6, 0xC7, 0xC8, 0x12, 0x6A, 0xF8, 0xFA, 0xC5, + 0x90, 0xD3, 0x6E, 0x47, 0xE9, 0x4D, 0x87, 0x8C, 0xBE, 0x82, 0x4D, 0xF8, 0xF2, 0x31, 0x3B, 0xCE, 0xFC, 0x9C, 0x7C, 0x76, 0x7D, 0x03, 0xB5, 0x90, + 0x87, 0x2C, 0x52, 0xC7, 0x09, 0xE4, 0xEC, 0xC9, 0xDC, 0x5F, 0xFD, 0xAA, 0x86, 0x0A, 0xE2, 0x8E, 0x73, 0x6B, 0x9D, 0x6F, 0x75, 0xC7, 0x9D, 0x56, + 0x71, 0xE6, 0xEF, 0xDF, 0x84, 0x5D, 0x36, 0xCA, 0x68, 0x64, 0xCA, 0x34, 0x38, 0xE3, 0x5C, 0xFC, 0x9E, 0xD3, 0x1C, 0xA9, 0x71, 0x1C, 0x43, 0x6C, + 0x86, 0x4F, 0xFD, 0x46, 0xF3, 0xDA, 0x50, 0x71, 0xB2, 0xF3, 0x07, 0xAF, 0x8A, 0xAD, 0xF9, 0xEC, 0x2C, 0x6A, 0x14, 0xA6, 0x57, 0x84, 0x9C, 0xFD, + 0x8B, 0xEE, 0xD9, 0xCA, 0xDA, 0xAC, 0x9A, 0x84, 0xDE, 0xB8, 0x51, 0x18, 0x93, 0xC4, 0x09, 0x1B, 0xC4, 0xD9, 0x88, 0x8C, 0x7A, 0x45, 0x28, 0x52, + 0x85, 0x48, 0x24, 0xEB, 0xB5, 0xE7, 0x1A, 0x49, 0xFA, 0x87, 0x53, 0x3F, 0x9F, 0x46, 0x8C, 0x89, 0xD3, 0x0A, 0x79, 0x3C, 0x4D, 0x77, 0xDE, 0xE2, + 0xA4, 0x28, 0xFE, 0xC0, 0xDE, 0xFD, 0x5C, 0xB1, 0xDE, 0xE3, 0xE8, 0x78, 0xF2, 0xF7, 0xA6, 0x2C, 0xE5, 0xA4, 0x1C, 0x5F, 0xBC, 0x5D, 0x65, 0x3F, + 0x68, 0xBD, 0x0B, 0xB6, 0xAA, 0x59, 0xEC, 0x01, 0x33, 0xA9, 0x55, 0xBB, 0xA4, 0xD5, 0x62, 0x4F, 0x3F, 0x59, 0xAE, 0x28, 0xCC, 0x30, 0xC6, 0x9C, + 0x47, 0x8B, 0x76, 0x66, 0x3D, 0x8B, 0x5E, 0x8F, 0xE2, 0xDC, 0x43, 0x8F, 0xE8, 0xB3, 0xCE, 0x73, 0x66, 0x82, 0xCA, 0xA8, 0x32, 0xD2, 0x24, 0x6B, + 0xA1, 0x8C, 0x26, 0x05, 0x65, 0xA4, 0xD0, 0x18, 0x92, 0x38, 0x0C, 0xC7, 0x09, 0x39, 0x10, 0xD5, 0x1E, 0x2F, 0x07, 0x82, 0x5A, 0x1E, 0x64, 0x18, + 0x0A, 0x1A, 0x54, 0x23, 0x49, 0x92, 0x0E, 0x23, 0x5A, 0x4B, 0x45, 0x3A, 0x79, 0x35, 0xC2, 0x10, 0x4C, 0xCA, 0x55, 0x23, 0x89, 0x6D, 0x71, 0x6B, + 0xCA, 0x1E, 0xCE, 0x4B, 0x55, 0xFA, 0x3C, 0xDA, 0x60, 0xD4, 0x52, 0x58, 0x98, 0x0C, 0x8F, 0x3C, 0x6D, 0x09, 0x72, 0x55, 0x9A, 0x82, 0x97, 0x61, + 0xDA, 0x3A, 0xB9, 0x0E, 0xD4, 0x4D, 0xAE, 0x3F, 0x73, 0x35, 0x00, 0xE4, 0xD0, 0xC2, 0xD5, 0x1C, 0xC0, 0x30, 0x5B, 0x7C, 0x34, 0xD9, 0x6C, 0x81, + 0x3C, 0x9B, 0x08, 0xC1, 0xA7, 0xA1, 0x1F, 0xB9, 0xB9, 0xAE, 0x2B, 0xF3, 0x8C, 0x02, 0x4C, 0xEA, 0x06, 0x59, 0x24, 0x12, 0x25, 0x86, 0xF4, 0xA9, + 0xF2, 0x55, 0x80, 0x7F, 0x42, 0x56, 0x1D, 0x0F, 0xA0, 0x68, 0x7B, 0x77, 0xB4, 0xAE, 0xC6, 0x45, 0xD5, 0xC3, 0x60, 0xA2, 0xAC, 0x55, 0xA8, 0x2D, + 0xA8, 0xE5, 0x6C, 0xD7, 0xF5, 0xB9, 0xA1, 0x06, 0x9B, 0x96, 0x93, 0xCE, 0xF8, 0xD6, 0x7C, 0x95, 0x31, 0x22, 0xF2, 0x45, 0x39, 0xBD, 0x21, 0x29, + 0x6E, 0x10, 0xCE, 0x41, 0x3E, 0x79, 0x43, 0x28, 0x5E, 0xC9, 0x04, 0x90, 0x61, 0x0B, 0x27, 0x38, 0xB6, 0x20, 0xE3, 0x14, 0xE6, 0xAC, 0xA4, 0x4F, + 0x10, 0xC7, 0x80, 0x1B, 0x73, 0x58, 0xE9, 0xCA, 0x5F, 0x1F, 0xAB, 0x6D, 0x1F, 0x73, 0x29, 0x32, 0xEB, 0x70, 0xF4, 0x8F, 0x6B, 0x20, 0x42, 0x15, + 0xD6, 0x92, 0x57, 0xB2, 0xC7, 0x70, 0x1B, 0x17, 0x4A, 0xD7, 0x08, 0x79, 0xFC, 0x74, 0x6B, 0x9B, 0xFE, 0x1A, 0x52, 0x9D, 0x32, 0xB0, 0x29, 0x01, + 0xD6, 0xF9, 0x77, 0x65, 0x9E, 0xBF, 0x51, 0xDE, 0x41, 0xA3, 0xE4, 0x91, 0x4E, 0x1E, 0x5C, 0x47, 0x85, 0x73, 0x2D, 0x0D, 0x3F, 0x33, 0x36, 0x24, + 0x9E, 0x27, 0x41, 0x5D, 0x9D, 0x84, 0x97, 0x97, 0xAD, 0xEA, 0xDB, 0x02, 0x67, 0x9B, 0x57, 0x39, 0x3B, 0xAA, 0x54, 0x5F, 0xDD, 0x20, 0xB8, 0x31, + 0x41, 0xE8, 0x9A, 0x32, 0x81, 0x46, 0xD9, 0x7F, 0xD8, 0xBF, 0x4E, 0xF7, 0x45, 0xB6, 0xD0, 0xC0, 0x92, 0xC8, 0xAD, 0x41, 0x05, 0x98, 0xC6, 0x8B, + 0xE7, 0x7A, 0x64, 0x2B, 0x87, 0xEF, 0x96, 0x31, 0xBC, 0xED, 0x34, 0x78, 0x0F, 0xFE, 0x2E, 0xB0, 0x1B, 0xA5, 0xED, 0xF8, 0x7F, 0xC7, 0xD0, 0xFC, + 0xA4, 0x70, 0x7D, 0x16, 0x95, 0x9F, 0xC4, 0x1D, 0x82, 0xAC, 0x9B, 0x06, 0xDD, 0x63, 0x06, 0xFE, 0xEB, 0xE3, 0xA1, 0x65, 0xCF, 0x30, 0x51, 0x89, + 0xE2, 0x22, 0x60, 0x87, 0xCB, 0x2B, 0x86, 0xA7, 0x81, 0x29, 0x16, 0x21, 0xE8, 0xC0, 0xCB, 0xDC, 0x82, 0x0B, 0x41, 0x0D, 0xC9, 0x37, 0xD4, 0x9F, + 0x3D, 0x64, 0x60, 0xCB, 0xFD, 0x25, 0xCA, 0x50, 0x65, 0x0E, 0x17, 0x7C, 0x0E, 0xC4, 0xC7, 0xE9, 0x77, 0xCB, 0x08, 0xC0, 0xD8, 0x92, 0x18, 0x11, + 0x75, 0x06, 0x23, 0xFF, 0xD0, 0x8E, 0xE1, 0x14, 0xF7, 0xA4, 0x04, 0xFA, 0x64, 0xA8, 0x08, 0x01, 0x6C, 0x67, 0x56, 0x47, 0xB3, 0xD9, 0x54, 0xF2, + 0x79, 0x17, 0x8B, 0x4B, 0x9A, 0x7B, 0xED, 0x05, 0xAA, 0x80, 0xD6, 0xA1, 0xC7, 0xC5, 0xF7, 0x62, 0x01, 0xE6, 0x19, 0x83, 0x26, 0xE1, 0x26, 0xBE, + 0xB8, 0xF1, 0x9F, 0xC7, 0x87, 0x6F, 0x09, 0x78, 0x5A, 0xC2, 0x43, 0x69, 0xA7, 0x8A, 0x2E, 0x5F, 0x52, 0x30, 0x32, 0x86, 0x24, 0x1C, 0x9B, 0xC5, + 0x46, 0x43, 0x0D, 0xEA, 0x99, 0xDE, 0x71, 0x13, 0x44, 0xF2, 0x1F, 0xB8, 0x0C, 0xF2, 0x75, 0x27, 0x74, 0x35, 0x9E, 0x7D, 0x09, 0x47, 0xC3, 0xEB, + 0xA7, 0xBA, 0x3F, 0x13, 0x56, 0x29, 0x9B, 0x1E, 0xBA, 0x3A, 0xDC, 0x14, 0xC0, 0x83, 0xA6, 0x18, 0x6E, 0x65, 0xD4, 0x36, 0x3F, 0xD0, 0x26, 0xA7, + 0x86, 0x03, 0x1E, 0x15, 0xC0, 0x0F, 0x9B, 0xEA, 0x16, 0xD6, 0xCF, 0x9A, 0x42, 0x73, 0xFA, 0xA5, 0x78, 0x21, 0x17, 0x87, 0x57, 0x0C, 0xA1, 0xE3, + 0xA7, 0x2B, 0x7E, 0xBB, 0x81, 0x2B, 0x3C, 0x37, 0x94, 0x87, 0x13, 0xF9, 0x85, 0xD0, 0xAA, 0xB9, 0x5B, 0xEA, 0x72, 0x67, 0x16, 0x33, 0x52, 0xB6, + 0x8E, 0x26, 0x5B, 0x2F, 0x00, 0x4E, 0xBB, 0x83, 0x73, 0xBF, 0x09, 0xE4, 0x0A, 0x77, 0xDD, 0xB1, 0x9E, 0x45, 0x7E, 0x11, 0x9E, 0xB6, 0xDD, 0xD6, + 0x1F, 0x79, 0xA6, 0x02, 0x0F, 0x68, 0x42, 0x2D, 0xC6, 0xEF, 0xA6, 0xE5, 0x04, 0x8A, 0xD2, 0x0B, 0xA9, 0xA9, 0x4B, 0xC7, 0x29, 0xAF, 0x8F, 0xAF, + 0x6E, 0x48, 0x68, 0x69, 0xE6, 0xE6, 0x86, 0x99, 0xA2, 0xD9, 0x1C, 0x72, 0x17, 0xB4, 0x30, 0x31, 0x4E, 0x88, 0x3B, 0xC1, 0x21, 0x4A, 0xFF, 0x71, + 0x82, 0x7B, 0x9A, 0xA0, 0xB4, 0x4E, 0x72, 0x6D, 0x49, 0x5A, 0x79, 0xDF, 0x25, 0x25, 0x8D, 0xB1, 0x6A, 0x70, 0xB2, 0x74, 0xB2, 0xE4, 0x38, 0xB4, + 0x29, 0x34, 0x9F, 0xC9, 0x45, 0x63, 0x33, 0xD8, 0x76, 0x1E, 0x76, 0x2A, 0xAB, 0x64, 0x81, 0xD1, 0x43, 0x18, 0x09, 0x59, 0x4B, 0x54, 0x0C, 0x03, + 0x77, 0xAE, 0x43, 0xE2, 0x4B, 0x09, 0x86, 0x68, 0xD1, 0x59, 0xA2, 0x61, 0x48, 0x17, 0x17, 0xA8, 0xCF, 0x3B, 0xA6, 0xE1, 0xE9, 0x8F, 0x5D, 0x00, + 0x1D, 0x5F, 0x4A, 0x78, 0x5A, 0x2E, 0x96, 0xAD, 0x82, 0xF0, 0xD4, 0x78, 0x06, 0x63, 0x43, 0x28, 0x4D, 0xD7, 0xD5, 0xC9, 0x4B, 0xE6, 0x71, 0x73, + 0xE3, 0x4C, 0xA1, 0x65, 0x30, 0x1A, 0x43, 0xEC, 0x9F, 0x5B, 0xE8, 0xF2, 0xBE, 0x1A, 0x5E, 0xAD, 0x57, 0xA6, 0x6D, 0xC4, 0x66, 0x45, 0x41, 0x9C, + 0x12, 0x31, 0x8C, 0xDC, 0xCA, 0xF9, 0xF5, 0x16, 0x93, 0xAA, 0xAB, 0xE6, 0x2F, 0xB0, 0x36, 0x37, 0xB1, 0x62, 0xD8, 0x2A, 0x7D, 0x8F, 0x85, 0x46, + 0xDE, 0x80, 0x50, 0x96, 0x07, 0x00, 0xC3, 0x55, 0xB1, 0xB8, 0x67, 0x82, 0x47, 0xB8, 0x41, 0x72, 0x89, 0xA1, 0x32, 0x83, 0xA0, 0x28, 0x5E, 0x74, + 0xC4, 0x20, 0xAD, 0x64, 0xBD, 0x28, 0x8D, 0xDF, 0x5D, 0xC6, 0xC4, 0x05, 0x5D, 0x03, 0xAE, 0xED, 0xD8, 0x24, 0xE0, 0x23, 0xF0, 0x71, 0x7A, 0xE6, + 0xBC, 0xC4, 0x6A, 0x15, 0x86, 0x29, 0x14, 0x33, 0xD4, 0x4E, 0xF0, 0x42, 0xDB, 0xDF, 0x81, 0xC2, 0x66, 0x82, 0x0D, 0xDF, 0x42, 0x83, 0xA8, 0xD5, + 0x46, 0x0B, 0x3B, 0x24, 0xBD, 0x32, 0x15, 0xFA, 0x00, 0x3B, 0x26, 0xAB, 0x1C, 0xDF, 0x07, 0xF3, 0x80, 0x25, 0x51, 0x3F, 0xFD, 0x9B, 0x46, 0x14, + 0x5A, 0xAC, 0xC1, 0x27, 0x70, 0x3E, 0x5D, 0x52, 0x15, 0x69, 0x7B, 0xF1, 0x23, 0xD2, 0x54, 0x68, 0xBB, 0xA5, 0xAA, 0x49, 0x9E, 0x8C, 0x84, 0x6F, + 0x55, 0x49, 0x5C, 0x73, 0x38, 0xEB, 0x77, 0x79, 0xD6, 0x98, 0xFB, 0xEA, 0x4D, 0x91, 0x91, 0xF5, 0x61, 0xEF, 0x02, 0xDA, 0x81, 0x8B, 0x73, 0xDC, + 0x31, 0x23, 0xFE, 0xBE, 0x2A, 0x3E, 0x84, 0xEC, 0x24, 0x55, 0xEB, 0x96, 0x50, 0x3B, 0x1D, 0xA3, 0x42, 0x69, 0x28, 0x96, 0x74, 0xE8, 0x62, 0x26, + 0x89, 0xB6, 0xAB, 0x18, 0x0C, 0x75, 0x29, 0xBE, 0x41, 0x29, 0x2B, 0x5C, 0x34, 0x7A, 0x65, 0x86, 0x6E, 0xB2, 0xB9, 0xEF, 0x28, 0x7D, 0xDE, 0x04, + 0x54, 0xCE, 0x0E, 0x05, 0x5C, 0x9D, 0xF0, 0x20, 0x88, 0xE6, 0x31, 0xDD, 0x3D, 0xCE, 0x02, 0x5B, 0xB6, 0x0F, 0x46, 0x4F, 0x4E, 0xCC, 0x5D, 0xA9, + 0x44, 0x08, 0x2D, 0x47, 0xC9, 0x28, 0x6F, 0x62, 0x86, 0x59, 0xC5, 0x8E, 0xD4, 0x00, 0x1C, 0xC6, 0x5C, 0x4E, 0x2C, 0x34, 0x25, 0xC7, 0x74, 0x3C, + 0x6B, 0x5B, 0x46, 0x0D, 0xA1, 0x8B, 0xFA, 0x67, 0x1D, 0xB2, 0xC7, 0x15, 0x83, 0x3D, 0x44, 0x36, 0x5D, 0x95, 0x14, 0x03, 0x77, 0x27, 0xE0, 0x97, + 0x51, 0x3A, 0x23, 0x0E, 0x38, 0x54, 0xD3, 0x42, 0x89, 0x30, 0xE3, 0x16, 0x36, 0xCB, 0x33, 0x52, 0x96, 0xCA, 0x2A, 0x06, 0x7D, 0x8F, 0x28, 0x81, + 0x7E, 0x75, 0x61, 0x8C, 0x2E, 0xA8, 0xB2, 0x2C, 0x65, 0xAD, 0x91, 0xA4, 0x5F, 0x8D, 0x9E, 0xB4, 0xFF, 0xCF, 0x5C, 0xE8, 0xDD, 0x85, 0x95, 0x52, + 0xB8, 0x50, 0x80, 0x2D, 0x44, 0xFE, 0x4B, 0x92, 0x45, 0x1B, 0x45, 0xE1, 0x76, 0x40, 0x84, 0x86, 0x7B, 0x58, 0xA2, 0x91, 0xCD, 0xD9, 0x5A, 0xF7, + 0xC6, 0x03, 0x78, 0x8E, 0xF5, 0x7A, 0xA3, 0x8B, 0x66, 0xDB, 0x69, 0xD9, 0x26, 0xD8, 0x75, 0xD8, 0x46, 0x9B, 0x98, 0x40, 0x4F, 0x66, 0x7D, 0x90, + 0x59, 0xA3, 0x9C, 0xE8, 0x26, 0x0C, 0x53, 0xB7, 0x62, 0x9E, 0xDA, 0x44, 0xE6, 0x2C, 0x25, 0xA9, 0xF3, 0xD5, 0x95, 0xB4, 0x08, 0x49, 0xE8, 0x7A, + 0xD2, 0x06, 0xDD, 0x45, 0x30, 0x29, 0xF3, 0x59, 0xAB, 0xA3, 0xF6, 0x64, 0x43, 0xFC, 0xBD, 0x74, 0xA9, 0xBB, 0x06, 0x37, 0x4B, 0x51, 0x72, 0xB3, + 0x2D, 0x45, 0x46, 0x7E, 0x7C, 0x88, 0xA8, 0x80, 0xFF, 0x74, 0x96, 0x2C, 0x99, 0x19, 0xBD, 0x3B, 0x22, 0x19, 0x57, 0xF4, 0x03, 0xC8, 0x02, 0x02, + 0x25, 0x66, 0xB6, 0x46, 0x5F, 0x96, 0x90, 0x63, 0x42, 0x55, 0x1B, 0xFB, 0x94, 0x6B, 0xFD, 0x37, 0x94, 0x54, 0x2E, 0x2C, 0x9F, 0x03, 0x00, 0xA7, + 0x18, 0x84, 0xA9, 0xFB, 0x24, 0xC0, 0xCD, 0x73, 0x39, 0x8E, 0x94, 0xA0, 0x37, 0x07, 0x77, 0xD0, 0xE0, 0x00, 0x14, 0xF8, 0x9D, 0xE4, 0xA4, 0x88, + 0x2E, 0x42, 0x8F, 0x45, 0x9E, 0x86, 0x83, 0xCD, 0x7D, 0x83, 0xCA, 0xCE, 0xFF, 0x3B, 0x17, 0x86, 0x22, 0x0A, 0xE0, 0x18, 0x7B, 0xC9, 0x36, 0x47, + 0x18, 0xCC, 0x64, 0x3D, 0x73, 0xE0, 0x2D, 0x38, 0xE6, 0x06, 0xCB, 0x3C, 0x15, 0x7F, 0xB6, 0x15, 0x01, 0x21, 0x23, 0x9C, 0x96, 0xB6, 0x4C, 0x5F, + 0x31, 0x30, 0xDC, 0x0D, 0x1B, 0xCC, 0xF4, 0x7D, 0x6B, 0x6B, 0xE0, 0x2C, 0x97, 0xB1, 0x45, 0x1C, 0x79, 0xD7, 0x77, 0x80, 0xBC, 0xCE, 0xDF, 0x3E, + 0xDB, 0x20, 0x6D, 0xCF, 0x40, 0xAA, 0x7A, 0x47, 0x94, 0x53, 0x50, 0xD2, 0xA1, 0x35, 0xAC, 0xE8, 0x90, 0x8F, 0x9F, 0x8D, 0x77, 0x42, 0x26, 0x88, + 0xAD, 0x51, 0x4D, 0xF3, 0x9B, 0x9F, 0x18, 0x16, 0x89, 0xC3, 0x4F, 0x77, 0x1F, 0xAA, 0x34, 0x96, 0x3F, 0xDF, 0x81, 0x1A, 0xF3, 0x4E, 0xD6, 0x5B, + 0x78, 0x32, 0x66, 0x6E, 0x32, 0x5F, 0xA9, 0xA9, 0xFA, 0xBB, 0x46, 0x7E, 0xBF, 0xB4, 0xD6, 0xD8, 0xB4, 0x89, 0x68, 0x8A, 0x1D, 0x67, 0x5A, 0x76, + 0x87, 0xB5, 0xC8, 0x77, 0xE8, 0xCF, 0x3D, 0xA8, 0x06, 0x94, 0x23, 0x00, 0x87, 0xA5, 0x6E, 0x7B, 0x00, 0x63, 0x00, 0x6C, 0x00, 0x0D, 0x7A, 0x38, + 0x41, 0x74, 0xBA, 0x59, 0xC3, 0xBB, 0x1C, 0xC7, 0x77, 0xF1, 0x78, 0x2E, 0x27, 0x8D, 0x72, 0x11, 0x8C, 0x21, 0x83, 0x85, 0x15, 0x54, 0x48, 0x01, + 0x85, 0x13, 0x4C, 0x28, 0x21, 0x46, 0x87, 0x0C, 0x16, 0x56, 0x50, 0x21, 0x05, 0x14, 0x4E, 0x30, 0xA1, 0x84, 0x18, 0x21, 0x78, 0x34, 0x18, 0x12, + 0x28, 0x09, 0xA2, 0x0D, 0x1D, 0x44, 0x25, 0x28, 0xB3, 0x40, 0x40, 0x52, 0x00, 0xB9, 0x80, 0x80, 0x44, 0x91, 0xE7, 0xB2, 0x9D, 0xB7, 0xBF, 0x66, + 0x0D, 0xE6, 0x54, 0x2A, 0xFE, 0x1A, 0xD8, 0x8F, 0x45, 0xDD, 0xA8, 0xC8, 0x9D, 0x0E, 0x12, 0xD8, 0xF3, 0x71, 0x51, 0xA1, 0xB3, 0xB9, 0x5C, 0xD4, + 0x63, 0xB9, 0xC8, 0xC8, 0x20, 0xFD, 0x41, 0x82, 0xF3, 0x11, 0xC3, 0x8E, 0x87, 0x87, 0xF2, 0x7B, 0x2A, 0x76, 0x0A, 0xE5, 0x28, 0xFE, 0xAA, 0x2C, + 0xEE, 0x24, 0x42, 0x7F, 0x8E, 0x3D, 0xEE, 0x9B, 0x74, 0x95, 0xFF, 0x80, 0xFE, 0x72, 0xDF, 0x2A, 0x98, 0x77, 0x64, 0xA8, 0x3F, 0x0C, 0xFF, 0x39, + 0x64, 0xEC, 0x2D, 0x37, 0x79, 0xAB, 0xFA, 0xC8, 0x71, 0x71, 0x46, 0x7C, 0x8A, 0xDF, 0x5F, 0xF1, 0xF9, 0xC3, 0xB8, 0xB5, 0xC3, 0xCA, 0xA1, 0x85, + 0xB5, 0x8D, 0x59, 0xBD, 0xFF, 0x7C, 0xDE, 0x97, 0x78, 0xF6, 0x30, 0xD4, 0xFE, 0x9C, 0x44, 0xD3, 0x7E, 0xB9, 0xCE, 0x64, 0x1D, 0x27, 0x64, 0x39, + 0x39, 0x86, 0xDB, 0x9B, 0xDC, 0x11, 0xC4, 0xD5, 0x74, 0x1D, 0xE3, 0xE4, 0x90, 0x4B, 0x86, 0x10, 0x5A, 0x2A, 0xAE, 0x3D, 0x9A, 0xBC, 0xBE, 0x7A, + 0x18, 0x57, 0x01, 0x9D, 0x8B, 0xC9, 0x86, 0xA3, 0x9E, 0x12, 0x8E, 0xFE, 0x87, 0x43, 0x6C, 0xC9, 0x5C, 0x3A, 0x6A, 0xE8, 0x6C, 0x36, 0xFD, 0x1A, + 0x03, 0x67, 0xA7, 0x3D, 0x48, 0xF8, 0xD0, 0xAC, 0xD0, 0x11, 0xD1, 0x68, 0x94, 0x33, 0x7D, 0xFE, 0x61, 0x11, 0x09, 0x68, 0x84, 0x61, 0x64, 0xF8, + 0x6D, 0x22, 0xE5, 0x67, 0xD2, 0xE1, 0x8C, 0x95, 0xEB, 0xC6, 0x9A, 0xD7, 0x0E, 0x36, 0x09, 0x7C, 0xEC, 0xA9, 0x8F, 0x0E, 0xDB, 0x05, 0x3E, 0x6E, + 0x4A, 0x44, 0x44, 0x44, 0xAF, 0x4C, 0x87, 0x07, 0x46, 0x33, 0x0E, 0x81, 0xB3, 0xB3, 0x36, 0x02, 0x4D, 0x0D, 0x2D, 0xAE, 0x81, 0x53, 0xDE, 0x72, + 0x1F, 0xA7, 0x3F, 0xC7, 0x8F, 0x72, 0x39, 0x9A, 0x15, 0xA3, 0x7C, 0x1B, 0x9D, 0x84, 0x3E, 0x9E, 0x0F, 0x0B, 0x0A, 0x24, 0xA0, 0x60, 0x59, 0xA7, + 0xA3, 0x24, 0x97, 0x19, 0x26, 0xD6, 0x7C, 0x8E, 0x82, 0xB8, 0x46, 0x5F, 0x9C, 0x02, 0x27, 0x88, 0x25, 0x8B, 0x18, 0x36, 0xF6, 0x3C, 0xE6, 0xDC, + 0xB1, 0x1E, 0xB2, 0x89, 0x06, 0xC4, 0xCF, 0x1B, 0xF4, 0x28, 0xE9, 0x93, 0x9D, 0xC4, 0x69, 0x6C, 0xAA, 0xC0, 0xEF, 0xE9, 0x73, 0xC3, 0xA2, 0xCA, + 0x23, 0x47, 0xF8, 0x61, 0xCD, 0x63, 0xFE, 0x98, 0xE4, 0xBD, 0x74, 0xEF, 0xD8, 0xB1, 0x4F, 0x18, 0x88, 0x1D, 0x63, 0xE4, 0x54, 0xE1, 0x37, 0xFD, + 0xE3, 0xAF, 0xF2, 0x21, 0x19, 0x9C, 0x53, 0x4B, 0x56, 0xB9, 0xE6, 0x94, 0xD6, 0x7C, 0x8F, 0x8B, 0x9A, 0xEC, 0x20, 0x0B, 0x09, 0x1F, 0x1C, 0x16, + 0x02, 0x81, 0x65, 0xA8, 0x51, 0xBD, 0xB4, 0x6C, 0x52, 0x6A, 0x33, 0x61, 0x10, 0x83, 0x4C, 0xA2, 0x90, 0x72, 0x66, 0x1E, 0x41, 0x1D, 0x43, 0x04, + 0x59, 0x4C, 0x6D, 0x07, 0xA4, 0xB4, 0xD5, 0x1B, 0xF0, 0xC1, 0x93, 0x58, 0xA3, 0x3E, 0x51, 0x3A, 0xD3, 0x28, 0xC0, 0x3D, 0x7C, 0x04, 0x7A, 0xBF, + 0x95, 0x04, 0x51, 0xEA, 0x5F, 0x4E, 0xC1, 0x22, 0xD2, 0x00, 0xF3, 0x10, 0x3C, 0x75, 0x05, 0xB3, 0xCD, 0x0E, 0x04, 0xD5, 0x34, 0x1E, 0xE4, 0xF2, + 0x40, 0x9A, 0x06, 0xDD, 0x1E, 0x0B, 0x02, 0xFF, 0xEA, 0x44, 0x2A, 0x8A, 0xA5, 0xBC, 0xDC, 0x64, 0x54, 0xF2, 0x17, 0x7A, 0x16, 0xFE, 0x4A, 0x60, + 0x2A, 0x65, 0xC8, 0x8C, 0x70, 0x6C, 0x1B, 0x38, 0x36, 0xF7, 0x6E, 0x03, 0x2C, 0x0C, 0x60, 0x74, 0x4B, 0x80, 0xD6, 0x13, 0x9A, 0xB9, 0x0B, 0x7D, + 0x44, 0xA7, 0xDE, 0xB0, 0xD7, 0xA2, 0xD4, 0xB8, 0x37, 0x6F, 0x51, 0x72, 0xF7, 0xE7, 0x16, 0x55, 0xB4, 0xF4, 0x2E, 0x3A, 0xB1, 0x94, 0x33, 0x34, + 0x93, 0x47, 0x0C, 0x49, 0xE7, 0xF9, 0x8E, 0xB6, 0x3C, 0x6A, 0x98, 0x03, 0xA5, 0x52, 0xE4, 0x6D, 0x22, 0x08, 0x60, 0xE6, 0xF1, 0xAC, 0x8E, 0xEB, + 0x2C, 0x73, 0x50, 0x31, 0x90, 0xE6, 0xC2, 0x9D, 0xC6, 0xEC, 0x10, 0x01, 0x07, 0xE8, 0xE4, 0x68, 0xA2, 0x2A, 0x90, 0x09, 0x3D, 0x82, 0x2E, 0x24, + 0x97, 0x1F, 0x18, 0xC6, 0x7A, 0x07, 0x49, 0xDD, 0xE7, 0x3F, 0x0E, 0x1F, 0xB5, 0x63, 0xF1, 0x7B, 0xDC, 0x18, 0xBF, 0x6E, 0x8E, 0x42, 0x18, 0xF9, + 0xFF, 0x05, 0xC9, 0x5B, 0x7D, 0xA9, 0xF4, 0x65, 0x64, 0xD6, 0x18, 0xE9, 0xFA, 0xD6, 0xBF, 0x9F, 0x7A, 0x29, 0xCF, 0xEC, 0x39, 0x3B, 0x84, 0xA9, + 0x15, 0x99, 0xD2, 0x83, 0x10, 0x3C, 0x9C, 0x00, 0x96, 0xAC, 0xBE, 0xB3, 0xA2, 0x5F, 0x57, 0x94, 0x63, 0x2A, 0xCB, 0x4E, 0xCE, 0x9C, 0x06, 0x5C, + 0x80, 0xB0, 0x77, 0x07, 0x13, 0xA9, 0x84, 0xE8, 0x0A, 0x70, 0xAA, 0x7A, 0xEA, 0x01, 0x40, 0x06, 0x51, 0xB8, 0x59, 0x37, 0x0F, 0xC5, 0x52, 0x78, + 0x6E, 0xA6, 0x41, 0xCE, 0x76, 0x8E, 0xD7, 0x93, 0xD2, 0x8B, 0x05, 0xAC, 0x21, 0x60, 0x0E, 0x91, 0x3B, 0x13, 0x40, 0x53, 0xA1, 0xA2, 0x8A, 0xB6, + 0xAA, 0xD8, 0xDD, 0x0B, 0xD6, 0x7D, 0x06, 0x98, 0x53, 0xEB, 0x38, 0xCC, 0xA1, 0xAE, 0xD0, 0xFB, 0x76, 0x01, 0x84, 0xF1, 0xBB, 0xA0, 0x83, 0x82, + 0x70, 0x60, 0x99, 0x71, 0x1E, 0x58, 0xA7, 0xEB, 0x5B, 0x17, 0x9E, 0x33, 0x76, 0x42, 0x63, 0x71, 0xA4, 0x84, 0xBE, 0x97, 0x1B, 0x72, 0x92, 0xB5, + 0xBC, 0xAE, 0x1E, 0xE7, 0x27, 0x84, 0x80, 0x8A, 0x11, 0xA5, 0xD8, 0xBA, 0x0E, 0xFA, 0x44, 0xA3, 0xA6, 0x22, 0x1E, 0x4D, 0x04, 0x64, 0x81, 0x70, + 0x2F, 0xDB, 0x4B, 0xE8, 0x7E, 0x02, 0x75, 0xD6, 0x79, 0x27, 0x70, 0x50, 0x4B, 0x09, 0x2C, 0x18, 0xC8, 0xAC, 0x2E, 0x63, 0x23, 0xB8, 0xA0, 0x4A, + 0x5F, 0x73, 0x34, 0xDE, 0x9D, 0x51, 0x52, 0x80, 0xF7, 0xBC, 0x8B, 0xBF, 0x9C, 0x59, 0xEA, 0xF1, 0x96, 0xF6, 0xA3, 0x28, 0xD1, 0x4D, 0xAE, 0xAE, + 0x8E, 0x2E, 0x6C, 0xB1, 0xED, 0x08, 0x04, 0xB2, 0xBB, 0x60, 0x53, 0x28, 0x60, 0x11, 0xFF, 0x24, 0x44, 0xB0, 0x65, 0x8E, 0xCF, 0xF5, 0x9A, 0x46, + 0x05, 0x28, 0x65, 0x39, 0xBE, 0xEC, 0xAE, 0x8C, 0xA9, 0x80, 0xA3, 0x18, 0x69, 0xA5, 0xE7, 0x9D, 0xAF, 0x1B, 0xC4, 0xF3, 0xCE, 0x84, 0xA5, 0x22, + 0xB8, 0x73, 0xC8, 0xB0, 0xA3, 0xDB, 0x32, 0x7D, 0xF8, 0x02, 0xB3, 0xA0, 0x94, 0x5A, 0xA2, 0x36, 0x86, 0xE0, 0x4B, 0xB0, 0x12, 0xB1, 0xC1, 0x1D, + 0x6F, 0xF0, 0x8A, 0x59, 0xCF, 0x4F, 0x2A, 0x3F, 0x9C, 0xC6, 0x19, 0x0B, 0x64, 0x0D, 0x3D, 0x88, 0xD4, 0x34, 0xDE, 0x4A, 0xBC, 0x21, 0x38, 0xE9, + 0xF1, 0xD8, 0x91, 0xE5, 0x68, 0xFE, 0xBB, 0xB2, 0x4C, 0x45, 0xA8, 0xC6, 0x5E, 0xBB, 0x6B, 0x55, 0x53, 0x10, 0xC5, 0x77, 0x3A, 0x23, 0x2B, 0x8B, + 0xA2, 0x97, 0xE6, 0x97, 0x96, 0xFE, 0xCA, 0x51, 0xCC, 0x18, 0x7A, 0xF1, 0x84, 0x76, 0x16, 0xF5, 0xBE, 0x89, 0xF6, 0x23, 0x97, 0xE7, 0x57, 0x07, + 0xBB, 0xAC, 0xCB, 0x12, 0xE8, 0x08, 0x4D, 0x93, 0x34, 0xE6, 0x28, 0x69, 0x17, 0x59, 0x3A, 0x72, 0xF2, 0x3D, 0x1A, 0x7D, 0x2C, 0x66, 0xEA, 0x2D, + 0x50, 0x6F, 0x9B, 0x93, 0x30, 0xC2, 0x09, 0x51, 0x00, 0x31, 0xB3, 0x4D, 0xBB, 0xE6, 0x38, 0x37, 0x0F, 0x86, 0x0C, 0x68, 0x9F, 0x2B, 0x79, 0xF2, + 0x7C, 0x4D, 0x5D, 0xBD, 0xE0, 0xDC, 0xEC, 0x13, 0xA2, 0xEE, 0x96, 0x59, 0x1E, 0x90, 0x26, 0x4E, 0x35, 0x0A, 0xCE, 0xF5, 0x05, 0x14, 0x8B, 0x81, + 0x0A, 0x51, 0xCB, 0x03, 0xDC, 0xF3, 0x25, 0xF6, 0xAC, 0x36, 0xF5, 0x41, 0x02, 0x03, 0x28, 0xFA, 0xC5, 0x39, 0xB8, 0x68, 0x9D, 0x8C, 0x59, 0x17, + 0x66, 0x64, 0x0C, 0xCB, 0xE8, 0x8D, 0xB2, 0x50, 0x93, 0xE9, 0xA5, 0x2D, 0xA8, 0xFC, 0x20, 0xD9, 0x6D, 0x7E, 0x83, 0x9A, 0x1A, 0x33, 0xA5, 0x2A, + 0x00, 0x66, 0xF0, 0x83, 0x24, 0x20, 0x6D, 0xB6, 0x1A, 0x17, 0x95, 0xE5, 0xD6, 0x53, 0xD3, 0xDF, 0x5F, 0x06, 0x84, 0x87, 0xD1, 0xA4, 0xA2, 0x16, + 0x0D, 0x25, 0xE4, 0xDB, 0xF5, 0xCE, 0x11, 0xAE, 0xB2, 0x30, 0x09, 0x14, 0x60, 0x00, 0x40, 0x97, 0x02, 0x81, 0x00, 0x74, 0x00, 0x79, 0x00, 0xB0, + 0x4E, 0x9B, 0x39, 0x1D, 0xD1, 0x29, 0xE7, 0xB7, 0x44, 0x76, 0x4B, 0x5D, 0x39, 0x67, 0xF0, 0xD9, 0x69, 0x9C, 0x8C, 0x96, 0x9E, 0x1B, 0x4F, 0x62, + 0xD9, 0x9F, 0x7A, 0x95, 0x53, 0xF0, 0x4C, 0x19, 0x98, 0x3E, 0x89, 0xE6, 0x98, 0x58, 0xCA, 0x72, 0x4C, 0x7B, 0x6C, 0xCB, 0x4C, 0x83, 0xE4, 0x31, + 0xF5, 0x9D, 0xCE, 0x1C, 0x38, 0xAD, 0x62, 0xE0, 0x9A, 0xF2, 0x07, 0xA7, 0x53, 0x37, 0x1E, 0x47, 0x96, 0x4D, 0xA5, 0x63, 0xC4, 0x7E, 0xF6, 0xD7, + 0xF8, 0x8A, 0x76, 0x96, 0x04, 0x2D, 0x42, 0x3D, 0xB6, 0xD5, 0x0D, 0xC3, 0xC2, 0x63, 0x2C, 0x16, 0x6F, 0x8A, 0x42, 0x44, 0x53, 0x50, 0x14, 0x5B, + 0xBD, 0x6F, 0xBC, 0xAE, 0xAC, 0xC0, 0x65, 0x4D, 0x30, 0x70, 0x54, 0x80, 0xE3, 0x9C, 0x0E, 0x52, 0xC1, 0x45, 0x26, 0x9B, 0xAD, 0xA6, 0xD8, 0xB0, + 0x83, 0x6B, 0xB1, 0x89, 0x2E, 0x18, 0x11, 0x06, 0x3B, 0xD1, 0xE1, 0x80, 0x44, 0xB0, 0x97, 0xED, 0xA1, 0x30, 0xB4, 0x47, 0xEA, 0x6A, 0x7B, 0x4C, + 0x40, 0x1C, 0x48, 0xB4, 0x75, 0xD8, 0xA4, 0xB4, 0x68, 0x09, 0x82, 0x9E, 0x53, 0xB5, 0x99, 0x8E, 0xBE, 0x9A, 0xB3, 0xBC, 0x57, 0xFB, 0xB4, 0x3B, + 0xF4, 0x39, 0xB7, 0xCF, 0x97, 0xBC, 0xCA, 0x1D, 0xF9, 0x03, 0x6F, 0xA2, 0x9C, 0x92, 0x63, 0xCB, 0x95, 0x47, 0x68, 0xFA, 0x1C, 0x9F, 0xA5, 0x5C, + 0x6A, 0xB6, 0xD0, 0xAF, 0xDA, 0x9A, 0x3F, 0xCD, 0x71, 0x19, 0x21, 0xCE, 0xB8, 0xB4, 0xCB, 0x93, 0xA1, 0xF1, 0x8B, 0x2D, 0xAB, 0xB3, 0xBB, 0x64, + 0x97, 0x74, 0x1A, 0x1D, 0xA3, 0x6F, 0x1C, 0x62, 0x16, 0x62, 0xC7, 0x3D, 0x98, 0x2B, 0x89, 0x1E, 0x39, 0x0D, 0x12, 0xE5, 0x00, 0x00, 0x05, 0x81, + 0x5E, 0x59, 0x2F, 0xF6, 0x5F, 0xCB, 0xCF, 0xB2, 0xB4, 0x3B, 0xF4, 0xFA, 0x55, 0x20, 0xF6, 0x9A, 0x46, 0x22, 0x1B, 0x37, 0x29, 0x12, 0x1D, 0xA7, + 0xD9, 0xAB, 0xB5, 0x73, 0x7F, 0x73, 0x27, 0x9A, 0x79, 0x46, 0x80, 0xD1, 0x5A, 0x5A, 0x43, 0x6B, 0x84, 0x69, 0x4B, 0x6F, 0xD0, 0x1B, 0x3A, 0x9C, + 0xD7, 0x68, 0x4C, 0x3E, 0xC9, 0x19, 0xB9, 0xC4, 0x4C, 0x99, 0xAF, 0x65, 0x69, 0x79, 0x2E, 0x2F, 0xCB, 0xD7, 0x5B, 0x6E, 0x57, 0x9C, 0x7E, 0xD3, + 0x58, 0x34, 0x85, 0x96, 0x20, 0x65, 0x6F, 0xE4, 0x51, 0xF3, 0x6C, 0x01, 0x63, 0xC1, 0x80, 0x64, 0x92, 0x49, 0x73, 0xC4, 0x1C, 0x17, 0x47, 0xA7, + 0x9D, 0x8D, 0x51, 0x44, 0xD3, 0x83, 0x36, 0xBD, 0xA7, 0x1B, 0x6D, 0xCB, 0x94, 0x89, 0xA9, 0x46, 0x6C, 0xF5, 0x97, 0xC0, 0x41, 0x68, 0x55, 0x19, + 0xA0, 0x43, 0x0A, 0xFA, 0x68, 0x4F, 0xD2, 0x76, 0xDA, 0x92, 0x55, 0xD3, 0x3B, 0x74, 0x6F, 0xEE, 0x16, 0x85, 0xD0, 0x67, 0x4D, 0xED, 0x90, 0x5D, + 0xAA, 0x4F, 0x3A, 0x9C, 0x3F, 0xCF, 0x0F, 0xB3, 0x33, 0x73, 0xBD, 0x33, 0x77, 0x59, 0x8F, 0xF5, 0x86, 0x3C, 0x83, 0x4B, 0x38, 0xF4, 0x8E, 0xD6, + 0x63, 0x9B, 0x54, 0x58, 0xD7, 0xAB, 0xBA, 0x7D, 0x33, 0x18, 0x07, 0x75, 0xDA, 0xC0, 0xCA, 0x09, 0x16, 0x02, 0xD1, 0xBD, 0xA0, 0xB9, 0xA6, 0xD5, + 0x56, 0xDD, 0xA1, 0x43, 0x0D, 0x3E, 0x45, 0x42, 0x3D, 0xB4, 0x07, 0xC9, 0x5D, 0xBA, 0x0C, 0xDD, 0x73, 0x7A, 0x92, 0x68, 0x0E, 0xC8, 0x75, 0xC7, + 0x6C, 0x84, 0xC2, 0xCE, 0x1C, 0x3D, 0x74, 0xDA, 0x54, 0xB8, 0x88, 0xDD, 0x2A, 0x4C, 0xEC, 0x57, 0xF6, 0xCB, 0xCE, 0xEC, 0x17, 0xFD, 0xA2, 0xDB, + 0x39, 0x03, 0x03, 0x81, 0x66, 0xA8, 0x51, 0xA5, 0x85, 0x68, 0x44, 0x44, 0x92, 0xA4, 0xA0, 0x50, 0xE8, 0x41, 0x0C, 0x01, 0x91, 0x98, 0x42, 0x8C, + 0x39, 0xF8, 0x06, 0xD1, 0x98, 0x63, 0x84, 0x20, 0x43, 0x08, 0x11, 0x4A, 0x34, 0x92, 0xD4, 0x30, 0x06, 0x03, 0x66, 0xFA, 0xAA, 0xB8, 0x5B, 0x9D, + 0xF3, 0x14, 0x2B, 0x70, 0x0E, 0x33, 0xDE, 0x13, 0xD3, 0x1E, 0x86, 0xA8, 0x14, 0x11, 0xFF, 0x50, 0x2A, 0x46, 0x51, 0x0A, 0xBE, 0x9F, 0xF6, 0x58, + 0xA4, 0x03, 0x3D, 0xBE, 0xD1, 0x4C, 0x81, 0x8E, 0xF0, 0x2C, 0xB1, 0xEC, 0x30, 0x4B, 0x5D, 0x2D, 0x44, 0x4E, 0x1B, 0x66, 0x97, 0xE9, 0x2D, 0x6B, + 0x29, 0x3D, 0x74, 0x48, 0x1D, 0xD6, 0x8D, 0x00, 0xBD, 0x20, 0xAD, 0x7F, 0x77, 0xE7, 0x41, 0xCC, 0xF2, 0x5C, 0x44, 0x6A, 0xC7, 0xBA, 0xF4, 0x24, + 0x2B, 0xA4, 0xFF, 0x13, 0x85, 0xDC, 0xD1, 0x21, 0x80, 0x5A, 0x8D, 0xEB, 0xDC, 0xCB, 0x75, 0x00, 0xA6, 0x87, 0x27, 0xA9, 0x28, 0xEF, 0x16, 0x62, + 0x85, 0x59, 0x3D, 0x7A, 0xF5, 0xF3, 0x83, 0x23, 0x7D, 0x15, 0xA7, 0x43, 0xEA, 0x6D, 0x7E, 0x2C, 0xDA, 0x2C, 0x84, 0x52, 0xD7, 0xE4, 0x58, 0x14, + 0x77, 0xE6, 0xA2, 0xC3, 0x67, 0x30, 0x18, 0x64, 0x9C, 0x8F, 0x89, 0x4B, 0x61, 0x41, 0x8A, 0x55, 0x24, 0x75, 0xE6, 0x0E, 0x7A, 0xDA, 0x27, 0x53, + 0x84, 0x7B, 0xD5, 0x95, 0x71, 0x4E, 0x47, 0xA5, 0x08, 0x15, 0x46, 0x01, 0xAA, 0x5C, 0xCC, 0x74, 0xFB, 0xC6, 0x70, 0xCC, 0x38, 0x4D, 0x80, 0x36, + 0xD6, 0xE9, 0x46, 0xE7, 0x19, 0x2C, 0xFA, 0xC4, 0x40, 0x2B, 0xED, 0x02, 0xBF, 0x68, 0x52, 0x19, 0x8A, 0x85, 0x1E, 0xA8, 0xD5, 0x2B, 0xDB, 0xB3, + 0xEF, 0xED, 0x6C, 0x0F, 0x2F, 0x73, 0x7B, 0xBA, 0x9A, 0x28, 0xAF, 0x00, 0x01, 0xCF, 0x7A, 0x16, 0x8D, 0x53, 0x95, 0xF4, 0xC1, 0x6A, 0xFF, 0x86, + 0x11, 0xD4, 0x4A, 0x9D, 0x74, 0xC2, 0x25, 0x52, 0x63, 0x8C, 0x56, 0x0C, 0xAE, 0xC8, 0x52, 0x04, 0xF0, 0x68, 0x63, 0x6E, 0xE9, 0x63, 0x4B, 0xB1, + 0x0E, 0x03, 0x16, 0x02, 0xA2, 0xC6, 0xA2, 0x4F, 0x32, 0x63, 0x37, 0x41, 0x33, 0x9B, 0x8C, 0x28, 0xA5, 0x82, 0xE0, 0xC1, 0xAB, 0x72, 0xE3, 0x12, + 0x54, 0x00, 0x85, 0x4B, 0x84, 0xFC, 0x67, 0xF9, 0xE8, 0x49, 0xCD, 0x8C, 0x2F, 0xF4, 0x0B, 0x50, 0x32, 0xCD, 0x39, 0x0D, 0x5D, 0x2E, 0x3D, 0xAE, + 0x19, 0x3B, 0x5F, 0x1C, 0x09, 0xB1, 0x37, 0x24, 0x4E, 0xB9, 0x1C, 0xE5, 0x62, 0x98, 0xA1, 0xD0, 0x8C, 0xC2, 0x07, 0x06, 0xE6, 0x9F, 0xA0, 0x8C, + 0x89, 0x99, 0xA1, 0xEE, 0x4A, 0xD2, 0x5D, 0xEA, 0x42, 0xB9, 0x84, 0xCE, 0x06, 0x96, 0x6D, 0x60, 0x32, 0x08, 0xE0, 0x52, 0xDF, 0xB8, 0x6B, 0xC6, + 0x5D, 0x1B, 0xD4, 0xF8, 0xE6, 0xBF, 0x3B, 0x72, 0x3D, 0x89, 0xE3, 0xF0, 0x94, 0x42, 0xBB, 0x79, 0x4A, 0x5B, 0x86, 0xDF, 0x3C, 0x9B, 0xEA, 0xF4, + 0x30, 0xDB, 0xAD, 0xC0, 0x41, 0x5E, 0xE6, 0x18, 0x85, 0xFA, 0xAB, 0x9B, 0x30, 0x86, 0x37, 0xF2, 0x9E, 0x24, 0x8A, 0x00, 0x60, 0x1C, 0xCA, 0x39, + 0x98, 0x2A, 0xCE, 0xE7, 0xBB, 0x27, 0x0A, 0xB7, 0x92, 0x13, 0xE9, 0xB6, 0x1E, 0x57, 0x6E, 0x6C, 0x93, 0x39, 0xEB, 0x2E, 0xA9, 0x4E, 0x70, 0xC2, + 0x44, 0x09, 0xD0, 0x26, 0xED, 0xAA, 0xA3, 0xB0, 0xAD, 0xAF, 0xB4, 0xEB, 0x08, 0xC2, 0x5D, 0xAC, 0x3D, 0x12, 0x41, 0x17, 0x08, 0x67, 0x13, 0xE2, + 0x47, 0xC3, 0x3E, 0xB3, 0x74, 0xE3, 0x36, 0x30, 0x0F, 0xD3, 0x0E, 0xBB, 0xDA, 0x86, 0x04, 0xCD, 0x72, 0xA8, 0x6B, 0x9D, 0x60, 0x94, 0x07, 0xF6, + 0x03, 0x0F, 0xFA, 0xE0, 0x4A, 0x55, 0x02, 0x32, 0x94, 0x92, 0xCC, 0x53, 0xFC, 0x44, 0xD8, 0x6C, 0x47, 0x0E, 0x02, 0xC8, 0xF4, 0x0E, 0xE0, 0xB9, + 0xC5, 0x5E, 0xE7, 0xFB, 0xDC, 0x7B, 0x8A, 0x6F, 0x45, 0x3E, 0xF3, 0x2D, 0xF8, 0x66, 0x0A, 0x5E, 0x1A, 0x14, 0xAC, 0xFC, 0xC7, 0x00, 0xA5, 0x8C, + 0x75, 0x33, 0xB8, 0x06, 0x14, 0x30, 0x80, 0x97, 0x07, 0xC1, 0xFB, 0xC9, 0x56, 0x68, 0x07, 0x7E, 0x9F, 0x69, 0x93, 0xE7, 0x85, 0x05, 0xE4, 0x88, + 0xAD, 0x33, 0x8D, 0xBA, 0x51, 0xDD, 0x38, 0xCF, 0xA0, 0xFC, 0xB1, 0x31, 0x26, 0x88, 0x70, 0xAF, 0xF7, 0x89, 0x39, 0x77, 0xA1, 0xAC, 0x19, 0x6E, + 0xC2, 0x28, 0x0C, 0x62, 0x75, 0xE8, 0xA0, 0x2A, 0xE0, 0x6C, 0xA9, 0xC1, 0x59, 0x4F, 0x3B, 0xD8, 0x78, 0x87, 0xB8, 0x7E, 0x9B, 0xF4, 0x04, 0x36, + 0x2D, 0xF6, 0xBD, 0xB8, 0x79, 0xE0, 0xE0, 0x90, 0xD4, 0x03, 0xD2, 0xA9, 0xC5, 0x80, 0xE3, 0x39, 0x8B, 0x8D, 0xEB, 0x91, 0xEC, 0x39, 0xA3, 0x7A, + 0x43, 0x99, 0xED, 0xD8, 0x29, 0xBA, 0x31, 0x97, 0x28, 0x09, 0x3D, 0x96, 0xD3, 0x1B, 0x64, 0xAA, 0x2C, 0x2C, 0x56, 0x3D, 0x80, 0x67, 0x9D, 0x16, + 0x76, 0xDE, 0x83, 0x26, 0x68, 0xBB, 0x8F, 0xBD, 0x73, 0x05, 0x16, 0x08, 0x5E, 0x3C, 0xCC, 0x41, 0x01, 0x86, 0xB6, 0x13, 0x3B, 0x27, 0x71, 0x03, + 0xA5, 0xE7, 0x29, 0x6B, 0xA0, 0xE0, 0x70, 0xAE, 0x0E, 0xD0, 0xAA, 0xAC, 0x24, 0x88, 0x67, 0xB1, 0xB8, 0xD1, 0x30, 0x6B, 0xFF, 0x58, 0x1E, 0xBF, + 0x0C, 0xEF, 0x34, 0x84, 0xE8, 0x2B, 0x14, 0x6F, 0xEE, 0x10, 0x4F, 0xC6, 0xA5, 0x98, 0x21, 0xE8, 0xA1, 0x4E, 0x7C, 0xC2, 0x6E, 0xD7, 0x69, 0xB7, + 0x43, 0xF0, 0xBC, 0xDA, 0x32, 0x4B, 0xFE, 0xDC, 0xFC, 0xCA, 0xB7, 0x12, 0x3F, 0x4C, 0xB9, 0x02, 0xB9, 0x90, 0x82, 0xF5, 0xAC, 0xE1, 0xF5, 0x43, + 0x5C, 0x60, 0x8F, 0x82, 0xDA, 0xF3, 0x86, 0x59, 0x8C, 0x70, 0x2B, 0xEC, 0xB1, 0x49, 0xB0, 0xF2, 0xE6, 0x48, 0x2F, 0xEC, 0x5B, 0xBF, 0x35, 0x13, + 0xFE, 0xB9, 0x74, 0xF9, 0xF4, 0x30, 0xAF, 0x82, 0x54, 0xB3, 0x28, 0x28, 0xF4, 0xA5, 0x77, 0x06, 0xE1, 0x92, 0x72, 0x1F, 0xEC, 0x90, 0x9C, 0x74, + 0x4B, 0xB3, 0x53, 0x18, 0xF0, 0xE4, 0x3D, 0x75, 0xAC, 0x5E, 0x11, 0xC2, 0xB3, 0x50, 0x5C, 0x0B, 0xAD, 0x36, 0x10, 0x6A, 0x5E, 0x35, 0xAF, 0x7E, + 0x66, }; -const idx_t TZ_COMPRESSED_SIZE = 44667; -const idx_t TZ_UNCOMPRESSED_SIZE = 205625; -const char *const TZ_VERSION = "2026c"; +const idx_t TZ_COMPRESSED_SIZE = 44641; +const idx_t TZ_UNCOMPRESSED_SIZE = 209325; +const char *const TZ_VERSION = "2026d"; } // namespace datetime } // namespace duckdb diff --git a/src/duckdb/extension/icu/icu-table-range.cpp b/src/duckdb/extension/icu/icu-table-range.cpp index 5f69878ef..3a494f92f 100644 --- a/src/duckdb/extension/icu/icu-table-range.cpp +++ b/src/duckdb/extension/icu/icu-table-range.cpp @@ -1,3 +1,4 @@ +#include "duckdb/common/atomic.hpp" #include "duckdb/common/exception.hpp" #include "duckdb/common/operator/subtract.hpp" #include "duckdb/common/types/interval.hpp" @@ -69,10 +70,27 @@ struct ICUTableRange { idx_t cardinality; }; + //! Progress of a range used as a source (i.e. with a single input row) + struct ICURangeGlobalState : public GlobalTableFunctionState { + //! The bounds of the range, and the timestamp that is generated next + atomic start {0}; + atomic end {0}; + atomic current {0}; + + void Initialize(timestamp_tz_t start_p, timestamp_tz_t end_p) { + start.store(start_p.value, std::memory_order_relaxed); + end.store(end_p.value, std::memory_order_relaxed); + current.store(start_p.value, std::memory_order_relaxed); + } + }; + struct ICURangeLocalState : public LocalTableFunctionState { - ICURangeLocalState() { + explicit ICURangeLocalState(optional_ptr global_state) + : global_state(global_state ? &global_state->Cast() : nullptr) { } + optional_ptr global_state; + bool initialized_row = false; idx_t current_input_row = 0; timestamp_tz_t current_state; @@ -163,7 +181,24 @@ struct ICUTableRange { static unique_ptr RangeDateTimeLocalInit(ExecutionContext &context, TableFunctionInitInput &input, GlobalTableFunctionState *global_state) { - return make_uniq(); + return make_uniq(global_state); + } + + static unique_ptr RangeDateTimeGlobalInit(ClientContext &context, + TableFunctionInitInput &input) { + return make_uniq(); + } + + static double Progress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &state = global_state->Cast(); + auto start = static_cast(state.start.load(std::memory_order_relaxed)); + auto range = static_cast(state.end.load(std::memory_order_relaxed)) - start; + if (range == 0) { + return 0; + } + auto fraction = (static_cast(state.current.load(std::memory_order_relaxed)) - start) / range; + return 100.0 * MaxValue(MinValue(fraction, 1.0), 0.0); } static unique_ptr Cardinality(ClientContext &context, const FunctionData *bind_data_p) { @@ -192,6 +227,9 @@ struct ICUTableRange { GenerateRangeDateTimeParameters(input, state.current_input_row, state); state.initialized_row = true; state.current_state = state.start; + if (state.global_state) { + state.global_state->Initialize(state.start, state.end); + } } if (state.empty_range) { // empty range @@ -219,6 +257,9 @@ struct ICUTableRange { continue; } output.SetChildCardinality(size); + if (state.global_state) { + state.global_state->current.store(state.current_state.value, std::memory_order_relaxed); + } return OperatorResultType::HAVE_MORE_OUTPUT; } } @@ -226,8 +267,9 @@ struct ICUTableRange { static void AddICUTableRangeFunction(ExtensionLoader &loader) { TableFunctionSet range("range"); TableFunction range_function({LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL}, - nullptr, Bind, nullptr, RangeDateTimeLocalInit); + nullptr, Bind, RangeDateTimeGlobalInit, RangeDateTimeLocalInit); range_function.in_out_function = ICUTableRangeFunction; + range_function.table_scan_progress = Progress; range_function.cardinality = Cardinality; range_function.return_type = TableFunctionReturnType::SET_RETURNING_FUNCTION; range.AddFunction(range_function); @@ -237,9 +279,10 @@ struct ICUTableRange { // generate_series: similar to range, but inclusive instead of exclusive bounds on the RHS TableFunctionSet generate_series("generate_series"); TableFunction generate_series_function( - {LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL}, nullptr, Bind, nullptr, - RangeDateTimeLocalInit); + {LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL}, nullptr, Bind, + RangeDateTimeGlobalInit, RangeDateTimeLocalInit); generate_series_function.in_out_function = ICUTableRangeFunction; + generate_series_function.table_scan_progress = Progress; generate_series_function.cardinality = Cardinality; generate_series_function.return_type = TableFunctionReturnType::SET_RETURNING_FUNCTION; generate_series.AddFunction(generate_series_function); diff --git a/src/duckdb/extension/json/include/json_reader.hpp b/src/duckdb/extension/json/include/json_reader.hpp index ec41fd1ea..1e6a5a933 100644 --- a/src/duckdb/extension/json/include/json_reader.hpp +++ b/src/duckdb/extension/json/include/json_reader.hpp @@ -58,6 +58,8 @@ struct JSONFileHandle { idx_t FileSize() const; idx_t Remaining() const; + //! The fraction of the file that has been read, in [0, 1] + double GetProgress() const; bool CanSeek() const; bool IsPipe() const; @@ -84,6 +86,8 @@ struct JSONFileHandle { //! File properties const bool can_seek; const idx_t file_size; + //! Whether the file is compressed - the read position then refers to the decompressed data + const bool compressed; //! Read properties atomic read_position; diff --git a/src/duckdb/extension/json/json_functions/json_table_in_out.cpp b/src/duckdb/extension/json/json_functions/json_table_in_out.cpp index f67c50e0e..046d97411 100644 --- a/src/duckdb/extension/json/json_functions/json_table_in_out.cpp +++ b/src/duckdb/extension/json/json_functions/json_table_in_out.cpp @@ -1,5 +1,6 @@ #include "json_common.hpp" #include "json_functions.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/function/table_function.hpp" @@ -48,6 +49,11 @@ struct JSONTableInOutGlobalState : GlobalTableFunctionState { static constexpr idx_t JSON_COLUMN_OFFSET = 0; static constexpr idx_t ROOT_COLUMN_OFFSET = 1; + + //! Progress when used as a source (i.e. with a single input row) - the rows that will be produced, and the rows + //! that were produced + atomic total_rows {0}; + atomic produced_rows {0}; }; static unique_ptr JSONTableInOutInitGlobal(ClientContext &, TableFunctionInitInput &input) { @@ -146,9 +152,9 @@ struct JSONTableInOutRecursionNode { }; struct JSONTableInOutLocalState : LocalTableFunctionState { - explicit JSONTableInOutLocalState(ClientContext &context) - : json_allocator(BufferAllocator::Get(context)), alc(json_allocator.GetYYAlc()), len(DConstants::INVALID_INDEX), - doc(nullptr), initialized(false), total_count(0) { + JSONTableInOutLocalState(ClientContext &context, JSONTableInOutGlobalState &gstate) + : gstate(gstate), json_allocator(BufferAllocator::Get(context)), alc(json_allocator.GetYYAlc()), + len(DConstants::INVALID_INDEX), doc(nullptr), initialized(false), total_count(0) { } string GetPath() const { @@ -169,8 +175,12 @@ struct JSONTableInOutLocalState : LocalTableFunctionState { recursion_nodes.emplace_back(str, val); } + JSONTableInOutGlobalState &gstate; JSONAllocator json_allocator; yyjson_alc *alc; + //! The rows the current input row is estimated to produce, and the rows it produced so far + idx_t estimated_rows = 0; + idx_t produced_rows = 0; string path; idx_t len; @@ -182,8 +192,19 @@ struct JSONTableInOutLocalState : LocalTableFunctionState { }; static unique_ptr JSONTableInOutInitLocal(ExecutionContext &context, TableFunctionInitInput &, - GlobalTableFunctionState *) { - return make_uniq(context.client); + GlobalTableFunctionState *global_state) { + return make_uniq(context.client, global_state->Cast()); +} + +static double JSONTableInOutProgress(ClientContext &, const FunctionData *, + const GlobalTableFunctionState *global_state) { + auto &gstate = global_state->Cast(); + auto total_rows = gstate.total_rows.load(std::memory_order_relaxed); + if (total_rows == 0) { + return 0; + } + auto produced_rows = MinValue(gstate.produced_rows.load(std::memory_order_relaxed), total_rows); + return 100.0 * static_cast(produced_rows) / static_cast(total_rows); } template @@ -315,6 +336,14 @@ static void InitializeLocalState(JSONTableInOutLocalState &lstate, DataChunk &in } const auto is_container = unsafe_yyjson_is_arr(root) || unsafe_yyjson_is_obj(root); + // json_each produces a row per element of the root, json_tree a row per value (the value count is an upper bound) + if (TYPE == JSONTableInOutType::TREE) { + lstate.estimated_rows = yyjson_doc_get_val_count(lstate.doc); + } else { + lstate.estimated_rows = is_container ? unsafe_yyjson_get_len(root) : 1; + } + lstate.produced_rows = 0; + lstate.gstate.total_rows.fetch_add(lstate.estimated_rows, std::memory_order_relaxed); if (!is_container || TYPE == JSONTableInOutType::TREE) { result.AddRow(lstate, nullptr, root); } @@ -384,6 +413,8 @@ static OperatorResultType JSONTableInOutFunction(ExecutionContext &, TableFuncti } } output.SetChildCardinality(result.count); + lstate.produced_rows += result.count; + gstate.produced_rows.fetch_add(result.count, std::memory_order_relaxed); // Set constant virtual columns ("json", "root", and "empty") if (gstate.json_column_index.IsValid()) { @@ -403,6 +434,14 @@ static OperatorResultType JSONTableInOutFunction(ExecutionContext &, TableFuncti if (output.size() == 0) { D_ASSERT(recursion_nodes.empty()); + // the input row is done - correct the estimate to the rows that were actually produced + if (lstate.estimated_rows > lstate.produced_rows) { + gstate.total_rows.fetch_sub(lstate.estimated_rows - lstate.produced_rows, std::memory_order_relaxed); + } else { + gstate.total_rows.fetch_add(lstate.produced_rows - lstate.estimated_rows, std::memory_order_relaxed); + } + lstate.estimated_rows = 0; + lstate.produced_rows = 0; lstate.json_allocator.Reset(); lstate.initialized = false; return OperatorResultType::NEED_MORE_INPUT; @@ -429,6 +468,7 @@ TableFunction GetJSONTableInOutFunction(const LogicalType &input_type, const boo } TableFunction function(arguments, nullptr, JSONTableInOutBind, JSONTableInOutInitGlobal, JSONTableInOutInitLocal); function.in_out_function = JSONTableInOutFunction; + function.table_scan_progress = JSONTableInOutProgress; function.get_virtual_columns = GetJSONTableInOutVirtualColumns; function.projection_pushdown = true; return function; diff --git a/src/duckdb/extension/json/json_reader.cpp b/src/duckdb/extension/json/json_reader.cpp index 915917837..114c2f219 100644 --- a/src/duckdb/extension/json/json_reader.cpp +++ b/src/duckdb/extension/json/json_reader.cpp @@ -20,8 +20,9 @@ JSONBufferHandle::JSONBufferHandle(JSONReader &reader, idx_t buffer_index_p, idx JSONFileHandle::JSONFileHandle(QueryContext context_p, unique_ptr file_handle_p, Allocator &allocator_p) : context(context_p), file_handle(std::move(file_handle_p)), allocator(allocator_p), - can_seek(file_handle->CanSeek()), file_size(file_handle->GetFileSize()), read_position(0), requested_reads(0), - actual_reads(0), last_read_requested(false), cached_size(0) { + can_seek(file_handle->CanSeek()), file_size(file_handle->GetFileSize()), + compressed(file_handle->GetFileCompressionType() != FileCompressionType::UNCOMPRESSED), read_position(0), + requested_reads(0), actual_reads(0), last_read_requested(false), cached_size(0) { } bool JSONFileHandle::IsOpen() const { @@ -62,6 +63,23 @@ idx_t JSONFileHandle::Remaining() const { return file_size - read_position; } +double JSONFileHandle::GetProgress() const { + if (file_size == 0) { + return 0; + } + idx_t position; + if (compressed) { + if (!IsOpen()) { + return last_read_requested ? 1 : 0; + } + // the progress of a compressed file is the position in the compressed stream + position = file_handle->GetProgress(); + } else { + position = read_position; + } + return MinValue(static_cast(position) / static_cast(file_size), 1.0); +} + bool JSONFileHandle::CanSeek() const { return can_seek; } @@ -377,11 +395,7 @@ double JSONReader::GetProgress() const { if (!HasFileHandle()) { return 0; } - const auto file_size = file_handle->FileSize(); - if (file_size == 0) { - return 0; - } - return 100.0 - 100.0 * double(file_handle->Remaining()) / double(file_size); + return 100.0 * file_handle->GetProgress(); } static inline void TrimWhitespace(JSONString &line) { diff --git a/src/duckdb/extension/loader/dummy_static_extension_loader.cpp b/src/duckdb/extension/loader/dummy_static_extension_loader.cpp deleted file mode 100644 index 406a8d9da..000000000 --- a/src/duckdb/extension/loader/dummy_static_extension_loader.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "duckdb/main/config.hpp" -#include "duckdb/main/extension_helper.hpp" - -// This is a dummy loader to produce a workable duckdb library without linking any extensions. -// Link this to libduckdb_static.a to get a working system. -// -// Note that it no longer stubs out LoadExtension: that lives in core and reads the registry on the -// config, so a binary (or an extension) that links this can still load whatever it was handed. - -namespace duckdb { - -void ExtensionHelper::RegisterLinkedExtensions(DBConfig &config) { - // nothing is linked into this binary -} - -vector ExtensionHelper::LoadedExtensionTestPaths() { - return {}; -} - -} // namespace duckdb diff --git a/src/duckdb/extension/loader/static_extension_autoregister.cpp b/src/duckdb/extension/loader/static_extension_autoregister.cpp new file mode 100644 index 000000000..463bf2db7 --- /dev/null +++ b/src/duckdb/extension/loader/static_extension_autoregister.cpp @@ -0,0 +1,16 @@ +// Calls the generated static extension loader before main. Compile it into a program that wants its statically linked +// extensions registered without calling duckdb_register_static_extensions itself. Compile it into the program, not into +// an archive, or the linker drops it. + +#include + +extern "C" int32_t duckdb_register_static_extensions(void); + +namespace { +struct DuckDBStaticExtensionLoader { + DuckDBStaticExtensionLoader() { + duckdb_register_static_extensions(); + } +}; +const DuckDBStaticExtensionLoader duckdb_static_extension_loader; +} // namespace diff --git a/src/duckdb/generated_extension_loader_package_build.cpp b/src/duckdb/generated_extension_loader_package_build.cpp index 2ff26a8ce..4d3b22962 100644 --- a/src/duckdb/generated_extension_loader_package_build.cpp +++ b/src/duckdb/generated_extension_loader_package_build.cpp @@ -1,3 +1,4 @@ +// Generated by package_build.py. Do not edit. #ifndef DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED #define DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED 1 #endif @@ -14,74 +15,170 @@ #define DUCKDB_EXTENSION_JSON_LINKED 1 #endif +#include "duckdb/main/extension/extension_loader.hpp" +#include "duckdb_static_extension.h" + #if DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED -#include "core_functions_extension.hpp" +#ifndef EXT_VERSION_CORE_FUNCTIONS +#define EXT_VERSION_CORE_FUNCTIONS "" #endif -#if DUCKDB_EXTENSION_PARQUET_LINKED -#include "parquet_extension.hpp" +// Generated from extension/loader/extension_describe.c.in. Do not edit. +// Describes the core_functions extension to duckdb_register_static_extension. + +#include "duckdb_static_extension.h" + +extern "C" void core_functions_duckdb_cpp_init(duckdb::ExtensionLoader &loader); + +#ifdef __cplusplus +extern "C" { #endif -#if DUCKDB_EXTENSION_ICU_LINKED -#include "icu_extension.hpp" + +int32_t duckdb_extension_core_functions_describe(duckdb_extension_descriptor *descriptor) { + if (descriptor->version < 1) { + descriptor->set_error(descriptor, "extension core_functions needs descriptor layout 1"); + return 1; + } + descriptor->version = 1; + descriptor->name = "core_functions"; + descriptor->extension_version = EXT_VERSION_CORE_FUNCTIONS; + descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->entry_cpp = (void (*)(void))core_functions_duckdb_cpp_init; + return 0; +} + +#ifdef __cplusplus +} #endif -#if DUCKDB_EXTENSION_JSON_LINKED -#include "json_extension.hpp" #endif -#include "duckdb/main/extension/generated_extension_loader.hpp" -#include "duckdb/main/extension_helper.hpp" -#include "duckdb/main/config.hpp" -#include "duckdb/main/database.hpp" +#if DUCKDB_EXTENSION_PARQUET_LINKED +#ifndef EXT_VERSION_PARQUET +#define EXT_VERSION_PARQUET "" +#endif +// Generated from extension/loader/extension_describe.c.in. Do not edit. +// Describes the parquet extension to duckdb_register_static_extension. -namespace duckdb { +#include "duckdb_static_extension.h" -//! Publishes the package_build.py-generated list of extensions linked into this binary onto the config, so that -//! ExtensionHelper::LoadExtension can find them - including when it is called from code carrying its -//! own copy of DuckDB, which links no generated loader of its own. -void ExtensionHelper::RegisterLinkedExtensions(DBConfig &config) { -#if DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED - config.linked_extensions.push_back({"core_functions", [](DuckDB &db) { - db.LoadStaticExtension(); - }}); +extern "C" void parquet_duckdb_cpp_init(duckdb::ExtensionLoader &loader); + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t duckdb_extension_parquet_describe(duckdb_extension_descriptor *descriptor) { + if (descriptor->version < 1) { + descriptor->set_error(descriptor, "extension parquet needs descriptor layout 1"); + return 1; + } + descriptor->version = 1; + descriptor->name = "parquet"; + descriptor->extension_version = EXT_VERSION_PARQUET; + descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->entry_cpp = (void (*)(void))parquet_duckdb_cpp_init; + return 0; +} + +#ifdef __cplusplus +} #endif -#if DUCKDB_EXTENSION_PARQUET_LINKED - config.linked_extensions.push_back({"parquet", [](DuckDB &db) { - db.LoadStaticExtension(); - }}); #endif + #if DUCKDB_EXTENSION_ICU_LINKED - config.linked_extensions.push_back({"icu", [](DuckDB &db) { - db.LoadStaticExtension(); - }}); +#ifndef EXT_VERSION_ICU +#define EXT_VERSION_ICU "" +#endif +// Generated from extension/loader/extension_describe.c.in. Do not edit. +// Describes the icu extension to duckdb_register_static_extension. + +#include "duckdb_static_extension.h" + +extern "C" void icu_duckdb_cpp_init(duckdb::ExtensionLoader &loader); + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t duckdb_extension_icu_describe(duckdb_extension_descriptor *descriptor) { + if (descriptor->version < 1) { + descriptor->set_error(descriptor, "extension icu needs descriptor layout 1"); + return 1; + } + descriptor->version = 1; + descriptor->name = "icu"; + descriptor->extension_version = EXT_VERSION_ICU; + descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->entry_cpp = (void (*)(void))icu_duckdb_cpp_init; + return 0; +} + +#ifdef __cplusplus +} +#endif #endif + #if DUCKDB_EXTENSION_JSON_LINKED - config.linked_extensions.push_back({"json", [](DuckDB &db) { - db.LoadStaticExtension(); - }}); +#ifndef EXT_VERSION_JSON +#define EXT_VERSION_JSON "" #endif +// Generated from extension/loader/extension_describe.c.in. Do not edit. +// Describes the json extension to duckdb_register_static_extension. + +#include "duckdb_static_extension.h" + +extern "C" void json_duckdb_cpp_init(duckdb::ExtensionLoader &loader); +#ifdef __cplusplus +extern "C" { +#endif + +int32_t duckdb_extension_json_describe(duckdb_extension_descriptor *descriptor) { + if (descriptor->version < 1) { + descriptor->set_error(descriptor, "extension json needs descriptor layout 1"); + return 1; + } + descriptor->version = 1; + descriptor->name = "json"; + descriptor->extension_version = EXT_VERSION_JSON; + descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->entry_cpp = (void (*)(void))json_duckdb_cpp_init; + return 0; +} + +#ifdef __cplusplus } +#endif +#endif -vector LinkedExtensions(){ - vector VEC = { +#ifndef DUCKDB_STATIC_EXTENSION_LOADER_API +#if defined(__GNUC__) || defined(__clang__) +#define DUCKDB_STATIC_EXTENSION_LOADER_API __attribute__((visibility("hidden"))) +#else +#define DUCKDB_STATIC_EXTENSION_LOADER_API +#endif +#endif + +extern "C" DUCKDB_STATIC_EXTENSION_LOADER_API int32_t duckdb_register_static_extensions(void) { + int32_t result = 0; #if DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED - "core_functions", + if (duckdb_register_static_extension(duckdb_extension_core_functions_describe) != 0) { + result = 1; + } #endif #if DUCKDB_EXTENSION_PARQUET_LINKED - "parquet", + if (duckdb_register_static_extension(duckdb_extension_parquet_describe) != 0) { + result = 1; + } #endif #if DUCKDB_EXTENSION_ICU_LINKED - "icu", + if (duckdb_register_static_extension(duckdb_extension_icu_describe) != 0) { + result = 1; + } #endif #if DUCKDB_EXTENSION_JSON_LINKED - "json", + if (duckdb_register_static_extension(duckdb_extension_json_describe) != 0) { + result = 1; + } #endif - }; - return VEC; -} - -vector ExtensionHelper::LoadedExtensionTestPaths(){ - vector VEC = { - }; - return VEC; + return result; } -} \ No newline at end of file diff --git a/src/duckdb/src/catalog/catalog.cpp b/src/duckdb/src/catalog/catalog.cpp index 18bd31655..15b82ecb4 100644 --- a/src/duckdb/src/catalog/catalog.cpp +++ b/src/duckdb/src/catalog/catalog.cpp @@ -35,7 +35,6 @@ #include "duckdb/planner/expression_binder/index_binder.hpp" #include "duckdb/catalog/default/default_types.hpp" #include "duckdb/main/extension_entries.hpp" -#include "duckdb/main/extension/generated_extension_loader.hpp" #include "duckdb/main/connection.hpp" #include "duckdb/main/attached_database.hpp" #include "duckdb/main/database_manager.hpp" diff --git a/src/duckdb/src/common/compressed_file_system.cpp b/src/duckdb/src/common/compressed_file_system.cpp index 3060eac5b..076859546 100644 --- a/src/duckdb/src/common/compressed_file_system.cpp +++ b/src/duckdb/src/common/compressed_file_system.cpp @@ -74,7 +74,8 @@ void CompressedFile::Initialize(QueryContext context, bool write) { stream_data.out_buff_start = stream_data.out_buff.get(); stream_data.out_buff_end = stream_data.out_buff.get(); - current_position = 0; + compressed_bytes_read = 0; + compressed_bytes_consumed.store(0, std::memory_order_relaxed); stream_wrapper = compressed_fs.CreateStream(); stream_wrapper->Initialize(context, *this, write); @@ -82,7 +83,7 @@ void CompressedFile::Initialize(QueryContext context, bool write) { } idx_t CompressedFile::GetProgress() { - return current_position; + return compressed_bytes_consumed.load(std::memory_order_relaxed); } int64_t CompressedFile::ReadData(void *buffer, int64_t remaining) { @@ -108,7 +109,6 @@ int64_t CompressedFile::ReadData(void *buffer, int64_t remaining) { if (!stream_wrapper) { return UnsafeNumericCast(total_read); } - current_position += static_cast(stream_data.in_buff_end - stream_data.in_buff_start); // ran out of buffer: read more data from the child stream stream_data.out_buff_start = stream_data.out_buff.get(); stream_data.out_buff_end = stream_data.out_buff.get(); @@ -124,13 +124,19 @@ int64_t CompressedFile::ReadData(void *buffer, int64_t remaining) { if (sz <= 0) { stream_wrapper->FinalizeRead(stream_data); stream_wrapper.reset(); + compressed_bytes_consumed.store(compressed_bytes_read, std::memory_order_relaxed); break; } else { stream_data.in_buff_end = stream_data.in_buff_start + sz; + compressed_bytes_read += UnsafeNumericCast(sz); } } auto finished = stream_wrapper->Read(stream_data); + // the input that remains in the buffer has not been consumed by the decompressor yet + auto unconsumed = static_cast(stream_data.in_buff_end - stream_data.in_buff_start); + compressed_bytes_consumed.store(compressed_bytes_read - MinValue(unconsumed, compressed_bytes_read), + std::memory_order_relaxed); if (finished) { stream_wrapper.reset(); } diff --git a/src/duckdb/src/common/sort/full_sort.cpp b/src/duckdb/src/common/sort/full_sort.cpp index 7f450a1ca..40339704e 100644 --- a/src/duckdb/src/common/sort/full_sort.cpp +++ b/src/duckdb/src/common/sort/full_sort.cpp @@ -38,7 +38,7 @@ class FullSortGlobalSinkState : public GlobalSinkState { FullSortGlobalSinkState(ClientContext &client, const FullSort &full_sort); // OVER(PARTITION BY...) (hash grouping) - ProgressData GetSinkProgress(ClientContext &context, const ProgressData source_progress) const; + ProgressData GetSinkProgress(ClientContext &context, const ProgressData source_progress); //! System and query state ClientContext &client; @@ -50,6 +50,8 @@ class FullSortGlobalSinkState : public GlobalSinkState { // Threading atomic count; + //! Keeps the sink progress monotonic + MonotonicProgress sink_progress; }; FullSortGlobalSinkState::FullSortGlobalSinkState(ClientContext &client, const FullSort &full_sort) @@ -58,23 +60,10 @@ FullSortGlobalSinkState::FullSortGlobalSinkState(ClientContext &client, const Fu hash_group = make_uniq(client, *full_sort.sort); } -ProgressData FullSortGlobalSinkState::GetSinkProgress(ClientContext &client, const ProgressData source) const { - ProgressData result; - result.done = source.done / 2; - result.total = source.total; - result.invalid = source.invalid; - - // Sort::GetSinkProgress assumes that there is only 1 sort. - // So we just use it to figure out how many rows have been sorted. - const ProgressData zero_progress; +ProgressData FullSortGlobalSinkState::GetSinkProgress(ClientContext &client, const ProgressData source) { lock_guard guard(lock); - const auto &sort = full_sort.sort; - - const auto group_progress = sort->GetSinkProgress(client, *hash_group->sort_global, zero_progress); - result.done += group_progress.done; - result.invalid = result.invalid || group_progress.invalid; - - return result; + const auto sorted_count = hash_group ? full_sort.sort->GetSortedCount(*hash_group->sort_global) : 0; + return Sort::GetSinkProgress(source, sorted_count, count, sink_progress); } SinkFinalizeType FullSort::Finalize(ClientContext &client, OperatorSinkFinalizeInput &finalize) const { diff --git a/src/duckdb/src/common/sort/hashed_sort.cpp b/src/duckdb/src/common/sort/hashed_sort.cpp index 56535eaa3..b76e837c4 100644 --- a/src/duckdb/src/common/sort/hashed_sort.cpp +++ b/src/duckdb/src/common/sort/hashed_sort.cpp @@ -272,27 +272,8 @@ bool HashedSortGlobalSinkState::CanBypassSort(idx_t hash_bin) const { } ProgressData HashedSortGlobalSinkState::GetSinkProgress(ClientContext &client, const ProgressData source) const { - ProgressData result; - result.done = source.done / 2; - result.total = source.total; - result.invalid = source.invalid; - - // Sort::GetSinkProgress assumes that there is only 1 sort. - // So we just use it to figure out how many rows have been sorted. - const ProgressData zero_progress; - lock_guard guard(lock); - const auto &sort = hashed_sort.sort; - for (auto &hash_group : hash_groups) { - if (!hash_group || !hash_group->sort_global) { - continue; - } - - const auto group_progress = sort->GetSinkProgress(client, *hash_group->sort_global, zero_progress); - result.done += group_progress.done; - result.invalid = result.invalid || group_progress.invalid; - } - - return result; + // the hash groups are sorted after the sink has finished + return source; } SinkFinalizeType HashedSort::Finalize(ClientContext &client, OperatorSinkFinalizeInput &finalize) const { diff --git a/src/duckdb/src/common/sort/natural_sort.cpp b/src/duckdb/src/common/sort/natural_sort.cpp index 3dd27c1ff..6f94b0682 100644 --- a/src/duckdb/src/common/sort/natural_sort.cpp +++ b/src/duckdb/src/common/sort/natural_sort.cpp @@ -47,12 +47,8 @@ NaturalSortGlobalSinkState::NaturalSortGlobalSinkState(ClientContext &client, co } ProgressData NaturalSortGlobalSinkState::GetSinkProgress(ClientContext &client, const ProgressData source) const { - ProgressData result; - result.done = source.done / 2; - result.total = source.total; - result.invalid = source.invalid; - - return result; + // there is nothing to sort + return source; } SinkFinalizeType NaturalSort::Finalize(ClientContext &client, OperatorSinkFinalizeInput &finalize) const { diff --git a/src/duckdb/src/common/sort/sort.cpp b/src/duckdb/src/common/sort/sort.cpp index 73d2fc983..786f0b697 100644 --- a/src/duckdb/src/common/sort/sort.cpp +++ b/src/duckdb/src/common/sort/sort.cpp @@ -134,8 +134,8 @@ class SortGlobalSinkState : public GlobalSinkState { explicit SortGlobalSinkState(ClientContext &context) : num_threads(TaskScheduler::GetScheduler(context).NumberOfThreads()), temporary_memory_state(TemporaryMemoryManager::Get(context).Register(context)), sorted_tuples(0), - external(Settings::Get(context)), any_combined(false), total_count(0), - partition_size(0) { + sunk_tuples(0), external(Settings::Get(context)), any_combined(false), + total_count(0), partition_size(0) { } public: @@ -192,6 +192,10 @@ class SortGlobalSinkState : public GlobalSinkState { vector> sorted_runs; //! Sorted tuple count (for progress) atomic sorted_tuples; + //! Sunk tuple count (for progress) + atomic sunk_tuples; + //! Keeps the sink progress monotonic + MonotonicProgress sink_progress; //! Whether this is an external sort bool external; @@ -251,6 +255,7 @@ SinkResultType Sort::Sink(ExecutionContext &context, DataChunk &chunk, OperatorS lstate.key_executor.Execute(chunk, lstate.key); lstate.payload.ReferenceColumns(chunk, input_projection_map); lstate.sorted_run->Sink(lstate.key, lstate.payload); + gstate.sunk_tuples.fetch_add(chunk.size(), std::memory_order_relaxed); // Try to finish this call to Sink unique_lock guard; @@ -322,13 +327,33 @@ SinkFinalizeType Sort::Finalize(ClientContext &context, OperatorSinkFinalizeInpu ProgressData Sort::GetSinkProgress(ClientContext &context, GlobalSinkState &gstate_p, const ProgressData source_progress) const { auto &gstate = gstate_p.Cast(); - // Estimate that half of the Sink effort is sorting + return GetSinkProgress(source_progress, gstate.sorted_tuples, gstate.sunk_tuples, gstate.sink_progress); +} + +idx_t Sort::GetSortedCount(GlobalSinkState &gstate) const { + return gstate.Cast().sorted_tuples; +} + +ProgressData Sort::GetSinkProgress(const ProgressData &source_progress, idx_t sorted_count, idx_t sunk_count, + MonotonicProgress &monotonic_progress) { ProgressData res; - const auto sorted_tuples = static_cast(gstate.sorted_tuples); - res.done = source_progress.done / 2 + sorted_tuples / 2; res.total = source_progress.total; res.invalid = source_progress.invalid; - return res; + if (source_progress.total <= 0) { + return res; + } + const auto source_fraction = MinValue(source_progress.done / source_progress.total, 1.0); + // the total number of tuples is unknown - relate the sorted tuples to the tuples sunk so far + double sorted_fraction; + if (sunk_count == 0) { + // there is nothing to sort if the source finished without producing any tuples + sorted_fraction = source_fraction >= 1.0 ? 1.0 : 0.0; + } else { + sorted_fraction = MinValue(static_cast(sorted_count) / static_cast(sunk_count), 1.0); + } + res.done = source_progress.total * source_fraction * (1.0 + sorted_fraction) / 2; + // the sorted fraction drops when tuples are sunk faster than they are sorted + return monotonic_progress.Update(res); } //===--------------------------------------------------------------------===// @@ -477,8 +502,7 @@ SourceResultType Sort::MaterializeColumnData(ExecutionContext &context, Operator input.local_state.Cast().merger_local_state.reset(); // Return type indicates whether materialization is done - const auto progress_data = GetProgress(context.client, input.global_state); - if (progress_data.done == progress_data.total) { + if (gstate.merger.total_count == 0 || gstate.merger.IsFinished(*gstate.merger_global_state)) { // Destroy global state before returning gstate.Destroy(); return SourceResultType::FINISHED; diff --git a/src/duckdb/src/common/sort/sorted_run_merger.cpp b/src/duckdb/src/common/sort/sorted_run_merger.cpp index 04edb800f..2baecd162 100644 --- a/src/duckdb/src/common/sort/sorted_run_merger.cpp +++ b/src/duckdb/src/common/sort/sorted_run_merger.cpp @@ -151,6 +151,8 @@ class SortedRunMergerLocalState : public LocalSourceState { //! Variables for scanning idx_t merged_partition_count; idx_t merged_partition_index; + //! Rows of the current partition that were added to the global progress + idx_t progress_scanned; //! For scanning Vector sort_key_pointers; @@ -168,7 +170,7 @@ class SortedRunMergerGlobalState : public GlobalSourceState { num_partitions((merger.total_count + (merger.partition_size - 1)) / merger.partition_size), iterator_state_type(GetBlockIteratorStateType(merger.external)), sort_key_type(merger.sort.key_layout->GetSortKeyType()), next_partition_idx(0), total_scanned(0), - destroy_partition_idx(0) { + progress_scanned(0), destroy_partition_idx(0) { // Initialize partitions partitions.resize(num_partitions); for (idx_t partition_idx = 0; partition_idx < num_partitions; partition_idx++) { @@ -277,6 +279,8 @@ class SortedRunMergerGlobalState : public GlobalSourceState { idx_t next_partition_idx; vector> partitions; atomic total_scanned; + //! Rows scanned so far, updated per chunk (for progress) + atomic progress_scanned; mutex destroy_lock; idx_t destroy_partition_idx; @@ -292,7 +296,8 @@ SortedRunMergerLocalState::SortedRunMergerLocalState(SortedRunMergerGlobalState : iterator_state_type(gstate.iterator_state_type), sort_key_type(gstate.sort_key_type), task(SortedRunMergerTask::FINISHED), run_boundaries(gstate.num_runs), merged_partition_count(DConstants::INVALID_INDEX), merged_partition_index(DConstants::INVALID_INDEX), - sort_key_pointers(LogicalType::POINTER), sorted_run_scan_state(gstate.context, gstate.merger.sort) { + progress_scanned(0), sort_key_pointers(LogicalType::POINTER), + sorted_run_scan_state(gstate.context, gstate.merger.sort) { for (const auto &run : gstate.merger.sorted_runs) { auto &key_data = *run->key_data; switch (iterator_state_type) { @@ -351,10 +356,14 @@ SourceResultType SortedRunMergerLocalState::ExecuteTask(SortedRunMergerGlobalSta case SortedRunMergerTask::SCAN_PARTITION: if (chunk) { ScanPartition(gstate, *chunk); + gstate.progress_scanned.fetch_add(chunk->size(), std::memory_order_relaxed); + progress_scanned += chunk->size(); } else { MaterializePartition(gstate); } if (!chunk || chunk->size() == 0) { + gstate.progress_scanned.fetch_add(merged_partition_count - progress_scanned, std::memory_order_relaxed); + progress_scanned = 0; gstate.DestroyScannedData(); gstate.partitions[partition_idx.GetIndex()]->scanned = true; // fetch_add returns the _previous_ value! @@ -824,12 +833,17 @@ OperatorPartitionData SortedRunMerger::GetPartitionData(ExecutionContext &, Data ProgressData SortedRunMerger::GetProgress(ClientContext &, GlobalSourceState &gstate_p) const { auto &gstate = gstate_p.Cast(); ProgressData res; - res.done = static_cast(gstate.total_scanned); + res.done = static_cast(MinValue(gstate.progress_scanned, total_count)); res.total = static_cast(total_count); res.invalid = false; return res; } +bool SortedRunMerger::IsFinished(GlobalSourceState &gstate_p) const { + auto &gstate = gstate_p.Cast(); + return gstate.total_scanned == total_count; +} + //===--------------------------------------------------------------------===// // Non-Standard Interface //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/execution/aggregate_hashtable.cpp b/src/duckdb/src/execution/aggregate_hashtable.cpp index 30086378e..edaa1d94c 100644 --- a/src/duckdb/src/execution/aggregate_hashtable.cpp +++ b/src/duckdb/src/execution/aggregate_hashtable.cpp @@ -1165,7 +1165,7 @@ void GroupedAggregateHashTable::Combine(GroupedAggregateHashTable &other) { } } -void GroupedAggregateHashTable::Combine(TupleDataCollection &other_data, optional_ptr> progress) { +void GroupedAggregateHashTable::Combine(TupleDataCollection &other_data, optional_ptr> combined_chunks) { D_ASSERT(other_data.GetLayout().GetAggrWidth() == layout_ptr->GetAggrWidth()); D_ASSERT(other_data.GetLayout().GetDataWidth() == layout_ptr->GetDataWidth()); D_ASSERT(other_data.GetLayout().GetRowWidth() == layout_ptr->GetRowWidth()); @@ -1176,8 +1176,6 @@ void GroupedAggregateHashTable::Combine(TupleDataCollection &other_data, optiona FlushMoveState fm_state(other_data); - idx_t chunk_idx = 0; - const auto chunk_count = other_data.ChunkCount(); while (fm_state.Scan()) { // Check for interrupts with each chunk context.InterruptCheck(); @@ -1188,8 +1186,8 @@ void GroupedAggregateHashTable::Combine(TupleDataCollection &other_data, optiona RowOperations::DestroyStates(state.row_state, *layout_ptr, fm_state.scan_state.chunk_state.row_locations); } - if (progress) { - *progress = static_cast(++chunk_idx) / static_cast(chunk_count); + if (combined_chunks) { + combined_chunks->fetch_add(1, std::memory_order_relaxed); } } diff --git a/src/duckdb/src/execution/join_hashtable.cpp b/src/duckdb/src/execution/join_hashtable.cpp index aef0040c9..4d66cd57c 100644 --- a/src/duckdb/src/execution/join_hashtable.cpp +++ b/src/duckdb/src/execution/join_hashtable.cpp @@ -2334,6 +2334,7 @@ void JoinHashTable::ScanFullOuter(JoinHTScanState &state, Vector &addresses, Dat break; } state.offset_in_chunk = 0; + state.chunks_done++; } while (iterator.Next()); // now gather from the found rows diff --git a/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp b/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp index d3955ce95..c0a2efcc1 100644 --- a/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp +++ b/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp @@ -207,7 +207,7 @@ SourceResultType PhysicalPerfectHashAggregate::GetDataInternal(ExecutionContext auto &gstate = sink_state->Cast(); gstate.ht->Scan(state.ht_scan_position, chunk); - state.scanned_slots = state.ht_scan_position; + state.scanned_slots.store(state.ht_scan_position, std::memory_order_relaxed); if (chunk.size() > 0) { return SourceResultType::HAVE_MORE_OUTPUT; diff --git a/src/duckdb/src/execution/operator/aggregate/physical_window.cpp b/src/duckdb/src/execution/operator/aggregate/physical_window.cpp index a5ad6a8e3..baff3cea0 100644 --- a/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +++ b/src/duckdb/src/execution/operator/aggregate/physical_window.cpp @@ -220,6 +220,8 @@ class WindowGlobalSinkState : public GlobalSinkState { value_map_t strategy_sinks; //! The number of sunk rows (for progress) atomic count; + //! Keeps the sink progress monotonic + MonotonicProgress sink_progress; //! The execution functions Executors executors; //! The shared expressions library @@ -238,6 +240,7 @@ class WindowGlobalSinkState : public GlobalSinkState { strategy_sinks.insert(make_pair(Value(), sort_strategy->GetGlobalSinkState(context))); } count = 0; + sink_progress.Reset(); GlobalSinkState::Reset(context); } @@ -483,7 +486,8 @@ ProgressData PhysicalWindow::GetSinkProgress(ClientContext &context, GlobalSinkS for (auto &strategy_sink : gsink.strategy_sinks) { progress.Add(gsink.sort_strategy->GetSinkProgress(context, *strategy_sink.second, progress)); } - return progress; + // strategy sinks can be added while sinking (e.g. for partitioned input) - keep the progress monotonic + return gsink.sink_progress.Update(progress); } //===--------------------------------------------------------------------===// @@ -1233,11 +1237,11 @@ ProgressData PhysicalWindow::GetProgress(ClientContext &client, GlobalSourceStat auto &gsource = gsource_p.Cast(); auto &gsink = gsource.gsink; const auto count = gsink.count.load(); - const auto completed = gsource.completed.load(); + const auto finished = gsource.finished.load(); ProgressData res; if (count) { - res.done = double(completed); + res.done = double(finished); res.total = double(gsource.total_tasks); // Convert to tuples. res.Normalize(double(count)); diff --git a/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_file_handle.cpp b/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_file_handle.cpp index 0b7ae7c30..8e922902b 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_file_handle.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/buffer_manager/csv_file_handle.cpp @@ -103,7 +103,7 @@ idx_t CSVFileHandle::Read(void *buffer, idx_t nr_bytes) { if (!finished) { finished = bytes_read == 0; } - uncompressed_bytes_read += static_cast(bytes_read); + uncompressed_bytes_read.fetch_add(static_cast(bytes_read), std::memory_order_relaxed); return UnsafeNumericCast(bytes_read); } diff --git a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp index 2e2e9287b..7cd367d73 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/table_function/csv_file_scanner.cpp @@ -162,17 +162,28 @@ double CSVFileScan::GetProgressInFile(ClientContext &context) { // We are done with this file, so it's 100% return 100.0; } - double total_bytes_read; - if (manager->file_handle->compression_type == FileCompressionType::GZIP || - manager->file_handle->compression_type == FileCompressionType::ZSTD) { - // compressed file: we care about the progress made in the *underlying* file handle - // the bytes read from the uncompressed file are skewed - total_bytes_read = manager->file_handle->GetProgress(); - } else { - total_bytes_read = static_cast(bytes_read); - } - double file_progress = total_bytes_read / static_cast(file_size); - return file_progress * 100.0; + if (file_size == 0) { + // empty file + return 100.0; + } + auto &file_handle = *manager->file_handle; + if (file_handle.compression_type == FileCompressionType::GZIP || + file_handle.compression_type == FileCompressionType::ZSTD) { + // compressed file: the file is decompressed ahead of parsing - the progress is the fraction of the file that + // was decompressed, times the fraction of the decompressed bytes that was parsed + auto decompressed_fraction = file_handle.GetProgress() / static_cast(file_size); + auto decompressed_bytes = file_handle.UncompressedBytesRead(); + double parsed_fraction = 0; + if (decompressed_bytes > 0) { + parsed_fraction = MinValue(static_cast(bytes_read.load(std::memory_order_relaxed)) / + static_cast(decompressed_bytes), + 1.0); + } + auto progress = compressed_progress.Update( + ProgressData {MinValue(decompressed_fraction, 1.0) * parsed_fraction, 1.0, false}); + return progress.done * 100.0; + } + return static_cast(bytes_read.load(std::memory_order_relaxed)) / static_cast(file_size) * 100.0; } } // namespace duckdb diff --git a/src/duckdb/src/execution/operator/helper/physical_limit.cpp b/src/duckdb/src/execution/operator/helper/physical_limit.cpp index 10697f344..2245a1c71 100644 --- a/src/duckdb/src/execution/operator/helper/physical_limit.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_limit.cpp @@ -1,6 +1,7 @@ #include "duckdb/execution/operator/helper/physical_limit.hpp" #include "duckdb/common/algorithm.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/common/types/batched_data_collection.hpp" #include "duckdb/common/vector/constant_vector.hpp" #include "duckdb/execution/expression_executor.hpp" @@ -159,11 +160,17 @@ class LimitSourceState : public GlobalSourceState { LimitSourceState() { initialized = false; current_offset = 0; + scanned_rows = 0; + total_rows = 0; } bool initialized; idx_t current_offset; BatchedChunkScanState scan_state; + //! The number of rows scanned from the collection (including rows skipped by the offset) + atomic scanned_rows; + //! The number of rows that will be scanned - set when the scan is initialized + atomic total_rows; }; unique_ptr PhysicalLimit::GetGlobalSourceState(ClientContext &context) const { @@ -177,9 +184,15 @@ SourceResultType PhysicalLimit::GetDataInternal(ExecutionContext &context, DataC while (state.current_offset < gstate.limit + gstate.offset) { if (!state.initialized) { gstate.data.InitializeScan(state.scan_state); + idx_t total_rows = gstate.data.Count(); + if (gstate.limit != DConstants::INVALID_INDEX) { + total_rows = MinValue(total_rows, gstate.limit + gstate.offset); + } + state.total_rows = total_rows; state.initialized = true; } gstate.data.Scan(state.scan_state, chunk); + state.scanned_rows.fetch_add(chunk.size(), std::memory_order_relaxed); if (chunk.size() == 0) { return SourceResultType::FINISHED; } @@ -191,6 +204,15 @@ SourceResultType PhysicalLimit::GetDataInternal(ExecutionContext &context, DataC return chunk.size() > 0 ? SourceResultType::HAVE_MORE_OUTPUT : SourceResultType::FINISHED; } +ProgressData PhysicalLimit::GetProgress(ClientContext &context, GlobalSourceState &gstate_p) const { + auto &state = gstate_p.Cast(); + idx_t total = state.total_rows; + ProgressData progress; + progress.total = static_cast(MaxValue(total, 1)); + progress.done = static_cast(MinValue(state.scanned_rows, total)); + return progress; +} + bool PhysicalLimit::HandleOffset(DataChunk &input, idx_t ¤t_offset, idx_t offset, idx_t limit) { idx_t max_element = limit + offset; if (limit == DConstants::INVALID_INDEX) { diff --git a/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp b/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp index 4a96ee71b..73e70a89e 100644 --- a/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_limit_percent.cpp @@ -104,8 +104,7 @@ SinkResultType PhysicalLimitPercent::Sink(ExecutionContext &context, DataChunk & //===--------------------------------------------------------------------===// class LimitPercentOperatorState : public GlobalSourceState { public: - explicit LimitPercentOperatorState(const PhysicalLimitPercent &op) - : current_offset(0), progress(0), limit_validated(false) { + explicit LimitPercentOperatorState(const PhysicalLimitPercent &op) : current_offset(0), limit_validated(false) { D_ASSERT(op.sink_state); auto &gstate = op.sink_state->Cast(); gstate.data.InitializeScan(scan_state); @@ -114,8 +113,11 @@ class LimitPercentOperatorState : public GlobalSourceState { ColumnDataScanState scan_state; optional_idx limit; idx_t current_offset; - atomic progress; atomic limit_validated; + //! The number of rows that will be emitted, the rows scanned so far and whether the source finished + atomic total_rows {0}; + atomic scanned_rows {0}; + atomic finished {false}; }; unique_ptr PhysicalLimitPercent::GetGlobalSourceState(ClientContext &context) const { @@ -123,16 +125,22 @@ unique_ptr PhysicalLimitPercent::GetGlobalSourceState(ClientC } ProgressData PhysicalLimitPercent::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { - ProgressData progress; - progress.done = gstate.Cast().progress.load(std::memory_order_relaxed); - progress.total = 1.0; - return progress; + auto &state = gstate.Cast(); + if (state.finished.load(std::memory_order_relaxed)) { + return ProgressData {1.0, 1.0, false}; + } + auto total_rows = state.total_rows.load(std::memory_order_relaxed); + if (total_rows == 0) { + return ProgressData {0.0, 1.0, false}; + } + auto scanned_rows = MinValue(state.scanned_rows.load(std::memory_order_relaxed), total_rows); + return ProgressData {double(scanned_rows), double(total_rows), false}; } void PhysicalLimitPercent::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { auto &state = gstate.Cast(); if (state.limit_validated.load(std::memory_order_relaxed)) { - state.progress.store(1.0, std::memory_order_relaxed); + state.finished.store(true, std::memory_order_relaxed); } } @@ -166,6 +174,7 @@ SourceResultType PhysicalLimitPercent::GetDataInternal(ExecutionContext &context } else { limit = idx_t(limit_percentage); } + state.total_rows.store(MinValue(limit.GetIndex(), gstate.data.Count()), std::memory_order_relaxed); state.limit_validated.store(true, std::memory_order_relaxed); if (limit == 0) { return SourceResultType::FINISHED; @@ -180,9 +189,7 @@ SourceResultType PhysicalLimitPercent::GetDataInternal(ExecutionContext &context } PhysicalLimit::HandleOffset(chunk, current_offset, 0, limit.GetIndex()); - const auto total = MinValue(limit.GetIndex(), gstate.data.Count()); - D_ASSERT(total > 0); - state.progress.store(double(MinValue(current_offset, total)) / double(total), std::memory_order_relaxed); + state.scanned_rows.store(current_offset, std::memory_order_relaxed); return SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp b/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp index de46fdf48..e9b6c354f 100644 --- a/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp +++ b/src/duckdb/src/execution/operator/helper/physical_reservoir_sample.cpp @@ -83,7 +83,7 @@ class SampleGlobalSourceState : public GlobalSourceState { public: atomic total_rows {0}; atomic rows_scanned {0}; - atomic progress {0.0}; + atomic finished {false}; }; unique_ptr PhysicalReservoirSample::GetGlobalSourceState(ClientContext &context) const { @@ -91,11 +91,20 @@ unique_ptr PhysicalReservoirSample::GetGlobalSourceState(Clie } ProgressData PhysicalReservoirSample::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { - return ProgressData {gstate.Cast().progress.load(), 1.0, false}; + auto &state = gstate.Cast(); + if (state.finished.load(std::memory_order_relaxed)) { + return ProgressData {1.0, 1.0, false}; + } + auto total_rows = state.total_rows.load(std::memory_order_relaxed); + if (total_rows == 0) { + return ProgressData {0.0, 1.0, false}; + } + auto rows_scanned = MinValue(state.rows_scanned.load(std::memory_order_relaxed), total_rows); + return ProgressData {double(rows_scanned), double(total_rows), false}; } void PhysicalReservoirSample::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { - gstate.Cast().progress = 1.0; + gstate.Cast().finished = true; } SourceResultType PhysicalReservoirSample::GetDataInternal(ExecutionContext &context, DataChunk &chunk, @@ -104,13 +113,13 @@ SourceResultType PhysicalReservoirSample::GetDataInternal(ExecutionContext &cont auto &state = input.global_state.Cast(); lock_guard glock(sink.lock); if (!sink.sample) { - state.progress = 1.0; + state.finished = true; return SourceResultType::FINISHED; } auto sample_chunk = sink.sample->GetChunk(); if (!sample_chunk) { - state.progress = 1.0; + state.finished = true; return SourceResultType::FINISHED; } if (state.total_rows == 0) { @@ -119,8 +128,7 @@ SourceResultType PhysicalReservoirSample::GetDataInternal(ExecutionContext &cont state.total_rows = sample_chunk->size() + remaining; } chunk.Move(*sample_chunk); - state.rows_scanned += chunk.size(); - state.progress = double(state.rows_scanned.load()) / double(state.total_rows.load()); + state.rows_scanned.fetch_add(chunk.size(), std::memory_order_relaxed); return SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/join/outer_join_marker.cpp b/src/duckdb/src/execution/operator/join/outer_join_marker.cpp index 4ee8e8721..86a69dbbd 100644 --- a/src/duckdb/src/execution/operator/join/outer_join_marker.cpp +++ b/src/duckdb/src/execution/operator/join/outer_join_marker.cpp @@ -117,7 +117,7 @@ void OuterJoinMarker::Scan(OuterJoinGlobalScanState &gstate, OuterJoinLocalScanS result_count); } } - gstate.rows_scanned += lstate.scan_chunk.size(); + gstate.rows_scanned.fetch_add(lstate.scan_chunk.size(), std::memory_order_relaxed); if (result_count > 0) { return; } diff --git a/src/duckdb/src/execution/operator/join/physical_asof_join.cpp b/src/duckdb/src/execution/operator/join/physical_asof_join.cpp index 86605ddd0..81df617a6 100644 --- a/src/duckdb/src/execution/operator/join/physical_asof_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_asof_join.cpp @@ -774,6 +774,8 @@ class AsOfGlobalSourceState : public GlobalSourceState { atomic finished; //! Stop producing tasks atomic stopped; + //! The progress of the tasks + TaskProgress task_progress; public: idx_t MaxThreads() override { @@ -1458,6 +1460,9 @@ class AsOfLocalSourceState : public LocalSourceState { TaskPtr task; //! The task storage Task task_local; + //! The start of the range of the current task, and the progress reported for it + idx_t task_begin = 0; + TaskProgressTracker task_progress; //! The rhs group HashGroupPtr hash_group; //! The read cursor @@ -1546,6 +1551,7 @@ bool AsOfLocalSourceState::TryAssignTask() { // Because downstream operators may be using our internal buffers, // we can't "finish" a task until we are about to get the next one. if (task) { + task_progress.Finish(gsource.task_progress); switch (task->stage) { case AsOfJoinSourceStage::SORT: gsource.asof_groups[task_local.group_idx]->sorted++; @@ -1571,6 +1577,8 @@ bool AsOfLocalSourceState::TryAssignTask() { if (!gsource.TryNextTask(task, task_local)) { return false; } + task_begin = task->begin_idx; + task_progress.Start(); switch (task->stage) { case AsOfJoinSourceStage::SORT: @@ -1719,17 +1727,12 @@ void AsOfLocalSourceState::ExecuteLeftTask(ExecutionContext &context, DataChunk ProgressData PhysicalAsOfJoin::GetProgress(ClientContext &context, GlobalSourceState &gsource_p) const { auto &gsource = gsource_p.Cast(); const auto count = gsource.total_tasks; - - const auto returned = gsource.finished.load(); - - ProgressData res; - if (count) { - res.done = double(returned); - res.total = double(count); - } else { + if (!count) { + ProgressData res; res.SetInvalid(); + return res; } - return res; + return gsource.task_progress.GetProgress(count); } SourceResultType PhysicalAsOfJoin::GetDataInternal(ExecutionContext &context, DataChunk &chunk, @@ -1747,6 +1750,12 @@ SourceResultType PhysicalAsOfJoin::GetDataInternal(ExecutionContext &context, Da gsource.stopped = true; throw; } + if (lsource.task) { + auto &task = *lsource.task; + auto done = task.begin_idx > lsource.task_begin ? task.begin_idx - lsource.task_begin : 0; + auto total = task.end_idx > lsource.task_begin ? task.end_idx - lsource.task_begin : 0; + lsource.task_progress.Update(gsource.task_progress, done, total); + } } else { annotated_lock_guard guard(gsource.lock); if (!gsource.HasMoreTasks()) { diff --git a/src/duckdb/src/execution/operator/join/physical_hash_join.cpp b/src/duckdb/src/execution/operator/join/physical_hash_join.cpp index 9d4d5fb22..aa50361fa 100644 --- a/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_hash_join.cpp @@ -2209,6 +2209,8 @@ class HashJoinGlobalSourceState : public GlobalSourceState { idx_t full_outer_chunk_idx = DConstants::INVALID_INDEX; atomic full_outer_chunk_count; atomic full_outer_chunk_done; + //! Chunks of the full/outer scan that have been scanned, updated while scanning (for progress) + atomic full_outer_chunk_progress; idx_t full_outer_chunks_per_thread = DConstants::INVALID_INDEX; vector blocked_tasks; @@ -2227,6 +2229,7 @@ class HashJoinGlobalSourceState : public GlobalSourceState { full_outer_chunk_idx = DConstants::INVALID_INDEX; full_outer_chunk_count = 0; full_outer_chunk_done = 0; + full_outer_chunk_progress = 0; full_outer_chunks_per_thread = DConstants::INVALID_INDEX; blocked_tasks.clear(); GlobalSourceState::Reset(context); @@ -2282,6 +2285,8 @@ class HashJoinLocalSourceState : public LocalSourceState { idx_t full_outer_chunk_idx_from = DConstants::INVALID_INDEX; idx_t full_outer_chunk_idx_to = DConstants::INVALID_INDEX; unique_ptr full_outer_scan_state; + //! Chunks of the current full/outer scan that were added to the global progress + idx_t full_outer_chunks_reported = 0; private: void ResetState() { @@ -2302,6 +2307,7 @@ class HashJoinLocalSourceState : public LocalSourceState { full_outer_chunk_idx_from = DConstants::INVALID_INDEX; full_outer_chunk_idx_to = DConstants::INVALID_INDEX; full_outer_scan_state.reset(); + full_outer_chunks_reported = 0; } public: @@ -2442,6 +2448,7 @@ void HashJoinGlobalSourceState::PrepareScanHT(HashJoinGlobalSinkState &sink) { full_outer_chunk_idx = 0; full_outer_chunk_count = data_collection.ChunkCount(); full_outer_chunk_done = 0; + full_outer_chunk_progress = 0; full_outer_chunks_per_thread = MaxValue((full_outer_chunk_count + sink.num_threads - 1) / sink.num_threads, 1); @@ -2607,9 +2614,17 @@ void HashJoinLocalSourceState::ExternalScanHT(HashJoinGlobalSinkState &sink, Has if (!full_outer_scan_state) { full_outer_scan_state = make_uniq(sink.hash_table->GetDataCollection(), full_outer_chunk_idx_from, full_outer_chunk_idx_to); + full_outer_chunks_reported = 0; } sink.hash_table->ScanFullOuter(*full_outer_scan_state, addresses, chunk); + auto chunks_scanned = + chunk.size() == 0 ? full_outer_chunk_idx_to - full_outer_chunk_idx_from : full_outer_scan_state->chunks_done; + if (chunks_scanned > full_outer_chunks_reported) { + gstate.full_outer_chunk_progress.fetch_add(chunks_scanned - full_outer_chunks_reported, + std::memory_order_relaxed); + full_outer_chunks_reported = chunks_scanned; + } if (chunk.size() == 0) { full_outer_scan_state = nullptr; annotated_lock_guard guard(gstate.lock); @@ -2668,7 +2683,7 @@ ProgressData PhysicalHashJoin::GetProgress(ClientContext &context, GlobalSourceS if (!sink.external) { if (PropagatesBuildSide(join_type)) { - res.done = static_cast(gstate.full_outer_chunk_done); + res.done = static_cast(gstate.full_outer_chunk_progress.load(std::memory_order_relaxed)); res.total = static_cast(gstate.full_outer_chunk_count); return res; } diff --git a/src/duckdb/src/execution/operator/join/physical_iejoin.cpp b/src/duckdb/src/execution/operator/join/physical_iejoin.cpp index cd8b66a6a..05f7ab25c 100644 --- a/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +++ b/src/duckdb/src/execution/operator/join/physical_iejoin.cpp @@ -336,6 +336,8 @@ class IEJoinGlobalSourceState : public GlobalSourceState { atomic stopped; //! The number of completed tasks for each stage array, static_cast(IEJoinSourceStage::DONE) + 1> completed; + //! The progress of the tasks + TaskProgress task_progress; //! L1 unique_ptr l1; @@ -482,6 +484,20 @@ class IEJoinLocalSourceState : public LocalSourceState { } bool TryAssignTask(); + //! Reports the progress of the current task + void UpdateProgress() { + if (!task) { + return; + } + if (TaskFinished()) { + task_progress.Finish(gsource.task_progress); + } else if (task->stage == IEJoinSourceStage::INNER && joiner) { + // the inner join advances over the rows of its range + auto done = joiner->i > inner_begin ? joiner->i - inner_begin : 0; + auto total = joiner->n > inner_begin ? joiner->n - inner_begin : 0; + task_progress.Update(gsource.task_progress, done, total); + } + } // Sort L1 void ExecuteSinkL1Task(ExecutionContext &context, InterruptState &interrupt); // Finalize L1 sort @@ -535,6 +551,10 @@ class IEJoinLocalSourceState : public LocalSourceState { TaskPtr task; //! The task storage Task task_local; + //! The progress reported for the current task + TaskProgressTracker task_progress; + //! The first row of the current inner join task + idx_t inner_begin = 0; // Joining unique_ptr joiner; @@ -588,6 +608,7 @@ bool IEJoinLocalSourceState::TryAssignTask() { // Because downstream operators may be using our internal buffers, // we can't "finish" a task until we are about to get the next one. if (task) { + task_progress.Finish(gsource.task_progress); ++gsource.GetStageNext(task->stage); left_matches = nullptr; right_matches = nullptr; @@ -596,6 +617,7 @@ bool IEJoinLocalSourceState::TryAssignTask() { if (!gsource.TryNextTask(task, task_local)) { return false; } + task_progress.Start(); auto &gsink = gsource.gsink; auto &left_table = *gsink.tables[0]; @@ -620,6 +642,7 @@ bool IEJoinLocalSourceState::TryAssignTask() { right_base = 0; joiner = make_uniq(*gsource.l2, *gsource.li, *gsource.p, gsource.op.conditions, task->range); + inner_begin = joiner->i; break; case IEJoinSourceStage::OUTER: if (task->thread_idx < gsource.left_outers) { @@ -1408,17 +1431,12 @@ bool IEJoinGlobalSourceState::TryNextTask(Task &task) { ProgressData IEJoinGlobalSourceState::GetProgress() const { const auto count = GetTaskCount(); - - const auto returned = finished.load(); - - ProgressData res; - if (count) { - res.done = double(returned); - res.total = double(count); - } else { + if (!count) { + ProgressData res; res.SetInvalid(); + return res; } - return res; + return task_progress.GetProgress(count); } unique_ptr PhysicalIEJoin::GetGlobalSourceState(ClientContext &client) const { auto &gsink = sink_state->Cast(); @@ -1446,6 +1464,7 @@ SourceResultType PhysicalIEJoin::GetDataInternal(ExecutionContext &context, Data while (gsource.stage != IEJoinSourceStage::DONE && result.size() == 0) { if (!lsource.TaskFinished() || lsource.TryAssignTask()) { lsource.ExecuteTask(context, result, input.interrupt_state); + lsource.UpdateProgress(); } else { annotated_lock_guard guard(gsource.lock); if (gsource.TryPrepareNextStage() || gsource.stage == IEJoinSourceStage::DONE) { diff --git a/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp b/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp index 98a218f60..334b2d9f4 100644 --- a/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp +++ b/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp @@ -891,7 +891,7 @@ SourceResultType PhysicalPiecewiseMergeJoin::GetDataInternal(ExecutionContext &c result.data[left_column_count + col_idx].Slice(rhs_chunk.data[col_idx], rsel, result_count); } } - gsource.rows_scanned += count; + gsource.rows_scanned.fetch_add(count, std::memory_order_relaxed); if (result_count > 0) { break; } diff --git a/src/duckdb/src/execution/operator/order/physical_top_n.cpp b/src/duckdb/src/execution/operator/order/physical_top_n.cpp index 1395be181..ef449579c 100644 --- a/src/duckdb/src/execution/operator/order/physical_top_n.cpp +++ b/src/duckdb/src/execution/operator/order/physical_top_n.cpp @@ -617,7 +617,7 @@ SourceResultType PhysicalTopN::GetDataInternal(ExecutionContext &context, DataCh } sink.heap.Scan(gstate.state, chunk, lstate.pos); - gstate.rows_scanned += chunk.size(); + gstate.rows_scanned.fetch_add(chunk.size(), std::memory_order_relaxed); return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp b/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp index f967e6b8c..4c66dfc43 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp @@ -678,7 +678,7 @@ class PartitionWriteManager { ReservationLock LockForReservation() DUCKDB_EXCLUDES(lock); PartitionFileStateReservation ReserveFileState(ReservationLock &reservation_lock, const vector &values, FileCreationReason reason) DUCKDB_NO_THREAD_SAFETY_ANALYSIS; - //! Claims the directory of a partition, throws if it equals, contains or is inside another partition's directory + //! Claims the directory of a partition, throws if another partition already owns it void ClaimDirectory(ReservationLock &reservation_lock, const vector &values, const string &directory) DUCKDB_NO_THREAD_SAFETY_ANALYSIS; FileStateHandle TryTakeInactiveFileState(const vector &values) DUCKDB_EXCLUDES(lock); @@ -697,7 +697,7 @@ class PartitionWriteManager { idx_t global_offset DUCKDB_GUARDED_BY(lock) = 0; //! The claimed directory of each partition, and the partition owning each directory vector_of_value_map_t partition_directories DUCKDB_GUARDED_BY(lock); - map> directory_partitions DUCKDB_GUARDED_BY(lock); + unordered_map> directory_partitions DUCKDB_GUARDED_BY(lock); friend class PartitionWriteLease; }; @@ -1879,29 +1879,11 @@ void PartitionWriteManager::ClaimDirectory(ReservationLock &reservation_lock, co if (claimed != partition_directories.end() && claimed->second == directory) { return; } - auto throw_overlap = [&](const string &other_directory, const vector &other_values) { - if (other_directory == directory) { - throw InvalidInputException("PARTITION_PATH puts partitions (%s) and (%s) in the same directory \"%s\"", - PartitionValuesToString(op, other_values), PartitionValuesToString(op, values), - directory); - } - throw InvalidInputException( - "PARTITION_PATH puts partitions (%s) and (%s) in overlapping directories \"%s\" and \"%s\"", - PartitionValuesToString(op, other_values), PartitionValuesToString(op, values), other_directory, directory); - }; - // the same directory, or a directory containing it - string ancestor; - for (auto &component : StringUtil::Split(directory, '/')) { - ancestor += ancestor.empty() ? component : "/" + component; - auto owner = directory_partitions.find(ancestor); - if (owner != directory_partitions.end()) { - throw_overlap(owner->first, owner->second); - } - } - // a directory inside it - those all start with the directory and a separator, so they are adjacent in the map - auto descendant = directory_partitions.lower_bound(directory + "/"); - if (descendant != directory_partitions.end() && StringUtil::StartsWith(descendant->first, directory + "/")) { - throw_overlap(descendant->first, descendant->second); + auto owner = directory_partitions.find(directory); + if (owner != directory_partitions.end()) { + throw InvalidInputException("PARTITION_PATH puts partitions (%s) and (%s) in the same directory \"%s\"", + PartitionValuesToString(op, owner->second), PartitionValuesToString(op, values), + directory); } directory_partitions.emplace(directory, values); partition_directories[values] = directory; diff --git a/src/duckdb/src/execution/operator/persistent/physical_delete.cpp b/src/duckdb/src/execution/operator/persistent/physical_delete.cpp index 6bc679ea6..ff76754b8 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_delete.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_delete.cpp @@ -224,12 +224,13 @@ unique_ptr PhysicalDelete::GetLocalSinkState(ExecutionContext &c //===--------------------------------------------------------------------===// class DeleteSourceState : public GlobalSourceState { public: - explicit DeleteSourceState(const PhysicalDelete &op) { + explicit DeleteSourceState(const PhysicalDelete &op) : total_rows(1), rows_scanned(0) { if (op.return_chunk) { D_ASSERT(op.sink_state); auto &g = op.sink_state->Cast(); g.return_collection.InitializeScan(global_scan_state); max_threads = MaxValue(g.return_collection.ChunkCount(), 1); + total_rows = g.return_collection.Count(); } else { max_threads = 1; } @@ -241,6 +242,8 @@ class DeleteSourceState : public GlobalSourceState { ColumnDataParallelScanState global_scan_state; idx_t max_threads; + idx_t total_rows; + atomic rows_scanned; }; class DeleteLocalSourceState : public LocalSourceState { @@ -256,17 +259,27 @@ unique_ptr PhysicalDelete::GetLocalSourceState(ExecutionContex return make_uniq(); } +ProgressData PhysicalDelete::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + ProgressData progress; + progress.total = double(MaxValue(state.total_rows, 1)); + progress.done = state.total_rows == 0 ? 1.0 : double(state.rows_scanned.load(std::memory_order_relaxed)); + return progress; +} + SourceResultType PhysicalDelete::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &state = input.global_state.Cast(); auto &g = sink_state->Cast(); if (!return_chunk) { chunk.data[0].Append(Value::BIGINT(NumericCast(g.deleted_count.load()))); + state.rows_scanned.store(1, std::memory_order_relaxed); return SourceResultType::FINISHED; } auto &lstate = input.local_state.Cast(); g.return_collection.Scan(state.global_scan_state, lstate.local_scan_state, chunk); + state.rows_scanned.fetch_add(chunk.size(), std::memory_order_relaxed); return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/persistent/physical_merge_into.cpp b/src/duckdb/src/execution/operator/persistent/physical_merge_into.cpp index 57eea4527..32bc4ef54 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_merge_into.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_merge_into.cpp @@ -77,6 +77,8 @@ class MergeActionGlobalSourceState : public GlobalSourceState { idx_t consumer_idx; idx_t max_threads; atomic unregistered {false}; + //! The exchange total grows while the producer outruns its estimate - keeps the scan progress monotonic + MonotonicProgress scan_progress; }; class MergeActionLocalSourceState : public LocalSourceState { @@ -110,7 +112,7 @@ ProgressData PhysicalMergeActionSource::GetProgress(ClientContext &context, Glob auto &gstate = gstate_p.Cast(); // we do not know how many rows the merge into will push into this action - the exchange reports the rows we have // consumed out of the rows that have been pushed so far - return gstate.exchange->ScanProgress(gstate.consumer_idx, estimated_cardinality); + return gstate.scan_progress.Update(gstate.exchange->ScanProgress(gstate.consumer_idx, estimated_cardinality)); } void PhysicalMergeActionSource::SourceFinished(ClientContext &context, GlobalSourceState &gstate_p) const { diff --git a/src/duckdb/src/execution/operator/persistent/physical_update.cpp b/src/duckdb/src/execution/operator/persistent/physical_update.cpp index 5880a12b5..a5fb85fe4 100644 --- a/src/duckdb/src/execution/operator/persistent/physical_update.cpp +++ b/src/duckdb/src/execution/operator/persistent/physical_update.cpp @@ -301,31 +301,44 @@ SinkCombineResultType PhysicalUpdate::Combine(ExecutionContext &context, Operato //===--------------------------------------------------------------------===// class UpdateSourceState : public GlobalSourceState { public: - explicit UpdateSourceState(const PhysicalUpdate &op) { + explicit UpdateSourceState(const PhysicalUpdate &op) : total_rows(1), rows_scanned(0) { if (op.return_chunk) { D_ASSERT(op.sink_state); auto &g = op.sink_state->Cast(); g.return_collection.InitializeScan(scan_state); + total_rows = g.return_collection.Count(); } } ColumnDataScanState scan_state; + idx_t total_rows; + atomic rows_scanned; }; unique_ptr PhysicalUpdate::GetGlobalSourceState(ClientContext &context) const { return make_uniq(*this); } +ProgressData PhysicalUpdate::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + auto &state = gstate.Cast(); + ProgressData progress; + progress.total = double(MaxValue(state.total_rows, 1)); + progress.done = state.total_rows == 0 ? 1.0 : double(state.rows_scanned.load(std::memory_order_relaxed)); + return progress; +} + SourceResultType PhysicalUpdate::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &state = input.global_state.Cast(); auto &g = sink_state->Cast(); if (!return_chunk) { chunk.data[0].Append(Value::BIGINT(NumericCast(g.updated_count.load()))); + state.rows_scanned.store(1, std::memory_order_relaxed); return SourceResultType::FINISHED; } g.return_collection.Scan(state.scan_state, chunk); + state.rows_scanned.fetch_add(chunk.size(), std::memory_order_relaxed); return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } diff --git a/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp b/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp index 3db3e3591..d656c33ad 100644 --- a/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp +++ b/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp @@ -65,11 +65,11 @@ class TableScanGlobalSourceState : public GlobalSourceState { idx_t max_threads = 0; PhysicalTableScanExecutionStrategy physical_table_scan_execution_strategy; + //! Combined dynamic table filters - before global_state, which references them during teardown + unique_ptr table_filters; unique_ptr global_state; bool in_out_final = false; DataChunk input_chunk; - //! Combined table filters, if we have dynamic filters - unique_ptr table_filters; optional_ptr GetTableFilters(const PhysicalTableScan &op) const { return table_filters ? table_filters.get() : op.table_filters.get(); diff --git a/src/duckdb/src/execution/operator/set/physical_cte.cpp b/src/duckdb/src/execution/operator/set/physical_cte.cpp index 229b6058d..4e3222f33 100644 --- a/src/duckdb/src/execution/operator/set/physical_cte.cpp +++ b/src/duckdb/src/execution/operator/set/physical_cte.cpp @@ -44,6 +44,8 @@ class CTEConsumerGlobalSourceState : public GlobalSourceState { idx_t consumer_idx; idx_t max_threads; atomic unregistered {false}; + //! The exchange total grows while the producer outruns its estimate - keeps the scan progress monotonic + MonotonicProgress scan_progress; }; class CTEConsumerLocalSourceState : public LocalSourceState { @@ -110,7 +112,7 @@ bool PhysicalCTEConsumerSource::ParallelSource() const { ProgressData PhysicalCTEConsumerSource::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { auto &state = gstate.Cast(); - return state.exchange->ScanProgress(state.consumer_idx, estimated_cardinality); + return state.scan_progress.Update(state.exchange->ScanProgress(state.consumer_idx, estimated_cardinality)); } void PhysicalCTEConsumerSource::SourceFinished(ClientContext &context, GlobalSourceState &gstate) const { @@ -606,11 +608,8 @@ ProgressData PhysicalCTE::GetSinkProgress(ClientContext &context, GlobalSinkStat if (!state.working_table_ref) { return ProgressData {0, 1, true}; } - auto count = double(state.ordered_data ? state.ordered_data->Count() : state.working_table_ref->Count()); - auto progress = source_progress; - progress.done += count; - progress.total += count; - return progress; + // materializing the CTE is done once the source is exhausted + return source_progress; } } // namespace duckdb diff --git a/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp b/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp index 6e0e22fe0..db0986fca 100644 --- a/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp +++ b/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp @@ -10,6 +10,8 @@ #include "duckdb/main/settings.hpp" +#include + namespace duckdb { RecursiveCTEPartialKeySpec::RecursiveCTEPartialKeySpec(vector indices_p, idx_t full_key_count) @@ -1164,6 +1166,9 @@ class RecursiveCTEStateScanGlobalState : public GlobalSourceState { mutex lock; AggregateHTScanState scan_state; bool initialized = false; + //! The number of groups in the hash table and the number of groups scanned (for progress) + atomic total_groups {0}; + atomic scanned_groups {0}; }; class RecursiveCTEStateScanLocalState : public LocalSourceState { @@ -1233,11 +1238,13 @@ SourceResultType PhysicalRecursiveCTEStateScan::GetDataFromState(DataChunk &chun lock_guard guard(gstate.lock); if (!gstate.initialized) { recursive_state.GetHashTable().InitializeScan(gstate.scan_state); + gstate.total_groups = recursive_state.GetHashTable().Count(); gstate.initialized = true; } if (!recursive_state.GetHashTable().ScanGroups(gstate.scan_state, lstate.distinct_rows)) { return SourceResultType::FINISHED; } + gstate.scanned_groups.fetch_add(lstate.distinct_rows.size(), std::memory_order_relaxed); } if (lstate.distinct_rows.size() == 0) { continue; @@ -1258,6 +1265,15 @@ SourceResultType PhysicalRecursiveCTEStateScan::GetDataFromState(DataChunk &chun } } +ProgressData PhysicalRecursiveCTEStateScan::GetProgress(ClientContext &context, GlobalSourceState &gstate_p) const { + auto &gstate = gstate_p.Cast(); + idx_t total_groups = gstate.total_groups; + ProgressData progress; + progress.total = static_cast(MaxValue(total_groups, 1)); + progress.done = static_cast(MinValue(gstate.scanned_groups, total_groups)); + return progress; +} + InsertionOrderPreservingMap PhysicalRecursiveCTEStateScan::ParamsToString() const { InsertionOrderPreservingMap result; result["CTE Index"] = StringUtil::Format("%llu", cte_index.index); @@ -1350,30 +1366,38 @@ SinkCombineResultType PhysicalRecursiveCTE::Combine(ExecutionContext &context, O SourceResultType PhysicalRecursiveCTE::GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const { auto &gstate = sink_state->Cast(); - return gstate.GetData(context, chunk); + return gstate.GetData(context, chunk, input.global_state.Cast()); } -SourceResultType RecursiveCTEState::GetData(ExecutionContext &context, DataChunk &chunk) { +unique_ptr PhysicalRecursiveCTE::GetGlobalSourceState(ClientContext &context) const { + return make_uniq(); +} + +SourceResultType RecursiveCTEState::GetData(ExecutionContext &context, DataChunk &chunk, + RecursiveCTEGlobalSourceState &source) { if (source_phase == RecursiveCTESourcePhase::INITIAL) { if (op.using_key) { source_phase = RecursiveCTESourcePhase::RECURSING_KEY; } else { CurrentOutputTable().InitializeScan(scan_state); + source.StartIteration(CurrentOutputTable().Count()); source_phase = RecursiveCTESourcePhase::SCANNING_UNION; } } - return op.using_key ? GetUsingKeyData(context, chunk) : GetUnionData(context, chunk); + return op.using_key ? GetUsingKeyData(context, chunk, source) : GetUnionData(context, chunk, source); } -SourceResultType RecursiveCTEState::GetUsingKeyData(ExecutionContext &context, DataChunk &chunk) { +SourceResultType RecursiveCTEState::GetUsingKeyData(ExecutionContext &context, DataChunk &chunk, + RecursiveCTEGlobalSourceState &source) { if (metrics.Enabled()) { - return GetUsingKeyDataInternal(context, chunk); + return GetUsingKeyDataInternal(context, chunk, source); } - return GetUsingKeyDataInternal(context, chunk); + return GetUsingKeyDataInternal(context, chunk, source); } template -SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &context, DataChunk &chunk) { +SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &context, DataChunk &chunk, + RecursiveCTEGlobalSourceState &source) { D_ASSERT(op.using_key); while (true) { switch (source_phase) { @@ -1388,6 +1412,7 @@ SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &co expected_new = op.working_table->Count(); if (expected_new == 0) { ht->InitializeScan(ht_scan_state); + source.StartFinalDrain(ht->Count()); source_phase = RecursiveCTESourcePhase::DRAINING_FINAL_KEY_STATE; break; } @@ -1405,6 +1430,7 @@ SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &co const auto next_count = op.union_all ? intermediate_table.Count() : op.working_table->Count(); if (next_count == 0) { ht->InitializeScan(ht_scan_state); + source.StartFinalDrain(ht->Count()); source_phase = RecursiveCTESourcePhase::DRAINING_FINAL_KEY_STATE; } break; @@ -1417,6 +1443,7 @@ SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &co continue; } AssembleStateRows(source_distinct_rows, source_aggregate_rows, chunk); + source.AddEmittedRows(chunk.size()); if constexpr (COLLECT_METRICS) { metrics.RecordFinalStateRows(chunk.size()); const auto drain_end = std::chrono::steady_clock::now(); @@ -1431,6 +1458,7 @@ SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &co std::chrono::duration_cast(drain_end - drain_start).count())); } source_phase = RecursiveCTESourcePhase::FINISHED; + source.Finish(); break; } case RecursiveCTESourcePhase::FINISHED: @@ -1441,13 +1469,15 @@ SourceResultType RecursiveCTEState::GetUsingKeyDataInternal(ExecutionContext &co } } -SourceResultType RecursiveCTEState::GetUnionData(ExecutionContext &context, DataChunk &chunk) { +SourceResultType RecursiveCTEState::GetUnionData(ExecutionContext &context, DataChunk &chunk, + RecursiveCTEGlobalSourceState &source) { D_ASSERT(!op.using_key); while (chunk.size() == 0) { if (source_phase == RecursiveCTESourcePhase::SCANNING_UNION) { // scan any chunks we have collected so far CurrentOutputTable().Scan(scan_state, chunk); if (chunk.size() != 0) { + source.AddEmittedRows(chunk.size()); break; } } else if (source_phase == RecursiveCTESourcePhase::FINISHED) { @@ -1514,16 +1544,75 @@ SourceResultType RecursiveCTEState::GetUnionData(ExecutionContext &context, Data // if not, we are done if (CurrentOutputTable().Count() == 0) { source_phase = RecursiveCTESourcePhase::FINISHED; + source.Finish(); break; } // set up the scan again CurrentOutputTable().InitializeScan(scan_state); + source.StartIteration(CurrentOutputTable().Count()); } } return chunk.size() == 0 ? SourceResultType::FINISHED : SourceResultType::HAVE_MORE_OUTPUT; } +void RecursiveCTEGlobalSourceState::StartIteration(idx_t row_count) { + lock_guard guard(iteration_lock); + if (iterations == 0) { + anchor_rows = row_count; + } + iterations++; + iteration_start_rows = emitted_rows.load(std::memory_order_relaxed); + previous_iteration_rows = iteration_rows; + iteration_rows = row_count; +} + +void RecursiveCTEGlobalSourceState::StartFinalDrain(idx_t row_count) { + lock_guard guard(iteration_lock); + draining = true; + iteration_start_rows = emitted_rows.load(std::memory_order_relaxed); + iteration_rows = row_count; +} + +ProgressData RecursiveCTEGlobalSourceState::GetProgress() { + if (finished.load(std::memory_order_relaxed)) { + return ProgressData {1.0, 1.0, false}; + } + auto emitted = static_cast(emitted_rows.load(std::memory_order_relaxed)); + double fraction; + { + lock_guard guard(iteration_lock); + if (draining) { + // the final state of a USING KEY recursion is emitted in one go - its size is known + auto total = static_cast(iteration_start_rows + iteration_rows); + fraction = total == 0 ? 1.0 : emitted / total; + } else { + // the total number of rows is unknown - converge towards 100% as rows are emitted, logarithmically in the + // number of rows relative to the first iteration (50% after one anchor's worth of rows, 67% after 3, 91% + // after ~1000) + auto anchor = static_cast(MaxValue(anchor_rows, 1)); + fraction = 1 - 1 / (1 + std::log2(1 + emitted / anchor)); + // if the iterations are shrinking, extrapolate the remaining rows as a geometric series + if (iteration_rows < previous_iteration_rows) { + auto current = static_cast(iteration_rows); + auto ratio = current / static_cast(previous_iteration_rows); + auto total = static_cast(iteration_start_rows) + current + current * ratio / (1 - ratio); + if (total > 0) { + fraction = MaxValue(fraction, emitted / total); + } + } + // we are not done until the recursion finishes + fraction = MinValue(fraction, 0.999); + } + } + // the estimate can drop when an iteration is larger than expected + return progress.Update(ProgressData {MinValue(fraction, 1.0), 1.0, false}); +} + +ProgressData PhysicalRecursiveCTE::GetProgress(ClientContext &context, GlobalSourceState &gstate) const { + return gstate.Cast().GetProgress(); +} + vector> PhysicalRecursiveCTE::GetSources() const { return {*this}; } diff --git a/src/duckdb/src/execution/radix_partitioned_hashtable.cpp b/src/duckdb/src/execution/radix_partitioned_hashtable.cpp index b323e5235..f39849a21 100644 --- a/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +++ b/src/duckdb/src/execution/radix_partitioned_hashtable.cpp @@ -90,7 +90,7 @@ enum class AggregatePartitionState : uint8_t { struct AggregatePartition : StateWithBlockableTasks { explicit AggregatePartition(unique_ptr data_p) - : state(AggregatePartitionState::READY_TO_FINALIZE), data(std::move(data_p)), progress(0) { + : state(AggregatePartitionState::READY_TO_FINALIZE), data(std::move(data_p)) { } AggregatePartitionState state; @@ -102,7 +102,22 @@ struct AggregatePartition : StateWithBlockableTasks { shared_ptr allocator; //! Arena holding the imported states (combining may steal from them, so it must live as long) shared_ptr import_allocator; - atomic progress; + //! Combine progress of this partition + atomic combine_chunk_count {0}; + atomic combined_chunks {0}; + atomic finalized {false}; + + double GetCombineProgress() const { + if (finalized.load(std::memory_order_relaxed)) { + return 1; + } + auto chunk_count = combine_chunk_count.load(std::memory_order_relaxed); + if (chunk_count == 0) { + return 0; + } + auto combined = MinValue(combined_chunks.load(std::memory_order_relaxed), chunk_count); + return static_cast(combined) / static_cast(chunk_count); + } }; class RadixHTGlobalSinkState; @@ -1023,7 +1038,7 @@ void RadixPartitionedHashTable::Finalize(ClientContext &context, GlobalSinkState gstate.max_partition_size = MaxValue(gstate.max_partition_size, partition_size); if (single_ht) { gstate.finalize_done++; - gstate.partitions.back()->progress = 1; + gstate.partitions.back()->finalized = true; gstate.partitions.back()->state = AggregatePartitionState::READY_TO_SCAN; } } @@ -1092,6 +1107,12 @@ class RadixHTGlobalSourceState : public GlobalSourceState { //! For synchronizing tasks atomic task_idx; atomic task_done; + //! Scan progress: the partitions whose scan started, the rows in these partitions, and the rows scanned + atomic started_partitions; + atomic started_rows; + atomic scanned_rows; + //! The scan progress estimate drops when a larger partition starts scanning + MonotonicProgress scan_progress; }; enum class RadixHTScanStatus : uint8_t { INIT, IN_PROGRESS, DONE }; @@ -1146,10 +1167,15 @@ void RadixPartitionedHashTable::ResetGlobalSourceState(ClientContext &context, G gstate.finished = false; gstate.task_idx = 0; gstate.task_done = 0; + gstate.started_partitions = 0; + gstate.started_rows = 0; + gstate.scanned_rows = 0; + gstate.scan_progress.Reset(); } RadixHTGlobalSourceState::RadixHTGlobalSourceState(ClientContext &context_p, const RadixPartitionedHashTable &radix_ht) - : context(context_p), finished(false), task_idx(0), task_done(0) { + : context(context_p), finished(false), task_idx(0), task_done(0), started_partitions(0), started_rows(0), + scanned_rows(0) { for (column_t column_id = 0; column_id < radix_ht.group_types.size(); column_id++) { column_ids.push_back(column_id); } @@ -1259,7 +1285,8 @@ void RadixHTLocalSourceState::Finalize(RadixHTGlobalSinkState &sink, RadixHTGlob } // Now combine the uncombined data using this thread's HT - ht->Combine(*partition.data, &partition.progress); + partition.combine_chunk_count = partition.data->ChunkCount(); + ht->Combine(*partition.data, &partition.combined_chunks); if (partition.exported_data) { // Rebuild the exported states on an arena of their own, one chunk at a time, and combine // them like the rest. Combining may steal from the imported states, so the arena lives @@ -1270,7 +1297,7 @@ void RadixHTLocalSourceState::Finalize(RadixHTGlobalSinkState &sink, RadixHTGlob [&](TupleDataCollection &imported) { ht->Combine(imported); }); partition.exported_data.reset(); } - partition.progress = 1; + partition.finalized = true; // Move the combined data back to the partition partition.data = @@ -1317,6 +1344,8 @@ void RadixHTLocalSourceState::Scan(RadixHTGlobalSinkState &sink, RadixHTGlobalSo if (scan_status == RadixHTScanStatus::INIT) { data_collection.InitializeScan(scan_state, gstate.column_ids, sink.scan_pin_properties); scan_status = RadixHTScanStatus::IN_PROGRESS; + gstate.started_rows.fetch_add(data_collection.Count(), std::memory_order_relaxed); + gstate.started_partitions.fetch_add(1, std::memory_order_relaxed); } if (!data_collection.Scan(scan_state, scan_chunk)) { @@ -1333,6 +1362,8 @@ void RadixHTLocalSourceState::Scan(RadixHTGlobalSinkState &sink, RadixHTGlobalSo return; } + gstate.scanned_rows.fetch_add(scan_chunk.size(), std::memory_order_relaxed); + const auto group_cols = layout.ColumnCount() - 1; RowOperations::FinalizeStates(row_state, layout, scan_state.chunk_state.row_locations, scan_chunk, group_cols); @@ -1451,14 +1482,25 @@ ProgressData RadixPartitionedHashTable::GetProgress(ClientContext &, GlobalSinkS // Get partition combine progress, weigh it 2x ProgressData progress; for (auto &partition : sink.partitions) { - progress.done += 2.0 * partition->progress; + progress.done += 2.0 * partition->GetCombineProgress(); } - // Get scan progress, weigh it 1x - progress.done += 1.0 * double(gstate.task_done); + // Get scan progress in partitions, weigh it 1x - weigh the partitions whose scan started by the scanned rows + const auto partition_count = static_cast(sink.partitions.size()); + const auto started_partitions = static_cast(gstate.started_partitions.load(std::memory_order_relaxed)); + const auto started_rows = gstate.started_rows.load(std::memory_order_relaxed); + const auto scanned_rows = gstate.scanned_rows.load(std::memory_order_relaxed); + double scanned_partitions = started_partitions; + if (started_rows > 0) { + scanned_partitions *= + static_cast(MinValue(scanned_rows, started_rows)) / static_cast(started_rows); + } + auto scan_progress = + gstate.scan_progress.Update(ProgressData {scanned_partitions, MaxValue(partition_count, 1.0), false}); + progress.done += 1.0 * scan_progress.done; // Divide by 3x for the weights, and the number of partitions to get a value between 0 and 1 again - progress.total += 3.0 * double(sink.partitions.size()); + progress.total += 3.0 * partition_count; return progress; } diff --git a/src/duckdb/src/function/cast/variant/to_variant.cpp b/src/duckdb/src/function/cast/variant/to_variant.cpp index 9da98fa7e..d275e2d04 100644 --- a/src/duckdb/src/function/cast/variant/to_variant.cpp +++ b/src/duckdb/src/function/cast/variant/to_variant.cpp @@ -116,10 +116,14 @@ struct VariantCastData : BoundCastData { }; struct VariantLocalData : FunctionLocalState { - explicit VariantLocalData(const LogicalType &shredded_type) { + VariantLocalData(const LogicalType &shredded_type, Allocator &allocator) : allocator(allocator) { Initialize(shredded_type, STANDARD_VECTOR_SIZE); } + //! Allocator for temporary conversion memory (e.g. JSON parsing), backed by the buffer allocator when possible + //! so the memory is tracked + Allocator &allocator; + void Initialize(const LogicalType &shredded_type, idx_t new_capacity) { capacity = new_capacity; shredded_vector = make_uniq(shredded_type, capacity); @@ -147,7 +151,8 @@ struct VariantLocalData : FunctionLocalState { unique_ptr CastToVariantLocalState(CastLocalStateParameters ¶meters) { auto &cast_data = parameters.cast_data->Cast(); - return make_uniq(cast_data.shredded_type); + auto &allocator = parameters.context ? BufferAllocator::Get(*parameters.context) : Allocator::DefaultAllocator(); + return make_uniq(cast_data.shredded_type, allocator); } static bool SupportsShreddedCast(const LogicalType &type) { @@ -214,6 +219,7 @@ static bool CastToVARIANT(Vector &source, Vector &result, idx_t count, CastParam if (TryToShreddedCast(source, result, count, parameters)) { return true; } + auto &local_data = parameters.local_state->Cast(); DataChunk offsets; offsets.Initialize(Allocator::DefaultAllocator(), {LogicalType::UINTEGER, LogicalType::UINTEGER, LogicalType::UINTEGER, LogicalType::UINTEGER}, @@ -229,7 +235,7 @@ static bool CastToVARIANT(Vector &source, Vector &result, idx_t count, CastParam { VariantVectorData variant_data(result); - ToVariantGlobalResultData result_data(variant_data, offsets, dictionary, keys_selvec); + ToVariantGlobalResultData result_data(variant_data, offsets, dictionary, keys_selvec, local_data.allocator); if (!GatherOffsetsAndSizes(source_data, result_data, count)) { return false; } @@ -241,7 +247,7 @@ static bool CastToVARIANT(Vector &source, Vector &result, idx_t count, CastParam { VariantVectorData variant_data(result); - ToVariantGlobalResultData result_data(variant_data, offsets, dictionary, keys_selvec); + ToVariantGlobalResultData result_data(variant_data, offsets, dictionary, keys_selvec, local_data.allocator); if (!WriteVariantResultData(source_data, result_data, count)) { return false; } diff --git a/src/duckdb/src/function/scalar/string/like.cpp b/src/duckdb/src/function/scalar/string/like.cpp index a9cd8250c..133b1738b 100644 --- a/src/duckdb/src/function/scalar/string/like.cpp +++ b/src/duckdb/src/function/scalar/string/like.cpp @@ -185,40 +185,50 @@ template ( - sdata + sidx, slen - sidx, pdata + pidx, plen - pidx, escape)) { - return true; + READER::NextCharacter(sdata, slen, sidx); + continue; + } else if (pchar == PERCENTAGE) { + pidx++; + while (pidx < plen && pdata[pidx] == PERCENTAGE) { + pidx++; } + if (pidx == plen) { + return true; /* tail is acceptable */ + } + has_percentage = true; + retry_pidx = pidx; + retry_sidx = sidx; + continue; + } else if (pchar == schar) { + pidx++; + sidx++; + continue; } - return false; - } else if (pchar == schar) { - sidx++; - } else { + } + if (!has_percentage) { return false; } + pidx = retry_pidx; + sidx = ++retry_sidx; } // a trailing '%' only matches an empty suffix when it is not escaped while (pidx < plen) { diff --git a/src/duckdb/src/function/table/glob.cpp b/src/duckdb/src/function/table/glob.cpp index b9ca555ab..ed269d241 100644 --- a/src/duckdb/src/function/table/glob.cpp +++ b/src/duckdb/src/function/table/glob.cpp @@ -1,9 +1,13 @@ #include "duckdb/function/table/range.hpp" #include "duckdb/function/table_function.hpp" #include "duckdb/function/function_set.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/common/file_system.hpp" #include "duckdb/main/config.hpp" #include "duckdb/common/multi_file/multi_file_reader.hpp" +#include "duckdb/execution/progress_data.hpp" + +#include namespace duckdb { @@ -22,10 +26,13 @@ static unique_ptr GlobFunctionBind(ClientContext &context, TableFu } struct GlobFunctionState : public GlobalTableFunctionState { - GlobFunctionState() { + GlobFunctionState() : files_returned(0) { } MultiFileListScanData file_list_scan; + atomic files_returned; + //! The progress is estimated while the glob is being expanded - keeps it monotonic + MonotonicProgress progress; }; static unique_ptr GlobFunctionInit(ClientContext &context, TableFunctionInitInput &input) { @@ -53,10 +60,31 @@ static void GlobFunction(ClientContext &context, TableFunctionInput &data_p, Dat count++; state.file_list_scan.scan_type = MultiFileListScanType::FETCH_IF_AVAILABLE; } + state.files_returned.fetch_add(count, std::memory_order_relaxed); +} + +static double GlobFunctionProgress(ClientContext &context, const FunctionData *bind_data_p, + const GlobalTableFunctionState *global_state) { + auto &bind_data = bind_data_p->Cast(); + auto &state = global_state->Cast(); + auto files_returned = static_cast(state.files_returned.load(std::memory_order_relaxed)); + // only look at the files that have been expanded so far - expanding the glob here would perform I/O + auto file_count = bind_data.file_list->GetFileCount(0); + double fraction; + if (file_count.type == FileExpansionType::ALL_FILES_EXPANDED) { + fraction = file_count.count == 0 ? 1.0 : files_returned / static_cast(file_count.count); + } else { + // the number of files is not known yet - converge towards 100% as files are returned + fraction = 1 - 1 / (1 + std::log2(1 + files_returned / static_cast(STANDARD_VECTOR_SIZE))); + fraction = MinValue(fraction, 0.99); + } + auto result = state.progress.Update(ProgressData {MinValue(fraction, 1.0), 1.0, false}); + return 100.0 * result.done; } void GlobTableFunction::RegisterFunction(BuiltinFunctions &set) { TableFunction glob_function("glob", {LogicalType::VARCHAR}, GlobFunction, GlobFunctionBind, GlobFunctionInit); + glob_function.table_scan_progress = GlobFunctionProgress; set.AddFunction(MultiFileReader::CreateFunctionSet(glob_function)); } diff --git a/src/duckdb/src/function/table/range.cpp b/src/duckdb/src/function/table/range.cpp index 40a7d1e91..353a0124a 100644 --- a/src/duckdb/src/function/table/range.cpp +++ b/src/duckdb/src/function/table/range.cpp @@ -4,6 +4,7 @@ #include "duckdb/function/function_set.hpp" #include "duckdb/common/operator/add.hpp" #include "duckdb/common/operator/subtract.hpp" +#include "duckdb/common/atomic.hpp" namespace duckdb { @@ -69,10 +70,36 @@ static unique_ptr RangeFunctionBind(ClientContext &context, TableF return make_uniq(input.inputs, GENERATE_SERIES); } +//! Progress of a range used as a source (i.e. with a single input row) +struct RangeFunctionGlobalState : public GlobalTableFunctionState { + //! The number of values of the input rows, and the number of values that were generated + atomic total_values {0}; + atomic generated_values {0}; +}; + +static unique_ptr RangeFunctionGlobalInit(ClientContext &context, + TableFunctionInitInput &input) { + return make_uniq(); +} + +static double RangeFunctionProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &state = global_state->Cast(); + auto total = state.total_values.load(std::memory_order_relaxed); + if (total == 0) { + return 0; + } + auto generated = MinValue(state.generated_values.load(std::memory_order_relaxed), total); + return 100.0 * static_cast(generated) / static_cast(total); +} + struct RangeFunctionLocalState : public LocalTableFunctionState { - RangeFunctionLocalState() { + explicit RangeFunctionLocalState(optional_ptr global_state) + : global_state(global_state ? &global_state->Cast() : nullptr) { } + optional_ptr global_state; + bool initialized_row = false; idx_t current_input_row = 0; idx_t current_idx = 0; @@ -80,6 +107,8 @@ struct RangeFunctionLocalState : public LocalTableFunctionState { hugeint_t start; hugeint_t end; hugeint_t increment; + //! The number of values generated for the current input row + idx_t row_count = 0; bool empty_range = false; }; @@ -87,7 +116,7 @@ struct RangeFunctionLocalState : public LocalTableFunctionState { static unique_ptr RangeFunctionLocalInit(ExecutionContext &context, TableFunctionInitInput &input, GlobalTableFunctionState *global_state) { - return make_uniq(); + return make_uniq(global_state); } template @@ -98,6 +127,7 @@ static void GenerateRangeParameters(DataChunk &input, idx_t row_id, RangeFunctio result.start = GENERATE_SERIES ? 1 : 0; result.end = 0; result.increment = 1; + result.row_count = 0; return; } } @@ -127,6 +157,18 @@ static void GenerateRangeParameters(DataChunk &input, idx_t row_id, RangeFunctio result.end = result.end + 1; } } + if (result.empty_range) { + result.row_count = 0; + } else { + auto difference = result.end - result.start; + auto row_count = difference / result.increment; + if (difference % result.increment != 0) { + row_count += 1; + } + if (!Hugeint::TryCast(row_count, result.row_count)) { + result.row_count = NumericLimits::Maximum(); + } + } } template @@ -145,6 +187,9 @@ static OperatorResultType RangeFunction(ExecutionContext &context, TableFunction GenerateRangeParameters(input, state.current_input_row, state); state.initialized_row = true; state.current_idx = 0; + if (state.global_state) { + state.global_state->total_values.fetch_add(state.row_count, std::memory_order_relaxed); + } } if (state.empty_range) { // empty range @@ -175,6 +220,9 @@ static OperatorResultType RangeFunction(ExecutionContext &context, TableFunction state.initialized_row = false; continue; } + if (state.global_state) { + state.global_state->generated_values.fetch_add(remaining, std::memory_order_relaxed); + } return OperatorResultType::HAVE_MORE_OUTPUT; } } @@ -243,10 +291,44 @@ unique_ptr RangeDateTimeCardinality(ClientContext &context, cons return make_uniq(bind_data.cardinality, bind_data.cardinality); } +//! Progress of a timestamp range used as a source (i.e. with a single input row) +struct RangeDateTimeGlobalState : public GlobalTableFunctionState { + //! The bounds of the range, and the timestamp that is generated next + atomic start {0}; + atomic end {0}; + atomic current {0}; + + void Initialize(timestamp_t start_p, timestamp_t end_p) { + start.store(start_p.value, std::memory_order_relaxed); + end.store(end_p.value, std::memory_order_relaxed); + current.store(start_p.value, std::memory_order_relaxed); + } +}; + +static unique_ptr RangeDateTimeGlobalInit(ClientContext &context, + TableFunctionInitInput &input) { + return make_uniq(); +} + +static double RangeDateTimeProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &state = global_state->Cast(); + auto start = static_cast(state.start.load(std::memory_order_relaxed)); + auto range = static_cast(state.end.load(std::memory_order_relaxed)) - start; + if (range == 0) { + return 0; + } + auto fraction = (static_cast(state.current.load(std::memory_order_relaxed)) - start) / range; + return 100.0 * MaxValue(MinValue(fraction, 1.0), 0.0); +} + struct RangeDateTimeLocalState : public LocalTableFunctionState { - RangeDateTimeLocalState() { + explicit RangeDateTimeLocalState(optional_ptr global_state) + : global_state(global_state ? &global_state->Cast() : nullptr) { } + optional_ptr global_state; + bool initialized_row = false; idx_t current_input_row = 0; timestamp_t current_state; @@ -332,7 +414,7 @@ static void GenerateRangeDateTimeParameters(DataChunk &input, idx_t row_id, Rang static unique_ptr RangeDateTimeLocalInit(ExecutionContext &context, TableFunctionInitInput &input, GlobalTableFunctionState *global_state) { - return make_uniq(); + return make_uniq(global_state); } template @@ -351,6 +433,9 @@ static OperatorResultType RangeDateTimeFunction(ExecutionContext &context, Table GenerateRangeDateTimeParameters(input, state.current_input_row, state); state.initialized_row = true; state.current_state = state.start; + if (state.global_state) { + state.global_state->Initialize(state.start, state.end); + } } if (state.empty_range) { // empty range @@ -379,6 +464,9 @@ static OperatorResultType RangeDateTimeFunction(ExecutionContext &context, Table continue; } output.SetChildCardinality(size); + if (state.global_state) { + state.global_state->current.store(state.current_state.value, std::memory_order_relaxed); + } return OperatorResultType::HAVE_MORE_OUTPUT; } } @@ -390,8 +478,9 @@ static bool RangeIsRepeatable(optional_ptr) { void RangeTableFunction::RegisterFunction(BuiltinFunctions &set) { TableFunctionSet range("range"); - TableFunction range_function({LogicalType::BIGINT}, nullptr, RangeFunctionBind, nullptr, + TableFunction range_function({LogicalType::BIGINT}, nullptr, RangeFunctionBind, RangeFunctionGlobalInit, RangeFunctionLocalInit); + range_function.table_scan_progress = RangeFunctionProgress; range_function.in_out_function = RangeFunction; range_function.cardinality = RangeCardinality; range_function.is_repeatable = RangeIsRepeatable; @@ -407,7 +496,8 @@ void RangeTableFunction::RegisterFunction(BuiltinFunctions &set) { range_function.GetArguments() = {LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT}; range.AddFunction(range_function); TableFunction range_in_out({LogicalType::TIMESTAMP, LogicalType::TIMESTAMP, LogicalType::INTERVAL}, nullptr, - RangeDateTimeBind, nullptr, RangeDateTimeLocalInit); + RangeDateTimeBind, RangeDateTimeGlobalInit, RangeDateTimeLocalInit); + range_in_out.table_scan_progress = RangeDateTimeProgress; range_in_out.in_out_function = RangeDateTimeFunction; range_in_out.cardinality = RangeDateTimeCardinality; range_in_out.is_repeatable = RangeIsRepeatable; @@ -427,7 +517,9 @@ void RangeTableFunction::RegisterFunction(BuiltinFunctions &set) { range_function.GetArguments() = {LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BIGINT}; generate_series.AddFunction(range_function); TableFunction generate_series_in_out({LogicalType::TIMESTAMP, LogicalType::TIMESTAMP, LogicalType::INTERVAL}, - nullptr, RangeDateTimeBind, nullptr, RangeDateTimeLocalInit); + nullptr, RangeDateTimeBind, RangeDateTimeGlobalInit, + RangeDateTimeLocalInit); + generate_series_in_out.table_scan_progress = RangeDateTimeProgress; generate_series_in_out.in_out_function = RangeDateTimeFunction; generate_series_in_out.is_repeatable = RangeIsRepeatable; generate_series_in_out.parallelism = TableFunctionParallelism::FORCE_SINGLE_THREADED; diff --git a/src/duckdb/src/function/table/system/duckdb_columns.cpp b/src/duckdb/src/function/table/system/duckdb_columns.cpp index 8e5206b5e..5f6bf7e9d 100644 --- a/src/duckdb/src/function/table/system/duckdb_columns.cpp +++ b/src/duckdb/src/function/table/system/duckdb_columns.cpp @@ -1,4 +1,5 @@ #include "duckdb/function/table/system_functions.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/catalog/catalog.hpp" #include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" @@ -19,7 +20,7 @@ struct DuckDBColumnsData : public GlobalTableFunctionState { } vector> entries; - idx_t offset; + atomic offset; idx_t column_offset; }; @@ -414,12 +415,23 @@ static void DuckDBColumnsFunction(ClientContext &context, TableFunctionInput &da } } // WriteColumns appends to the child vectors - record the resulting cardinality on the chunk - data.offset = next; + data.offset.store(next, std::memory_order_relaxed); data.column_offset = column_offset; } +static double DuckDBColumnsProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &data = global_state->Cast(); + if (data.entries.empty()) { + return 100.0; + } + return 100.0 * static_cast(data.offset) / static_cast(data.entries.size()); +} + void DuckDBColumnsFun::RegisterFunction(BuiltinFunctions &set) { - set.AddFunction(TableFunction("duckdb_columns", {}, DuckDBColumnsFunction, DuckDBColumnsBind, DuckDBColumnsInit)); + TableFunction columns("duckdb_columns", {}, DuckDBColumnsFunction, DuckDBColumnsBind, DuckDBColumnsInit); + columns.table_scan_progress = DuckDBColumnsProgress; + set.AddFunction(columns); } } // namespace duckdb diff --git a/src/duckdb/src/function/table/system/duckdb_extensions.cpp b/src/duckdb/src/function/table/system/duckdb_extensions.cpp index 25a05438d..98819818d 100644 --- a/src/duckdb/src/function/table/system/duckdb_extensions.cpp +++ b/src/duckdb/src/function/table/system/duckdb_extensions.cpp @@ -84,11 +84,9 @@ unique_ptr DuckDBExtensionsInit(ClientContext &context auto extension = ExtensionHelper::GetDefaultExtension(i); ExtensionInformation info; info.name = extension.name; - info.installed = extension.statically_loaded; + info.installed = false; info.loaded = false; - info.file_path = extension.statically_loaded ? "(BUILT-IN)" : string(); - info.install_mode = - extension.statically_loaded ? ExtensionInstallMode::STATICALLY_LINKED : ExtensionInstallMode::NOT_INSTALLED; + info.install_mode = ExtensionInstallMode::NOT_INSTALLED; info.description = extension.description; for (idx_t k = 0; k < alias_count; k++) { auto alias = ExtensionHelper::GetInternalExtensionAlias(k); @@ -99,6 +97,15 @@ unique_ptr DuckDBExtensionsInit(ClientContext &context installed_extensions[info.name] = std::move(info); } + // Extensions linked into this binary are built in, whether or not the default list knows them + for (auto &linked : DBConfig::GetConfig(db).linked_extensions) { + auto &info = installed_extensions[linked.name]; + info.name = linked.name; + info.installed = true; + info.file_path = "(BUILT-IN)"; + info.install_mode = ExtensionInstallMode::STATICALLY_LINKED; + } + // Secondly we scan all installed extensions and their install info #ifndef WASM_LOADABLE_EXTENSIONS auto ext_directories = ExtensionHelper::GetExtensionDirectoryPath(context); diff --git a/src/duckdb/src/function/table/system/duckdb_external_file_cache.cpp b/src/duckdb/src/function/table/system/duckdb_external_file_cache.cpp index 7085874b6..8e13a4078 100644 --- a/src/duckdb/src/function/table/system/duckdb_external_file_cache.cpp +++ b/src/duckdb/src/function/table/system/duckdb_external_file_cache.cpp @@ -1,4 +1,5 @@ #include "duckdb/function/table/system_functions.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/storage/external_file_cache/external_file_cache.hpp" namespace duckdb { @@ -9,6 +10,8 @@ struct DuckDBExternalFileCacheData : public GlobalTableFunctionState { vector entries; idx_t offset; + //! The offset, published once per chunk (for progress) + atomic progress_offset {0}; }; static unique_ptr DuckDBExternalFileCacheBind(ClientContext &context, TableFunctionBindInput &input, @@ -69,11 +72,24 @@ void DuckDBExternalFileCacheFunction(ClientContext &context, TableFunctionInput spilled.Append(Value::BOOLEAN(entry.spilled)); count++; } + data.progress_offset.store(data.offset, std::memory_order_relaxed); +} + +static double DuckDBExternalFileCacheProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &data = global_state->Cast(); + if (data.entries.empty()) { + return 100.0; + } + auto offset = data.progress_offset.load(std::memory_order_relaxed); + return 100.0 * static_cast(offset) / static_cast(data.entries.size()); } void DuckDBExternalFileCacheFun::RegisterFunction(BuiltinFunctions &set) { - set.AddFunction(TableFunction("duckdb_external_file_cache", {}, DuckDBExternalFileCacheFunction, - DuckDBExternalFileCacheBind, DuckDBExternalFileCacheInit)); + TableFunction function("duckdb_external_file_cache", {}, DuckDBExternalFileCacheFunction, + DuckDBExternalFileCacheBind, DuckDBExternalFileCacheInit); + function.table_scan_progress = DuckDBExternalFileCacheProgress; + set.AddFunction(function); } } // namespace duckdb diff --git a/src/duckdb/src/function/table/system/duckdb_functions.cpp b/src/duckdb/src/function/table/system/duckdb_functions.cpp index 1e807837f..240bc4639 100644 --- a/src/duckdb/src/function/table/system/duckdb_functions.cpp +++ b/src/duckdb/src/function/table/system/duckdb_functions.cpp @@ -1,4 +1,5 @@ #include "duckdb/function/table/system_functions.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/catalog/catalog.hpp" #include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp" @@ -28,6 +29,8 @@ struct DuckDBFunctionsData : public GlobalTableFunctionState { vector> entries; idx_t offset; idx_t offset_in_entry; + //! The offset, published once per chunk (for progress) + atomic progress_offset {0}; }; static unique_ptr DuckDBFunctionsBind(ClientContext &context, TableFunctionBindInput &input, @@ -805,11 +808,23 @@ void DuckDBFunctionsFunction(ClientContext &context, TableFunctionInput &data_p, } count++; } + data.progress_offset.store(data.offset, std::memory_order_relaxed); +} + +static double DuckDBFunctionsProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &data = global_state->Cast(); + if (data.entries.empty()) { + return 100.0; + } + auto offset = data.progress_offset.load(std::memory_order_relaxed); + return 100.0 * static_cast(offset) / static_cast(data.entries.size()); } void DuckDBFunctionsFun::RegisterFunction(BuiltinFunctions &set) { - set.AddFunction( - TableFunction("duckdb_functions", {}, DuckDBFunctionsFunction, DuckDBFunctionsBind, DuckDBFunctionsInit)); + TableFunction functions("duckdb_functions", {}, DuckDBFunctionsFunction, DuckDBFunctionsBind, DuckDBFunctionsInit); + functions.table_scan_progress = DuckDBFunctionsProgress; + set.AddFunction(functions); } } // namespace duckdb diff --git a/src/duckdb/src/function/table/system/duckdb_log.cpp b/src/duckdb/src/function/table/system/duckdb_log.cpp index dfa8ca71f..9287bb4ca 100644 --- a/src/duckdb/src/function/table/system/duckdb_log.cpp +++ b/src/duckdb/src/function/table/system/duckdb_log.cpp @@ -13,6 +13,7 @@ struct DuckDBLogData : public GlobalTableFunctionState { explicit DuckDBLogData(shared_ptr log_storage_p) : log_storage(std::move(log_storage_p)) { scan_state = log_storage->CreateScanState(LoggingTargetTable::LOG_ENTRIES); log_storage->InitializeScan(*scan_state); + total_rows = log_storage->GetScanRowCount(LoggingTargetTable::LOG_ENTRIES); } DuckDBLogData() : log_storage(nullptr) { } @@ -20,6 +21,9 @@ struct DuckDBLogData : public GlobalTableFunctionState { //! The log storage we are scanning shared_ptr log_storage; unique_ptr scan_state; + //! The number of log entries when the scan started, if known (for progress) + optional_idx total_rows; + atomic scanned_rows {0}; }; static unique_ptr DuckDBLogBind(ClientContext &context, TableFunctionBindInput &input, @@ -53,9 +57,27 @@ void DuckDBLogFunction(ClientContext &context, TableFunctionInput &data_p, DataC auto &data = data_p.global_state->Cast(); if (data.log_storage) { data.log_storage->Scan(*data.scan_state, output); + data.scanned_rows.fetch_add(output.size(), std::memory_order_relaxed); } } +static double DuckDBLogProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &data = global_state->Cast(); + if (!data.log_storage) { + return 100.0; + } + if (!data.total_rows.IsValid()) { + return -1; + } + auto total_rows = data.total_rows.GetIndex(); + if (total_rows == 0) { + return 100.0; + } + // log entries that are added while scanning are not part of the total + return MinValue(100.0 * static_cast(data.scanned_rows) / static_cast(total_rows), 100.0); +} + unique_ptr DuckDBLogBindReplace(ClientContext &context, TableFunctionBindInput &input) { auto log_storage = LogManager::Get(context).GetLogStorage(); @@ -96,6 +118,7 @@ unique_ptr DuckDBLogBindReplace(ClientContext &context, TableFunctionB void DuckDBLogFun::RegisterFunction(BuiltinFunctions &set) { TableFunction logs_fun("duckdb_logs", {}, DuckDBLogFunction, DuckDBLogBind, DuckDBLogInit); logs_fun.bind_replace = DuckDBLogBindReplace; + logs_fun.table_scan_progress = DuckDBLogProgress; logs_fun.named_parameters["denormalized_table"] = LogicalType::BOOLEAN; set.AddFunction(logs_fun); } diff --git a/src/duckdb/src/function/table/system/pragma_storage_info.cpp b/src/duckdb/src/function/table/system/pragma_storage_info.cpp index 96e66166a..39bfc7112 100644 --- a/src/duckdb/src/function/table/system/pragma_storage_info.cpp +++ b/src/duckdb/src/function/table/system/pragma_storage_info.cpp @@ -4,11 +4,13 @@ #include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp" #include "duckdb/parser/qualified_name.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/common/mutex.hpp" #include "duckdb/execution/partition_info.hpp" #include "duckdb/parallel/task_scheduler.hpp" #include "duckdb/storage/data_table.hpp" #include "duckdb/storage/table/row_group_collection.hpp" +#include "duckdb/storage/table/row_group_segment_tree.hpp" #include "duckdb/storage/table_storage_info.hpp" #include "duckdb/planner/binder.hpp" #include "duckdb/common/enums/column_segment_info_scan_type.hpp" @@ -31,6 +33,9 @@ struct PragmaStorageGlobalState : public GlobalTableFunctionState { mutex lock; idx_t max_threads; ColumnSegmentInfoScanState scan_state; + //! The total number of row groups and the number of row groups that were scanned (for progress) + idx_t total_row_groups = 0; + atomic scanned_row_groups {0}; idx_t MaxThreads() const override { return max_threads; @@ -125,6 +130,12 @@ unique_ptr PragmaStorageInfoInitGlobal(ClientContext & auto gstate = make_uniq(max_threads); gstate->scan_state.options = bind_data.options; bind_data.table_entry.InitializeColumnSegmentInfoScan(gstate->scan_state); + if (gstate->scan_state.row_groups) { + for (auto &row_group : gstate->scan_state.row_groups->SegmentNodes()) { + (void)row_group; + gstate->total_row_groups++; + } + } return std::move(gstate); } @@ -177,6 +188,9 @@ static void PragmaStorageInfoFunction(ClientContext &context, TableFunctionInput { lock_guard guard(gstate.lock); has_more = bind_data.table_entry.ScanColumnSegmentInfo(query_context, gstate.scan_state, lstate.buffer); + if (has_more) { + gstate.scanned_row_groups.fetch_add(1, std::memory_order_relaxed); + } } if (!has_more) { break; @@ -228,6 +242,16 @@ static void PragmaStorageInfoFunction(ClientContext &context, TableFunctionInput } } +static double PragmaStorageInfoProgress(ClientContext &context, const FunctionData *bind_data_p, + const GlobalTableFunctionState *global_state) { + auto &gstate = global_state->Cast(); + if (gstate.total_row_groups == 0) { + return 100.0; + } + auto scanned = MinValue(gstate.scanned_row_groups, gstate.total_row_groups); + return 100.0 * static_cast(scanned) / static_cast(gstate.total_row_groups); +} + static OperatorPartitionData PragmaStorageInfoGetPartitionData(ClientContext &context, TableFunctionGetPartitionInput &input) { auto &lstate = input.local_state->Cast(); @@ -238,6 +262,7 @@ void PragmaStorageInfo::RegisterFunction(BuiltinFunctions &set) { TableFunction storage_info("pragma_storage_info", {LogicalType::VARCHAR}, PragmaStorageInfoFunction, PragmaStorageInfoBind, PragmaStorageInfoInitGlobal, PragmaStorageInfoInitLocal); storage_info.get_partition_data = PragmaStorageInfoGetPartitionData; + storage_info.table_scan_progress = PragmaStorageInfoProgress; storage_info.named_parameters["include_segment_info"] = LogicalType::BOOLEAN; storage_info.named_parameters["loaded_segments_only"] = LogicalType::BOOLEAN; set.AddFunction(std::move(storage_info)); diff --git a/src/duckdb/src/function/table/system/test_vector_types.cpp b/src/duckdb/src/function/table/system/test_vector_types.cpp index a91964061..2a0a74258 100644 --- a/src/duckdb/src/function/table/system/test_vector_types.cpp +++ b/src/duckdb/src/function/table/system/test_vector_types.cpp @@ -1,4 +1,5 @@ #include "duckdb/common/vector/flat_vector.hpp" +#include "duckdb/common/atomic.hpp" #include "duckdb/common/vector/list_vector.hpp" #include "duckdb/common/vector/map_vector.hpp" #include "duckdb/common/vector/struct_vector.hpp" @@ -21,7 +22,7 @@ struct TestVectorTypesData : public GlobalTableFunctionState { } vector> entries; - idx_t offset; + atomic offset; }; struct TestVectorInfo { @@ -329,7 +330,16 @@ void TestVectorTypesFunction(ClientContext &context, TableFunctionInput &data_p, return; } output.Reference(*data.entries[data.offset]); - data.offset++; + data.offset.fetch_add(1, std::memory_order_relaxed); +} + +static double TestVectorTypesProgress(ClientContext &context, const FunctionData *bind_data, + const GlobalTableFunctionState *global_state) { + auto &data = global_state->Cast(); + if (data.entries.empty()) { + return 100.0; + } + return 100.0 * static_cast(data.offset) / static_cast(data.entries.size()); } void TestVectorTypesFun::RegisterFunction(BuiltinFunctions &set) { @@ -337,6 +347,7 @@ void TestVectorTypesFun::RegisterFunction(BuiltinFunctions &set) { TestVectorTypesBind, TestVectorTypesInit); test_vector_types.SetVarArgs(LogicalType::ANY); test_vector_types.named_parameters["all_flat"] = LogicalType::BOOLEAN; + test_vector_types.table_scan_progress = TestVectorTypesProgress; set.AddFunction(std::move(test_vector_types)); } diff --git a/src/duckdb/src/function/table/table_scan.cpp b/src/duckdb/src/function/table/table_scan.cpp index 840a00e97..7b47f9b46 100644 --- a/src/duckdb/src/function/table/table_scan.cpp +++ b/src/duckdb/src/function/table/table_scan.cpp @@ -62,6 +62,44 @@ static unique_ptr CreateTableScanReadAhead(ClientContext &context return ScanReadAhead::Create(context); } +//! Tracks how many rows of a scan assignment have been consumed, for reporting progress +struct ScanAssignmentProgress { + //! Rows of the current assignment + idx_t assignment_rows = 0; + //! Rows of the current assignment that were counted as scanned + idx_t reported_rows = 0; + + void Start(idx_t rows) { + assignment_rows = rows; + reported_rows = 0; + } + //! Returns the rows consumed since the last update + idx_t Update(const TableScanState &scan_state) { + idx_t remaining = 0; + if (scan_state.table_state.GetRowGroup()) { + remaining = scan_state.table_state.RemainingAssignmentRows(); + } else if (scan_state.local_state.GetRowGroup()) { + remaining = scan_state.local_state.RemainingAssignmentRows(); + } + auto consumed = assignment_rows - MinValue(remaining, assignment_rows); + return Report(consumed); + } + //! Returns the rows of the assignment that were not yet counted + idx_t Finish() { + return Report(assignment_rows); + } + +private: + idx_t Report(idx_t consumed) { + if (consumed <= reported_rows) { + return 0; + } + auto delta = consumed - reported_rows; + reported_rows = consumed; + return delta; + } +}; + struct TableScanLocalState : public LocalTableFunctionState { //! The current position in the scan. TableScanState scan_state; @@ -72,6 +110,8 @@ struct TableScanLocalState : public LocalTableFunctionState { unique_ptr job; //! Rows scanned by finished read-ahead jobs, folded in when their scan state is recycled idx_t job_rows_scanned = 0; + //! Consumed rows of the assignment (or read-ahead job) currently being scanned + ScanAssignmentProgress assignment_progress; idx_t row_groups_scanned = 0; }; @@ -321,8 +361,8 @@ class DuckTableScanState : public TableScanGlobalState { //! Batch index assigned to the next produced job idx_t next_job_index = 0; ScanStatePool state_pool; - //! Rows claimed by read-ahead jobs that no thread is decoding yet - atomic queued_rows {0}; + //! Rows of claimed assignments that have been consumed by a scan + atomic scanned_rows {0}; public: //! Retains the scan initialization info shared by all scan states of this scan @@ -362,13 +402,21 @@ class DuckTableScanState : public TableScanGlobalState { //! Claims the next assignment into the thread's own scan state, returns false when none are left bool ClaimAssignment(ClientContext &context, TableScanLocalState &l_state) { - if (!storage.NextParallelScan(context, state, l_state.scan_state).IsValid()) { + scanned_rows.fetch_add(l_state.assignment_progress.Finish(), std::memory_order_relaxed); + auto rows = storage.NextParallelScan(context, state, l_state.scan_state); + if (!rows.IsValid()) { return false; } + l_state.assignment_progress.Start(rows.GetIndex()); l_state.row_groups_scanned++; return true; } + //! Counts the rows of the current assignment that were consumed by the scan + void UpdateScanProgress(TableScanLocalState &l_state, const TableScanState &scan_state) { + scanned_rows.fetch_add(l_state.assignment_progress.Update(scan_state), std::memory_order_relaxed); + } + //! How TableScanFunc's loop proceeds after a persistent scan iteration enum class PersistentScanResult { YIELD, NEXT_VECTOR, EXHAUSTED }; @@ -428,7 +476,6 @@ class DuckTableScanState : public TableScanGlobalState { } job->rows = rows.GetIndex(); job->batch_index = next_job_index++; - queued_rows += job->rows; } job->scan_state->InitializeColumnScans(); // preparing the first vector skips the leading vectors the zonemaps or sampling reject before registering I/O @@ -463,14 +510,16 @@ class DuckTableScanState : public TableScanGlobalState { } l_state.job = unique_ptr_cast(std::move(claimed)); l_state.row_groups_scanned++; - queued_rows -= l_state.job->rows; + l_state.assignment_progress.Start(l_state.job->rows); if (acquired == ScanReadAheadAcquire::PARKED) { return true; } } auto &job_scan = *l_state.job->scan_state; // the job's I/O was registered when it was produced, so no I/O is scheduled here - switch (ScanPersistentStorage(context, data_p, l_state, job_scan, output)) { + auto scan_result = ScanPersistentStorage(context, data_p, l_state, job_scan, output); + UpdateScanProgress(l_state, job_scan); + switch (scan_result) { case PersistentScanResult::YIELD: return true; case PersistentScanResult::NEXT_VECTOR: @@ -486,6 +535,7 @@ class DuckTableScanState : public TableScanGlobalState { return true; } // the job is exhausted, fold its scan counters into this thread and recycle its state + scanned_rows.fetch_add(l_state.assignment_progress.Finish(), std::memory_order_relaxed); l_state.job_rows_scanned += job_scan.RowsScanned(); job_scan.table_state.rows_scanned = 0; job_scan.local_state.rows_scanned = 0; @@ -513,6 +563,7 @@ class DuckTableScanState : public TableScanGlobalState { do { if (bind_data.is_create_index) { storage.CreateIndexScan(l_state.scan_state, output); + UpdateScanProgress(l_state, l_state.scan_state); } else if (read_ahead) { if (!ScanWithReadAhead(context, data_p, l_state, output) && data_p.results_execution_mode == AsyncResultsExecutionMode::TASK_EXECUTOR) { @@ -521,7 +572,9 @@ class DuckTableScanState : public TableScanGlobalState { } return; } else { - switch (ScanPersistentStorage(context, data_p, l_state, l_state.scan_state, output)) { + auto scan_result = ScanPersistentStorage(context, data_p, l_state, l_state.scan_state, output); + UpdateScanProgress(l_state, l_state.scan_state); + switch (scan_result) { case PersistentScanResult::YIELD: return; case PersistentScanResult::NEXT_VECTOR: @@ -555,14 +608,11 @@ class DuckTableScanState : public TableScanGlobalState { return 100; } - // queued rows are read first, a claim raises the processed rows before it is queued - const idx_t queued = queued_rows.load(); - idx_t scanned_rows = state.scan_state.processed_rows; - scanned_rows += state.local_state.processed_rows; - // claimed assignments count once a thread decodes them, like they do without read-ahead - D_ASSERT(queued <= scanned_rows); - scanned_rows -= queued; - auto percentage = 100 * (static_cast(scanned_rows) / static_cast(total_rows)); + // rows count once they are consumed by a scan, or when their assignment is skipped entirely + idx_t done_rows = scanned_rows.load(); + done_rows += state.scan_state.skipped_rows.load(); + done_rows += state.local_state.skipped_rows.load(); + auto percentage = 100 * (static_cast(done_rows) / static_cast(total_rows)); if (percentage > 100) { // If the last chunk has fewer elements than STANDARD_VECTOR_SIZE, and if our percentage is over 100, // then we finished this table. diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index 8126c8080..c7743cb10 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "0-alpha43089" +#define DUCKDB_PATCH_VERSION "0-alpha43260" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 0 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 2 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v2.0.0-alpha43089" +#define DUCKDB_VERSION "v2.0.0-alpha43260" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "6844d1bd8b" +#define DUCKDB_SOURCE_ID "233847abfa" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp b/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp index ad184ac33..9ef129c70 100644 --- a/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp +++ b/src/duckdb/src/include/duckdb/common/compressed_file_system.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/atomic.hpp" #include "duckdb/common/common.hpp" #include "duckdb/common/file_system.hpp" #include "duckdb/common/query_context.hpp" @@ -92,7 +93,10 @@ class CompressedFile : public FileHandle { void Clear(); // for Initialize re-use to support FS.Reset() void ResetStreamData(); - idx_t current_position = 0; + //! The number of compressed bytes read from the child handle + idx_t compressed_bytes_read = 0; + //! The number of compressed bytes consumed by the decompressor (for progress) + atomic compressed_bytes_consumed {0}; bool initialized = false; unique_ptr stream_wrapper; }; diff --git a/src/duckdb/src/include/duckdb/common/sorting/sort.hpp b/src/duckdb/src/include/duckdb/common/sorting/sort.hpp index 254f36c8f..e7a21ad69 100644 --- a/src/duckdb/src/include/duckdb/common/sorting/sort.hpp +++ b/src/duckdb/src/include/duckdb/common/sorting/sort.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/atomic.hpp" #include "duckdb/execution/physical_operator_states.hpp" #include "duckdb/execution/progress_data.hpp" #include "duckdb/common/sorting/sort_projection_column.hpp" @@ -82,6 +83,11 @@ class Sort { SinkFinalizeType Finalize(ClientContext &context, OperatorSinkFinalizeInput &input) const; ProgressData GetSinkProgress(ClientContext &context, GlobalSinkState &gstate, const ProgressData source_progress) const; + //! The number of tuples that have been sorted so far + idx_t GetSortedCount(GlobalSinkState &gstate) const; + //! Sink progress of a sort: half of the effort is sinking, half is sorting the sunk tuples + static ProgressData GetSinkProgress(const ProgressData &source_progress, idx_t sorted_count, idx_t sunk_count, + MonotonicProgress &monotonic_progress); public: //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/include/duckdb/common/sorting/sorted_run_merger.hpp b/src/duckdb/src/include/duckdb/common/sorting/sorted_run_merger.hpp index 7ce6f763c..d4b7ee364 100644 --- a/src/duckdb/src/include/duckdb/common/sorting/sorted_run_merger.hpp +++ b/src/duckdb/src/include/duckdb/common/sorting/sorted_run_merger.hpp @@ -39,6 +39,8 @@ class SortedRunMerger { OperatorPartitionData GetPartitionData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, LocalSourceState &lstate, const OperatorPartitionInfo &partition_info) const; ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const; + //! Whether all partitions have been scanned + bool IsFinished(GlobalSourceState &gstate) const; public: //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp b/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp index d3aab0a8a..2ec91041e 100644 --- a/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +++ b/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp @@ -173,7 +173,8 @@ class GroupedAggregateHashTable : public BaseAggregateHashTable { //! Executes the filter(if any) and update the aggregates void Combine(GroupedAggregateHashTable &other); - void Combine(TupleDataCollection &other_data, optional_ptr> progress = nullptr); + //! Combines the data into this HT - combined_chunks (if set) is incremented for every combined chunk + void Combine(TupleDataCollection &other_data, optional_ptr> combined_chunks = nullptr); //! Reset the HT for a new execution while reusing internal allocations where possible void ResetForNewIteration(idx_t radix_bits); diff --git a/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp b/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp index d0af8bdd1..c376a91b8 100644 --- a/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp +++ b/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp @@ -37,11 +37,13 @@ struct JoinHTScanState { public: JoinHTScanState(TupleDataCollection &collection, idx_t chunk_idx_from, idx_t chunk_idx_to, TupleDataPinProperties properties = TupleDataPinProperties::ALREADY_PINNED) - : iterator(collection, properties, chunk_idx_from, chunk_idx_to, false), offset_in_chunk(0) { + : iterator(collection, properties, chunk_idx_from, chunk_idx_to, false), offset_in_chunk(0), chunks_done(0) { } TupleDataChunkIterator iterator; idx_t offset_in_chunk; + //! The number of chunks that have been scanned entirely + idx_t chunks_done; private: //! Implicit copying is not allowed diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_handle.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_handle.hpp index aad2e83ff..2c245b67e 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_handle.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_handle.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/atomic.hpp" #include "duckdb/common/file_system.hpp" #include "duckdb/common/mutex.hpp" #include "duckdb/common/helper.hpp" @@ -58,6 +59,10 @@ class CSVFileHandle { FileCompressionType compression_type; double GetProgress() const; + //! The number of (decompressed) bytes that have been read from the file + idx_t UncompressedBytesRead() const { + return uncompressed_bytes_read.load(std::memory_order_relaxed); + } private: QueryContext context; @@ -67,7 +72,7 @@ class CSVFileHandle { bool can_seek = false; bool on_disk_file = false; bool is_pipe = false; - idx_t uncompressed_bytes_read = 0; + atomic uncompressed_bytes_read {0}; idx_t file_size = 0; diff --git a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp index ca864a0cf..b62ed51d8 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/csv_file_scanner.hpp @@ -15,6 +15,7 @@ #include "duckdb/execution/operator/csv_scanner/csv_schema.hpp" #include "duckdb/execution/operator/csv_scanner/csv_validator.hpp" #include "duckdb/common/multi_file/multi_file_data.hpp" +#include "duckdb/execution/progress_data.hpp" namespace duckdb { struct ReadCSVData; @@ -72,6 +73,8 @@ class CSVFileScan { shared_ptr state_machine; //! How many bytes were read up to this point atomic bytes_read {0}; + //! The progress of a compressed file is estimated - keeps it monotonic + MonotonicProgress compressed_progress; //! Size of this file idx_t file_size; //! Line Info used in error messages diff --git a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit.hpp b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit.hpp index db8599722..2cad1e185 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit.hpp @@ -36,6 +36,7 @@ class PhysicalLimit : public PhysicalOperator { public: // Source interface unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; diff --git a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_delete.hpp b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_delete.hpp index e58a69b69..52bb3e5ba 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_delete.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_delete.hpp @@ -35,6 +35,7 @@ class PhysicalDelete : public PhysicalOperator { public: // Source interface unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; unique_ptr GetLocalSourceState(ExecutionContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, diff --git a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_update.hpp b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_update.hpp index 2145f8990..4a573d560 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_update.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_update.hpp @@ -51,6 +51,7 @@ class PhysicalUpdate : public PhysicalOperator { public: // Source interface unique_ptr GetGlobalSourceState(ClientContext &context) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; diff --git a/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte.hpp b/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte.hpp index e6b8c29cf..b73105c9e 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte.hpp @@ -103,8 +103,10 @@ class PhysicalRecursiveCTE : public PhysicalOperator { public: // Source interface + unique_ptr GetGlobalSourceState(ClientContext &context) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; bool IsSource() const override { return true; @@ -169,6 +171,7 @@ class PhysicalRecursiveCTEStateScan : public PhysicalColumnDataScan { GlobalSourceState &gstate) const override; SourceResultType GetDataInternal(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const override; + ProgressData GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; bool IsSource() const override { return true; diff --git a/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte_state.hpp b/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte_state.hpp index 0549c39ff..84608d970 100644 --- a/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte_state.hpp +++ b/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte_state.hpp @@ -250,12 +250,43 @@ class RecursiveCTESchedulerState { vector ready_schedule_stages; }; +//! The source state of a recursive CTE - tracks the rows emitted to estimate the progress, as the number of recursive +//! iterations is not known up front +class RecursiveCTEGlobalSourceState : public GlobalSourceState { +public: + void StartIteration(idx_t row_count); + void StartFinalDrain(idx_t row_count); + void AddEmittedRows(idx_t row_count) { + emitted_rows.fetch_add(row_count, std::memory_order_relaxed); + } + void Finish() { + finished.store(true, std::memory_order_relaxed); + } + ProgressData GetProgress(); + +private: + atomic emitted_rows {0}; + atomic finished {false}; + //! Protects the iteration statistics, which are updated once per iteration + mutex iteration_lock; + //! Whether the final state of a USING KEY recursion is being emitted (its size is then known) + bool draining = false; + idx_t iterations = 0; + //! Rows of the first, the current and the previous iteration + idx_t anchor_rows = 0; + idx_t iteration_rows = 0; + idx_t previous_iteration_rows = 0; + //! Rows emitted before the current iteration started + idx_t iteration_start_rows = 0; + MonotonicProgress progress; +}; + class RecursiveCTEState : public GlobalSinkState { public: explicit RecursiveCTEState(ClientContext &context, const PhysicalRecursiveCTE &op); ~RecursiveCTEState() override; - SourceResultType GetData(ExecutionContext &context, DataChunk &chunk); + SourceResultType GetData(ExecutionContext &context, DataChunk &chunk, RecursiveCTEGlobalSourceState &source); const ColumnDataCollection &CurrentInputTable() const; idx_t CurrentInputCount() const { return CurrentInputTable().Count(); @@ -400,10 +431,12 @@ class RecursiveCTEState : public GlobalSinkState { bool can_reuse_new_group_candidates = false; bool can_reuse_changed_group_candidates = false; - SourceResultType GetUsingKeyData(ExecutionContext &context, DataChunk &chunk); + SourceResultType GetUsingKeyData(ExecutionContext &context, DataChunk &chunk, + RecursiveCTEGlobalSourceState &source); template - SourceResultType GetUsingKeyDataInternal(ExecutionContext &context, DataChunk &chunk); - SourceResultType GetUnionData(ExecutionContext &context, DataChunk &chunk); + SourceResultType GetUsingKeyDataInternal(ExecutionContext &context, DataChunk &chunk, + RecursiveCTEGlobalSourceState &source); + SourceResultType GetUnionData(ExecutionContext &context, DataChunk &chunk, RecursiveCTEGlobalSourceState &source); void InitializeIntermediateAppend(); ColumnDataCollection &CurrentOutputTable(); ColumnDataCollection &CurrentInputTable(); diff --git a/src/duckdb/src/include/duckdb/execution/progress_data.hpp b/src/duckdb/src/include/duckdb/execution/progress_data.hpp index 1d234d653..fdafc1a0e 100644 --- a/src/duckdb/src/include/duckdb/execution/progress_data.hpp +++ b/src/duckdb/src/include/duckdb/execution/progress_data.hpp @@ -9,6 +9,8 @@ #pragma once #include "duckdb/common/assert.hpp" +#include "duckdb/common/atomic.hpp" +#include "duckdb/common/constants.hpp" namespace duckdb { @@ -55,4 +57,89 @@ struct ProgressData { } }; +//! Keeps an estimated progress from decreasing, for operators whose total is only known once they finish. +//! The highest fraction reported so far is kept as fixed-point, and is only touched when progress is requested. +struct MonotonicProgress { +public: + //! Returns the given progress, raised to the highest fraction that was returned before + ProgressData Update(const ProgressData &progress) const { + if (!progress.IsValid() || progress.total <= 0) { + return progress; + } + auto fraction = static_cast(progress.done / progress.total * static_cast(PRECISION)); + fraction = fraction > PRECISION ? PRECISION : fraction; + auto previous = max_fraction.load(std::memory_order_relaxed); + while (fraction > previous && + !max_fraction.compare_exchange_weak(previous, fraction, std::memory_order_relaxed)) { + } + auto result_fraction = fraction > previous ? fraction : previous; + ProgressData result; + result.done = static_cast(result_fraction) / static_cast(PRECISION) * progress.total; + result.total = progress.total; + return result; + } + void Reset() { + max_fraction.store(0, std::memory_order_relaxed); + } + +private: + static constexpr idx_t PRECISION = 1000000000; + //! Updated when progress is requested, which only has const access to the operator state + mutable atomic max_fraction {0}; +}; + +//! Progress of a source that executes a known number of tasks - every task contributes UNITS_PER_TASK units once it +//! is finished, and threads report the units of the task they are working on as it advances +struct TaskProgress { +public: + static constexpr idx_t UNITS_PER_TASK = 1 << 20; + + void AddUnits(idx_t count) { + units.fetch_add(count, std::memory_order_relaxed); + } + ProgressData GetProgress(idx_t task_count) const { + ProgressData result; + result.total = static_cast(task_count); + result.done = static_cast(units.load(std::memory_order_relaxed)) / static_cast(UNITS_PER_TASK); + if (result.done > result.total) { + result.done = result.total; + } + return result; + } + void Reset() { + units.store(0, std::memory_order_relaxed); + } + +private: + atomic units {0}; +}; + +//! Reports the progress of the task a thread is working on to a TaskProgress +struct TaskProgressTracker { +public: + //! Starts reporting a new task + void Start() { + reported_units = 0; + } + //! Reports that the current task has done "done" out of "total" work + void Update(TaskProgress &progress, idx_t done, idx_t total) { + idx_t task_units = TaskProgress::UNITS_PER_TASK; + if (total > 0 && done < total) { + task_units = static_cast(static_cast(TaskProgress::UNITS_PER_TASK) * + static_cast(done) / static_cast(total)); + } + if (task_units > reported_units) { + progress.AddUnits(task_units - reported_units); + reported_units = task_units; + } + } + //! Reports that the current task is finished + void Finish(TaskProgress &progress) { + Update(progress, 1, 1); + } + +private: + idx_t reported_units = 0; +}; + } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/function/cast/variant/json_to_variant.hpp b/src/duckdb/src/include/duckdb/function/cast/variant/json_to_variant.hpp index 68c30b4e5..104c71ae4 100644 --- a/src/duckdb/src/include/duckdb/function/cast/variant/json_to_variant.hpp +++ b/src/duckdb/src/include/duckdb/function/cast/variant/json_to_variant.hpp @@ -4,6 +4,7 @@ #include "duckdb/function/scalar/variant_utils.hpp" #include "duckdb/function/cast/default_casts.hpp" #include "yyjson.hpp" +#include "yyjson_memory.hpp" #include "duckdb/common/serializer/memory_stream.hpp" #include "duckdb/common/serializer/varint.hpp" #include "duckdb/common/typedefs.hpp" @@ -21,22 +22,6 @@ using namespace duckdb_yyjson; // NOLINT namespace { -struct ReadJSONHolder { -public: - ~ReadJSONHolder() { - if (doc) { - yyjson_doc_free(doc); - } - } - void Reset() { - yyjson_doc_free(doc); - doc = nullptr; - } - -public: - yyjson_doc *doc = nullptr; -}; - static inline string_t GetString(yyjson_val *val) { return string_t(unsafe_yyjson_get_str(val), NumericCast(unsafe_yyjson_get_len(val))); } @@ -271,7 +256,7 @@ bool ConvertJSONToVariant(ToVariantSourceData &source, ToVariantGlobalResultData auto blob_offset_data = OffsetData::GetBlob(result.offsets); auto &variant = result.variant; - ReadJSONHolder json_holder; + JSONAllocator json_allocator(result.allocator); for (idx_t i = 0; i < count; i++) { auto source_index = source[i]; auto result_index = selvec ? selvec->get_index(i) : i; @@ -290,22 +275,24 @@ bool ConvertJSONToVariant(ToVariantSourceData &source, ToVariantGlobalResultData } auto &val = source_data[source_index]; - json_holder.doc = - yyjson_read(val.GetData(), val.GetSize(), - YYJSON_READ_ALLOW_INF_AND_NAN | YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_BIGNUM_AS_RAW); - if (!json_holder.doc) { + auto doc = yyjson_read_opts(val.GetDataWriteable(), val.GetSize(), + YYJSON_READ_ALLOW_INF_AND_NAN | YYJSON_READ_ALLOW_TRAILING_COMMAS | + YYJSON_READ_BIGNUM_AS_RAW, + json_allocator.GetYYAlc(), nullptr); + if (!doc) { + json_allocator.Reset(); if (!IGNORE_NULLS) { HandleVariantNull(result, result_index, values_offset_data, blob_offset_data[result_index], values_index_selvec, i, is_root); } continue; } - auto *root = yyjson_doc_get_root(json_holder.doc); + auto *root = yyjson_doc_get_root(doc); if (!ConvertJSON(root, result, result_index, is_root)) { return false; } - json_holder.Reset(); + json_allocator.Reset(); } return true; } diff --git a/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp b/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp index fbc32bf5c..83c37856a 100644 --- a/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp +++ b/src/duckdb/src/include/duckdb/function/cast/variant/to_variant_fwd.hpp @@ -47,8 +47,9 @@ struct OffsetData { struct ToVariantGlobalResultData { public: ToVariantGlobalResultData(VariantVectorData &variant, DataChunk &offsets, - OrderedOwningStringMap &dictionary, SelectionVector &keys_selvec) - : variant(variant), offsets(offsets), dictionary(dictionary), keys_selvec(keys_selvec) { + OrderedOwningStringMap &dictionary, SelectionVector &keys_selvec, + Allocator &allocator) + : variant(variant), offsets(offsets), dictionary(dictionary), keys_selvec(keys_selvec), allocator(allocator) { } public: @@ -65,6 +66,8 @@ struct ToVariantGlobalResultData { OrderedOwningStringMap &dictionary; //! The selection vector to populate with mapping from keys index -> dictionary index SelectionVector &keys_selvec; + //! Allocator for temporary conversion memory (e.g. JSON parsing), tracked by DuckDB's memory accounting + Allocator &allocator; }; template diff --git a/src/duckdb/src/include/duckdb/function/function_serialization.hpp b/src/duckdb/src/include/duckdb/function/function_serialization.hpp index 93b490154..aadc052be 100644 --- a/src/duckdb/src/include/duckdb/function/function_serialization.hpp +++ b/src/duckdb/src/include/duckdb/function/function_serialization.hpp @@ -177,7 +177,7 @@ class FunctionSerializer { template static unique_ptr FunctionDeserialize(Deserializer &deserializer, FUNC &function) { - if (!function.HasSerializationCallbacks()) { + if (!function.GetDeserializeCallback()) { throw SerializationException("Function requires deserialization but no deserialization function for %s", function.GetName()); } diff --git a/src/duckdb/src/include/duckdb/logging/log_storage.hpp b/src/duckdb/src/include/duckdb/logging/log_storage.hpp index 48be5586b..7e05e0108 100644 --- a/src/duckdb/src/include/duckdb/logging/log_storage.hpp +++ b/src/duckdb/src/include/duckdb/logging/log_storage.hpp @@ -90,6 +90,8 @@ class LogStorage { DUCKDB_API virtual unique_ptr CreateScanState(LoggingTargetTable table) const; DUCKDB_API virtual bool Scan(LogStorageScanState &state, DataChunk &result) const; DUCKDB_API virtual void InitializeScan(LogStorageScanState &state) const; + //! The number of rows a scan of the table produces, if known (used for progress reporting) + DUCKDB_API virtual optional_idx GetScanRowCount(LoggingTargetTable table) const; // Reading interface 2: using bind_replace DUCKDB_API virtual unique_ptr BindReplace(ClientContext &context, TableFunctionBindInput &input, @@ -338,6 +340,7 @@ class InMemoryLogStorage : public BufferingLogStorage { unique_ptr CreateScanState(LoggingTargetTable table) const override; bool Scan(LogStorageScanState &state, DataChunk &result) const override; void InitializeScan(LogStorageScanState &state) const override; + optional_idx GetScanRowCount(LoggingTargetTable table) const override; protected: /// Implement BufferingLogStorage interface diff --git a/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp b/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp index b86090aa8..4927d66f2 100644 --- a/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp +++ b/src/duckdb/src/include/duckdb/main/capi_v2/capi_v2_internal.hpp @@ -74,6 +74,10 @@ inline auto Convert(duckdb_v2_str str) -> std::string_view { } return std::string_view(str.ptr, str.len); } + +// Validates identifier UTF-8 and returns its text; throws on invalid input. Defined in capi_v2_utf8.cpp. +auto ConvertIdentifierName(duckdb_v2_identifier_t name) -> std::string_view; + inline auto Convert(std::string_view str) -> duckdb_v2_str { return duckdb_v2_str {str.data(), str.size()}; } @@ -717,7 +721,7 @@ inline void BuildParameterMap(const duckdb_v2_identifier_t *parameter_names, throw InvalidInputException("null parameter value passed to %s", function_name); } // Named iff the name view is non-empty; otherwise positional - auto str = Convert(name); + auto str = ConvertIdentifierName(name); Identifier key = (name.ptr && name.len > 0) ? Identifier(str) : Identifier(std::to_string(i + 1)); out[key] = BoundParameterData(*Convert(parameter_values[i])); } diff --git a/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp b/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp index 28518ba4e..162648fda 100644 --- a/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp +++ b/src/duckdb/src/include/duckdb/main/capi_v2/extension_api_v2.hpp @@ -638,7 +638,7 @@ typedef struct { (duckdb_v2_scalar_function_handle function, duckdb_v2_scalar_function_init_callback_fn callback, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_scalar_function_set_name) - (duckdb_v2_scalar_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_scalar_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_scalar_function_set_user_data) (duckdb_v2_scalar_function_handle function, duckdb_v2_opaque *data, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_aggregate_function_bind_get_user_data) @@ -715,7 +715,7 @@ typedef struct { (duckdb_v2_aggregate_function_handle function, duckdb_v2_aggregate_function_init_callback_fn callback, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_aggregate_function_set_name) - (duckdb_v2_aggregate_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_aggregate_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_aggregate_function_set_size_callback) (duckdb_v2_aggregate_function_handle function, duckdb_v2_aggregate_function_size_callback_fn callback, duckdb_v2_error_info_handle *err); @@ -826,7 +826,7 @@ typedef struct { (duckdb_v2_table_function_handle function, duckdb_v2_table_function_init_local_callback_fn callback, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_name) - (duckdb_v2_table_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_table_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_progress_callback) (duckdb_v2_table_function_handle function, duckdb_v2_table_function_progress_callback_fn callback, duckdb_v2_error_info_handle *err); @@ -1077,7 +1077,7 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_copy_function_register) (duckdb_v2_copy_function_handle function, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_copy_function_set_name) - (duckdb_v2_copy_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_copy_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_copy_function_set_user_data) (duckdb_v2_copy_function_handle function, duckdb_v2_opaque *data, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_copy_to_batch_get_bind_data) diff --git a/src/duckdb/src/include/duckdb/main/config.hpp b/src/duckdb/src/include/duckdb/main/config.hpp index a6d9758e7..6f79a7031 100644 --- a/src/duckdb/src/include/duckdb/main/config.hpp +++ b/src/duckdb/src/include/duckdb/main/config.hpp @@ -29,6 +29,7 @@ #include "duckdb/function/replacement_scan.hpp" #include "duckdb/storage/compression/bitpacking.hpp" #include "duckdb/function/encoding_function.hpp" +#include "duckdb/main/extension/linked_extension_registry.hpp" #include "duckdb/main/setting_info.hpp" #include "duckdb/execution/index/index_type_set.hpp" #include "duckdb/logging/logging.hpp" @@ -52,10 +53,6 @@ class ClientContext; class DuckDB; //! An extension linked into the binary, and how to load it into a database. -struct LinkedExtension { - string name; - std::function load; -}; class ErrorManager; class CompressionFunction; class TableFunctionRef; diff --git a/src/duckdb/src/include/duckdb/main/database.hpp b/src/duckdb/src/include/duckdb/main/database.hpp index dac712fc9..0f4942193 100644 --- a/src/duckdb/src/include/duckdb/main/database.hpp +++ b/src/duckdb/src/include/duckdb/main/database.hpp @@ -16,6 +16,7 @@ #include "duckdb/main/valid_checker.hpp" #include "duckdb/main/extension/extension_loader.hpp" #include "duckdb/main/extension_manager.hpp" +#include "duckdb_static_extension.h" namespace duckdb { class LocalDatabaseFileSystem; @@ -134,6 +135,25 @@ class DatabaseInstance : public enable_shared_from_this { invoke_ext_capi_v2_fun_t invoke_capi_v2; }; +//! A describe function for an extension class, so that loading it by class goes through the same path as linked +//! extensions. +template +struct StaticExtensionDescriber { + static void Entry(ExtensionLoader &loader) { + T extension; + extension.Load(loader); + } + static int32_t Describe(duckdb_extension_descriptor *descriptor) { + static const std::string name = T().Name(); + static const std::string version = T().Version(); + descriptor->version = 1; + descriptor->name = name.c_str(); + descriptor->extension_version = version.c_str(); + descriptor->entry_cpp = reinterpret_cast(&Entry); + return 0; + } +}; + //! The database object. This object holds the catalog and all the //! database-specific meta information. class DuckDB { @@ -153,32 +173,16 @@ class DuckDB { shared_ptr instance; public: - // Load a statically loaded extension by its class + // Load a statically linked extension by its class, through a describe function generated for it template void LoadStaticExtension() { - T extension; - auto &manager = ExtensionManager::Get(*instance); - auto load_info = manager.BeginLoad({extension.Name()}); - if (!load_info) { - // already loaded - return - return; - } - - // Instantiate a new loader - ExtensionLoader loader(*load_info); - - // Call the Load method of the extension - extension.Load(loader); - - // Finalize the loading process - loader.FinalizeLoad(); - - ExtensionInstallInfo install_info; - install_info.mode = ExtensionInstallMode::STATICALLY_LINKED; - install_info.version = extension.Version(); - load_info->FinishLoad(install_info); + LoadStaticExtension(&StaticExtensionDescriber::Describe); } + // Load the statically linked extension a describe function describes into this database + DUCKDB_API void LoadStaticExtension(duckdb_extension_describe_t describe); + // Function pointer type for the C++ extension entrypoint, _duckdb_cpp_init + typedef void (*ext_init_cpp_fun_t)(ExtensionLoader &loader); // Function pointer type for the C API extension init function typedef bool (*ext_init_c_api_fun_t)(duckdb_extension_info info, duckdb_extension_access *access); // Load a statically compiled C API extension by calling its init function directly (no vtable needed) diff --git a/src/duckdb/src/include/duckdb/main/extension/generated_extension_loader.hpp b/src/duckdb/src/include/duckdb/main/extension/generated_extension_loader.hpp deleted file mode 100644 index f00f338a1..000000000 --- a/src/duckdb/src/include/duckdb/main/extension/generated_extension_loader.hpp +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/extension/generated_extension_loader.hpp -// -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "duckdb/common/string.hpp" -#include "duckdb/common/vector.hpp" -#include "duckdb/main/database.hpp" - -#if defined(GENERATED_EXTENSION_HEADERS) -#include "duckdb/common/common.hpp" -#include "generated_extension_headers.hpp" - -namespace duckdb { - -vector LinkedExtensions(); -vector LoadedExtensionTestPaths(); - -} // namespace duckdb -#endif diff --git a/src/duckdb/src/include/duckdb/main/extension/linked_extension_registry.hpp b/src/duckdb/src/include/duckdb/main/extension/linked_extension_registry.hpp new file mode 100644 index 000000000..975b6ee78 --- /dev/null +++ b/src/duckdb/src/include/duckdb/main/extension/linked_extension_registry.hpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/extension/linked_extension_registry.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/string.hpp" +#include "duckdb/common/vector.hpp" +#include "duckdb/common/winapi.hpp" +#include "duckdb_static_extension.h" + +#include + +namespace duckdb { +class DuckDB; + +//! An extension compiled into this binary, as a name and the callable that loads it. +struct LinkedExtension { + string name; + std::function load; +}; + +//! What a describe function described, once validated. +struct StaticExtensionDescription { + string name; + string version; + //! the DuckDB version a C++ entry point was built against, or the C API version a C entry point targets + string api_version; + duckdb_extension_descriptor descriptor; +}; + +//! The extensions linked into this binary, registered through duckdb_register_static_extension. +class LinkedExtensionRegistry { +public: + //! Calls describe and validates the descriptor it fills. Returns the reason on failure, otherwise an empty string. + DUCKDB_API static string Describe(duckdb_extension_describe_t describe, StaticExtensionDescription &result); + //! A copy, in registration order. Throws if a registration failed. + DUCKDB_API static vector Get(); +}; + +} // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/main/extension_entries.hpp b/src/duckdb/src/include/duckdb/main/extension_entries.hpp index 513272b68..949be7b65 100644 --- a/src/duckdb/src/include/duckdb/main/extension_entries.hpp +++ b/src/duckdb/src/include/duckdb/main/extension_entries.hpp @@ -397,6 +397,8 @@ static constexpr ExtensionFunctionEntry EXTENSION_FUNCTIONS[] = { {"iceberg_rewrite_data_files", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, {"iceberg_rollback_to_snapshot", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, {"iceberg_scan", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, + {"iceberg_scan_plan", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, + {"iceberg_scan_tasks", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, {"iceberg_schema_properties", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, {"iceberg_snapshots", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, {"iceberg_table_properties", "iceberg", CatalogType::TABLE_FUNCTION_ENTRY}, @@ -677,6 +679,7 @@ static constexpr ExtensionFunctionEntry EXTENSION_FUNCTIONS[] = { {"now", "core_functions", CatalogType::SCALAR_FUNCTION_ENTRY}, {"odbc_begin_transaction", "odbc_scanner", CatalogType::SCALAR_FUNCTION_ENTRY}, {"odbc_bind_params", "odbc_scanner", CatalogType::SCALAR_FUNCTION_ENTRY}, + {"odbc_cancel_query", "odbc_scanner", CatalogType::SCALAR_FUNCTION_ENTRY}, {"odbc_close", "odbc_scanner", CatalogType::SCALAR_FUNCTION_ENTRY}, {"odbc_commit", "odbc_scanner", CatalogType::SCALAR_FUNCTION_ENTRY}, {"odbc_connect", "odbc_scanner", CatalogType::SCALAR_FUNCTION_ENTRY}, @@ -1333,7 +1336,6 @@ static constexpr ExtensionEntry EXTENSION_SETTINGS[] = { {"iceberg_unsafe_skip_puffin_verification", "iceberg"}, {"iceberg_use_metadata_log", "iceberg"}, {"iceberg_use_server_side_scan_planning", "iceberg"}, - {"iceberg_via_aws_sdk_for_catalog_interactions", "iceberg"}, {"json_geometry_format", "json"}, {"merge_http_secret_into_s3_request", "httpfs"}, {"mysql_bit1_as_boolean", "mysql_scanner"}, diff --git a/src/duckdb/src/include/duckdb/main/extension_helper.hpp b/src/duckdb/src/include/duckdb/main/extension_helper.hpp index 2d89dd6e2..a0e9c6133 100644 --- a/src/duckdb/src/include/duckdb/main/extension_helper.hpp +++ b/src/duckdb/src/include/duckdb/main/extension_helper.hpp @@ -26,7 +26,6 @@ enum class ExtensionLoadResult : uint8_t { LOADED_EXTENSION = 0, EXTENSION_UNKNO struct DefaultExtension { const char *name; const char *description; - bool statically_loaded; }; struct ExtensionAlias { @@ -100,10 +99,8 @@ struct ExtensionInstallOptions { class ExtensionHelper { public: static void LoadAllExtensions(DuckDB &db); - static vector LoadedExtensionTestPaths(); static ExtensionLoadResult LoadExtension(DuckDB &db, const std::string &extension); - //! Publishes the extensions linked into this binary onto the config. Generated at build time; - //! a build that links none (or an extension carrying its own DuckDB) registers nothing. + //! Publishes the extensions linked into this binary, as collected by LinkedExtensionRegistry, onto the config static void RegisterLinkedExtensions(DBConfig &config); //! Install an extension diff --git a/src/duckdb/src/include/duckdb/main/query_profiler.hpp b/src/duckdb/src/include/duckdb/main/query_profiler.hpp index 7a763c0b3..483736c12 100644 --- a/src/duckdb/src/include/duckdb/main/query_profiler.hpp +++ b/src/duckdb/src/include/duckdb/main/query_profiler.hpp @@ -181,6 +181,14 @@ class QueryProfiler { //! disabled case. Only used on the terminal-print paths. void PrintProfilerOutput(optional_ptr renderer) const; +public: + //! Provides access to the root of the query tree, but ensures there are no concurrent modifications + //! This can be useful when implementing continuous profiling or making customizations + DUCKDB_API void GetRootUnderLock(const std::function)> &callback) { + lock_guard guard(lock); + callback(root.get()); + } + private: ClientContext &context; diff --git a/src/duckdb/src/include/duckdb/main/settings.hpp b/src/duckdb/src/include/duckdb/main/settings.hpp index 12513510b..445c73fcb 100644 --- a/src/duckdb/src/include/duckdb/main/settings.hpp +++ b/src/duckdb/src/include/duckdb/main/settings.hpp @@ -2480,12 +2480,12 @@ struct VacuumRebuildIndexesSetting { using RETURN_TYPE = idx_t; static constexpr const char *Name = "vacuum_rebuild_indexes"; static constexpr const char *Description = - "(Experimental) Allow vacuum to compact row groups on tables with bound ART indexes, rebuilding the indexes " - "afterward. Tables with a row count exceeding this threshold are skipped. 0 = disabled. Can also be set " - "per-database via the 'vacuum_rebuild_indexes' ATTACH option, which overrides this default."; + "Deprecated compatibility setting: maximum table row count for rebuilding bound ART indexes when checkpoint " + "vacuum cannot remap their row IDs. 0 disables the rebuild fallback but does not disable index remapping on " + "v2.0 storage. The 'vacuum_rebuild_indexes' ATTACH option overrides this default per database."; static constexpr const char *InputType = "UBIGINT"; static constexpr bool IsDebug = false; - static constexpr bool IsDeprecated = false; + static constexpr bool IsDeprecated = true; static constexpr const char *DefaultValue = "0"; static constexpr SettingScopeTarget Scope = SettingScopeTarget::GLOBAL_DEFAULT; static constexpr idx_t SettingIndex = NEXT_SETTING_INDEX(); diff --git a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp index e63de5e5d..c9a265465 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp @@ -2196,1230 +2196,1248 @@ const unsigned char INLINED_PEG_GRAMMAR[] = { 65, 78, 68, 39, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 35, 32, 76, 69, 86, 69, 76, 32, 56, 10, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, - 108, 42, 10, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, 108, - 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 66, 105, - 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 116, 104, 101, - 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, 65, 110, 121, - 65, 108, 108, 80, 97, 114, 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, - 78, 97, 109, 101, 100, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 10, 65, - 110, 121, 65, 108, 108, 80, 97, 114, 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, - 60, 45, 32, 65, 110, 121, 65, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 78, 97, - 109, 101, 100, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, - 32, 32, 32, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, - 114, 32, 47, 32, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, - 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, - 114, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 10, 65, 110, 121, 65, 108, 108, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, - 32, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, - 65, 110, 121, 79, 114, 65, 108, 108, 10, 65, 110, 121, 79, 114, 65, 108, 108, 32, 60, 45, - 32, 83, 117, 98, 113, 117, 101, 114, 121, 65, 110, 121, 32, 47, 32, 83, 117, 98, 113, 117, - 101, 114, 121, 65, 108, 108, 10, 83, 117, 98, 113, 117, 101, 114, 121, 65, 110, 121, 32, 60, - 45, 32, 39, 65, 78, 89, 39, 10, 83, 117, 98, 113, 117, 101, 114, 121, 65, 108, 108, 32, - 60, 45, 32, 39, 65, 76, 76, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, - 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 79, 80, 69, 82, 65, 84, 79, 82, 39, - 32, 80, 97, 114, 101, 110, 115, 40, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, - 114, 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, 41, 10, 81, 117, 97, 108, 105, - 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, - 32, 60, 45, 32, 67, 111, 108, 73, 100, 68, 111, 116, 42, 32, 65, 110, 121, 79, 112, 101, - 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, 35, 32, 76, 69, 86, 69, 76, - 32, 57, 10, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 84, 97, 105, 108, 42, 10, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 66, 105, 116, 79, 112, 101, 114, 97, 116, - 111, 114, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 38, 39, - 32, 47, 32, 39, 124, 39, 32, 47, 32, 39, 60, 60, 39, 32, 47, 32, 39, 62, 62, 39, - 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 48, 10, 65, 100, 100, 105, 116, 105, 118, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 77, 117, 108, 116, 105, 112, - 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, - 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, - 108, 42, 10, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 84, 97, 105, 108, 32, 60, 45, 32, 84, 101, 114, 109, 32, 77, 117, 108, 116, 105, 112, - 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, - 101, 114, 109, 32, 60, 45, 32, 39, 43, 39, 32, 47, 32, 39, 45, 39, 10, 35, 32, 76, - 69, 86, 69, 76, 32, 49, 49, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, - 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 111, - 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, - 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, - 60, 45, 32, 70, 97, 99, 116, 111, 114, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, - 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 97, 99, 116, 111, - 114, 32, 60, 45, 32, 39, 42, 39, 32, 47, 32, 39, 47, 39, 32, 47, 32, 39, 47, 47, - 39, 32, 47, 32, 39, 37, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 50, 10, 69, - 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 69, 120, 112, 111, 110, - 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, - 97, 105, 108, 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, - 116, 111, 114, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 69, 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, - 45, 32, 39, 94, 39, 32, 47, 32, 39, 42, 42, 39, 10, 35, 32, 76, 69, 86, 69, 76, - 32, 49, 51, 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 84, 97, 105, 108, 42, 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, - 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 108, 97, 116, 101, 79, 112, - 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, 39, 10, - 35, 32, 76, 69, 86, 69, 76, 32, 49, 52, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, - 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, - 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, 116, 84, 105, 109, 101, 90, 111, - 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 116, - 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, - 105, 108, 32, 60, 45, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, - 97, 116, 111, 114, 32, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, - 32, 60, 45, 32, 39, 65, 84, 39, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, - 69, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 53, 10, 80, 114, 101, 102, 105, 120, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, - 79, 112, 101, 114, 97, 116, 111, 114, 42, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 10, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, - 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, - 32, 47, 32, 77, 105, 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, - 111, 114, 32, 47, 32, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, - 116, 111, 114, 32, 47, 32, 84, 105, 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, - 114, 97, 116, 111, 114, 10, 77, 105, 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 45, 39, 10, 80, 108, 117, 115, 80, 114, 101, - 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 43, 39, 10, 84, - 105, 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, - 45, 32, 39, 126, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 54, 32, 40, 72, 105, - 103, 104, 101, 115, 116, 41, 10, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 83, 105, 110, 103, 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 73, - 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, - 100, 105, 114, 101, 99, 116, 105, 111, 110, 43, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, - 111, 110, 32, 60, 45, 32, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, - 32, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 83, 108, 105, 99, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 116, 102, 105, 120, - 79, 112, 101, 114, 97, 116, 111, 114, 10, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, - 114, 32, 60, 45, 32, 39, 58, 58, 39, 32, 84, 121, 112, 101, 10, 68, 111, 116, 79, 112, - 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, - 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, - 112, 101, 114, 97, 116, 111, 114, 10, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 46, 39, 32, 77, 101, 116, 104, 111, 100, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, - 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 46, 39, 32, 67, 111, 108, 76, 97, - 98, 101, 108, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 67, 111, 108, 76, 97, 98, 101, 108, 32, 77, 101, 116, 104, 111, 100, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 10, 77, - 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, - 101, 110, 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 77, 101, 116, 104, 111, - 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, - 105, 115, 116, 41, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 68, 105, 115, - 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 32, 77, 101, 116, 104, 111, 100, 70, 117, - 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 63, 32, 79, 114, 100, - 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 73, 103, 110, 111, 114, 101, 79, 114, - 82, 101, 115, 112, 101, 99, 116, 78, 117, 108, 108, 115, 63, 10, 77, 101, 116, 104, 111, 100, - 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, - 32, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, - 110, 116, 41, 10, 83, 108, 105, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 39, 91, 39, 32, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 39, 93, - 39, 10, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 63, 32, 69, 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, - 100, 63, 32, 83, 116, 101, 112, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 10, 69, - 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, - 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, 108, 117, 101, 63, 10, 69, 110, 100, 83, 108, - 105, 99, 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 47, 32, 69, 110, 100, 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 10, 69, - 110, 100, 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 32, 60, 45, 32, 39, 45, 39, 10, - 83, 116, 101, 112, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, - 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 80, 111, 115, 116, 102, 105, - 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 33, 39, 10, 83, 112, 101, - 99, 105, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 47, 32, 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 47, 32, 84, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 47, 32, 67, 111, 108, 117, 109, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 47, 32, 69, 120, 116, 114, 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 47, 32, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, - 32, 78, 117, 108, 108, 73, 102, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, - 80, 111, 115, 105, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, - 32, 82, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 83, 117, 98, - 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, - 114, 105, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 79, 118, 101, 114, - 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 97, 108, 101, 115, - 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 65, - 76, 69, 83, 67, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 85, 110, 112, 97, 99, 107, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 85, 78, 80, 65, 67, 75, 39, - 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, - 84, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, - 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 41, 10, 67, 111, 108, 117, 109, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 63, 32, 39, 67, 79, 76, 85, - 77, 78, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 39, 69, 88, 84, 82, 65, 67, 84, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, - 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, - 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 39, 70, 82, 79, - 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, 97, 109, 98, 100, 97, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 76, 65, 77, 66, 68, - 65, 39, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, - 103, 41, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 117, - 108, 108, 73, 102, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 78, - 85, 76, 76, 73, 70, 39, 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 108, 108, 73, 102, - 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 78, 117, 108, 108, 73, 102, 65, 114, 103, - 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 39, 44, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 111, 115, 105, - 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 80, - 79, 83, 73, 84, 73, 79, 78, 39, 32, 80, 97, 114, 101, 110, 115, 40, 80, 111, 115, 105, - 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 80, 111, 115, 105, 116, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 116, 104, 101, - 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 39, 73, 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 82, 111, 119, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 80, + 111, 110, 32, 60, 45, 32, 73, 110, 102, 105, 120, 79, 116, 104, 101, 114, 79, 112, 101, 114, + 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 67, 117, 115, + 116, 111, 109, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 73, 110, 102, 105, 120, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 66, 105, 116, 119, 105, 115, 101, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, + 116, 111, 114, 84, 97, 105, 108, 42, 10, 67, 117, 115, 116, 111, 109, 80, 114, 101, 102, 105, + 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 79, 112, 101, 114, 97, + 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, + 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 116, 104, 101, 114, + 79, 112, 101, 114, 97, 116, 111, 114, 84, 97, 105, 108, 32, 60, 45, 32, 79, 116, 104, 101, + 114, 79, 112, 101, 114, 97, 116, 111, 114, 32, 66, 105, 116, 119, 105, 115, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 60, 45, 10, 32, 32, 32, 32, 65, 110, 121, 65, 108, 108, 80, 97, 114, 115, 101, + 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 78, 97, 109, 101, 100, 79, 116, 104, + 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 10, 65, 110, 121, 65, 108, 108, 80, 97, 114, + 115, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 65, 110, 121, 65, 108, + 108, 79, 112, 101, 114, 97, 116, 111, 114, 10, 78, 97, 109, 101, 100, 79, 116, 104, 101, 114, + 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 10, 32, 32, 32, 32, 81, 117, 97, 108, + 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 79, 112, 101, 114, + 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, 79, 112, 101, 114, 97, 116, 111, 114, + 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 10, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, + 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 65, 110, 121, 65, 108, + 108, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 65, 110, 121, 79, 112, 101, 114, + 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 32, 65, 110, 121, 79, 114, 65, 108, 108, + 10, 65, 110, 121, 79, 114, 65, 108, 108, 32, 60, 45, 32, 83, 117, 98, 113, 117, 101, 114, + 121, 65, 110, 121, 32, 47, 32, 83, 117, 98, 113, 117, 101, 114, 121, 65, 108, 108, 10, 83, + 117, 98, 113, 117, 101, 114, 121, 65, 110, 121, 32, 60, 45, 32, 39, 65, 78, 89, 39, 10, + 83, 117, 98, 113, 117, 101, 114, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, + 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, + 45, 32, 39, 79, 80, 69, 82, 65, 84, 79, 82, 39, 32, 80, 97, 114, 101, 110, 115, 40, + 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 67, 111, 110, + 116, 101, 110, 116, 115, 41, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, + 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, 32, 60, 45, 32, 67, 111, 108, 73, + 100, 68, 111, 116, 42, 32, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, + 101, 114, 97, 108, 10, 35, 32, 76, 69, 86, 69, 76, 32, 57, 10, 66, 105, 116, 119, 105, + 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 100, 100, 105, + 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 66, 105, 116, 119, 105, + 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 66, 105, + 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, + 60, 45, 32, 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 65, 100, 100, 105, 116, + 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 66, 105, 116, 79, 112, 101, + 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 38, 39, 32, 47, 32, 39, 124, 39, 32, 47, + 32, 39, 60, 60, 39, 32, 47, 32, 39, 62, 62, 39, 10, 35, 32, 76, 69, 86, 69, 76, + 32, 49, 48, 10, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 100, 100, 105, 116, + 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, + 32, 84, 101, 114, 109, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 101, 114, 109, 32, 60, 45, 32, 39, + 43, 39, 32, 47, 32, 39, 45, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 49, 10, + 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, + 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 77, 117, 108, 116, 105, 112, 108, + 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, + 108, 42, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 70, 97, 99, 116, 111, + 114, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 10, 70, 97, 99, 116, 111, 114, 32, 60, 45, 32, 39, 42, 39, + 32, 47, 32, 39, 47, 39, 32, 47, 32, 39, 47, 47, 39, 32, 47, 32, 39, 37, 39, 10, + 35, 32, 76, 69, 86, 69, 76, 32, 49, 50, 10, 69, 120, 112, 111, 110, 101, 110, 116, 105, + 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, + 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 69, 120, 112, + 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 84, 97, 105, 108, 42, 10, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, + 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 69, + 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 67, 111, 108, 108, + 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 111, 110, 101, + 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 94, 39, 32, 47, 32, + 39, 42, 42, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 51, 10, 67, 111, 108, 108, + 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 116, 84, + 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 67, 111, + 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, + 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, + 105, 108, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 67, 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, + 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, + 49, 52, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 65, 116, + 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 80, 114, 101, + 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 84, 105, 109, 101, + 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 65, 84, 39, + 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 10, 35, 32, 76, 69, 86, + 69, 76, 32, 49, 53, 10, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, + 42, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 114, 101, + 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 81, 117, 97, 108, 105, + 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 77, 105, 110, 117, 115, + 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 80, 108, 117, + 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 84, 105, + 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 10, 77, 105, + 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, + 32, 39, 45, 39, 10, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, + 116, 111, 114, 32, 60, 45, 32, 39, 43, 39, 10, 84, 105, 108, 100, 101, 80, 114, 101, 102, + 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 126, 39, 10, 35, 32, + 76, 69, 86, 69, 76, 32, 49, 54, 32, 40, 72, 105, 103, 104, 101, 115, 116, 41, 10, 66, + 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 105, 110, + 103, 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 110, 100, 105, 114, 101, + 99, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, + 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, + 110, 43, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, + 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, 116, 79, 112, 101, 114, + 97, 116, 111, 114, 32, 47, 32, 83, 108, 105, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 47, 32, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, + 10, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 58, 58, + 39, 32, 84, 121, 112, 101, 10, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, + 45, 32, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, + 47, 32, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, 111, 114, 10, + 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, + 32, 39, 46, 39, 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, 111, 114, 32, + 60, 45, 32, 39, 46, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 10, 77, 101, 116, 104, + 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 76, + 97, 98, 101, 108, 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 41, 10, 77, 101, 116, + 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, + 116, 76, 105, 115, 116, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, + 108, 108, 63, 32, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, + 103, 117, 109, 101, 110, 116, 115, 63, 32, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, + 115, 101, 63, 32, 73, 103, 110, 111, 114, 101, 79, 114, 82, 101, 115, 112, 101, 99, 116, 78, + 117, 108, 108, 115, 63, 10, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, 110, + 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 76, 105, 115, 116, 40, 70, 117, + 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 10, 83, 108, 105, 99, + 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 91, 39, 32, 83, + 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 39, 93, 39, 10, 83, 108, 105, 99, 101, 66, + 111, 117, 110, 100, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, + 69, 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 32, 83, 116, 101, 112, 83, + 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 66, + 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 110, 100, 83, 108, 105, 99, 101, + 86, 97, 108, 117, 101, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, 108, 117, 101, + 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 110, 100, + 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 10, 69, 110, 100, 83, 108, 105, 99, 101, 77, + 105, 110, 117, 115, 32, 60, 45, 32, 39, 45, 39, 10, 83, 116, 101, 112, 83, 108, 105, 99, + 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 63, 10, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 60, 45, 32, 39, 33, 39, 10, 83, 112, 101, 99, 105, 97, 108, 70, 117, 110, 99, + 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, + 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 85, + 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, 114, + 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 67, 111, 108, 117, 109, 110, + 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 116, 114, 97, 99, + 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 76, 97, 109, 98, 100, 97, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 78, 117, 108, 108, 73, 102, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 82, 111, 119, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, 114, 105, 109, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 10, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 65, 76, 69, 83, 67, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 41, 63, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 39, 83, 85, 66, 83, 84, 82, 73, 78, 71, 39, 32, - 80, 97, 114, 101, 110, 115, 40, 83, 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, - 109, 101, 110, 116, 115, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, - 109, 101, 110, 116, 115, 32, 60, 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, - 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 83, 117, 98, 115, 116, - 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, - 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 83, - 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, - 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 83, 117, 98, 115, 116, 114, 105, - 110, 103, 70, 114, 111, 109, 70, 111, 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, - 114, 111, 109, 70, 111, 114, 32, 60, 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, - 114, 111, 109, 79, 112, 116, 105, 111, 110, 97, 108, 70, 111, 114, 32, 47, 32, 83, 117, 98, - 115, 116, 114, 105, 110, 103, 70, 111, 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, - 114, 111, 109, 79, 112, 116, 105, 111, 110, 97, 108, 70, 111, 114, 32, 60, 45, 32, 70, 114, - 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 63, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, 114, - 32, 60, 45, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 114, - 105, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 73, - 77, 39, 32, 80, 97, 114, 101, 110, 115, 40, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, - 110, 116, 115, 41, 10, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, - 45, 32, 84, 114, 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 63, 32, 84, 114, 105, - 109, 83, 111, 117, 114, 99, 101, 63, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 41, 10, 84, 114, 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 32, - 60, 45, 32, 84, 114, 105, 109, 66, 111, 116, 104, 32, 47, 32, 84, 114, 105, 109, 76, 101, - 97, 100, 105, 110, 103, 32, 47, 32, 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, - 10, 84, 114, 105, 109, 66, 111, 116, 104, 32, 60, 45, 32, 39, 66, 79, 84, 72, 39, 10, - 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, 32, 60, 45, 32, 39, 76, 69, 65, 68, - 73, 78, 71, 39, 10, 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, 32, 60, 45, - 32, 39, 84, 82, 65, 73, 76, 73, 78, 71, 39, 10, 84, 114, 105, 109, 83, 111, 117, 114, - 99, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 70, - 82, 79, 77, 39, 10, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 39, 79, 86, 69, 82, 76, 65, 89, 39, 32, 80, 97, 114, 101, - 110, 115, 40, 79, 118, 101, 114, 108, 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, - 10, 79, 118, 101, 114, 108, 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, - 32, 79, 118, 101, 114, 108, 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, - 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, - 115, 116, 10, 79, 118, 101, 114, 108, 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, - 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 80, 76, 65, 67, - 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 114, 111, 109, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 63, 10, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, - 70, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 118, 101, 114, - 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, - 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, - 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, - 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, - 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 83, 116, - 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 10, 69, 120, 116, 114, 97, 99, 116, - 68, 97, 116, 101, 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, - 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 10, 69, 120, 116, 114, - 97, 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, - 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 69, 120, 116, 114, - 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, - 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 114, 97, - 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 32, 60, 45, 10, 32, 32, 32, 32, 89, 101, - 97, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 111, 110, 116, 104, 75, 101, 121, - 119, 111, 114, 100, 32, 47, 32, 68, 97, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, - 72, 111, 117, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 110, 117, 116, 101, - 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 83, 101, 99, 111, 110, 100, 75, 101, 121, 119, - 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 77, 105, 108, 108, 105, 115, 101, 99, 111, 110, - 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 99, 114, 111, 115, 101, 99, 111, - 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 87, 101, 101, 107, 75, 101, 121, 119, - 111, 114, 100, 32, 47, 32, 81, 117, 97, 114, 116, 101, 114, 75, 101, 121, 119, 111, 114, 100, - 32, 47, 32, 68, 101, 99, 97, 100, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, - 32, 32, 32, 67, 101, 110, 116, 117, 114, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, - 77, 105, 108, 108, 101, 110, 110, 105, 117, 109, 75, 101, 121, 119, 111, 114, 100, 10, 35, 32, - 69, 118, 101, 114, 121, 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 97, 98, 111, 117, - 116, 32, 101, 120, 116, 101, 114, 110, 97, 108, 32, 114, 101, 115, 111, 117, 114, 99, 101, 115, - 44, 32, 115, 111, 32, 116, 104, 101, 32, 116, 111, 112, 45, 108, 101, 118, 101, 108, 32, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 104, 111, 105, 99, 101, 32, 99, 97, 114, 114, - 105, 101, 115, 32, 111, 110, 101, 32, 101, 110, 116, 114, 121, 10, 35, 32, 114, 97, 116, 104, - 101, 114, 32, 116, 104, 97, 110, 32, 111, 110, 101, 32, 112, 101, 114, 32, 102, 111, 114, 109, - 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, - 82, 101, 103, 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, - 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 68, 101, 115, 116, 114, 111, 121, 69, 120, - 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, - 32, 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, - 101, 115, 83, 116, 109, 116, 32, 47, 32, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 32, 47, 32, 67, 111, 110, 110, - 101, 99, 116, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, - 101, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, - 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, - 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, - 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, - 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 69, 120, 116, 101, 114, 110, 97, 108, - 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, - 111, 110, 115, 63, 10, 82, 101, 103, 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, - 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 82, 69, - 71, 73, 83, 84, 69, 82, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, - 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, - 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 39, - 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 101, 115, - 116, 114, 111, 121, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, - 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 69, 83, 84, 82, 79, 89, 39, 32, 69, 120, + 110, 41, 41, 10, 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 39, 85, 78, 80, 65, 67, 75, 39, 32, 80, 97, 114, 101, 110, 115, 40, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 121, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 89, 39, 32, 80, 97, 114, 101, 110, + 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 67, 111, 108, 117, 109, 110, + 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 83, + 121, 109, 98, 111, 108, 63, 32, 39, 67, 79, 76, 85, 77, 78, 83, 39, 32, 80, 97, 114, + 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, + 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 69, 88, + 84, 82, 65, 67, 84, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 116, 114, 97, 99, + 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, + 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 65, + 114, 103, 117, 109, 101, 110, 116, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 10, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 39, 76, 65, 77, 66, 68, 65, 39, 32, 76, 105, 115, 116, 40, + 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 32, 39, 58, 39, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 117, 108, 108, 73, 102, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 78, 85, 76, 76, 73, 70, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, + 115, 41, 10, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, + 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 44, 39, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 80, 111, 115, 105, 116, 105, 111, 110, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, + 32, 80, 97, 114, 101, 110, 115, 40, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, 103, 117, + 109, 101, 110, 116, 115, 41, 10, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, 103, 117, 109, + 101, 110, 116, 115, 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, + 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 82, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, + 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 83, 117, 98, + 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, + 39, 83, 85, 66, 83, 84, 82, 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, + 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 83, + 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, + 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, + 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 76, 105, 115, 116, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, + 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, + 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, 114, 32, 60, + 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, 116, 105, 111, + 110, 97, 108, 70, 111, 114, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, + 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, 116, 105, 111, + 110, 97, 108, 70, 111, 114, 32, 60, 45, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, + 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, 114, 32, 60, 45, 32, 70, 111, 114, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 114, 105, 109, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 73, 77, 39, 32, 80, 97, 114, 101, 110, + 115, 40, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 84, 114, 105, + 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 84, 114, 105, 109, 68, 105, + 114, 101, 99, 116, 105, 111, 110, 63, 32, 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 63, + 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, + 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 114, 105, 109, 66, + 111, 116, 104, 32, 47, 32, 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, 32, 47, 32, + 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, 10, 84, 114, 105, 109, 66, 111, 116, + 104, 32, 60, 45, 32, 39, 66, 79, 84, 72, 39, 10, 84, 114, 105, 109, 76, 101, 97, 100, + 105, 110, 103, 32, 60, 45, 32, 39, 76, 69, 65, 68, 73, 78, 71, 39, 10, 84, 114, 105, + 109, 84, 114, 97, 105, 108, 105, 110, 103, 32, 60, 45, 32, 39, 84, 82, 65, 73, 76, 73, + 78, 71, 39, 10, 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 70, 82, 79, 77, 39, 10, 79, 118, 101, + 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 79, + 86, 69, 82, 76, 65, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 118, 101, 114, 108, + 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 79, 118, 101, 114, 108, 97, 121, + 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 118, 101, 114, 108, 97, 121, + 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 79, 118, 101, 114, 108, + 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 39, 80, 76, 65, 67, 73, 78, 71, 39, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 70, 114, + 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 70, 82, 79, + 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 111, 114, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, + 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, + 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, 120, 116, 114, 97, + 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, 116, + 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, 114, 103, 117, + 109, 101, 110, 116, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, + 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 68, + 97, 116, 101, 80, 97, 114, 116, 10, 69, 120, 116, 114, 97, 99, 116, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 10, 69, 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, + 103, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, + 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, + 114, 116, 32, 60, 45, 10, 32, 32, 32, 32, 89, 101, 97, 114, 75, 101, 121, 119, 111, 114, + 100, 32, 47, 32, 77, 111, 110, 116, 104, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, + 97, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 72, 111, 117, 114, 75, 101, 121, 119, + 111, 114, 100, 32, 47, 32, 77, 105, 110, 117, 116, 101, 75, 101, 121, 119, 111, 114, 100, 32, + 47, 32, 83, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, 32, + 32, 32, 77, 105, 108, 108, 105, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, + 32, 47, 32, 77, 105, 99, 114, 111, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, + 100, 32, 47, 32, 87, 101, 101, 107, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 81, 117, + 97, 114, 116, 101, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, 101, 99, 97, 100, + 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 67, 101, 110, 116, 117, + 114, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 108, 108, 101, 110, 110, 105, + 117, 109, 75, 101, 121, 119, 111, 114, 100, 10, 35, 32, 69, 118, 101, 114, 121, 32, 115, 116, + 97, 116, 101, 109, 101, 110, 116, 32, 97, 98, 111, 117, 116, 32, 101, 120, 116, 101, 114, 110, + 97, 108, 32, 114, 101, 115, 111, 117, 114, 99, 101, 115, 44, 32, 115, 111, 32, 116, 104, 101, + 32, 116, 111, 112, 45, 108, 101, 118, 101, 108, 32, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 32, 99, 104, 111, 105, 99, 101, 32, 99, 97, 114, 114, 105, 101, 115, 32, 111, 110, 101, 32, + 101, 110, 116, 114, 121, 10, 35, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, + 111, 110, 101, 32, 112, 101, 114, 32, 102, 111, 114, 109, 46, 10, 69, 120, 116, 101, 114, 110, + 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, + 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 82, 101, 103, 105, 115, 116, 101, 114, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, + 32, 47, 32, 68, 101, 115, 116, 114, 111, 121, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, + 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 83, 104, 111, 119, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 115, 83, 116, 109, 116, 32, 47, + 32, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, + 111, 117, 114, 99, 101, 32, 47, 32, 67, 111, 110, 110, 101, 99, 116, 84, 111, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 10, 67, 114, 101, 97, 116, 101, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, + 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 69, 120, 116, 101, 114, 110, 97, + 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 83, 116, 114, + 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, + 97, 115, 63, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, + 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 82, 101, 103, + 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 82, 69, 71, 73, 83, 84, 69, 82, 39, 32, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, + 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, 116, + 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 101, 115, 116, 114, 111, 121, 69, 120, 116, 101, + 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, + 39, 68, 69, 83, 84, 82, 79, 89, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, + 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, + 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, + 115, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 72, 79, 87, 39, 32, 83, 104, 111, 119, + 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 63, 32, 39, 69, 88, 84, 69, 82, 78, + 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 83, 39, 10, 83, 104, 111, 119, + 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 65, 76, 76, 39, + 10, 35, 32, 83, 121, 110, 116, 97, 120, 32, 111, 110, 108, 121, 58, 32, 116, 104, 101, 32, + 107, 101, 121, 119, 111, 114, 100, 32, 112, 97, 105, 114, 32, 101, 118, 101, 114, 121, 32, 115, + 105, 110, 103, 117, 108, 97, 114, 32, 102, 111, 114, 109, 32, 114, 101, 112, 101, 97, 116, 115, + 46, 32, 84, 104, 101, 32, 112, 108, 117, 114, 97, 108, 32, 105, 110, 32, 83, 72, 79, 87, + 32, 99, 97, 110, 110, 111, 116, 32, 115, 104, 97, 114, 101, 32, 105, 116, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, - 100, 32, 67, 111, 108, 73, 100, 10, 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, - 82, 101, 115, 111, 117, 114, 99, 101, 115, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 72, - 79, 87, 39, 32, 83, 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 63, - 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, - 69, 83, 39, 10, 83, 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 32, - 60, 45, 32, 39, 65, 76, 76, 39, 10, 35, 32, 83, 121, 110, 116, 97, 120, 32, 111, 110, - 108, 121, 58, 32, 116, 104, 101, 32, 107, 101, 121, 119, 111, 114, 100, 32, 112, 97, 105, 114, - 32, 101, 118, 101, 114, 121, 32, 115, 105, 110, 103, 117, 108, 97, 114, 32, 102, 111, 114, 109, - 32, 114, 101, 112, 101, 97, 116, 115, 46, 32, 84, 104, 101, 32, 112, 108, 117, 114, 97, 108, - 32, 105, 110, 32, 83, 72, 79, 87, 32, 99, 97, 110, 110, 111, 116, 32, 115, 104, 97, 114, - 101, 32, 105, 116, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, - 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 69, 88, 84, 69, 82, 78, - 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 39, 10, 35, 32, 84, 104, 101, - 32, 114, 101, 99, 105, 112, 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, - 97, 109, 115, 46, 32, 73, 116, 115, 32, 111, 119, 110, 32, 114, 117, 108, 101, 32, 114, 97, - 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, - 111, 110, 115, 58, 32, 116, 104, 101, 32, 116, 119, 111, 32, 111, 112, 116, 105, 111, 110, 32, - 98, 97, 103, 115, 32, 97, 114, 101, 10, 35, 32, 100, 105, 115, 116, 105, 110, 99, 116, 44, - 32, 97, 110, 100, 32, 97, 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 97, 110, - 32, 99, 97, 114, 114, 121, 32, 98, 111, 116, 104, 46, 10, 69, 120, 116, 101, 114, 110, 97, - 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, - 105, 111, 110, 115, 32, 60, 45, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, - 112, 116, 105, 111, 110, 76, 105, 115, 116, 10, 35, 32, 84, 104, 101, 32, 97, 116, 116, 97, - 99, 104, 32, 97, 108, 105, 97, 115, 32, 105, 115, 32, 109, 97, 110, 100, 97, 116, 111, 114, - 121, 58, 32, 105, 116, 32, 115, 101, 112, 97, 114, 97, 116, 101, 115, 32, 116, 104, 101, 32, - 114, 101, 99, 105, 112, 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, - 109, 115, 44, 32, 119, 104, 105, 99, 104, 32, 112, 114, 101, 99, 101, 100, 101, 32, 105, 116, - 44, 32, 102, 114, 111, 109, 32, 116, 104, 101, 10, 35, 32, 97, 116, 116, 97, 99, 104, 109, - 101, 110, 116, 39, 115, 32, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 115, 44, 32, 119, - 104, 105, 99, 104, 32, 102, 111, 108, 108, 111, 119, 46, 32, 87, 105, 116, 104, 111, 117, 116, - 32, 105, 116, 32, 97, 32, 115, 105, 110, 103, 108, 101, 32, 111, 112, 116, 105, 111, 110, 32, - 108, 105, 115, 116, 32, 119, 111, 117, 108, 100, 32, 98, 101, 32, 97, 109, 98, 105, 103, 117, - 111, 117, 115, 46, 10, 35, 32, 67, 79, 78, 78, 69, 67, 84, 32, 104, 97, 115, 32, 110, - 111, 32, 115, 117, 99, 104, 32, 115, 101, 112, 97, 114, 97, 116, 111, 114, 46, 32, 66, 111, - 114, 114, 111, 119, 105, 110, 103, 32, 97, 32, 114, 101, 103, 105, 115, 116, 101, 114, 101, 100, - 32, 114, 101, 115, 111, 117, 114, 99, 101, 32, 104, 97, 115, 32, 110, 111, 32, 99, 114, 101, - 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 32, 116, 111, 32, 98, 101, 32, 99, 111, 110, - 102, 117, 115, 101, 100, 10, 35, 32, 119, 105, 116, 104, 44, 32, 115, 111, 32, 97, 32, 108, - 105, 115, 116, 32, 116, 104, 101, 114, 101, 32, 105, 115, 32, 116, 104, 101, 32, 99, 111, 110, - 110, 101, 99, 116, 105, 111, 110, 39, 115, 59, 32, 112, 114, 111, 118, 105, 115, 105, 111, 110, - 105, 110, 103, 32, 100, 111, 101, 115, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 116, 114, - 97, 110, 115, 102, 111, 114, 109, 101, 114, 32, 114, 101, 106, 101, 99, 116, 115, 32, 116, 104, - 101, 32, 115, 101, 99, 111, 110, 100, 10, 35, 32, 108, 105, 115, 116, 32, 114, 97, 116, 104, - 101, 114, 32, 116, 104, 97, 110, 32, 108, 101, 116, 32, 112, 111, 115, 105, 116, 105, 111, 110, - 32, 100, 101, 99, 105, 100, 101, 46, 10, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 65, 84, - 84, 65, 67, 72, 39, 32, 39, 84, 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, - 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, - 65, 108, 105, 97, 115, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, - 10, 67, 111, 110, 110, 101, 99, 116, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, - 115, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 67, 79, 78, 78, 69, 67, 84, 39, 32, - 39, 84, 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, - 101, 83, 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, - 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, - 111, 117, 114, 99, 101, 32, 60, 45, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, - 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 47, 32, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, - 114, 101, 110, 99, 101, 67, 108, 97, 117, 115, 101, 10, 69, 120, 116, 101, 114, 110, 97, 108, - 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 39, 78, 69, 87, 39, 32, 39, 84, 69, 77, 80, 79, 82, 65, 82, 89, - 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, - 121, 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, - 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, - 108, 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, - 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, 73, 110, - 115, 101, 114, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, - 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 73, 78, 83, 69, 82, 84, 39, 32, 79, 114, - 65, 99, 116, 105, 111, 110, 63, 32, 39, 73, 78, 84, 79, 39, 32, 73, 110, 115, 101, 114, - 116, 84, 97, 114, 103, 101, 116, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, - 116, 105, 111, 110, 63, 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, - 115, 116, 63, 32, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 79, 110, 67, - 111, 110, 102, 108, 105, 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, - 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 79, 114, 65, 99, 116, 105, 111, 110, - 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, - 47, 32, 73, 110, 115, 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, 10, 73, 110, 115, - 101, 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, 60, 45, 32, 39, 79, 82, 39, - 32, 39, 82, 69, 80, 76, 65, 67, 69, 39, 10, 73, 110, 115, 101, 114, 116, 79, 114, 73, - 103, 110, 111, 114, 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 73, 71, 78, 79, 82, - 69, 39, 10, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, - 60, 45, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, - 32, 47, 32, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, - 114, 100, 101, 114, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, - 101, 114, 32, 60, 45, 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, - 97, 109, 101, 10, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, - 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, - 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, - 97, 109, 101, 32, 60, 45, 32, 39, 78, 65, 77, 69, 39, 10, 73, 110, 115, 101, 114, 116, - 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, - 73, 79, 78, 39, 10, 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, - 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, - 116, 65, 108, 105, 97, 115, 63, 10, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 32, - 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, - 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, - 108, 73, 100, 41, 10, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, - 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, - 115, 116, 41, 10, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, - 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 47, - 32, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 10, 83, 101, 108, 101, 99, - 116, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, - 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, - 10, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, - 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 110, 67, - 111, 110, 102, 108, 105, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, - 39, 32, 39, 67, 79, 78, 70, 76, 73, 67, 84, 39, 32, 79, 110, 67, 111, 110, 102, 108, - 105, 99, 116, 84, 97, 114, 103, 101, 116, 63, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, - 116, 65, 99, 116, 105, 111, 110, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, - 114, 103, 101, 116, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 47, 32, 79, 110, 67, - 111, 110, 102, 108, 105, 99, 116, 73, 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 10, 79, - 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, - 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, - 116, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, - 102, 108, 105, 99, 116, 73, 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, - 39, 79, 78, 39, 32, 39, 67, 79, 78, 83, 84, 82, 65, 73, 78, 84, 39, 32, 67, 111, - 110, 115, 116, 114, 97, 105, 110, 116, 78, 97, 109, 101, 10, 79, 110, 67, 111, 110, 102, 108, - 105, 99, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, - 105, 99, 116, 85, 112, 100, 97, 116, 101, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, - 99, 116, 78, 111, 116, 104, 105, 110, 103, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, - 85, 112, 100, 97, 116, 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 85, 80, 68, 65, - 84, 69, 39, 32, 39, 83, 69, 84, 39, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, - 108, 97, 117, 115, 101, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, - 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, 116, 104, 105, 110, 103, 32, 60, 45, 32, - 39, 68, 79, 39, 32, 39, 78, 79, 84, 72, 73, 78, 71, 39, 10, 82, 101, 116, 117, 114, - 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 82, 69, 84, 85, 82, - 78, 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 76, 111, 97, - 100, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 76, 79, 65, 68, 39, - 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 70, 114, 111, 109, 83, - 111, 117, 114, 99, 101, 63, 32, 69, 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, - 115, 63, 10, 69, 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 32, 60, 45, - 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 73, 110, 115, - 116, 97, 108, 108, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, - 82, 67, 69, 39, 63, 32, 39, 73, 78, 83, 84, 65, 76, 76, 39, 32, 73, 110, 115, 116, - 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 70, 114, - 111, 109, 83, 111, 117, 114, 99, 101, 63, 32, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, - 98, 101, 114, 63, 10, 73, 110, 115, 116, 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 32, - 60, 45, 32, 39, 65, 78, 68, 39, 32, 39, 76, 79, 65, 68, 39, 10, 85, 112, 100, 97, - 116, 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 115, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 69, 88, 84, 69, 78, - 83, 73, 79, 78, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 41, 41, 63, 10, 70, 114, 111, 109, 83, 111, 117, - 114, 99, 101, 32, 60, 45, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, - 83, 116, 114, 105, 110, 103, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, - 116, 114, 105, 110, 103, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 83, 116, 114, 105, - 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, - 98, 101, 114, 32, 60, 45, 32, 39, 86, 69, 82, 83, 73, 79, 78, 39, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 10, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, - 114, 121, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, - 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, - 83, 116, 109, 116, 32, 47, 32, 68, 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, - 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 10, 67, 114, 101, 97, 116, - 101, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, - 83, 116, 109, 116, 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, - 101, 112, 108, 97, 99, 101, 63, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, - 39, 82, 69, 80, 79, 83, 73, 84, 79, 82, 89, 39, 32, 73, 102, 78, 111, 116, 69, 120, - 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, - 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 114, 101, 102, 105, 120, 32, 82, 101, 112, - 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, 105, 99, 75, 101, 121, 63, 10, 82, 101, - 112, 111, 115, 105, 116, 111, 114, 121, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 87, - 73, 84, 72, 39, 63, 32, 39, 80, 82, 69, 70, 73, 88, 39, 32, 83, 116, 114, 105, 110, - 103, 76, 105, 116, 101, 114, 97, 108, 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, - 117, 98, 108, 105, 99, 75, 101, 121, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 63, - 32, 39, 80, 85, 66, 76, 73, 67, 39, 32, 40, 39, 75, 69, 89, 83, 39, 32, 47, 32, - 39, 75, 69, 89, 39, 41, 32, 76, 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, - 116, 101, 114, 97, 108, 41, 10, 68, 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, - 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, - 82, 79, 80, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, - 80, 79, 83, 73, 84, 79, 82, 89, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 77, 101, 114, 103, 101, 73, - 110, 116, 111, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, - 67, 108, 97, 117, 115, 101, 63, 32, 39, 77, 69, 82, 71, 69, 39, 32, 39, 73, 78, 84, - 79, 39, 32, 84, 97, 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 77, 101, - 114, 103, 101, 73, 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 74, - 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, 77, 101, 114, 103, 101, 77, 97, - 116, 99, 104, 43, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, - 63, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 84, 97, 98, 108, 101, 82, - 101, 102, 10, 77, 101, 114, 103, 101, 77, 97, 116, 99, 104, 32, 60, 45, 32, 77, 97, 116, - 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 47, 32, 78, 111, 116, 77, 97, 116, 99, - 104, 101, 100, 67, 108, 97, 117, 115, 101, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 78, 39, 32, 39, 77, 65, 84, 67, 72, - 69, 68, 39, 32, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, - 84, 72, 69, 78, 39, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, - 99, 116, 105, 111, 110, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, - 99, 116, 105, 111, 110, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, - 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 69, 114, 114, 111, 114, 77, 97, 116, - 99, 104, 67, 108, 97, 117, 115, 101, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, - 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, 10, 85, 112, 100, 97, - 116, 101, 77, 97, 116, 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, - 101, 77, 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 47, 32, 85, 112, + 100, 32, 60, 45, 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, + 79, 85, 82, 67, 69, 39, 10, 35, 32, 84, 104, 101, 32, 114, 101, 99, 105, 112, 101, 39, + 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 46, 32, 73, 116, 115, + 32, 111, 119, 110, 32, 114, 117, 108, 101, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, 97, + 110, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 58, 32, 116, 104, 101, + 32, 116, 119, 111, 32, 111, 112, 116, 105, 111, 110, 32, 98, 97, 103, 115, 32, 97, 114, 101, + 10, 35, 32, 100, 105, 115, 116, 105, 110, 99, 116, 44, 32, 97, 110, 100, 32, 97, 32, 115, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 97, 110, 32, 99, 97, 114, 114, 121, 32, 98, + 111, 116, 104, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, + 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, + 116, 10, 35, 32, 84, 104, 101, 32, 97, 116, 116, 97, 99, 104, 32, 97, 108, 105, 97, 115, + 32, 105, 115, 32, 109, 97, 110, 100, 97, 116, 111, 114, 121, 58, 32, 105, 116, 32, 115, 101, + 112, 97, 114, 97, 116, 101, 115, 32, 116, 104, 101, 32, 114, 101, 99, 105, 112, 101, 39, 115, + 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 44, 32, 119, 104, 105, 99, + 104, 32, 112, 114, 101, 99, 101, 100, 101, 32, 105, 116, 44, 32, 102, 114, 111, 109, 32, 116, + 104, 101, 10, 35, 32, 97, 116, 116, 97, 99, 104, 109, 101, 110, 116, 39, 115, 32, 111, 119, + 110, 32, 111, 112, 116, 105, 111, 110, 115, 44, 32, 119, 104, 105, 99, 104, 32, 102, 111, 108, + 108, 111, 119, 46, 32, 87, 105, 116, 104, 111, 117, 116, 32, 105, 116, 32, 97, 32, 115, 105, + 110, 103, 108, 101, 32, 111, 112, 116, 105, 111, 110, 32, 108, 105, 115, 116, 32, 119, 111, 117, + 108, 100, 32, 98, 101, 32, 97, 109, 98, 105, 103, 117, 111, 117, 115, 46, 10, 35, 32, 67, + 79, 78, 78, 69, 67, 84, 32, 104, 97, 115, 32, 110, 111, 32, 115, 117, 99, 104, 32, 115, + 101, 112, 97, 114, 97, 116, 111, 114, 46, 32, 66, 111, 114, 114, 111, 119, 105, 110, 103, 32, + 97, 32, 114, 101, 103, 105, 115, 116, 101, 114, 101, 100, 32, 114, 101, 115, 111, 117, 114, 99, + 101, 32, 104, 97, 115, 32, 110, 111, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, + 109, 115, 32, 116, 111, 32, 98, 101, 32, 99, 111, 110, 102, 117, 115, 101, 100, 10, 35, 32, + 119, 105, 116, 104, 44, 32, 115, 111, 32, 97, 32, 108, 105, 115, 116, 32, 116, 104, 101, 114, + 101, 32, 105, 115, 32, 116, 104, 101, 32, 99, 111, 110, 110, 101, 99, 116, 105, 111, 110, 39, + 115, 59, 32, 112, 114, 111, 118, 105, 115, 105, 111, 110, 105, 110, 103, 32, 100, 111, 101, 115, + 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 101, + 114, 32, 114, 101, 106, 101, 99, 116, 115, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, + 10, 35, 32, 108, 105, 115, 116, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, + 108, 101, 116, 32, 112, 111, 115, 105, 116, 105, 111, 110, 32, 100, 101, 99, 105, 100, 101, 46, + 10, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, + 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 65, 84, 84, 65, 67, 72, 39, 32, 39, 84, + 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, + 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 32, 65, 116, + 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 67, 111, 110, 110, 101, 99, 116, + 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 32, 60, + 45, 32, 39, 67, 79, 78, 78, 69, 67, 84, 39, 32, 39, 84, 79, 39, 32, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, 32, + 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, + 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, 32, 60, 45, + 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, + 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 47, 32, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, 97, + 117, 115, 101, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, + 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 78, 69, 87, + 39, 32, 39, 84, 69, 77, 80, 79, 82, 65, 82, 89, 39, 32, 69, 120, 116, 101, 114, 110, + 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 83, 116, + 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, + 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, + 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, 73, 110, 115, 101, 114, 116, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, + 32, 39, 73, 78, 83, 69, 82, 84, 39, 32, 79, 114, 65, 99, 116, 105, 111, 110, 63, 32, + 39, 73, 78, 84, 79, 39, 32, 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, + 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 63, 32, 73, 110, + 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 73, 110, 115, 101, + 114, 116, 86, 97, 108, 117, 101, 115, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 67, + 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, + 115, 101, 63, 10, 79, 114, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, 115, 101, + 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, 47, 32, 73, 110, 115, 101, 114, 116, + 79, 114, 73, 103, 110, 111, 114, 101, 10, 73, 110, 115, 101, 114, 116, 79, 114, 82, 101, 112, + 108, 97, 99, 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 82, 69, 80, 76, 65, 67, + 69, 39, 10, 73, 110, 115, 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, 32, 60, 45, + 32, 39, 79, 82, 39, 32, 39, 73, 71, 78, 79, 82, 69, 39, 10, 66, 121, 78, 97, 109, + 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, 115, 101, 114, + 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 47, 32, 73, 110, 115, 101, 114, + 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 10, 73, 110, 115, + 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 66, + 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 10, 73, 110, 115, 101, + 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 32, 60, 45, + 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, + 111, 110, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 39, + 78, 65, 77, 69, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, + 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, 10, 73, 110, 115, + 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, + 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 63, 10, + 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 117, 109, 110, 76, 105, 115, + 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 41, 10, 73, 110, 115, + 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, + 101, 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, 10, 73, 110, 115, 101, + 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 73, 110, + 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 68, 101, 102, 97, 117, 108, 116, + 86, 97, 108, 117, 101, 115, 10, 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, 114, 116, 86, + 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 68, 101, 102, 97, 117, 108, 116, + 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, + 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, 78, 70, 76, + 73, 67, 84, 39, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, + 116, 63, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, 111, 110, 10, + 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, + 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 84, 97, 114, 103, 101, 116, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 73, + 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, + 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, + 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 32, 87, 104, 101, 114, 101, 67, + 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 73, 110, 100, + 101, 120, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, + 78, 83, 84, 82, 65, 73, 78, 84, 39, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 78, 97, 109, 101, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, 111, + 110, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, + 101, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, 116, 104, 105, 110, + 103, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, 101, 32, 60, + 45, 32, 39, 68, 79, 39, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 83, 69, 84, + 39, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 87, 104, + 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, + 116, 78, 111, 116, 104, 105, 110, 103, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, + 84, 72, 73, 78, 71, 39, 10, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 82, 69, 84, 85, 82, 78, 73, 78, 71, 39, 32, 84, 97, + 114, 103, 101, 116, 76, 105, 115, 116, 10, 76, 111, 97, 100, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 60, 45, 32, 39, 76, 79, 65, 68, 39, 32, 67, 111, 108, 73, 100, 79, 114, + 83, 116, 114, 105, 110, 103, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 63, 32, 69, + 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 63, 10, 69, 120, 116, 101, 110, + 115, 105, 111, 110, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 10, 73, 110, 115, 116, 97, 108, 108, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 63, 32, 39, 73, + 78, 83, 84, 65, 76, 76, 39, 32, 73, 110, 115, 116, 97, 108, 108, 65, 110, 100, 76, 111, + 97, 100, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, + 63, 32, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 63, 10, 73, 110, 115, + 116, 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 32, 60, 45, 32, 39, 65, 78, 68, 39, + 32, 39, 76, 79, 65, 68, 39, 10, 85, 112, 100, 97, 116, 101, 69, 120, 116, 101, 110, 115, + 105, 111, 110, 115, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 85, 80, + 68, 65, 84, 69, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 83, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 41, 41, 63, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 70, + 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, + 47, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, 10, 70, + 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, + 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, 32, 60, 45, + 32, 39, 70, 82, 79, 77, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, + 108, 10, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 32, 60, 45, 32, 39, + 86, 69, 82, 83, 73, 79, 78, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, + 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 101, 110, + 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, + 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 47, 32, 68, + 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, + 114, 121, 83, 116, 109, 116, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, + 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, + 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, 101, 63, 32, + 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, 83, 73, 84, + 79, 82, 89, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, + 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 82, 101, 112, 111, 115, 105, 116, 111, + 114, 121, 80, 114, 101, 102, 105, 120, 32, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, + 117, 98, 108, 105, 99, 75, 101, 121, 63, 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, + 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 63, 32, 39, 80, + 82, 69, 70, 73, 88, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, 105, 99, 75, 101, 121, + 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 63, 32, 39, 80, 85, 66, 76, 73, 67, + 39, 32, 40, 39, 75, 69, 89, 83, 39, 32, 47, 32, 39, 75, 69, 89, 39, 41, 32, 76, + 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 41, 10, 68, + 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, + 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 39, 69, 88, + 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, 83, 73, 84, 79, 82, 89, + 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, 79, 114, 83, + 116, 114, 105, 110, 103, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, + 39, 77, 69, 82, 71, 69, 39, 32, 39, 73, 78, 84, 79, 39, 32, 84, 97, 114, 103, 101, + 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 77, 101, 114, 103, 101, 73, 110, 116, 111, 85, + 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, + 102, 105, 101, 114, 32, 77, 101, 114, 103, 101, 77, 97, 116, 99, 104, 43, 32, 82, 101, 116, + 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 77, 101, 114, 103, 101, 73, + 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, + 83, 73, 78, 71, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 10, 77, 101, 114, 103, 101, + 77, 97, 116, 99, 104, 32, 60, 45, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, + 115, 101, 32, 47, 32, 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, + 101, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, + 87, 72, 69, 78, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, 65, 110, 100, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, 32, 77, 97, + 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 10, 77, 97, + 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 32, 60, 45, + 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, + 32, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, + 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, + 32, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, + 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, + 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, + 99, 104, 73, 110, 102, 111, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 73, + 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, + 116, 65, 99, 116, 105, 111, 110, 32, 47, 32, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, + 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 77, + 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 85, 112, 100, + 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, 10, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, - 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, - 110, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, - 108, 97, 117, 115, 101, 10, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, 114, - 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, - 80, 111, 115, 105, 116, 105, 111, 110, 10, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 73, - 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 39, 73, 78, 83, 69, 82, 84, 39, 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, - 73, 110, 102, 111, 63, 10, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, - 111, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, - 116, 32, 47, 32, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, - 117, 101, 115, 32, 47, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, - 80, 111, 115, 105, 116, 105, 111, 110, 10, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, - 108, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, - 39, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, - 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, - 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 63, 32, 39, 42, 39, 63, 10, - 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 60, 45, 32, - 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 39, 86, - 65, 76, 85, 69, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 68, 111, 78, 111, 116, 104, 105, 110, - 103, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 79, 39, - 32, 39, 78, 79, 84, 72, 73, 78, 71, 39, 10, 69, 114, 114, 111, 114, 77, 97, 116, 99, - 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 69, 82, 82, 79, 82, 39, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, - 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 84, 39, - 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 10, - 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 32, 60, - 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, - 83, 116, 97, 114, 83, 121, 109, 98, 111, 108, 10, 65, 110, 100, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 39, 65, 78, 68, 39, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 10, 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 87, 72, 69, 78, 39, 32, 39, 78, 79, 84, 39, 32, 39, 77, - 65, 84, 67, 72, 69, 68, 39, 32, 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, - 114, 103, 101, 116, 63, 32, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, - 32, 39, 84, 72, 69, 78, 39, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, - 101, 65, 99, 116, 105, 111, 110, 10, 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, - 114, 103, 101, 116, 32, 60, 45, 32, 66, 121, 83, 111, 117, 114, 99, 101, 32, 47, 32, 66, - 121, 84, 97, 114, 103, 101, 116, 10, 66, 121, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, - 39, 66, 89, 39, 32, 39, 83, 79, 85, 82, 67, 69, 39, 10, 66, 121, 84, 97, 114, 103, - 101, 116, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 84, 65, 82, 71, 69, 84, 39, 10, - 80, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 105, - 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, - 80, 105, 118, 111, 116, 79, 110, 63, 32, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 63, - 32, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, - 105, 118, 111, 116, 79, 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 80, 105, 118, 111, 116, - 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 85, 115, 105, 110, - 103, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, - 105, 115, 116, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, - 60, 45, 32, 76, 105, 115, 116, 40, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, - 110, 116, 114, 121, 41, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, - 114, 121, 32, 60, 45, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, - 113, 117, 101, 114, 121, 32, 47, 32, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, - 115, 116, 32, 47, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, - 114, 121, 32, 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 39, 73, 78, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 80, 105, - 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, - 39, 32, 47, 32, 39, 80, 73, 86, 79, 84, 95, 87, 73, 68, 69, 82, 39, 10, 85, 110, - 112, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 85, 78, 80, - 73, 86, 79, 84, 39, 32, 47, 32, 39, 80, 73, 86, 79, 84, 95, 76, 79, 78, 71, 69, - 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, - 98, 108, 101, 82, 101, 102, 32, 39, 79, 78, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, - 115, 116, 32, 73, 110, 116, 111, 78, 97, 109, 101, 86, 97, 108, 117, 101, 115, 63, 10, 73, - 110, 116, 111, 78, 97, 109, 101, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 73, 78, - 84, 79, 39, 32, 39, 78, 65, 77, 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, - 114, 105, 110, 103, 32, 86, 97, 108, 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 79, - 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, - 116, 10, 86, 97, 108, 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, - 86, 65, 76, 85, 69, 39, 32, 47, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 112, - 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, - 32, 60, 45, 32, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, - 101, 76, 105, 115, 116, 32, 47, 32, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, - 10, 80, 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, - 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, - 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 66, 97, 114, 101, 78, 97, - 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, - 79, 114, 83, 116, 114, 105, 110, 103, 41, 10, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, - 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 73, 110, 99, 108, 117, - 100, 101, 78, 117, 108, 108, 115, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, - 108, 115, 10, 73, 110, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, - 73, 78, 67, 76, 85, 68, 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 69, 120, 99, - 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, - 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, - 97, 100, 101, 114, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, - 114, 83, 105, 110, 103, 108, 101, 32, 47, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, - 100, 101, 114, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, - 114, 83, 105, 110, 103, 108, 101, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, - 114, 105, 110, 103, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, - 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, - 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 80, 114, 97, 103, 109, 97, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 65, 71, 77, 65, - 39, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, - 116, 105, 111, 110, 10, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, - 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, - 105, 103, 110, 32, 47, 32, 80, 114, 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, - 10, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 32, 60, 45, 32, 83, 101, 116, - 116, 105, 110, 103, 78, 97, 109, 101, 32, 39, 61, 39, 32, 86, 97, 114, 105, 97, 98, 108, - 101, 76, 105, 115, 116, 10, 80, 114, 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, - 32, 60, 45, 32, 80, 114, 97, 103, 109, 97, 78, 97, 109, 101, 32, 80, 114, 97, 103, 109, - 97, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 63, 10, 80, 114, 97, 103, 109, 97, 80, - 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, - 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 80, 114, - 101, 112, 97, 114, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, - 82, 69, 80, 65, 82, 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, - 103, 32, 84, 121, 112, 101, 76, 105, 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, - 116, 101, 109, 101, 110, 116, 10, 84, 121, 112, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 84, 121, 112, 101, 41, 41, 10, 83, 101, - 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 108, - 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, - 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, - 114, 110, 97, 108, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, - 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 32, 82, 101, 115, - 117, 108, 116, 77, 111, 100, 105, 102, 105, 101, 114, 115, 63, 10, 83, 101, 108, 101, 99, 116, - 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 32, 60, 45, 32, 73, 110, 116, 101, 114, 115, - 101, 99, 116, 67, 104, 97, 105, 110, 32, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, - 67, 104, 97, 105, 110, 84, 97, 105, 108, 42, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, - 79, 112, 67, 104, 97, 105, 110, 84, 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 111, 112, - 67, 108, 97, 117, 115, 101, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, - 110, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 32, 60, 45, 32, - 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, - 67, 104, 97, 105, 110, 84, 97, 105, 108, 42, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, - 67, 104, 97, 105, 110, 84, 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 73, 110, 116, 101, - 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 65, 116, - 111, 109, 10, 83, 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 83, 69, 67, 84, 39, 32, 68, 105, 115, - 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, 10, 83, 101, 108, 101, 99, 116, 65, 116, - 111, 109, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, - 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, - 10, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, - 110, 116, 101, 114, 110, 97, 108, 41, 10, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 83, 101, 116, 111, 112, 84, 121, 112, 101, 32, 68, 105, 115, 116, 105, 110, - 99, 116, 79, 114, 65, 108, 108, 63, 32, 66, 121, 78, 97, 109, 101, 63, 10, 83, 101, 116, - 111, 112, 84, 121, 112, 101, 32, 60, 45, 32, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, - 32, 47, 32, 83, 101, 116, 111, 112, 69, 120, 99, 101, 112, 116, 10, 83, 101, 116, 111, 112, - 85, 110, 105, 111, 110, 32, 60, 45, 32, 39, 85, 78, 73, 79, 78, 39, 10, 83, 101, 116, - 111, 112, 69, 120, 99, 101, 112, 116, 32, 60, 45, 32, 39, 69, 88, 67, 69, 80, 84, 39, - 10, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 78, 65, 77, - 69, 39, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, - 112, 101, 32, 60, 45, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, - 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 47, 32, 86, 97, 108, 117, 101, - 115, 67, 108, 97, 117, 115, 101, 32, 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 32, 47, 32, 80, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 47, 32, 85, 110, 112, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 10, 82, 101, 115, 117, 108, 116, 77, 111, 100, 105, 102, 105, 101, 114, 115, 32, 60, 45, 32, - 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 76, 105, 109, 105, 116, - 79, 102, 102, 115, 101, 116, 63, 10, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 32, - 60, 45, 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, - 32, 47, 32, 79, 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, - 32, 47, 32, 79, 102, 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, - 32, 47, 32, 70, 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 10, 76, - 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, - 97, 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, - 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 70, - 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, - 67, 108, 97, 117, 115, 101, 32, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 70, - 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, - 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 66, 97, 115, 101, - 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, - 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, - 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, - 32, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 10, 83, 105, 109, 112, 108, 101, - 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 115, 40, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 41, 10, 83, 105, 109, - 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, - 114, 111, 109, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 71, 114, 111, - 117, 112, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 72, 97, 118, 105, 110, 103, 67, 108, - 97, 117, 115, 101, 63, 32, 87, 105, 110, 100, 111, 119, 67, 108, 97, 117, 115, 101, 63, 32, - 81, 117, 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, 108, - 101, 67, 108, 97, 117, 115, 101, 63, 10, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 32, - 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, - 47, 32, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 10, 83, - 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, - 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, - 115, 101, 63, 10, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, - 32, 60, 45, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, - 116, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, - 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 32, 85, 115, 105, 110, 103, - 75, 101, 121, 63, 32, 39, 65, 83, 39, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, - 101, 100, 63, 32, 67, 84, 69, 66, 111, 100, 121, 10, 67, 84, 69, 66, 111, 100, 121, 32, - 60, 45, 32, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, 121, 32, 47, 32, 67, - 84, 69, 68, 77, 76, 66, 111, 100, 121, 10, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, - 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 67, - 84, 69, 68, 77, 76, 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, - 83, 116, 97, 116, 101, 109, 101, 110, 116, 41, 10, 85, 115, 105, 110, 103, 75, 101, 121, 32, - 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 75, 69, 89, 39, 32, 80, 97, 114, - 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 77, 97, 116, 101, - 114, 105, 97, 108, 105, 122, 101, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 63, 32, 39, - 77, 65, 84, 69, 82, 73, 65, 76, 73, 90, 69, 68, 39, 10, 87, 105, 116, 104, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 99, 117, 114, - 115, 105, 118, 101, 63, 32, 76, 105, 115, 116, 40, 87, 105, 116, 104, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 41, 10, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, 45, 32, 39, - 82, 69, 67, 85, 82, 83, 73, 86, 69, 39, 10, 83, 101, 108, 101, 99, 116, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 76, 69, 67, 84, 39, 32, 68, 105, 115, 116, - 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 84, 97, 114, 103, 101, 116, 76, 105, - 115, 116, 63, 10, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, - 115, 116, 40, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 41, 10, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 32, 60, 45, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, - 114, 105, 110, 103, 41, 41, 10, 68, 105, 115, 116, 105, 110, 99, 116, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, 47, 32, 68, 105, - 115, 116, 105, 110, 99, 116, 65, 108, 108, 10, 68, 105, 115, 116, 105, 110, 99, 116, 65, 108, - 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 68, 105, 115, 116, 105, 110, 99, 116, 79, - 110, 32, 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 68, 105, 115, 116, - 105, 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 63, 10, 68, 105, 115, 116, 105, - 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 32, 60, 45, 32, 39, 79, 78, 39, - 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 41, 41, 10, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, 32, - 60, 45, 32, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 47, 32, 84, 97, 98, 108, 101, - 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 84, 97, 98, 108, 101, 83, 117, 98, 113, - 117, 101, 114, 121, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, - 47, 32, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 84, 97, 98, - 108, 101, 82, 101, 102, 32, 60, 45, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, - 101, 102, 32, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 42, 10, 84, 97, 98, 108, - 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, - 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, - 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 84, 97, 98, - 108, 101, 65, 108, 105, 97, 115, 63, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, - 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, - 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 84, 97, 98, 108, - 101, 65, 108, 105, 97, 115, 63, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, - 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, - 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, - 114, 105, 110, 103, 32, 39, 58, 39, 10, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, - 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 86, - 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 84, 97, 98, 108, 101, 65, 108, 105, - 97, 115, 63, 10, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, - 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 80, - 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 84, 97, 98, 108, - 101, 65, 108, 105, 97, 115, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, - 63, 10, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 32, 60, 45, 32, 74, 111, 105, - 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, - 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, - 116, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 80, 97, 114, 101, - 110, 115, 40, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, - 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, - 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, - 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 39, 70, 79, 82, 39, 32, 80, 105, - 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 32, 80, 105, 118, 111, 116, 71, - 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 71, 114, 111, - 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, - 39, 66, 89, 39, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, - 97, 109, 101, 76, 105, 115, 116, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, - 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, - 115, 63, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, - 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, - 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, - 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, - 101, 97, 100, 101, 114, 32, 39, 70, 79, 82, 39, 32, 85, 110, 112, 105, 118, 111, 116, 86, - 97, 108, 117, 101, 76, 105, 115, 116, 43, 10, 80, 105, 118, 111, 116, 72, 101, 97, 100, 101, - 114, 32, 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, - 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 105, - 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 80, 105, 118, 111, 116, - 86, 97, 108, 117, 101, 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 86, 97, 108, - 117, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 69, 110, 117, - 109, 84, 97, 114, 103, 101, 116, 32, 47, 32, 80, 105, 118, 111, 116, 76, 105, 115, 116, 84, - 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, 97, 114, 103, 101, - 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 105, 118, 111, - 116, 76, 105, 115, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, - 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 86, 97, - 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, - 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, - 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, - 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, - 76, 105, 115, 116, 41, 10, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, - 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, - 76, 105, 115, 116, 41, 10, 76, 97, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 76, 65, - 84, 69, 82, 65, 76, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, - 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, - 109, 101, 32, 47, 32, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, 97, 115, 101, - 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, - 100, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 84, 97, - 98, 108, 101, 78, 97, 109, 101, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, - 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, - 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 32, 47, 32, 83, - 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 10, 83, - 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 32, 60, - 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, - 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, - 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, - 97, 84, 97, 98, 108, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, - 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, - 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, - 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 84, 97, - 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, 101, - 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, 47, - 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, - 111, 108, 111, 110, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, - 116, 101, 114, 97, 108, 79, 112, 116, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, + 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, + 10, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, + 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 73, 110, 115, 101, 114, 116, 77, 97, 116, + 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, 83, 69, 82, 84, 39, + 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, 10, 73, 110, + 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, 73, 110, 115, + 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 47, 32, 73, 110, 115, 101, + 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 73, 110, + 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, + 10, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, + 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, 76, 85, 69, + 83, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, + 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, + 105, 116, 105, 111, 110, 63, 32, 39, 42, 39, 63, 10, 73, 110, 115, 101, 114, 116, 86, 97, + 108, 117, 101, 115, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 67, 111, + 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 41, 41, 10, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, 84, 72, 73, 78, + 71, 39, 10, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, + 60, 45, 32, 39, 69, 82, 82, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, + 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 85, 112, 100, 97, 116, 101, 77, + 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 10, 85, 112, 100, 97, 116, 101, 77, 97, + 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 83, 116, 97, 114, 83, 121, 109, 98, + 111, 108, 10, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, + 39, 65, 78, 68, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 111, 116, + 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, + 69, 78, 39, 32, 39, 78, 79, 84, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, + 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 63, 32, 65, 110, + 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, 32, + 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 10, + 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, + 66, 121, 83, 111, 117, 114, 99, 101, 32, 47, 32, 66, 121, 84, 97, 114, 103, 101, 116, 10, + 66, 121, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 83, 79, + 85, 82, 67, 69, 39, 10, 66, 121, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 66, + 89, 39, 32, 39, 84, 65, 82, 71, 69, 84, 39, 10, 80, 105, 118, 111, 116, 83, 116, 97, + 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 75, 101, 121, 119, 111, + 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 80, 105, 118, 111, 116, 79, 110, 63, + 32, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 63, 32, 80, 105, 118, 111, 116, 71, 114, + 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 79, 110, 32, 60, + 45, 32, 39, 79, 78, 39, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 76, 105, + 115, 116, 10, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 32, 60, 45, 32, 39, 85, 83, + 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, + 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, + 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 41, 10, 80, 105, + 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 32, 60, 45, 32, 80, 105, + 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, + 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 47, 32, 80, 105, 118, + 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, + 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, 116, + 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 66, 97, + 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, 80, 97, + 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 80, 105, 118, 111, 116, 75, 101, 121, 119, 111, + 114, 100, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 47, 32, 39, 80, 73, 86, + 79, 84, 95, 87, 73, 68, 69, 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, 75, 101, 121, + 119, 111, 114, 100, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, 47, 32, + 39, 80, 73, 86, 79, 84, 95, 76, 79, 78, 71, 69, 82, 39, 10, 85, 110, 112, 105, 118, + 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, + 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 39, + 79, 78, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 73, 110, 116, 111, 78, + 97, 109, 101, 86, 97, 108, 117, 101, 115, 63, 10, 73, 110, 116, 111, 78, 97, 109, 101, 86, + 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 73, 78, 84, 79, 39, 32, 39, 78, 65, 77, + 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 86, 97, 108, + 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, + 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 10, 86, 97, 108, 117, 101, 79, + 114, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, 39, 32, 47, + 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, + 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, + 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 47, 32, + 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, 10, 80, 97, 114, 101, 110, 116, 104, + 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, + 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, + 105, 110, 103, 41, 41, 10, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, + 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, + 41, 10, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, + 108, 108, 115, 32, 60, 45, 32, 73, 110, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, + 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 10, 73, 110, 99, 108, 117, + 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 73, 78, 67, 76, 85, 68, 69, 39, + 32, 39, 78, 85, 76, 76, 83, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, + 115, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 39, 78, 85, 76, 76, + 83, 39, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 60, 45, 32, + 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, 108, 101, 32, + 47, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 10, + 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, 108, 101, 32, + 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 85, 110, 112, + 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, + 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, + 105, 110, 103, 41, 41, 10, 80, 114, 97, 103, 109, 97, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 32, 60, 45, 32, 39, 80, 82, 65, 71, 77, 65, 39, 32, 80, 114, 97, 103, 109, 97, + 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, + 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 32, + 60, 45, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 32, 47, 32, 80, 114, + 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, 103, 109, 97, 65, + 115, 115, 105, 103, 110, 32, 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, + 32, 39, 61, 39, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 10, 80, 114, + 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 80, 114, 97, 103, + 109, 97, 78, 97, 109, 101, 32, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, 116, + 101, 114, 115, 63, 10, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, 116, 101, 114, + 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 80, 114, 101, 112, 97, 114, 101, 83, 116, 97, + 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 69, 80, 65, 82, 69, 39, 32, + 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 84, 121, 112, 101, 76, 105, + 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 84, + 121, 112, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, + 115, 116, 40, 84, 121, 112, 101, 41, 41, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 83, 101, 108, 101, 99, 116, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 32, 60, 45, 32, + 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 83, 101, 108, 101, 99, 116, 83, 101, + 116, 79, 112, 67, 104, 97, 105, 110, 32, 82, 101, 115, 117, 108, 116, 77, 111, 100, 105, 102, + 105, 101, 114, 115, 63, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, + 105, 110, 32, 60, 45, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, + 32, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 84, 97, 105, + 108, 42, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 84, + 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, 32, 73, + 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 10, 73, 110, 116, 101, 114, 115, + 101, 99, 116, 67, 104, 97, 105, 110, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 65, 116, + 111, 109, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 84, 97, 105, + 108, 42, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 84, 97, 105, + 108, 32, 60, 45, 32, 83, 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, + 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 10, 83, 101, 116, 73, 110, + 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, + 84, 69, 82, 83, 69, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, + 108, 108, 63, 10, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 32, 60, 45, 32, 83, 101, + 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, 32, 83, 101, 108, 101, 99, 116, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, 10, 83, 101, 108, 101, 99, 116, 80, + 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, + 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, + 10, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, 101, 116, 111, + 112, 84, 121, 112, 101, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, + 32, 66, 121, 78, 97, 109, 101, 63, 10, 83, 101, 116, 111, 112, 84, 121, 112, 101, 32, 60, + 45, 32, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, 32, 47, 32, 83, 101, 116, 111, 112, + 69, 120, 99, 101, 112, 116, 10, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, 32, 60, 45, + 32, 39, 85, 78, 73, 79, 78, 39, 10, 83, 101, 116, 111, 112, 69, 120, 99, 101, 112, 116, + 32, 60, 45, 32, 39, 69, 88, 67, 69, 80, 84, 39, 10, 66, 121, 78, 97, 109, 101, 32, + 60, 45, 32, 39, 66, 89, 39, 32, 39, 78, 65, 77, 69, 39, 10, 83, 101, 108, 101, 99, + 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, 32, 60, 45, 32, 79, 112, + 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, + 108, 101, 99, 116, 32, 47, 32, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, + 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 47, 32, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 80, + 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 85, 110, 112, 105, + 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 82, 101, 115, 117, 108, 116, 77, + 111, 100, 105, 102, 105, 101, 114, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 67, + 108, 97, 117, 115, 101, 63, 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 63, 10, + 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 32, 60, 45, 32, 76, 105, 109, 105, 116, + 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, 102, 115, 101, + 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, 102, 115, 101, + 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, 116, 99, 104, + 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, 116, 99, 104, + 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 10, 76, 105, 109, 105, 116, 79, 102, 102, 115, + 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 67, 108, 97, + 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 63, 10, 79, 102, + 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 79, + 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 76, 105, 109, 105, 116, 67, 108, 97, + 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 70, + 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 70, 101, 116, 99, 104, 79, 102, 102, 115, + 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, 104, 67, 108, 97, + 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 10, 70, 101, 116, + 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, + 104, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 66, 97, 115, 101, 84, 97, + 98, 108, 101, 78, 97, 109, 101, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, + 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 105, + 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, 32, 83, + 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 10, 83, 105, 109, 112, 108, 101, 83, 101, + 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, + 40, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 41, 10, 83, 105, 109, 112, 108, + 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, + 109, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 71, 114, 111, 117, 112, + 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, + 115, 101, 63, 32, 87, 105, 110, 100, 111, 119, 67, 108, 97, 117, 115, 101, 63, 32, 81, 117, + 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, + 108, 97, 117, 115, 101, 63, 10, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 32, 60, 45, + 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 47, 32, + 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 10, 83, 101, 108, + 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, 101, 108, + 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, + 63, 10, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, + 45, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 67, + 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, 110, 116, + 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 67, 111, + 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 32, 85, 115, 105, 110, 103, 75, 101, + 121, 63, 32, 39, 65, 83, 39, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, + 63, 32, 67, 84, 69, 66, 111, 100, 121, 10, 67, 84, 69, 66, 111, 100, 121, 32, 60, 45, + 32, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, 121, 32, 47, 32, 67, 84, 69, + 68, 77, 76, 66, 111, 100, 121, 10, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, + 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 67, 84, 69, + 68, 77, 76, 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 41, 10, 85, 115, 105, 110, 103, 75, 101, 121, 32, 60, 45, + 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 75, 69, 89, 39, 32, 80, 97, 114, 101, 110, + 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 77, 97, 116, 101, 114, 105, + 97, 108, 105, 122, 101, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 63, 32, 39, 77, 65, + 84, 69, 82, 73, 65, 76, 73, 90, 69, 68, 39, 10, 87, 105, 116, 104, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 99, 117, 114, 115, 105, + 118, 101, 63, 32, 76, 105, 115, 116, 40, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 41, 10, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, 45, 32, 39, 82, 69, + 67, 85, 82, 83, 73, 86, 69, 39, 10, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 83, 69, 76, 69, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, + 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, + 63, 10, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, + 40, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, + 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 32, 60, 45, 32, 80, 97, 114, + 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, + 110, 103, 41, 41, 10, 68, 105, 115, 116, 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 32, + 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, 47, 32, 68, 105, 115, 116, + 105, 110, 99, 116, 65, 108, 108, 10, 68, 105, 115, 116, 105, 110, 99, 116, 65, 108, 108, 32, + 60, 45, 32, 39, 65, 76, 76, 39, 10, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, + 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, + 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 63, 10, 68, 105, 115, 116, 105, 110, 99, + 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 32, 60, 45, 32, 39, 79, 78, 39, 32, 80, + 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 41, 41, 10, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, + 32, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 47, 32, 84, 97, 98, 108, 101, 70, 117, + 110, 99, 116, 105, 111, 110, 32, 47, 32, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, 101, + 114, 121, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, + 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 84, 97, 98, 108, 101, + 82, 101, 102, 32, 60, 45, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, + 32, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 42, 10, 84, 97, 98, 108, 101, 83, + 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, + 115, 67, 111, 108, 111, 110, 63, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, 98, + 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 84, 97, 98, 108, 101, + 65, 108, 105, 97, 115, 63, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, + 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 84, 97, 98, 108, 101, 65, + 108, 105, 97, 115, 63, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, + 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, + 67, 111, 108, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, + 110, 103, 32, 39, 58, 39, 10, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, + 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 86, 97, 108, + 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, + 63, 10, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, + 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 80, 97, 114, + 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 84, 97, 98, 108, 101, 65, + 108, 105, 97, 115, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, + 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 32, 60, 45, 32, 74, 111, 105, 110, 67, + 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, + 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, + 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 80, 97, 114, 101, 110, 115, + 40, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, + 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, + 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 84, + 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 39, 70, 79, 82, 39, 32, 80, 105, 118, 111, + 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 32, 80, 105, 118, 111, 116, 71, 114, 111, + 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, + 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, + 89, 39, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, + 101, 76, 105, 115, 116, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, 73, 110, + 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 63, + 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, + 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, + 97, 115, 63, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, + 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, + 100, 101, 114, 32, 39, 70, 79, 82, 39, 32, 85, 110, 112, 105, 118, 111, 116, 86, 97, 108, + 117, 101, 76, 105, 115, 116, 43, 10, 80, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, + 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, + 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 105, 118, 111, + 116, 72, 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 80, 105, 118, 111, 116, 86, 97, + 108, 117, 101, 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, + 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, + 97, 114, 103, 101, 116, 32, 47, 32, 80, 105, 118, 111, 116, 76, 105, 115, 116, 84, 97, 114, + 103, 101, 116, 10, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, 97, 114, 103, 101, 116, 32, + 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 105, 118, 111, 116, 76, + 105, 115, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 84, 97, + 114, 103, 101, 116, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 86, 97, 108, 117, + 101, 76, 105, 115, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, + 101, 114, 32, 39, 73, 78, 39, 32, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, + 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, + 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, + 115, 116, 41, 10, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, + 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, + 115, 116, 41, 10, 76, 97, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 76, 65, 84, 69, + 82, 65, 76, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, + 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, + 32, 47, 32, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, 97, 115, 101, 84, 97, + 98, 108, 101, 78, 97, 109, 101, 10, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, + 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 84, 97, 98, 108, + 101, 78, 97, 109, 101, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, + 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, + 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 32, 47, 32, 83, 99, 104, + 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 10, 83, 99, 104, + 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 32, 60, 45, 32, + 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, + 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 67, 97, + 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, + 97, 98, 108, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, + 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, + 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, 82, 101, + 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 84, 97, 98, 108, + 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, 101, 70, 117, + 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, 47, 32, 84, + 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, + 111, 110, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, + 114, 97, 108, 79, 112, 116, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 81, + 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, + 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, + 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, + 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, 70, 117, + 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, + 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 81, 117, 97, 108, + 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, + 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, + 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, 32, 83, 97, + 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 79, 114, 100, 105, + 110, 97, 108, 105, 116, 121, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, 79, 82, + 68, 73, 78, 65, 76, 73, 84, 89, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, + 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, 116, 97, + 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, 32, 83, 99, + 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 42, 32, 84, + 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, 84, 97, 98, + 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, + 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, + 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 63, 41, 10, 70, 117, 110, 99, 116, + 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, + 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 80, + 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, + 117, 109, 101, 110, 116, 10, 78, 97, 109, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, + 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, + 109, 101, 116, 101, 114, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, + 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, + 114, 32, 60, 45, 32, 84, 121, 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, 32, 84, 121, + 112, 101, 63, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, + 115, 105, 103, 110, 109, 101, 110, 116, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, 115, 105, 103, 110, + 109, 101, 110, 116, 32, 60, 45, 32, 39, 58, 61, 39, 32, 47, 32, 39, 61, 62, 39, 10, + 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, + 108, 105, 97, 115, 65, 115, 32, 47, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 87, + 105, 116, 104, 111, 117, 116, 65, 115, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 65, + 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 67, 111, 108, 117, + 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, + 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, + 102, 105, 101, 114, 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, + 65, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 65, 84, 39, 32, 80, 97, 114, + 101, 110, 115, 40, 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 41, 10, 65, 116, 83, + 112, 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 65, 116, 85, 110, 105, 116, 32, 39, + 61, 62, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 85, 110, 105, + 116, 32, 60, 45, 32, 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 47, + 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 10, 86, 101, 114, + 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 39, 86, 69, 82, 83, 73, + 79, 78, 39, 10, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 32, + 60, 45, 32, 39, 84, 73, 77, 69, 83, 84, 65, 77, 80, 39, 10, 74, 111, 105, 110, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 82, 101, 103, 117, 108, 97, 114, 74, 111, 105, 110, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, 110, 67, 108, 97, + 117, 115, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, 108, 97, + 117, 115, 101, 10, 35, 32, 78, 69, 65, 82, 69, 83, 84, 32, 66, 89, 32, 104, 97, 115, + 32, 116, 119, 111, 32, 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 115, 32, 115, 111, + 32, 80, 69, 71, 32, 99, 97, 110, 32, 98, 97, 99, 107, 116, 114, 97, 99, 107, 58, 32, + 116, 104, 101, 32, 98, 97, 114, 101, 32, 102, 111, 114, 109, 32, 117, 115, 101, 115, 32, 97, + 108, 105, 97, 115, 45, 108, 101, 115, 115, 32, 116, 97, 114, 103, 101, 116, 32, 109, 105, 114, + 114, 111, 114, 115, 32, 40, 116, 114, 105, 101, 100, 10, 35, 32, 102, 105, 114, 115, 116, 44, + 32, 115, 111, 32, 97, 110, 32, 117, 110, 97, 108, 105, 97, 115, 101, 100, 32, 116, 97, 114, + 103, 101, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 103, 114, 101, 101, 100, 105, 108, + 121, 32, 99, 111, 110, 115, 117, 109, 101, 32, 78, 69, 65, 82, 69, 83, 84, 47, 65, 80, + 80, 82, 79, 88, 47, 69, 88, 65, 67, 84, 32, 97, 115, 32, 97, 110, 32, 97, 108, 105, + 97, 115, 41, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 97, 108, 105, 97, 115, 101, 100, + 10, 35, 32, 102, 111, 114, 109, 32, 102, 97, 108, 108, 115, 32, 98, 97, 99, 107, 32, 116, + 111, 32, 97, 32, 102, 117, 108, 108, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 119, 104, + 101, 110, 32, 97, 32, 114, 101, 97, 108, 32, 97, 108, 105, 97, 115, 32, 105, 100, 101, 110, + 116, 105, 102, 105, 101, 114, 32, 102, 111, 108, 108, 111, 119, 115, 32, 116, 104, 101, 32, 116, + 97, 114, 103, 101, 116, 46, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 66, + 97, 114, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, 105, + 97, 115, 101, 100, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, 105, 97, + 115, 101, 100, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, + 73, 78, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, + 114, 69, 120, 97, 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, + 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, + 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, + 110, 66, 97, 114, 101, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, + 74, 79, 73, 78, 39, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, + 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, 99, 116, 63, + 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, + 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, 115, 116, 97, 110, 99, 101, 79, + 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, 108, 101, 82, + 101, 102, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, + 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 70, 117, 110, + 99, 116, 105, 111, 110, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, + 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, + 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, + 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 78, 101, 97, 114, 101, + 115, 116, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 86, 97, 108, 117, 101, + 115, 67, 108, 97, 117, 115, 101, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, - 121, 63, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, - 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 60, - 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 81, 117, - 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, - 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, - 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, 32, - 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 79, 114, - 100, 105, 110, 97, 108, 105, 116, 121, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, - 79, 82, 68, 73, 78, 65, 76, 73, 84, 89, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, - 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, - 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, 32, - 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 42, - 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, - 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 70, 117, 110, - 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 63, 41, 10, 70, 117, 110, - 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, - 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, - 32, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 65, - 114, 103, 117, 109, 101, 110, 116, 10, 78, 97, 109, 101, 100, 70, 117, 110, 99, 116, 105, 111, - 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, 97, - 114, 97, 109, 101, 116, 101, 114, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, - 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, - 116, 101, 114, 32, 60, 45, 32, 84, 121, 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, 32, - 84, 121, 112, 101, 63, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, - 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, 115, 105, - 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 39, 58, 61, 39, 32, 47, 32, 39, 61, 62, - 39, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, 84, 97, 98, 108, - 101, 65, 108, 105, 97, 115, 65, 115, 32, 47, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 65, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 67, 111, - 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, 84, 97, 98, 108, 101, 65, 108, - 105, 97, 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 32, 60, 45, 32, 73, 100, 101, 110, - 116, 105, 102, 105, 101, 114, 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, - 63, 10, 65, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 65, 84, 39, 32, 80, - 97, 114, 101, 110, 115, 40, 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 41, 10, 65, - 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 65, 116, 85, 110, 105, 116, - 32, 39, 61, 62, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 85, - 110, 105, 116, 32, 60, 45, 32, 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, - 32, 47, 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 10, 86, - 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 39, 86, 69, 82, - 83, 73, 79, 78, 39, 10, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, - 116, 32, 60, 45, 32, 39, 84, 73, 77, 69, 83, 84, 65, 77, 80, 39, 10, 74, 111, 105, - 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 66, 121, 67, 108, 97, - 117, 115, 101, 32, 47, 32, 82, 101, 103, 117, 108, 97, 114, 74, 111, 105, 110, 67, 108, 97, - 117, 115, 101, 32, 47, 32, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, 110, 67, - 108, 97, 117, 115, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, - 108, 97, 117, 115, 101, 10, 35, 32, 78, 69, 65, 82, 69, 83, 84, 32, 66, 89, 32, 104, - 97, 115, 32, 116, 119, 111, 32, 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 115, 32, - 115, 111, 32, 80, 69, 71, 32, 99, 97, 110, 32, 98, 97, 99, 107, 116, 114, 97, 99, 107, - 58, 32, 116, 104, 101, 32, 98, 97, 114, 101, 32, 102, 111, 114, 109, 32, 117, 115, 101, 115, - 32, 97, 108, 105, 97, 115, 45, 108, 101, 115, 115, 32, 116, 97, 114, 103, 101, 116, 32, 109, - 105, 114, 114, 111, 114, 115, 32, 40, 116, 114, 105, 101, 100, 10, 35, 32, 102, 105, 114, 115, - 116, 44, 32, 115, 111, 32, 97, 110, 32, 117, 110, 97, 108, 105, 97, 115, 101, 100, 32, 116, - 97, 114, 103, 101, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 103, 114, 101, 101, 100, - 105, 108, 121, 32, 99, 111, 110, 115, 117, 109, 101, 32, 78, 69, 65, 82, 69, 83, 84, 47, - 65, 80, 80, 82, 79, 88, 47, 69, 88, 65, 67, 84, 32, 97, 115, 32, 97, 110, 32, 97, - 108, 105, 97, 115, 41, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 97, 108, 105, 97, 115, - 101, 100, 10, 35, 32, 102, 111, 114, 109, 32, 102, 97, 108, 108, 115, 32, 98, 97, 99, 107, - 32, 116, 111, 32, 97, 32, 102, 117, 108, 108, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, - 119, 104, 101, 110, 32, 97, 32, 114, 101, 97, 108, 32, 97, 108, 105, 97, 115, 32, 105, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 32, 102, 111, 108, 108, 111, 119, 115, 32, 116, 104, 101, - 32, 116, 97, 114, 103, 101, 116, 46, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, - 110, 66, 97, 114, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, - 108, 105, 97, 115, 101, 100, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, - 105, 97, 115, 101, 100, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, - 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, - 120, 79, 114, 69, 120, 97, 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, - 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, - 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, - 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 74, - 111, 105, 110, 66, 97, 114, 101, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, - 32, 39, 74, 79, 73, 78, 39, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, - 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, 99, - 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, 109, 98, 101, 114, 76, - 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, 115, 116, 97, 110, 99, - 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, 108, - 101, 82, 101, 102, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 86, 97, 108, 117, 101, - 115, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 70, - 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, - 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, - 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, - 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 78, 101, 97, - 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 86, 97, 108, - 117, 101, 115, 67, 108, 97, 117, 115, 101, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, - 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, - 108, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, - 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, - 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, - 105, 116, 121, 63, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 83, 117, 98, - 113, 117, 101, 114, 121, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, - 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 78, 101, 97, 114, - 101, 115, 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 66, - 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 65, 116, 67, 108, 97, 117, 115, - 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 78, 101, 97, - 114, 101, 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 83, - 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 65, 112, 112, 114, 111, 120, 79, - 114, 69, 120, 97, 99, 116, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 65, 112, 112, - 114, 111, 120, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 10, 78, - 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, 120, 32, 60, 45, 32, 39, 65, 80, 80, - 82, 79, 88, 39, 10, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 32, 60, 45, - 32, 39, 69, 88, 65, 67, 84, 39, 10, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, - 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, - 68, 105, 115, 116, 97, 110, 99, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 83, 105, - 109, 105, 108, 97, 114, 105, 116, 121, 10, 78, 101, 97, 114, 101, 115, 116, 68, 105, 115, 116, - 97, 110, 99, 101, 32, 60, 45, 32, 39, 68, 73, 83, 84, 65, 78, 67, 69, 39, 10, 78, - 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, - 39, 83, 73, 77, 73, 76, 65, 82, 73, 84, 89, 39, 10, 82, 101, 103, 117, 108, 97, 114, - 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 65, 115, 111, 102, 63, 32, - 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 84, 97, 98, - 108, 101, 82, 101, 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, - 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 74, 79, 73, - 78, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 39, 84, 89, 80, 69, - 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 41, 32, 84, 97, 98, 108, 101, 82, 101, 102, - 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 65, 115, 111, 102, 32, - 60, 45, 32, 39, 65, 83, 79, 70, 39, 10, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, - 116, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 80, 114, 101, - 102, 105, 120, 32, 39, 74, 79, 73, 78, 39, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, - 101, 82, 101, 102, 10, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, 60, - 45, 32, 79, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 85, 115, 105, 110, 103, 67, 108, - 97, 117, 115, 101, 10, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, - 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 115, 105, 110, 103, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 80, 97, 114, 101, - 110, 115, 40, 76, 105, 115, 116, 40, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, - 97, 109, 101, 41, 41, 10, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, 109, - 101, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, 83, 116, - 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, - 114, 10, 74, 111, 105, 110, 84, 121, 112, 101, 32, 60, 45, 32, 70, 117, 108, 108, 74, 111, - 105, 110, 32, 47, 32, 76, 101, 102, 116, 74, 111, 105, 110, 32, 47, 32, 82, 105, 103, 104, - 116, 74, 111, 105, 110, 32, 47, 32, 83, 101, 109, 105, 74, 111, 105, 110, 32, 47, 32, 65, - 110, 116, 105, 74, 111, 105, 110, 32, 47, 32, 73, 110, 110, 101, 114, 74, 111, 105, 110, 10, - 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 67, 114, 111, 115, 115, 74, - 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 78, 97, 116, 117, 114, 97, 108, 74, - 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, - 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 10, 67, 114, 111, 115, 115, 74, 111, - 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 67, 82, 79, 83, 83, 39, 10, - 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, - 32, 39, 78, 65, 84, 85, 82, 65, 76, 39, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, - 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, - 120, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 65, 76, 39, 10, 70, 117, - 108, 108, 74, 111, 105, 110, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 32, 39, 79, 85, - 84, 69, 82, 39, 63, 10, 76, 101, 102, 116, 74, 111, 105, 110, 32, 60, 45, 32, 39, 76, - 69, 70, 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 82, 105, 103, 104, 116, 74, - 111, 105, 110, 32, 60, 45, 32, 39, 82, 73, 71, 72, 84, 39, 32, 39, 79, 85, 84, 69, - 82, 39, 63, 10, 83, 101, 109, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 83, 69, 77, - 73, 39, 10, 65, 110, 116, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 65, 78, 84, 73, - 39, 10, 73, 110, 110, 101, 114, 74, 111, 105, 110, 32, 60, 45, 32, 39, 73, 78, 78, 69, - 82, 39, 10, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, 82, - 79, 77, 39, 32, 76, 105, 115, 116, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, 87, - 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 82, 69, - 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, - 89, 39, 32, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 115, 10, 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 72, - 65, 86, 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 81, 117, - 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 81, 85, 65, 76, - 73, 70, 89, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 97, 109, 112, - 108, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 40, 84, 97, 98, 108, 101, 83, 97, - 109, 112, 108, 101, 32, 47, 32, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, 101, 41, 32, - 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 10, 85, 115, 105, 110, 103, 83, 97, 109, - 112, 108, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 83, 65, 77, 80, - 76, 69, 39, 10, 84, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, - 84, 65, 66, 76, 69, 83, 65, 77, 80, 76, 69, 39, 10, 87, 105, 110, 100, 111, 119, 67, - 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 78, 68, 79, 87, 39, 32, 76, 105, - 115, 116, 40, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 41, - 10, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, - 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 65, 83, 39, 32, 87, 105, 110, - 100, 111, 119, 70, 114, 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 10, 83, - 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, - 69, 110, 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 83, 97, 109, 112, - 108, 101, 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 10, 83, 97, 109, 112, 108, 101, 69, - 110, 116, 114, 121, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 67, - 111, 117, 110, 116, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 80, 114, - 111, 112, 101, 114, 116, 105, 101, 115, 41, 63, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, - 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, - 70, 117, 110, 99, 116, 105, 111, 110, 63, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, - 112, 108, 101, 67, 111, 117, 110, 116, 41, 32, 82, 101, 112, 101, 97, 116, 97, 98, 108, 101, - 83, 97, 109, 112, 108, 101, 63, 10, 83, 97, 109, 112, 108, 101, 70, 117, 110, 99, 116, 105, - 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 83, 97, 109, 112, 108, 101, 80, 114, - 111, 112, 101, 114, 116, 105, 101, 115, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 40, 39, - 44, 39, 32, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 41, 63, 10, 82, 101, 112, 101, - 97, 116, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 82, 69, 80, - 69, 65, 84, 65, 66, 76, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, - 108, 101, 83, 101, 101, 100, 41, 10, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 32, 60, - 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 83, 97, 109, 112, - 108, 101, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 86, 97, 108, - 117, 101, 32, 83, 97, 109, 112, 108, 101, 85, 110, 105, 116, 63, 10, 83, 97, 109, 112, 108, - 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, - 114, 97, 108, 32, 47, 32, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 83, 97, 109, 112, - 108, 101, 85, 110, 105, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, - 101, 110, 116, 97, 103, 101, 32, 47, 32, 83, 97, 109, 112, 108, 101, 82, 111, 119, 115, 10, - 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, 116, 97, 103, 101, 32, 60, 45, 32, - 39, 37, 39, 32, 47, 32, 39, 80, 69, 82, 67, 69, 78, 84, 39, 10, 83, 97, 109, 112, - 108, 101, 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, 79, 87, 83, 39, 10, 71, 114, 111, - 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 71, - 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, - 65, 108, 108, 10, 71, 114, 111, 117, 112, 66, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, - 76, 76, 39, 10, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 76, - 105, 115, 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 41, 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, - 109, 32, 47, 32, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 67, 108, 97, 117, - 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, 97, - 117, 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 10, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, - 109, 32, 60, 45, 32, 39, 40, 39, 32, 39, 41, 39, 10, 67, 117, 98, 101, 79, 114, 82, - 111, 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 67, 117, 98, 101, 79, - 114, 82, 111, 108, 108, 117, 112, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 67, 117, 98, 101, 79, 114, - 82, 111, 108, 108, 117, 112, 32, 60, 45, 32, 67, 117, 98, 101, 75, 101, 121, 119, 111, 114, - 100, 32, 47, 32, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 10, 67, 117, - 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 85, 66, 69, 39, 10, - 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 82, 79, - 76, 76, 85, 80, 39, 10, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 32, 39, - 83, 69, 84, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 71, 114, - 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 117, - 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, 80, - 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, - 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 68, 101, 115, 99, 79, 114, 65, 115, - 99, 32, 60, 45, 32, 68, 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, - 32, 47, 32, 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 10, 68, 101, - 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 68, 69, - 83, 67, 39, 32, 47, 32, 39, 68, 69, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 65, - 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 65, 83, - 67, 39, 32, 47, 32, 39, 65, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 78, 117, 108, - 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 32, 60, 45, 32, 78, 117, 108, - 108, 115, 70, 105, 114, 115, 116, 32, 47, 32, 78, 117, 108, 108, 115, 76, 97, 115, 116, 10, - 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, 83, - 39, 32, 39, 70, 73, 82, 83, 84, 39, 10, 78, 117, 108, 108, 115, 76, 97, 115, 116, 32, - 60, 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, 76, 65, 83, 84, 39, 10, 79, 114, - 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 82, 68, 69, - 82, 39, 32, 39, 66, 89, 39, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 115, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 65, 108, 108, 32, - 47, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, - 105, 115, 116, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 79, 114, 100, 101, 114, 66, - 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 79, 114, 100, 101, 114, 66, 121, - 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 32, 68, 101, 115, 99, 79, 114, 65, - 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, - 63, 10, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 76, 73, - 77, 73, 84, 39, 32, 76, 105, 109, 105, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, - 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 70, 70, 83, 69, 84, 39, - 32, 79, 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, 86, - 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 82, - 111, 119, 79, 114, 82, 111, 119, 115, 63, 10, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, - 60, 45, 32, 39, 82, 79, 87, 39, 32, 47, 32, 39, 82, 79, 87, 83, 39, 10, 76, 105, - 109, 105, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 65, 108, 108, - 32, 47, 32, 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, - 110, 116, 32, 47, 32, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 10, 76, 105, 109, 105, 116, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 76, - 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, 32, 60, - 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 39, 80, 69, 82, - 67, 69, 78, 84, 39, 10, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 37, 39, 63, - 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, 69, 84, - 67, 72, 39, 32, 70, 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 70, 101, 116, 99, - 104, 86, 97, 108, 117, 101, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, 78, - 76, 89, 39, 10, 70, 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 60, 45, 32, 39, - 70, 73, 82, 83, 84, 39, 32, 47, 32, 39, 78, 69, 88, 84, 39, 10, 70, 101, 116, 99, - 104, 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 10, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, + 121, 63, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, + 101, 114, 121, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, 98, 113, + 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 78, 101, 97, 114, 101, 115, + 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 66, 97, 115, + 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, + 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 78, 101, 97, 114, 101, + 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 83, 97, 109, + 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 65, 112, 112, 114, 111, 120, 79, 114, 69, + 120, 97, 99, 116, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, + 120, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 10, 78, 101, 97, + 114, 101, 115, 116, 65, 112, 112, 114, 111, 120, 32, 60, 45, 32, 39, 65, 80, 80, 82, 79, + 88, 39, 10, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 32, 60, 45, 32, 39, + 69, 88, 65, 67, 84, 39, 10, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, + 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 68, 105, + 115, 116, 97, 110, 99, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, + 108, 97, 114, 105, 116, 121, 10, 78, 101, 97, 114, 101, 115, 116, 68, 105, 115, 116, 97, 110, + 99, 101, 32, 60, 45, 32, 39, 68, 73, 83, 84, 65, 78, 67, 69, 39, 10, 78, 101, 97, + 114, 101, 115, 116, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 39, 83, + 73, 77, 73, 76, 65, 82, 73, 84, 89, 39, 10, 82, 101, 103, 117, 108, 97, 114, 74, 111, + 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 65, 115, 111, 102, 63, 32, 74, 111, + 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, + 82, 101, 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 74, 111, + 105, 110, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 74, 79, 73, 78, 39, + 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 39, 84, 89, 80, 69, 39, 32, + 67, 111, 108, 76, 97, 98, 101, 108, 41, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 74, + 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 65, 115, 111, 102, 32, 60, 45, + 32, 39, 65, 83, 79, 70, 39, 10, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, + 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 80, 114, 101, 102, 105, + 120, 32, 39, 74, 79, 73, 78, 39, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, + 101, 102, 10, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, 60, 45, 32, + 79, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 85, 115, 105, 110, 103, 67, 108, 97, 117, + 115, 101, 10, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 115, 105, 110, 103, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, 115, + 40, 76, 105, 115, 116, 40, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, 109, + 101, 41, 41, 10, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, + 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, + 74, 111, 105, 110, 84, 121, 112, 101, 32, 60, 45, 32, 70, 117, 108, 108, 74, 111, 105, 110, + 32, 47, 32, 76, 101, 102, 116, 74, 111, 105, 110, 32, 47, 32, 82, 105, 103, 104, 116, 74, + 111, 105, 110, 32, 47, 32, 83, 101, 109, 105, 74, 111, 105, 110, 32, 47, 32, 65, 110, 116, + 105, 74, 111, 105, 110, 32, 47, 32, 73, 110, 110, 101, 114, 74, 111, 105, 110, 10, 74, 111, + 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 67, 114, 111, 115, 115, 74, 111, 105, + 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, + 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, + 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 10, 67, 114, 111, 115, 115, 74, 111, 105, 110, + 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 67, 82, 79, 83, 83, 39, 10, 78, 97, + 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, + 78, 65, 84, 85, 82, 65, 76, 39, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 10, 80, + 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, + 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 65, 76, 39, 10, 70, 117, 108, 108, + 74, 111, 105, 110, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 32, 39, 79, 85, 84, 69, + 82, 39, 63, 10, 76, 101, 102, 116, 74, 111, 105, 110, 32, 60, 45, 32, 39, 76, 69, 70, + 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 82, 105, 103, 104, 116, 74, 111, 105, + 110, 32, 60, 45, 32, 39, 82, 73, 71, 72, 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, + 63, 10, 83, 101, 109, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 83, 69, 77, 73, 39, + 10, 65, 110, 116, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 65, 78, 84, 73, 39, 10, + 73, 110, 110, 101, 114, 74, 111, 105, 110, 32, 60, 45, 32, 39, 73, 78, 78, 69, 82, 39, + 10, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, 82, 79, 77, + 39, 32, 76, 105, 115, 116, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, 87, 104, 101, + 114, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 82, 69, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, 89, 39, + 32, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 10, + 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 72, 65, 86, + 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 81, 117, 97, 108, + 105, 102, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 81, 85, 65, 76, 73, 70, + 89, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 97, 109, 112, 108, 101, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 40, 84, 97, 98, 108, 101, 83, 97, 109, 112, + 108, 101, 32, 47, 32, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, 101, 41, 32, 83, 97, + 109, 112, 108, 101, 69, 110, 116, 114, 121, 10, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, + 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 83, 65, 77, 80, 76, 69, + 39, 10, 84, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 84, 65, + 66, 76, 69, 83, 65, 77, 80, 76, 69, 39, 10, 87, 105, 110, 100, 111, 119, 67, 108, 97, + 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 78, 68, 79, 87, 39, 32, 76, 105, 115, 116, + 40, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 41, 10, 87, + 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 65, 83, 39, 32, 87, 105, 110, 100, 111, + 119, 70, 114, 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 10, 83, 97, 109, + 112, 108, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 69, 110, + 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 83, 97, 109, 112, 108, 101, + 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, + 114, 121, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 67, 111, 117, + 110, 116, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 80, 114, 111, 112, + 101, 114, 116, 105, 101, 115, 41, 63, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, + 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 70, 117, + 110, 99, 116, 105, 111, 110, 63, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, + 101, 67, 111, 117, 110, 116, 41, 32, 82, 101, 112, 101, 97, 116, 97, 98, 108, 101, 83, 97, + 109, 112, 108, 101, 63, 10, 83, 97, 109, 112, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, + 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 83, 97, 109, 112, 108, 101, 80, 114, 111, 112, + 101, 114, 116, 105, 101, 115, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 40, 39, 44, 39, + 32, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 41, 63, 10, 82, 101, 112, 101, 97, 116, + 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 82, 69, 80, 69, 65, + 84, 65, 66, 76, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, + 83, 101, 101, 100, 41, 10, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 32, 60, 45, 32, + 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 83, 97, 109, 112, 108, 101, + 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 86, 97, 108, 117, 101, + 32, 83, 97, 109, 112, 108, 101, 85, 110, 105, 116, 63, 10, 83, 97, 109, 112, 108, 101, 86, + 97, 108, 117, 101, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, + 108, 32, 47, 32, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 83, 97, 109, 112, 108, 101, + 85, 110, 105, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, + 116, 97, 103, 101, 32, 47, 32, 83, 97, 109, 112, 108, 101, 82, 111, 119, 115, 10, 83, 97, + 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, 116, 97, 103, 101, 32, 60, 45, 32, 39, 37, + 39, 32, 47, 32, 39, 80, 69, 82, 67, 69, 78, 84, 39, 10, 83, 97, 109, 112, 108, 101, + 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, 79, 87, 83, 39, 10, 71, 114, 111, 117, 112, + 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 71, 114, 111, + 117, 112, 66, 121, 76, 105, 115, 116, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 65, 108, + 108, 10, 71, 114, 111, 117, 112, 66, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, + 39, 10, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, + 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, + 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, + 45, 32, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, 109, 32, + 47, 32, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, + 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, 109, 32, + 60, 45, 32, 39, 40, 39, 32, 39, 41, 39, 10, 67, 117, 98, 101, 79, 114, 82, 111, 108, + 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 67, 117, 98, 101, 79, 114, 82, + 111, 108, 108, 117, 112, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 67, 117, 98, 101, 79, 114, 82, 111, + 108, 108, 117, 112, 32, 60, 45, 32, 67, 117, 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, + 47, 32, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 10, 67, 117, 98, 101, + 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 85, 66, 69, 39, 10, 82, 111, + 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 82, 79, 76, 76, + 85, 80, 39, 10, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 32, 39, 83, 69, + 84, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 71, 114, 111, 117, + 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 117, 98, 113, + 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, 80, 97, 114, + 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, + 110, 116, 101, 114, 110, 97, 108, 41, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, + 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 68, 101, 115, 99, 79, 114, 65, 115, 99, 32, + 60, 45, 32, 68, 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 47, + 32, 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 10, 68, 101, 115, 99, + 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 68, 69, 83, 67, + 39, 32, 47, 32, 39, 68, 69, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 65, 115, 99, + 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 65, 83, 67, 39, + 32, 47, 32, 39, 65, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 78, 117, 108, 108, 115, + 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 32, 60, 45, 32, 78, 117, 108, 108, 115, + 70, 105, 114, 115, 116, 32, 47, 32, 78, 117, 108, 108, 115, 76, 97, 115, 116, 10, 78, 117, + 108, 108, 115, 70, 105, 114, 115, 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, + 39, 70, 73, 82, 83, 84, 39, 10, 78, 117, 108, 108, 115, 76, 97, 115, 116, 32, 60, 45, + 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, 76, 65, 83, 84, 39, 10, 79, 114, 100, 101, + 114, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 82, 68, 69, 82, 39, + 32, 39, 66, 89, 39, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 115, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 65, 108, 108, 32, 47, 32, + 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, + 116, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, + 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 79, 114, 100, 101, 114, 66, 121, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 79, 114, 100, 101, 114, 66, 121, 65, 108, + 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, + 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, + 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 76, 73, 77, 73, + 84, 39, 32, 76, 105, 109, 105, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 70, 70, 83, 69, 84, 39, 32, 79, + 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, 86, 97, 108, + 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 82, 111, 119, + 79, 114, 82, 111, 119, 115, 63, 10, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 60, 45, + 32, 39, 82, 79, 87, 39, 32, 47, 32, 39, 82, 79, 87, 83, 39, 10, 76, 105, 109, 105, + 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 65, 108, 108, 32, 47, + 32, 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, + 32, 47, 32, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, + 105, 109, 105, 116, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 76, 105, 109, + 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, 32, 60, 45, 32, + 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 39, 80, 69, 82, 67, 69, + 78, 84, 39, 10, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 37, 39, 63, 10, 70, + 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, 104, 67, + 108, 97, 117, 115, 101, 87, 105, 116, 104, 111, 117, 116, 86, 97, 108, 117, 101, 32, 47, 32, + 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 86, 97, 108, 117, 101, + 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 111, 117, 116, 86, + 97, 108, 117, 101, 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, 70, 105, 114, 115, + 116, 79, 114, 78, 101, 120, 116, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, + 78, 76, 89, 39, 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, + 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, 70, 105, 114, + 115, 116, 79, 114, 78, 101, 120, 116, 32, 70, 101, 116, 99, 104, 86, 97, 108, 117, 101, 32, + 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, 78, 76, 89, 39, 10, 70, 105, 114, + 115, 116, 79, 114, 78, 101, 120, 116, 32, 60, 45, 32, 39, 70, 73, 82, 83, 84, 39, 32, + 47, 32, 39, 78, 69, 88, 84, 39, 10, 70, 101, 116, 99, 104, 86, 97, 108, 117, 101, 32, + 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 108, 105, 97, 115, 101, + 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, 32, 47, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, + 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, + 111, 108, 73, 100, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, - 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, - 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 39, 58, 39, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, 67, - 111, 108, 108, 97, 98, 101, 108, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 39, 65, 83, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, 116, 114, - 105, 110, 103, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 63, 10, 86, 97, 108, 117, 101, 115, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 76, - 105, 115, 116, 40, 86, 97, 108, 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 115, 41, 10, 86, 97, 108, 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, - 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, - 109, 101, 110, 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 10, 83, 101, 116, 65, 115, - 115, 105, 103, 110, 109, 101, 110, 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 32, 60, - 45, 32, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, 116, 97, 110, 100, 97, - 114, 100, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 47, 32, 83, 101, 116, 84, 105, - 109, 101, 90, 111, 110, 101, 10, 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 39, 82, 69, 83, 69, 84, 39, 32, 83, 101, 116, 86, 97, 114, 105, - 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 83, 99, 104, - 101, 109, 97, 32, 60, 45, 32, 39, 83, 67, 72, 69, 77, 65, 39, 32, 83, 116, 114, 105, - 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, - 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, - 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, 32, 83, 101, 116, 65, 115, 115, 105, - 103, 110, 109, 101, 110, 116, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, - 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, - 108, 101, 32, 47, 32, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 84, - 105, 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, - 79, 78, 69, 39, 32, 90, 111, 110, 101, 86, 97, 108, 117, 101, 10, 90, 111, 110, 101, 86, - 97, 108, 117, 101, 32, 60, 45, 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, - 87, 105, 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 47, 32, 90, 111, 110, 101, - 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, - 32, 47, 32, 90, 111, 110, 101, 76, 111, 99, 97, 108, 32, 47, 32, 90, 111, 110, 101, 68, - 101, 102, 97, 117, 108, 116, 32, 47, 32, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 32, 47, 32, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, - 105, 101, 114, 32, 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, - 90, 111, 110, 101, 76, 111, 99, 97, 108, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, - 10, 90, 111, 110, 101, 68, 101, 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, 69, 70, - 65, 85, 76, 84, 39, 10, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, - 114, 97, 108, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, - 10, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, - 97, 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, 32, 60, 45, 32, 39, 73, - 78, 84, 69, 82, 86, 65, 76, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 32, 73, 110, 116, 101, 114, 118, 97, 108, 63, 10, 90, 111, 110, 101, 73, 110, 116, - 101, 114, 118, 97, 108, 87, 105, 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 60, - 45, 32, 39, 73, 78, 84, 69, 82, 86, 65, 76, 39, 32, 80, 97, 114, 101, 110, 115, 40, - 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 41, 32, 83, 116, 114, 105, 110, - 103, 76, 105, 116, 101, 114, 97, 108, 10, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 32, - 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 83, 99, 111, 112, 101, 63, 32, 83, 101, 116, - 116, 105, 110, 103, 78, 97, 109, 101, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, - 32, 60, 45, 32, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 10, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, - 112, 101, 32, 60, 45, 32, 39, 86, 65, 82, 73, 65, 66, 76, 69, 39, 10, 83, 101, 116, - 116, 105, 110, 103, 83, 99, 111, 112, 101, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, 99, - 111, 112, 101, 32, 47, 32, 83, 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, 32, 47, - 32, 71, 108, 111, 98, 97, 108, 83, 99, 111, 112, 101, 10, 76, 111, 99, 97, 108, 83, 99, - 111, 112, 101, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, 83, 101, 115, 115, 105, - 111, 110, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 83, 69, 83, 83, 73, 79, 78, 39, - 10, 71, 108, 111, 98, 97, 108, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 71, 76, 79, - 66, 65, 76, 39, 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, - 45, 32, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 86, 97, 114, - 105, 97, 98, 108, 101, 76, 105, 115, 116, 10, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, - 115, 105, 103, 110, 32, 60, 45, 32, 39, 61, 39, 32, 47, 32, 39, 84, 79, 39, 10, 86, - 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 97, 110, 115, 97, 99, 116, - 105, 111, 110, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 66, 101, 103, 105, - 110, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 82, 111, 108, 108, 98, - 97, 99, 107, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 67, 111, 109, - 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 10, 66, 101, 103, 105, 110, - 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 116, - 79, 114, 66, 101, 103, 105, 110, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, - 32, 82, 101, 97, 100, 79, 114, 87, 114, 105, 116, 101, 63, 10, 82, 111, 108, 108, 98, 97, - 99, 107, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 65, 98, 111, - 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, 107, 32, 84, 114, 97, 110, 115, 97, 99, - 116, 105, 111, 110, 63, 10, 67, 111, 109, 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, - 105, 111, 110, 32, 60, 45, 32, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 84, - 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 10, 83, 116, 97, 114, 116, 79, 114, 66, - 101, 103, 105, 110, 32, 60, 45, 32, 39, 83, 84, 65, 82, 84, 39, 32, 47, 32, 39, 66, - 69, 71, 73, 78, 39, 10, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, - 32, 39, 87, 79, 82, 75, 39, 32, 47, 32, 39, 84, 82, 65, 78, 83, 65, 67, 84, 73, - 79, 78, 39, 10, 82, 101, 97, 100, 79, 114, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, - 82, 69, 65, 68, 39, 32, 82, 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, - 87, 114, 105, 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, - 87, 114, 105, 116, 101, 32, 60, 45, 32, 82, 101, 97, 100, 79, 110, 108, 121, 32, 47, 32, - 82, 101, 97, 100, 87, 114, 105, 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 32, 60, - 45, 32, 39, 79, 78, 76, 89, 39, 10, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, - 45, 32, 39, 87, 82, 73, 84, 69, 39, 10, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, - 108, 98, 97, 99, 107, 32, 60, 45, 32, 39, 65, 66, 79, 82, 84, 39, 32, 47, 32, 39, - 82, 79, 76, 76, 66, 65, 67, 75, 39, 10, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, - 100, 32, 60, 45, 32, 39, 67, 79, 77, 77, 73, 84, 39, 32, 47, 32, 39, 69, 78, 68, - 39, 10, 85, 112, 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, - 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 85, 80, 68, 65, 84, 69, - 39, 32, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, 101, 116, 32, 85, 112, 100, 97, 116, - 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, - 101, 63, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, - 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 85, 112, 100, 97, 116, 101, 84, - 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, - 116, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, - 116, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 60, 45, 32, 66, 97, - 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 39, 83, 69, 84, 39, 10, 66, 97, - 115, 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, 116, 32, 60, 45, 32, 66, - 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 85, 112, 100, 97, 116, 101, 65, - 108, 105, 97, 115, 63, 32, 39, 83, 69, 84, 39, 10, 85, 112, 100, 97, 116, 101, 65, 108, - 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 63, 32, 67, 111, 108, 73, 100, 10, 85, - 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 85, 112, - 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 47, - 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 84, 117, 112, 108, 101, 10, 85, 112, 100, 97, - 116, 101, 83, 101, 116, 84, 117, 112, 108, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, - 40, 76, 105, 115, 116, 40, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 41, 41, 32, 39, - 61, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, - 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, - 115, 116, 40, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 41, - 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, - 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, - 101, 116, 32, 39, 61, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, - 100, 97, 116, 101, 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, - 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 42, 10, 85, 115, 101, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 39, 85, 83, 69, 39, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, - 10, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 85, 115, 101, 84, 97, 114, - 103, 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, + 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 65, 83, 39, 32, + 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, 116, 114, 105, 110, 103, 10, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 63, 10, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, + 60, 45, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 76, 105, 115, 116, 40, 86, 97, 108, + 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 41, 10, 86, 97, 108, 117, + 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, + 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, + 41, 10, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 83, + 69, 84, 39, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 79, 114, 84, + 105, 109, 101, 90, 111, 110, 101, 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, + 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 83, 101, 116, 83, 99, + 104, 101, 109, 97, 32, 47, 32, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, + 110, 109, 101, 110, 116, 32, 47, 32, 83, 101, 116, 84, 105, 109, 101, 90, 111, 110, 101, 10, + 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 82, + 69, 83, 69, 84, 39, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, + 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, + 39, 83, 67, 72, 69, 77, 65, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, + 97, 108, 10, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, 110, 109, 101, 110, + 116, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, + 116, 116, 105, 110, 103, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 10, + 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, + 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 47, 32, 83, 101, + 116, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 84, 105, 109, 101, 90, 111, 110, 101, + 32, 60, 45, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 32, 90, 111, + 110, 101, 86, 97, 108, 117, 101, 10, 90, 111, 110, 101, 86, 97, 108, 117, 101, 32, 60, 45, + 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 80, 114, 101, + 99, 105, 115, 105, 111, 110, 32, 47, 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, + 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, 32, 47, 32, 90, 111, 110, 101, + 76, 111, 99, 97, 108, 32, 47, 32, 90, 111, 110, 101, 68, 101, 102, 97, 117, 108, 116, 32, + 47, 32, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, + 47, 32, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 78, + 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, 76, 111, 99, + 97, 108, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, 90, 111, 110, 101, 68, 101, + 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 10, 90, + 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, + 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 73, + 110, 116, 101, 114, 118, 97, 108, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 86, 65, 76, + 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 73, 110, 116, 101, + 114, 118, 97, 108, 63, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, + 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 60, 45, 32, 39, 73, 78, 84, 69, + 82, 86, 65, 76, 39, 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 109, 98, 101, 114, 76, + 105, 116, 101, 114, 97, 108, 41, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, + 108, 10, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, 101, 116, 116, + 105, 110, 103, 83, 99, 111, 112, 101, 63, 32, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, + 101, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 60, 45, 32, 86, 97, 114, + 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, + 114, 10, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, + 86, 65, 82, 73, 65, 66, 76, 69, 39, 10, 83, 101, 116, 116, 105, 110, 103, 83, 99, 111, + 112, 101, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, 47, 32, 83, + 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, 32, 47, 32, 71, 108, 111, 98, 97, 108, + 83, 99, 111, 112, 101, 10, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, 60, 45, 32, + 39, 76, 79, 67, 65, 76, 39, 10, 83, 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, + 32, 60, 45, 32, 39, 83, 69, 83, 83, 73, 79, 78, 39, 10, 71, 108, 111, 98, 97, 108, + 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 71, 76, 79, 66, 65, 76, 39, 10, 83, 101, + 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 86, 97, 114, 105, 97, + 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, + 115, 116, 10, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 60, 45, + 32, 39, 61, 39, 32, 47, 32, 39, 84, 79, 39, 10, 86, 97, 114, 105, 97, 98, 108, 101, + 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 41, 10, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 66, 101, 103, 105, 110, 84, 114, 97, 110, 115, 97, + 99, 116, 105, 111, 110, 32, 47, 32, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, 97, 110, + 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 67, 111, 109, 109, 105, 116, 84, 114, 97, 110, + 115, 97, 99, 116, 105, 111, 110, 10, 66, 101, 103, 105, 110, 84, 114, 97, 110, 115, 97, 99, + 116, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, + 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 32, 82, 101, 97, 100, 79, 114, + 87, 114, 105, 116, 101, 63, 10, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, 97, 110, 115, + 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, + 108, 98, 97, 99, 107, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 10, 67, + 111, 109, 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, + 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 84, 114, 97, 110, 115, 97, 99, 116, + 105, 111, 110, 63, 10, 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, 32, 60, 45, + 32, 39, 83, 84, 65, 82, 84, 39, 32, 47, 32, 39, 66, 69, 71, 73, 78, 39, 10, 84, + 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 87, 79, 82, 75, 39, + 32, 47, 32, 39, 84, 82, 65, 78, 83, 65, 67, 84, 73, 79, 78, 39, 10, 82, 101, 97, + 100, 79, 114, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 82, 69, 65, 68, 39, 32, 82, + 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, 101, 10, 82, + 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, + 45, 32, 82, 101, 97, 100, 79, 110, 108, 121, 32, 47, 32, 82, 101, 97, 100, 87, 114, 105, + 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 32, 60, 45, 32, 39, 79, 78, 76, 89, + 39, 10, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 87, 82, 73, 84, + 69, 39, 10, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, 107, 32, 60, + 45, 32, 39, 65, 66, 79, 82, 84, 39, 32, 47, 32, 39, 82, 79, 76, 76, 66, 65, 67, + 75, 39, 10, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 60, 45, 32, 39, 67, + 79, 77, 77, 73, 84, 39, 32, 47, 32, 39, 69, 78, 68, 39, 10, 85, 112, 100, 97, 116, + 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, + 97, 117, 115, 101, 63, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, + 101, 84, 97, 114, 103, 101, 116, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, + 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 63, 32, 87, 104, 101, 114, + 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, + 97, 117, 115, 101, 63, 10, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, 101, 116, 32, 60, + 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 47, 32, 66, 97, 115, + 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, 116, 10, 66, 97, 115, 101, 84, + 97, 98, 108, 101, 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, + 78, 97, 109, 101, 32, 39, 83, 69, 84, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, + 65, 108, 105, 97, 115, 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, + 101, 78, 97, 109, 101, 32, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 63, 32, 39, + 83, 69, 84, 39, 10, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, + 39, 65, 83, 39, 63, 32, 67, 111, 108, 73, 100, 10, 85, 112, 100, 97, 116, 101, 83, 101, + 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, + 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 47, 32, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 84, 117, 112, 108, 101, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 84, 117, + 112, 108, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, + 111, 108, 117, 109, 110, 78, 97, 109, 101, 41, 41, 32, 39, 61, 39, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, + 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 85, 112, 100, 97, + 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 41, 10, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 39, 61, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, + 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 111, 108, 117, + 109, 110, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 42, 10, 85, 115, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 85, + 83, 69, 39, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 10, 85, 115, 101, 84, 97, 114, + 103, 101, 116, 32, 60, 45, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, 97, 116, 97, + 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, 99, 104, 101, 109, 97, 78, 97, + 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 47, 32, 67, 97, 116, 97, + 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 10, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, - 32, 47, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, - 97, 114, 103, 101, 116, 10, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, 115, - 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, - 101, 10, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, - 114, 103, 101, 116, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 10, - 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, - 109, 97, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 46, - 39, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, - 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 42, 10, 68, 111, 116, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 46, 39, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 10, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 39, 86, 65, 67, 85, 85, 77, 39, 32, 86, 97, 99, 117, - 117, 109, 79, 112, 116, 105, 111, 110, 115, 63, 32, 65, 110, 97, 108, 121, 122, 101, 84, 97, - 114, 103, 101, 116, 63, 10, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 115, 32, - 60, 45, 32, 86, 97, 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, - 110, 115, 32, 47, 32, 86, 97, 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, - 105, 111, 110, 115, 10, 86, 97, 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, - 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, - 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 41, 41, 10, 86, 97, 99, 117, 117, - 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 79, 112, - 116, 70, 117, 108, 108, 63, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, 63, 32, 79, 112, - 116, 86, 101, 114, 98, 111, 115, 101, 63, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, - 63, 10, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 79, 112, - 116, 65, 110, 97, 108, 121, 122, 101, 32, 47, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, - 32, 47, 32, 79, 112, 116, 70, 117, 108, 108, 32, 47, 32, 79, 112, 116, 86, 101, 114, 98, - 111, 115, 101, 32, 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 79, 112, 116, - 65, 110, 97, 108, 121, 122, 101, 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, - 121, 119, 111, 114, 100, 10, 79, 112, 116, 70, 117, 108, 108, 32, 60, 45, 32, 39, 70, 85, - 76, 76, 39, 10, 79, 112, 116, 70, 114, 101, 101, 122, 101, 32, 60, 45, 32, 39, 70, 82, - 69, 69, 90, 69, 39, 10, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 60, 45, 32, - 39, 86, 69, 82, 66, 79, 83, 69, 39, 10, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, - 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, - 114, 83, 116, 114, 105, 110, 103, 41, 41, 10, 0, + 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, + 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, + 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 10, 85, 115, 101, 84, 97, 114, 103, + 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, 67, + 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 46, 39, 32, 82, 101, 115, 101, 114, + 118, 101, 100, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 42, 10, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 32, 60, 45, 32, 39, 46, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, + 10, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, + 39, 86, 65, 67, 85, 85, 77, 39, 32, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, + 110, 115, 63, 32, 65, 110, 97, 108, 121, 122, 101, 84, 97, 114, 103, 101, 116, 63, 10, 86, + 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 86, 97, 99, 117, + 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 47, 32, 86, 97, + 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, 10, 86, 97, + 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, + 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 86, 97, 99, 117, 117, 109, 79, + 112, 116, 105, 111, 110, 41, 41, 10, 86, 97, 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, + 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 79, 112, 116, 70, 117, 108, 108, 63, 32, + 79, 112, 116, 70, 114, 101, 101, 122, 101, 63, 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, + 101, 63, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, 63, 10, 86, 97, 99, 117, 117, + 109, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, + 101, 32, 47, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, 32, 47, 32, 79, 112, 116, 70, + 117, 108, 108, 32, 47, 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 47, 32, 73, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, + 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 10, 79, + 112, 116, 70, 117, 108, 108, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 10, 79, 112, 116, + 70, 114, 101, 101, 122, 101, 32, 60, 45, 32, 39, 70, 82, 69, 69, 90, 69, 39, 10, 79, + 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 60, 45, 32, 39, 86, 69, 82, 66, 79, 83, + 69, 39, 10, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, + 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, + 41, 41, 10, 0, }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp index 2268919c7..639eeb6f2 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp @@ -2691,6 +2691,14 @@ class PEGTransformerFactory { GeneratedTransformProcess &process); static unique_ptr FinalizeOtherOperatorExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeInfixOtherOperatorExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeInfixOtherOperatorExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeCustomPrefixExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeCustomPrefixExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static void InitializeOtherOperatorTailTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeOtherOperatorTailTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -3362,6 +3370,9 @@ class PEGTransformerFactory { static void InitializeOffsetFetchClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeOffsetFetchClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeFetchOffsetClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static unique_ptr FinalizeFetchOffsetClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeFetchOnlyClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeFetchOnlyClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -3834,6 +3845,14 @@ class PEGTransformerFactory { static void InitializeFetchClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeFetchClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeFetchClauseWithoutValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr + FinalizeFetchClauseWithoutValueTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeFetchClauseWithValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); + static unique_ptr FinalizeFetchClauseWithValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeFetchValueTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeFetchValueTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -5033,8 +5052,11 @@ class PEGTransformerFactory { TransformBetweenClause(PEGTransformer &transformer, unique_ptr other_operator_expression, unique_ptr other_operator_expression_1); static unique_ptr - TransformOtherOperatorExpression(PEGTransformer &transformer, unique_ptr bitwise_expression, - optional> other_operator_tail); + TransformInfixOtherOperatorExpression(PEGTransformer &transformer, unique_ptr bitwise_expression, + optional> other_operator_tail); + static unique_ptr + TransformCustomPrefixExpression(PEGTransformer &transformer, const string &operator_literal, + unique_ptr other_operator_expression); static OtherOperatorTail TransformOtherOperatorTail(PEGTransformer &transformer, ParsedOperator other_operator, unique_ptr bitwise_expression); static ParsedOperator TransformAnyAllParsedOperator(PEGTransformer &transformer, @@ -5380,6 +5402,9 @@ class PEGTransformerFactory { static unique_ptr TransformOffsetFetchClause(PEGTransformer &transformer, LimitPercentResult offset_clause, LimitPercentResult fetch_clause); + static unique_ptr TransformFetchOffsetClause(PEGTransformer &transformer, + LimitPercentResult fetch_clause, + LimitPercentResult offset_clause); static unique_ptr TransformFetchOnlyClause(PEGTransformer &transformer, LimitPercentResult fetch_clause); static unique_ptr TransformTableStatement(PEGTransformer &transformer, @@ -5626,6 +5651,7 @@ class PEGTransformerFactory { unique_ptr number_literal); static LimitPercentResult TransformLimitExpression(PEGTransformer &transformer, unique_ptr expression, const bool &has_result); + static LimitPercentResult TransformFetchClauseWithoutValue(PEGTransformer &transformer); static LimitPercentResult TransformFetchValue(PEGTransformer &transformer, unique_ptr expression); static unique_ptr TransformColIdExpression(PEGTransformer &transformer, const Identifier &col_id, unique_ptr expression); diff --git a/src/duckdb/src/include/duckdb/planner/binder.hpp b/src/duckdb/src/include/duckdb/planner/binder.hpp index 3cfd7f07e..59e656786 100644 --- a/src/duckdb/src/include/duckdb/planner/binder.hpp +++ b/src/duckdb/src/include/duckdb/planner/binder.hpp @@ -309,8 +309,8 @@ class Binder : public enable_shared_from_this { SchemaCatalogEntry &BindCreateTriggerInfo(CreateTriggerInfo &info); //! Check usage, and cast named parameters to their types - static void BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values, - QueryErrorContext &error_context, const Identifier &func_name); + void BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values, + QueryErrorContext &error_context, const Identifier &func_name); unique_ptr BindPragma(PragmaInfo &info, QueryErrorContext error_context); BoundStatement Bind(TableRef &ref); diff --git a/src/duckdb/src/include/duckdb/storage/table/row_group_reorderer.hpp b/src/duckdb/src/include/duckdb/storage/table/row_group_reorderer.hpp index 7fd665a3c..822917336 100644 --- a/src/duckdb/src/include/duckdb/storage/table/row_group_reorderer.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/row_group_reorderer.hpp @@ -27,6 +27,8 @@ class RowGroupReorderer { RowGroupReorderer(const RowGroupOrderOptions &options_p, TransactionData transaction_p); optional_ptr> GetRootSegment(RowGroupSegmentTree &row_groups); optional_ptr> GetNextRowGroup(SegmentNode &row_group); + //! The number of rows in the row groups that will be scanned (after pruning) + idx_t ScanRowCount() const; static Value RetrieveStat(const BaseStatistics &stats, OrderByStatistics order_by, OrderByColumnType column_type); static OffsetPruningResult GetOffsetAfterPruning(OrderByStatistics order_by, OrderByColumnType column_type, diff --git a/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp b/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp index b438014c4..3347dc8d3 100644 --- a/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +++ b/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp @@ -416,6 +416,8 @@ struct ParallelCollectionScanState { idx_t max_row; idx_t batch_index; atomic processed_rows; + //! Rows of assignments that were skipped entirely (e.g. by zonemaps) without being handed out + atomic skipped_rows; optional_idx row_number_base; mutex lock; diff --git a/src/duckdb/src/include/duckdb_extension_v2.h b/src/duckdb/src/include/duckdb_extension_v2.h index afda09878..294f3b258 100644 --- a/src/duckdb/src/include/duckdb_extension_v2.h +++ b/src/duckdb/src/include/duckdb_extension_v2.h @@ -703,7 +703,7 @@ typedef struct { (duckdb_v2_scalar_function_handle function, duckdb_v2_scalar_function_init_callback_fn callback, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_scalar_function_set_name) - (duckdb_v2_scalar_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_scalar_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_scalar_function_set_user_data) (duckdb_v2_scalar_function_handle function, duckdb_v2_opaque *data, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_aggregate_function_bind_get_user_data) @@ -780,7 +780,7 @@ typedef struct { (duckdb_v2_aggregate_function_handle function, duckdb_v2_aggregate_function_init_callback_fn callback, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_aggregate_function_set_name) - (duckdb_v2_aggregate_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_aggregate_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_aggregate_function_set_size_callback) (duckdb_v2_aggregate_function_handle function, duckdb_v2_aggregate_function_size_callback_fn callback, duckdb_v2_error_info_handle *err); @@ -891,7 +891,7 @@ typedef struct { (duckdb_v2_table_function_handle function, duckdb_v2_table_function_init_local_callback_fn callback, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_name) - (duckdb_v2_table_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_table_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_table_function_set_progress_callback) (duckdb_v2_table_function_handle function, duckdb_v2_table_function_progress_callback_fn callback, duckdb_v2_error_info_handle *err); @@ -1142,7 +1142,7 @@ typedef struct { DUCKDB_V2_ERROR(*duckdb_v2_copy_function_register) (duckdb_v2_copy_function_handle function, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_copy_function_set_name) - (duckdb_v2_copy_function_handle function, duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + (duckdb_v2_copy_function_handle function, duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_copy_function_set_user_data) (duckdb_v2_copy_function_handle function, duckdb_v2_opaque *data, duckdb_v2_error_info_handle *err); DUCKDB_V2_ERROR(*duckdb_v2_copy_to_batch_get_bind_data) diff --git a/src/duckdb/src/include/duckdb_static_extension.h b/src/duckdb/src/include/duckdb_static_extension.h new file mode 100644 index 000000000..f30468923 --- /dev/null +++ b/src/duckdb/src/include/duckdb_static_extension.h @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// DuckDB +// +// duckdb_static_extension.h +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#ifndef DUCKDB_C_API +#ifdef _WIN32 +#ifdef DUCKDB_STATIC_BUILD +#define DUCKDB_C_API +#elif defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION) +#define DUCKDB_C_API __declspec(dllexport) +#else +#define DUCKDB_C_API __declspec(dllimport) +#endif +#else +#if defined(__GNUC__) || defined(__clang__) +#define DUCKDB_C_API __attribute__((visibility("default"))) +#else +#define DUCKDB_C_API +#endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +//! Descriptor layout this header defines. +#define DUCKDB_EXTENSION_DESCRIPTOR_VERSION 1 + +typedef struct duckdb_extension_descriptor duckdb_extension_descriptor; + +//! Describes a statically linked extension. DuckDB allocates and zero-fills it, the extension's describe function fills +//! it in. +struct duckdb_extension_descriptor { + //! In: the layout DuckDB offers. Out: the layout the describe function filled, never higher than the offer. + uint32_t version; + + // Layout 1, set by DuckDB + //! Reports why the describe function refused. DuckDB copies the message. + void (*set_error)(duckdb_extension_descriptor *descriptor, const char *message); + //! DuckDB's state for set_error, opaque to the extension. + void *internal; + + // Layout 1, set by the extension; DuckDB copies the strings before the describe function's caller returns + const char *name; + const char *extension_version; + //! What the entry point was built against: the DuckDB version for entry_cpp, the C API version the extension + //! targets for entry_capi_v1 and entry_capi_v2. The same values the loadable extension metadata carries. DuckDB + //! records it and reports it; it does not refuse a mismatch on it yet. + const char *api_version; + //! void (duckdb::ExtensionLoader &) + void (*entry_cpp)(void); + //! bool (duckdb_extension_info, struct duckdb_extension_access *) + void (*entry_capi_v1)(void); + //! void (struct duckdb_v2_extension_input *) + void (*entry_capi_v2)(void); +}; + +//! Every statically linkable extension provides duckdb_extension__describe with this signature. Returns 0 on +//! success. +typedef int32_t (*duckdb_extension_describe_t)(duckdb_extension_descriptor *descriptor); + +//! Calls describe and registers the extension it describes for every database opened afterwards. Returns 0 on +//! success. Registering the same describe function again is a no-op; a different one under a registered name is an +//! error. A failed registration also makes opening a database fail with the reason. +DUCKDB_C_API int32_t duckdb_register_static_extension(duckdb_extension_describe_t describe); + +#ifdef __cplusplus +} +#endif diff --git a/src/duckdb/src/include/duckdb_v2.h b/src/duckdb/src/include/duckdb_v2.h index 29bea6177..a35241a1e 100644 --- a/src/duckdb/src/include/duckdb_v2.h +++ b/src/duckdb/src/include/duckdb_v2.h @@ -342,6 +342,8 @@ typedef duckdb_v2_bytes duckdb_v2_bignum_t; * case-insensitively. Compare two identifiers case-insensitively rather than byte for byte, and render one into SQL * through the identifier-quoting entry point rather than embedding it raw. The catalog preserves casing; some * registries (config settings) canonicalize to lowercase. + * + * An identifier passed into the API must be valid UTF-8; otherwise the call fails with `ERROR_INPUT_INVALID`. */ typedef duckdb_v2_str duckdb_v2_identifier_t; @@ -2994,7 +2996,7 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_attach_options_create(duckdb_v2_instance_ * The key is matched case-insensitively, as an unquoted SQL identifier is. The setting is passed on as the text a * quoted SQL literal would produce: the engine casts the options it knows (READ_ONLY, RECOVERY_MODE, TYPE, * DEFAULT_TABLE, VACUUM_REBUILD_INDEXES, BLOCK_SIZE, ENCRYPTION_KEY, ...) and hands the rest to the storage extension - * that ends up owning the database, which decides what they mean. Nothing is validated here; an unknown or ill-typed + * that ends up owning the database, which decides what they mean. Keys must be valid UTF-8; an unknown or ill-typed * option fails the attach. Both views are borrowed and copied. Setting the same key again replaces it. * * history: @@ -3222,9 +3224,9 @@ typedef struct _duckdb_v2_qname { * Parses SQL text into a qualified name. * * Applies the engine's qualified-name rules: dots separate parts, and a double-quoted part may contain dots and doubled - * interior quotes. More than three parts and an unterminated quote are rejected with the parser's own error; text - * without at least one non-empty part is rejected with `ERROR_INPUT_INVALID`. When the parts are already separate, - * build the name with `duckdb_v2_qname_create()` rather than joining them and parsing the result. + * interior quotes. More than three parts and an unterminated quote are rejected with the parser's own error. Invalid + * UTF-8 and text without at least one non-empty part are rejected with `ERROR_INPUT_INVALID`. When the parts are + * already separate, build the name with `duckdb_v2_qname_create()` rather than joining them and parsing the result. * * history: * - stable: v2.0.0 @@ -4301,7 +4303,7 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_aggregate_function_create_with_extension( * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_aggregate_function_set_name(duckdb_v2_aggregate_function_handle function, - duckdb_v2_str *name, + duckdb_v2_identifier_t *name, duckdb_v2_error_info_handle *err); /*! @@ -5334,7 +5336,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_arrow_importer_destroy(duckdb_v2_arrow_im * * @param context The context whose Arrow settings are captured and whose transaction resolves the types. * @param types An array of `count` column types. May be NULL only when `count` is 0. - * @param names An array of `count` column names, parallel to `types`. May be NULL only when `count` is 0. + * @param names An array of `count` column names, parallel to `types`. Each name must be valid UTF-8. May be NULL only + * when `count` is 0. * @param count The number of columns, being the length of both `types` and `names`. * @param batch_size Maximum rows per produced array, or 0 for no maximum. * @param out_exporter On success, receives the new exporter. Owned by the caller; destroy via @@ -6103,7 +6106,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_copy_function_create_with_extension(duckd * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_copy_function_set_name(duckdb_v2_copy_function_handle function, - duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + duckdb_v2_identifier_t *name, + duckdb_v2_error_info_handle *err); /*! * Sets arbitrary user data on the copy function. @@ -6149,7 +6153,7 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_copy_to_set_bind_callback(duckdb_v2_copy_ * Sets the optional batch size callback of the `COPY ... TO` side. * * The batch size callback is invoked during query planning, after the bind callback, for each `COPY ... TO` statement - * that does not set `BATCH_SIZE` itself. It must report how many rows a batch should carry via + * that does not set `BATCH_SIZE` itself. It should report how many rows a batch should carry via * `duckdb_v2_copy_to_batch_size_set_target()`; the engine then cuts the rows being written into batches of that size * and hands each to the batch callback. Without a batch size from either the statement or the callback, a batch is cut * for every chunk of rows sunk, i.e. a vector at a time. A batch may still be smaller than the reported size (the last @@ -6455,7 +6459,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_copy_to_batch_size_get_bind_data(duckdb_v /*! * Sets the number of rows a batch should carry, as the target the engine cuts batches at. The batch size callback must - * set this to a value greater than 0; the statement fails otherwise. + * set this to a value greater than 0; the statement fails otherwise. DuckDB defines the `BATCH_SIZE` on omission of + * calling the function. * * history: * - stable: v2.0.0 @@ -8684,7 +8689,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_scalar_function_create_with_extension(duc * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_scalar_function_set_name(duckdb_v2_scalar_function_handle function, - duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + duckdb_v2_identifier_t *name, + duckdb_v2_error_info_handle *err); /*! * Returns the function's signature so it can be configured. @@ -12329,7 +12335,8 @@ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_create_with_extension(duck * @return DUCKDB_V2_ERROR */ DUCKDB_C_API DUCKDB_V2_ERROR duckdb_v2_table_function_set_name(duckdb_v2_table_function_handle function, - duckdb_v2_str *name, duckdb_v2_error_info_handle *err); + duckdb_v2_identifier_t *name, + duckdb_v2_error_info_handle *err); /*! * Returns the function's signature so it can be configured. diff --git a/src/duckdb/src/logging/log_storage.cpp b/src/duckdb/src/logging/log_storage.cpp index 815ebc53a..efc357ac1 100644 --- a/src/duckdb/src/logging/log_storage.cpp +++ b/src/duckdb/src/logging/log_storage.cpp @@ -79,6 +79,9 @@ bool LogStorage::Scan(LogStorageScanState &state, DataChunk &result) const { void LogStorage::InitializeScan(LogStorageScanState &state) const { throw NotImplementedException("Not implemented for this LogStorage: InitializeScanEntries"); } +optional_idx LogStorage::GetScanRowCount(LoggingTargetTable table) const { + return optional_idx(); +} void LogStorage::Truncate() { throw NotImplementedException("Not implemented for this LogStorage: TruncateLogStorage"); } @@ -770,6 +773,11 @@ bool InMemoryLogStorage::Scan(LogStorageScanState &state, DataChunk &result) con return GetBuffer(in_mem_scan_state.table).Scan(in_mem_scan_state.scan_state, result); } +optional_idx InMemoryLogStorage::GetScanRowCount(LoggingTargetTable table) const { + unique_lock lck(lock); + return GetBuffer(table).Count(); +} + void InMemoryLogStorage::InitializeScan(LogStorageScanState &state) const { unique_lock lck(lock); auto &in_mem_scan_state = state.Cast(); diff --git a/src/duckdb/src/main/capi/v2/capi_v2_arrow.cpp b/src/duckdb/src/main/capi/v2/capi_v2_arrow.cpp index e677598b1..540e2fc2c 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_arrow.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_arrow.cpp @@ -621,7 +621,7 @@ DUCKDB_V2_ERROR duckdb_v2_arrow_exporter_create(duckdb_v2_context_handle context throw duckdb::InvalidInputException("malformed column name at index %llu", i); } exporter->types.push_back(*Convert(types[i])); - exporter->names.emplace_back(Convert(names[i])); + exporter->names.emplace_back(ConvertIdentifierName(names[i])); } // Pin the settings and the extension map now: the schema below and every array this exporter produces are built // from them, which is what keeps the two consistent. diff --git a/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp b/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp index 7b149c747..f2d27ee21 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_connection.cpp @@ -56,8 +56,8 @@ DUCKDB_V2_ERROR duckdb_v2_connection_set_option(duckdb_v2_connection_handle conn DUCKDB_CHECK_ARG(setting); return WithErrorHandler(err, [&]() { auto &client = *Convert(conn)->context; - duckdb::PhysicalSet::SetVariable(client, duckdb::Identifier(Convert(name)), MapSettingScope(scope), - duckdb::Value(duckdb::string(Convert(setting)))); + duckdb::PhysicalSet::SetVariable(client, duckdb::Identifier(ConvertIdentifierName(name)), + MapSettingScope(scope), duckdb::Value(duckdb::string(Convert(setting)))); }); } @@ -70,7 +70,7 @@ DUCKDB_V2_ERROR duckdb_v2_connection_get_option_by_name(duckdb_v2_connection_han *out_option = nullptr; return WithErrorHandler(err, [&]() { CV2OptionSource source(*Convert(conn)->context); - *out_option = Convert(CV2Option::FromName(source, Convert(name)).release()); + *out_option = Convert(CV2Option::FromName(source, ConvertIdentifierName(name)).release()); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_custom_type.cpp b/src/duckdb/src/main/capi/v2/capi_v2_custom_type.cpp index 57aec59a4..4a26e6021 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_custom_type.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_custom_type.cpp @@ -116,7 +116,7 @@ DUCKDB_V2_ERROR duckdb_v2_custom_type_set_name(duckdb_v2_custom_type_handle type duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(type); DUCKDB_CHECK_ARG(name); - return WithErrorHandler(err, [&]() { Convert(type)->name = duckdb::Identifier(Convert(name)); }); + return WithErrorHandler(err, [&]() { Convert(type)->name = duckdb::Identifier(ConvertIdentifierName(name)); }); } DUCKDB_V2_ERROR duckdb_v2_custom_type_set_base_type(duckdb_v2_custom_type_handle type, diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_aggregate.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_aggregate.cpp index 3a4180071..373d13f03 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_aggregate.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_aggregate.cpp @@ -457,7 +457,7 @@ DUCKDB_V2_ERROR duckdb_v2_aggregate_function_set_name(duckdb_v2_aggregate_functi DUCKDB_CHECK_ARG(function); DUCKDB_CHECK_ARG(name); DUCKDB_CHECK_ARG(*name); - return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(Convert(*name)); }); + return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(ConvertIdentifierName(*name)); }); } DUCKDB_V2_ERROR duckdb_v2_aggregate_function_get_signature(duckdb_v2_aggregate_function_handle function, diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp index f92c578ea..9e146a481 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_copy.cpp @@ -842,7 +842,7 @@ DUCKDB_V2_ERROR duckdb_v2_copy_function_set_name(duckdb_v2_copy_function_handle DUCKDB_CHECK_ARG(function); DUCKDB_CHECK_ARG(name); DUCKDB_CHECK_ARG(*name); - return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(Convert(*name)); }); + return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(ConvertIdentifierName(*name)); }); } DUCKDB_V2_ERROR duckdb_v2_copy_function_set_user_data(duckdb_v2_copy_function_handle function, duckdb_v2_opaque *data, diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_scalar.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_scalar.cpp index 6f14ed015..fecb99561 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_scalar.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_scalar.cpp @@ -309,7 +309,7 @@ DUCKDB_V2_ERROR duckdb_v2_scalar_function_set_name(duckdb_v2_scalar_function_han DUCKDB_CHECK_ARG(function); DUCKDB_CHECK_ARG(name); DUCKDB_CHECK_ARG(*name); - return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(Convert(*name)); }); + return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(ConvertIdentifierName(*name)); }); } DUCKDB_V2_ERROR duckdb_v2_scalar_function_get_signature(duckdb_v2_scalar_function_handle function, diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp index 9a241a193..95933f18c 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_signature.cpp @@ -12,13 +12,14 @@ DUCKDB_V2_ERROR duckdb_v2_function_signature_add_parameter(duckdb_v2_function_si return WithErrorHandler(err, [&]() { auto &signature = *Convert(sig); + auto param_name = duckdb::Identifier(ConvertIdentifierName(name)); // the varargs can be set before the parameters, but they come after them in the signature auto varargs = signature.GetVarArgs(); signature.SetVarArgs(duckdb::LogicalType(duckdb::LogicalTypeId::INVALID)); if (value) { - signature.AddParameter(duckdb::Identifier(Convert(name)), *Convert(type), *Convert(value)); + signature.AddParameter(std::move(param_name), *Convert(type), *Convert(value)); } else { - signature.AddParameter(duckdb::Identifier(Convert(name)), *Convert(type)); + signature.AddParameter(std::move(param_name), *Convert(type)); } signature.SetVarArgs(std::move(varargs)); }); diff --git a/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp b/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp index 51b59c0e8..7ecc1c470 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_func_table.cpp @@ -798,7 +798,7 @@ DUCKDB_V2_ERROR duckdb_v2_table_function_set_name(duckdb_v2_table_function_handl DUCKDB_CHECK_ARG(function); DUCKDB_CHECK_ARG(name); DUCKDB_CHECK_ARG(*name); - return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(Convert(*name)); }); + return WithErrorHandler(err, [&]() { Convert(function)->name = duckdb::Identifier(ConvertIdentifierName(*name)); }); } DUCKDB_V2_ERROR duckdb_v2_table_function_get_signature(duckdb_v2_table_function_handle function, @@ -951,7 +951,7 @@ DUCKDB_V2_ERROR duckdb_v2_table_function_bind_add_result_column(duckdb_v2_table_ throw duckdb::InvalidInputException("Result column type must be a fully defined concrete type"); } auto &bind_info = *Convert(info); - bind_info.out_column_names.emplace_back(Convert(name)); + bind_info.out_column_names.emplace_back(ConvertIdentifierName(name)); bind_info.out_column_types.push_back(column_type); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_identifier.cpp b/src/duckdb/src/main/capi/v2/capi_v2_identifier.cpp index ddaf54350..e94b11fa0 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_identifier.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_identifier.cpp @@ -9,7 +9,7 @@ DUCKDB_V2_ERROR duckdb_v2_identifier_render_quoted(duckdb_v2_identifier_t name, DUCKDB_CHECK_ARG(out_length); return WithErrorHandler(err, [&]() { *out_length = 0; - auto rendered = duckdb::SQLIdentifier::ToString(duckdb::string(Convert(name))); + auto rendered = duckdb::SQLIdentifier::ToString(duckdb::string(ConvertIdentifierName(name))); FillCallerText(out_text, out_capacity, out_length, rendered, "duckdb_v2_identifier_render_quoted"); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp b/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp index 307f0ce62..26636371c 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_instance.cpp @@ -236,7 +236,7 @@ DUCKDB_V2_ERROR duckdb_v2_instance_attach(duckdb_v2_instance_handle instance, du return WithErrorHandler(err, [&]() { auto &wrapper = *Convert(instance); duckdb::lock_guard guard(wrapper.lock); - duckdb::Identifier attach_name = name ? duckdb::Identifier(Convert(*name)) : duckdb::Identifier(); + duckdb::Identifier attach_name = name ? duckdb::Identifier(ConvertIdentifierName(*name)) : duckdb::Identifier(); wrapper.Attach(duckdb::string(Convert(path)), attach_name, Convert(options), make_default); }); } @@ -260,7 +260,7 @@ DUCKDB_V2_ERROR duckdb_v2_attach_options_set(duckdb_v2_attach_options_handle opt DUCKDB_CHECK_ARG(setting); return WithErrorHandler(err, [&]() { // Keys are unquoted SQL identifiers, which the parser lowercases. - auto lowered = duckdb::StringUtil::Lower(duckdb::string(Convert(key))); + auto lowered = duckdb::StringUtil::Lower(duckdb::string(ConvertIdentifierName(key))); Convert(options)->options[lowered] = duckdb::Value(duckdb::string(Convert(setting))); }); } @@ -307,7 +307,7 @@ DUCKDB_V2_ERROR duckdb_v2_instance_set_option(duckdb_v2_instance_handle instance return WithErrorHandler(err, [&]() { auto &wrapper = *Convert(instance); duckdb::lock_guard guard(wrapper.lock); - wrapper.SetOption(duckdb::Identifier(Convert(name)), duckdb::string(Convert(setting))); + wrapper.SetOption(duckdb::Identifier(ConvertIdentifierName(name)), duckdb::string(Convert(setting))); }); } @@ -321,7 +321,7 @@ DUCKDB_V2_ERROR duckdb_v2_instance_get_option_by_name(duckdb_v2_instance_handle return WithErrorHandler(err, [&]() { auto &wrapper = *Convert(instance); duckdb::lock_guard guard(wrapper.lock); - *out_option = Convert(wrapper.GetOption(Convert(name)).release()); + *out_option = Convert(wrapper.GetOption(ConvertIdentifierName(name)).release()); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_logical_type.cpp b/src/duckdb/src/main/capi/v2/capi_v2_logical_type.cpp index a8a5ab120..8d211f095 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_logical_type.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_logical_type.cpp @@ -204,7 +204,7 @@ static duckdb::vector CollectTypeArgsV2(const duckdb_v2_id if (!param_values[i]) { throw duckdb::InvalidInputException("null parameter value at index %llu", i); } - args.emplace_back(duckdb::string(Convert(param_name)), *Convert(param_values[i])); + args.emplace_back(duckdb::string(ConvertIdentifierName(param_name)), *Convert(param_values[i])); } return args; } @@ -462,7 +462,7 @@ duckdb::LogicalType AliasOf(duckdb_v2_logical_type_handle base_type, duckdb_v2_i if (alias_name.len == 0) { throw duckdb::InvalidInputException("alias name cannot be empty"); } - return Convert(base_type)->WithAlias(std::string(Convert(alias_name))); + return Convert(base_type)->WithAlias(std::string(ConvertIdentifierName(alias_name))); } } // namespace diff --git a/src/duckdb/src/main/capi/v2/capi_v2_option.cpp b/src/duckdb/src/main/capi/v2/capi_v2_option.cpp index 9a20b0ea1..4fa60bda7 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_option.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_option.cpp @@ -84,7 +84,7 @@ DUCKDB_V2_ERROR duckdb_v2_context_get_option_by_name(duckdb_v2_context_handle ct *out_option = nullptr; return WithErrorHandler(err, [&]() { CV2OptionSource source(*Convert(ctx)); - *out_option = Convert(CV2Option::FromName(source, Convert(name)).release()); + *out_option = Convert(CV2Option::FromName(source, ConvertIdentifierName(name)).release()); }); } diff --git a/src/duckdb/src/main/capi/v2/capi_v2_qname.cpp b/src/duckdb/src/main/capi/v2/capi_v2_qname.cpp index a5333ac0c..20e3a0945 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_qname.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_qname.cpp @@ -32,7 +32,7 @@ DUCKDB_V2_ERROR duckdb_v2_qname_parse(duckdb_v2_str text, duckdb_v2_qname_handle DUCKDB_CHECK_ARG(out_name); *out_name = nullptr; return WithErrorHandler(err, [&]() { - auto parsed = duckdb::QualifiedName::Parse(duckdb::string(Convert(text))); + auto parsed = duckdb::QualifiedName::Parse(duckdb::string(ConvertIdentifierName(text))); CheckQNameParts(parsed, "duckdb_v2_qname_parse"); *out_name = Convert(new duckdb::QualifiedName(std::move(parsed))); }); @@ -54,9 +54,10 @@ DUCKDB_V2_ERROR duckdb_v2_qname_create(const duckdb_v2_identifier_t *parts, idx_ // The last part is the object name; everything before it is the qualification. duckdb::vector qualification; for (idx_t i = 0; i + 1 < part_count; i++) { - qualification.push_back(duckdb::Identifier(Convert(parts[i]))); + qualification.push_back(duckdb::Identifier(ConvertIdentifierName(parts[i]))); } - auto name = duckdb::QualifiedName(std::move(qualification), duckdb::Identifier(Convert(parts[part_count - 1]))); + auto name = duckdb::QualifiedName(std::move(qualification), + duckdb::Identifier(ConvertIdentifierName(parts[part_count - 1]))); CheckQNameParts(name, "duckdb_v2_qname_create"); *out_name = Convert(new duckdb::QualifiedName(std::move(name))); }); diff --git a/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp b/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp index 2e0091053..1bd502690 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_replacement_scan.cpp @@ -300,7 +300,7 @@ DUCKDB_V2_ERROR duckdb_v2_replacement_scan_add_named_argument(duckdb_v2_replacem return WithErrorHandler(err, [&]() { auto &args = *Convert(info); args.RequireFunctionClaim("duckdb_v2_replacement_scan_add_named_argument"); - args.out_named_arguments.emplace_back(duckdb::Identifier(Convert(name)), *Convert(value)); + args.out_named_arguments.emplace_back(duckdb::Identifier(ConvertIdentifierName(name)), *Convert(value)); }); } @@ -326,7 +326,7 @@ DUCKDB_V2_ERROR duckdb_v2_replacement_scan_set_collection(duckdb_v2_replacement_ } duckdb::vector names; for (idx_t i = 0; i < column_count; i++) { - auto name = duckdb::Identifier(Convert(column_names[i])); + auto name = duckdb::Identifier(ConvertIdentifierName(column_names[i])); if (name.empty()) { throw duckdb::InvalidInputException("Column names cannot be empty."); } @@ -367,7 +367,8 @@ DUCKDB_V2_ERROR duckdb_v2_replacement_scan_set_alias(duckdb_v2_replacement_scan_ duckdb_v2_identifier_t alias, duckdb_v2_error_info_handle *err) { DUCKDB_CHECK_ARG(info); DUCKDB_CHECK_ARG(alias); - return WithErrorHandler(err, [&]() { Convert(info)->out_alias = duckdb::Identifier(Convert(alias)); }); + return WithErrorHandler(err, + [&]() { Convert(info)->out_alias = duckdb::Identifier(ConvertIdentifierName(alias)); }); } DUCKDB_V2_ERROR duckdb_v2_replacement_scan_register(duckdb_v2_replacement_scan_handle scan, diff --git a/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp b/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp index fa65fe1fe..ceccf99b3 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_utf8.cpp @@ -2,6 +2,18 @@ #include "utf8proc_wrapper.hpp" +namespace duckdb::capiv2 { + +auto ConvertIdentifierName(duckdb_v2_identifier_t name) -> std::string_view { + auto bytes = Convert(name); + if (!Utf8Proc::IsValid(bytes.data(), bytes.size())) { + throw InvalidInputException("Identifier is not valid UTF-8"); + } + return bytes; +} + +} // namespace duckdb::capiv2 + using namespace duckdb::capiv2; DUCKDB_V2_ERROR duckdb_v2_validate_utf8(duckdb_v2_str text, duckdb_v2_error_info_handle *err) { diff --git a/src/duckdb/src/main/capi/v2/capi_v2_value.cpp b/src/duckdb/src/main/capi/v2/capi_v2_value.cpp index 7ad86a037..2d219f380 100644 --- a/src/duckdb/src/main/capi/v2/capi_v2_value.cpp +++ b/src/duckdb/src/main/capi/v2/capi_v2_value.cpp @@ -1155,7 +1155,7 @@ duckdb::Value BuildStruct(const duckdb_v2_identifier_t *names, const duckdb_v2_v if (!names[i].ptr && names[i].len > 0) { throw duckdb::InvalidInputException("field names cannot be null"); } - fields.emplace_back(std::string(names[i].ptr ? names[i].ptr : "", names[i].len), std::move(values[i])); + fields.emplace_back(std::string(ConvertIdentifierName(names[i])), std::move(values[i])); } return duckdb::Value::STRUCT(std::move(fields)); } diff --git a/src/duckdb/src/main/extension/extension_helper.cpp b/src/duckdb/src/main/extension/extension_helper.cpp index 67db84fc3..9a8ab333f 100644 --- a/src/duckdb/src/main/extension/extension_helper.cpp +++ b/src/duckdb/src/main/extension/extension_helper.cpp @@ -1,5 +1,6 @@ #include "duckdb/main/extension_helper.hpp" #include "duckdb/common/multi_file/multi_file_list.hpp" +#include "duckdb/main/extension/linked_extension_registry.hpp" #include "duckdb/common/file_system.hpp" #include "duckdb/common/local_file_system.hpp" @@ -16,82 +17,23 @@ #include "duckdb/main/extension_repository_manager.hpp" #include "duckdb/main/settings.hpp" -// Note that c++ preprocessor doesn't have a nice way to clean this up so we need to set the defines we use to false -// explicitly when they are undefined -#ifndef DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED -#define DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_ICU_LINKED -#define DUCKDB_EXTENSION_ICU_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_EXCEL_LINKED -#define DUCKDB_EXTENSION_EXCEL_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_PARQUET_LINKED -#define DUCKDB_EXTENSION_PARQUET_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_TPCH_LINKED -#define DUCKDB_EXTENSION_TPCH_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_TPCDS_LINKED -#define DUCKDB_EXTENSION_TPCDS_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_HTTPFS_LINKED -#define DUCKDB_EXTENSION_HTTPFS_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_JSON_LINKED -#define DUCKDB_EXTENSION_JSON_LINKED false -#endif - -#ifndef DUCKDB_EXTENSION_AUTOCOMPLETE_LINKED -#define DUCKDB_EXTENSION_AUTOCOMPLETE_LINKED false -#endif - -// Load the generated header file containing our list of extension headers -#if defined(GENERATED_EXTENSION_HEADERS) && GENERATED_EXTENSION_HEADERS -#include "duckdb/main/extension/generated_extension_loader.hpp" -#else -// TODO: rewrite package_build.py to allow also loading out-of-tree extensions in non-cmake builds, after that -// these can be removed -#if DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED -#include "core_functions_extension.hpp" -#endif - -#if DUCKDB_EXTENSION_ICU_LINKED -#include "icu_extension.hpp" -#endif - -#if DUCKDB_EXTENSION_PARQUET_LINKED -#include "parquet_extension.hpp" -#endif - -#if DUCKDB_EXTENSION_TPCH_LINKED -#include "tpch_extension.hpp" -#endif - -#if DUCKDB_EXTENSION_TPCDS_LINKED -#include "tpcds_extension.hpp" -#endif - -#if DUCKDB_EXTENSION_JSON_LINKED -#include "json_extension.hpp" -#endif - -#if DUCKDB_EXTENSION_AUTOCOMPLETE_LINKED -#include "autocomplete_extension.hpp" -#endif - -#endif - namespace duckdb { +void ExtensionHelper::RegisterLinkedExtensions(DBConfig &config) { + for (auto &linked : LinkedExtensionRegistry::Get()) { + bool present = false; + for (auto &existing : config.linked_extensions) { + if (StringUtil::CIEquals(existing.name, linked.name)) { + present = true; + break; + } + } + if (!present) { + config.linked_extensions.push_back(linked); + } + } +} + //! Loads an extension that was linked into the binary, via the registry the config carries. This is //! deliberately not generated code: an extension with its own copy of DuckDB links no generated //! loader, so a compile-time list would be invisible to it, while the config is data it can read. @@ -119,37 +61,37 @@ void ExtensionHelper::LoadAllExtensions(DuckDB &db) { // Default Extensions //===--------------------------------------------------------------------===// static const DefaultExtension internal_extensions[] = { - {"core_functions", "Core function library", DUCKDB_EXTENSION_CORE_FUNCTIONS_LINKED}, - {"icu", "Adds support for time zones and collations using the ICU library", DUCKDB_EXTENSION_ICU_LINKED}, - {"excel", "Adds support for Excel-like format strings", DUCKDB_EXTENSION_EXCEL_LINKED}, - {"parquet", "Adds support for reading and writing parquet files", DUCKDB_EXTENSION_PARQUET_LINKED}, - {"tpch", "Adds TPC-H data generation and query support", DUCKDB_EXTENSION_TPCH_LINKED}, - {"tpcds", "Adds TPC-DS data generation and query support", DUCKDB_EXTENSION_TPCDS_LINKED}, - {"httpfs", "Adds support for reading and writing files over a HTTP(S) connection", DUCKDB_EXTENSION_HTTPFS_LINKED}, - {"json", "Adds support for JSON operations", DUCKDB_EXTENSION_JSON_LINKED}, - {"autocomplete", "Adds support for autocomplete in the shell", DUCKDB_EXTENSION_AUTOCOMPLETE_LINKED}, - {"motherduck", "Enables motherduck integration with the system", false}, - {"mysql_scanner", "Adds support for connecting to a MySQL database", false}, - {"odbc_scanner", "Adds support for connecting to remote databases over ODBC", false}, - {"sqlite_scanner", "Adds support for reading and writing SQLite database files", false}, - {"postgres_scanner", "Adds support for connecting to a Postgres database", false}, - {"inet", "Adds support for IP-related data types and functions", false}, - {"spatial", "Geospatial extension that adds support for working with spatial data and functions", false}, - {"aws", "Provides features that depend on the AWS SDK", false}, - {"azure", "Adds a filesystem abstraction for Azure blob storage to DuckDB", false}, - {"encodings", "All unicode encodings to UTF-8", false}, - {"iceberg", "Adds support for Apache Iceberg", false}, - {"vss", "Adds indexing support to accelerate Vector Similarity Search", false}, - {"delta", "Adds support for Delta Lake", false}, - {"fts", "Adds support for Full-Text Search Indexes", false}, - {"ui", "Adds local UI for DuckDB", false}, - {"ducklake", "Adds support for DuckLake, SQL as a Lakehouse Format", false}, - {"quack", "The DuckDB 'Quack' Client/Server Protocol", false}, - {"vortex", "Adds support for reading and writing files using the Vortex file format", false}, - {"lance", "Adds support for querying Lance datasets", false}, - {"avro", "Adds support for reading Avro files", false}, - {"unity_catalog", "Adds support for connecting to Unity Catalog", false}, - {nullptr, nullptr, false}}; + {"core_functions", "Core function library"}, + {"icu", "Adds support for time zones and collations using the ICU library"}, + {"excel", "Adds support for Excel-like format strings"}, + {"parquet", "Adds support for reading and writing parquet files"}, + {"tpch", "Adds TPC-H data generation and query support"}, + {"tpcds", "Adds TPC-DS data generation and query support"}, + {"httpfs", "Adds support for reading and writing files over a HTTP(S) connection"}, + {"json", "Adds support for JSON operations"}, + {"autocomplete", "Adds support for autocomplete in the shell"}, + {"motherduck", "Enables motherduck integration with the system"}, + {"mysql_scanner", "Adds support for connecting to a MySQL database"}, + {"odbc_scanner", "Adds support for connecting to remote databases over ODBC"}, + {"sqlite_scanner", "Adds support for reading and writing SQLite database files"}, + {"postgres_scanner", "Adds support for connecting to a Postgres database"}, + {"inet", "Adds support for IP-related data types and functions"}, + {"spatial", "Geospatial extension that adds support for working with spatial data and functions"}, + {"aws", "Provides features that depend on the AWS SDK"}, + {"azure", "Adds a filesystem abstraction for Azure blob storage to DuckDB"}, + {"encodings", "All unicode encodings to UTF-8"}, + {"iceberg", "Adds support for Apache Iceberg"}, + {"vss", "Adds indexing support to accelerate Vector Similarity Search"}, + {"delta", "Adds support for Delta Lake"}, + {"fts", "Adds support for Full-Text Search Indexes"}, + {"ui", "Adds local UI for DuckDB"}, + {"ducklake", "Adds support for DuckLake, SQL as a Lakehouse Format"}, + {"quack", "The DuckDB 'Quack' Client/Server Protocol"}, + {"vortex", "Adds support for reading and writing files using the Vortex file format"}, + {"lance", "Adds support for querying Lance datasets"}, + {"avro", "Adds support for reading Avro files"}, + {"unity_catalog", "Adds support for connecting to Unity Catalog"}, + {nullptr, nullptr}}; idx_t ExtensionHelper::DefaultExtensionCount() { idx_t index; diff --git a/src/duckdb/src/main/extension/extension_load.cpp b/src/duckdb/src/main/extension/extension_load.cpp index 14f9af038..ba6afa008 100644 --- a/src/duckdb/src/main/extension/extension_load.cpp +++ b/src/duckdb/src/main/extension/extension_load.cpp @@ -7,6 +7,7 @@ #include "duckdb/main/capi/extension_api.hpp" #include "duckdb/main/capi_v2/extension_load_v2.hpp" #include "duckdb/main/error_manager.hpp" +#include "duckdb/main/extension/linked_extension_registry.hpp" #include "duckdb/main/extension_helper.hpp" #include "duckdb/main/extension_manager.hpp" #include "duckdb/main/extension_repository_manager.hpp" @@ -152,6 +153,40 @@ struct ExtensionAccess { //===--------------------------------------------------------------------===// // Static C API Extension Loading //===--------------------------------------------------------------------===// +void DuckDB::LoadStaticExtension(duckdb_extension_describe_t describe) { + StaticExtensionDescription description; + auto error = LinkedExtensionRegistry::Describe(describe, description); + if (!error.empty()) { + throw InvalidInputException("Failed to load statically linked extension: %s", error); + } + // C++ first, then C API v2, then C API v1 + auto &descriptor = description.descriptor; + if (!descriptor.entry_cpp) { + if (descriptor.entry_capi_v2) { + LoadStaticCAPIExtensionV2(description.name, + reinterpret_cast(descriptor.entry_capi_v2)); + } else { + LoadStaticCAPIExtension(description.name, reinterpret_cast(descriptor.entry_capi_v1)); + } + return; + } + auto &manager = ExtensionManager::Get(*instance); + auto load_info = manager.BeginLoad({description.name}); + if (!load_info) { + // already loaded + return; + } + + ExtensionLoader loader(*load_info); + (*reinterpret_cast(descriptor.entry_cpp))(loader); + loader.FinalizeLoad(); + + ExtensionInstallInfo install_info; + install_info.mode = ExtensionInstallMode::STATICALLY_LINKED; + install_info.version = description.version; + load_info->FinishLoad(install_info); +} + void DuckDB::LoadStaticCAPIExtension(const string &name, ext_init_c_api_fun_t init_fun) { auto &manager = ExtensionManager::Get(*instance); auto load_info = manager.BeginLoad({name}); @@ -777,8 +812,7 @@ string ExtensionHelper::GetExtensionName(const string &original_name) { void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileSystem &fs, const ExtensionLoadOptions &options, optional_ptr context) { // Loading a second copy of an extension that is already linked into this binary is an ODR - // violation. The default extension table cannot detect that for out-of-tree extensions, which - // are never marked statically_loaded, so ask the CMake-generated loader instead. + // violation, so ask the registry of extensions linked into this binary first. // Statically linked extensions are inherently core-trusted, so only take this shortcut for a bare // load or an explicit core namespace - never let community/x or myrepo/x resolve to a linked core extension. bool allow_static_shortcut = options.repository.empty() || StringUtil::Lower(options.repository) == "core"; diff --git a/src/duckdb/src/main/extension/linked_extension_registry.cpp b/src/duckdb/src/main/extension/linked_extension_registry.cpp new file mode 100644 index 000000000..95d7c21da --- /dev/null +++ b/src/duckdb/src/main/extension/linked_extension_registry.cpp @@ -0,0 +1,132 @@ +#include "duckdb/main/extension/linked_extension_registry.hpp" + +#include "duckdb/common/exception.hpp" +#include "duckdb/common/string_util.hpp" +#include "duckdb/main/database.hpp" +#include "duckdb_static_extension.h" + +#include +#include + +namespace duckdb { + +namespace { + +struct RegisteredExtension { + string name; + duckdb_extension_describe_t describe; +}; + +struct RegistryState { + std::mutex lock; + vector extensions; + vector registered; + vector errors; + //! set when a registration failed without recording why - recording it is what may have failed + std::atomic unknown_error {false}; +}; + +// function-local so that registrations during static initialization always find it constructed +RegistryState &GetRegistryState() { + static RegistryState state; + return state; +} + +void SetDescriptorError(duckdb_extension_descriptor *descriptor, const char *message) { + auto &error = *static_cast(descriptor->internal); + error = message ? message : ""; +} + +//! Returns an empty string on success, otherwise the reason the registration failed. +string Register(duckdb_extension_describe_t describe) { + StaticExtensionDescription description; + auto error = LinkedExtensionRegistry::Describe(describe, description); + if (!error.empty()) { + return error; + } + auto &state = GetRegistryState(); + std::lock_guard guard(state.lock); + for (auto &entry : state.registered) { + if (!StringUtil::CIEquals(entry.name, description.name)) { + continue; + } + if (entry.describe == describe) { + return string(); + } + return "extension '" + description.name + "' is registered by two different describe functions"; + } + state.registered.push_back({description.name, describe}); + state.extensions.push_back({description.name, [describe](DuckDB &db) { + db.LoadStaticExtension(describe); + }}); + return string(); +} + +} // namespace + +string LinkedExtensionRegistry::Describe(duckdb_extension_describe_t describe, StaticExtensionDescription &result) { + if (!describe) { + return "no describe function was given"; + } + string error; + auto &descriptor = result.descriptor; + descriptor = duckdb_extension_descriptor(); + descriptor.version = DUCKDB_EXTENSION_DESCRIPTOR_VERSION; + descriptor.set_error = SetDescriptorError; + descriptor.internal = &error; + + auto status = describe(&descriptor); + descriptor.internal = nullptr; + result.name = descriptor.name ? descriptor.name : ""; + result.version = descriptor.extension_version ? descriptor.extension_version : ""; + result.api_version = descriptor.api_version ? descriptor.api_version : ""; + const string subject = result.name.empty() ? string("an extension") : "extension '" + result.name + "'"; + if (status != 0) { + return subject + " refused to register: " + (error.empty() ? string("no reason given") : error); + } + if (!error.empty()) { + return subject + " reported an error but returned success: " + error; + } + if (descriptor.version < 1 || descriptor.version > DUCKDB_EXTENSION_DESCRIPTOR_VERSION) { + return StringUtil::Format("%s filled descriptor layout %d, but layout %d was offered", subject, + descriptor.version, DUCKDB_EXTENSION_DESCRIPTOR_VERSION); + } + if (result.name.empty()) { + return "an extension describe function did not set a name"; + } + if (!descriptor.entry_cpp && !descriptor.entry_capi_v1 && !descriptor.entry_capi_v2) { + return subject + " did not set an entry point"; + } + return string(); +} + +vector LinkedExtensionRegistry::Get() { + auto &state = GetRegistryState(); + std::lock_guard guard(state.lock); + if (state.errors.empty() && !state.unknown_error) { + return state.extensions; + } + auto errors = state.errors; + if (state.unknown_error) { + errors.push_back("an extension registration failed with an unknown error"); + } + throw InvalidConfigurationException("Failed to register statically linked extensions: %s", + StringUtil::Join(errors, "; ")); +} + +} // namespace duckdb + +int32_t duckdb_register_static_extension(duckdb_extension_describe_t describe) { + auto &state = duckdb::GetRegistryState(); + try { + auto error = duckdb::Register(describe); + if (error.empty()) { + return 0; + } + std::lock_guard guard(state.lock); + state.errors.push_back(std::move(error)); + } catch (...) { // NOLINT: never throw across the C API + state.unknown_error = true; + } + return 1; +} diff --git a/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp b/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp index 12424950f..6baf2f443 100644 --- a/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp +++ b/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp @@ -15,12 +15,11 @@ ArithmeticSimplificationRule::ArithmeticSimplificationRule(ExpressionRewriter &r op->matchers.push_back(make_uniq()); op->matchers.push_back(make_uniq()); op->policy = SetMatcher::Policy::SOME; - // we only match on simple arithmetic expressions (+, -, *, /) - op->function = make_uniq(identifier_set_t {"+", "-", "*", "//"}); + op->function = make_uniq(identifier_set_t {"+", "-", "*", "/", "//"}); // and only with numeric results - op->type = make_uniq(); - op->matchers[0]->type = make_uniq(); - op->matchers[1]->type = make_uniq(); + op->type = make_uniq(); + op->matchers[0]->type = make_uniq(); + op->matchers[1]->type = make_uniq(); root = std::move(op); } @@ -36,6 +35,17 @@ unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, return make_uniq(Value(root.GetReturnType())); } auto &func_name = root.Function().GetName(); + if (func_name == "/") { + if (constant_child == 1 && constant.GetValue() == 1 && + (root.GetChildren()[0]->GetReturnType().id() == LogicalTypeId::FLOAT || + root.GetChildren()[0]->GetReturnType().id() == LogicalTypeId::DOUBLE)) { + return std::move(root.GetChildrenMutable()[0]); + } + return nullptr; + } + if (!root.GetReturnType().IsIntegral()) { + return nullptr; + } if (func_name == "+") { if (constant.GetValue() == 0) { // addition with 0 diff --git a/src/duckdb/src/optimizer/rule/comparison_simplification.cpp b/src/duckdb/src/optimizer/rule/comparison_simplification.cpp index 5e68afab0..fa8574128 100644 --- a/src/duckdb/src/optimizer/rule/comparison_simplification.cpp +++ b/src/duckdb/src/optimizer/rule/comparison_simplification.cpp @@ -73,6 +73,34 @@ static bool DateTimestampComparisonIsInvertible(ClientContext &context, BoundFun return true; } +static bool IsLosslessIntegralToFloatingCast(const LogicalType &source_type, const LogicalType &target_type) { + if (target_type.id() == LogicalTypeId::DOUBLE) { + switch (source_type.id()) { + case LogicalTypeId::TINYINT: + case LogicalTypeId::SMALLINT: + case LogicalTypeId::INTEGER: + case LogicalTypeId::UTINYINT: + case LogicalTypeId::USMALLINT: + case LogicalTypeId::UINTEGER: + return true; + default: + return false; + } + } + if (target_type.id() == LogicalTypeId::FLOAT) { + switch (source_type.id()) { + case LogicalTypeId::TINYINT: + case LogicalTypeId::SMALLINT: + case LogicalTypeId::UTINYINT: + case LogicalTypeId::USMALLINT: + return true; + default: + return false; + } + } + return false; +} + static bool ConstantCastIsInvertible(ClientContext &context, BoundFunctionExpression &expr, BoundFunctionExpression &cast_expression, const Value &constant_value, Value &cast_constant, const LogicalType &target_type, bool column_ref_left, @@ -80,12 +108,15 @@ static bool ConstantCastIsInvertible(ClientContext &context, BoundFunctionExpres if (cast_constant.IsNull() || BoundCastExpression::CastIsInvertible(cast_expression.GetReturnType(), target_type)) { return true; } - // This asks about the constant, not the column, and the constant was cast strictly just above - for - // integers that already proves it is exactly representable, so no type-level guarantee is needed. The - // column side is checked separately by the caller. if (cast_expression.GetReturnType().IsIntegral() && target_type.IsIntegral()) { return true; } + // The constant must survive the integral round-trip exactly; the column side is checked by the caller. + if (IsLosslessIntegralToFloatingCast(target_type, cast_expression.GetReturnType())) { + string error_message; + auto roundtrip = cast_constant.TryCastAs(context, cast_expression.GetReturnType(), &error_message, true); + return roundtrip && *roundtrip == constant_value; + } if (target_type.id() != LogicalTypeId::DATE || cast_expression.GetReturnType().id() != LogicalTypeId::TIMESTAMP) { return false; } @@ -201,7 +232,8 @@ unique_ptr ComparisonSimplificationRule::Apply(LogicalOperator &op, //! invertible in practice. auto &cast_expression = column_ref_expr.Cast(); auto target_type = BoundCastExpression::SourceType(cast_expression); - if (!BoundCastExpression::CastIsInvertible(target_type, cast_expression.GetReturnType())) { + if (!BoundCastExpression::CastIsInvertible(target_type, cast_expression.GetReturnType()) && + !IsLosslessIntegralToFloatingCast(target_type, cast_expression.GetReturnType())) { return nullptr; } diff --git a/src/duckdb/src/parallel/pipeline_broadcast_exchange.cpp b/src/duckdb/src/parallel/pipeline_broadcast_exchange.cpp index c455bf010..9ab93544c 100644 --- a/src/duckdb/src/parallel/pipeline_broadcast_exchange.cpp +++ b/src/duckdb/src/parallel/pipeline_broadcast_exchange.cpp @@ -1767,24 +1767,23 @@ ProgressData PipelineBroadcastExchange::SinkProgress(const ProgressData &source_ idx_t estimated_cardinality) const { annotated_lock_guard guard(lock); ProgressData progress; - auto produced_count = produced_rows.load(std::memory_order_relaxed); - auto produced = double(produced_count); if (producer_state != ProducerState::ACTIVE) { - auto total = MaxValue(produced, 1.0); - progress.done = total; - progress.total = total; + progress.done = 1.0; + progress.total = 1.0; return progress; } - progress.done = produced; if (source_progress.IsValid()) { - progress.total = produced + MaxValue(source_progress.total - source_progress.done, 1.0); + // the producing pipeline is done once its source is exhausted + return source_progress; + } + auto produced_count = produced_rows.load(std::memory_order_relaxed); + auto produced = double(produced_count); + progress.done = produced; + static constexpr const idx_t MAX_PROGRESS_CARDINALITY = 1ULL << 48ULL; + if (estimated_cardinality > 0 && estimated_cardinality < MAX_PROGRESS_CARDINALITY) { + progress.total = double(MaxValue(estimated_cardinality, produced_count + 1)); } else { - static constexpr const idx_t MAX_PROGRESS_CARDINALITY = 1ULL << 48ULL; - if (estimated_cardinality > 0 && estimated_cardinality < MAX_PROGRESS_CARDINALITY) { - progress.total = double(MaxValue(estimated_cardinality, produced_count + 1)); - } else { - progress.total = produced + 1.0; - } + progress.total = produced + 1.0; } if (progress.done > progress.total) { progress.total = progress.done; diff --git a/src/duckdb/src/parser/peg/matcher_factory.cpp b/src/duckdb/src/parser/peg/matcher_factory.cpp index fafdc6388..6f1185f88 100644 --- a/src/duckdb/src/parser/peg/matcher_factory.cpp +++ b/src/duckdb/src/parser/peg/matcher_factory.cpp @@ -217,27 +217,11 @@ Matcher &MatcherFactory::CreateRootMatcher(const string &root_rule) { // START GENERATED PACKRAT MEMOIZED RULES //===--------------------------------------------------------------------===// AddPackratMemoizedRule("Expression"); - AddPackratMemoizedRule("LambdaArrowExpression"); - AddPackratMemoizedRule("LogicalOrExpression"); - AddPackratMemoizedRule("LogicalAndExpression"); - AddPackratMemoizedRule("LogicalNotExpression"); - AddPackratMemoizedRule("IsExpression"); - AddPackratMemoizedRule("ComparisonExpression"); - AddPackratMemoizedRule("BitwiseExpression"); - AddPackratMemoizedRule("AdditiveExpression"); - AddPackratMemoizedRule("MultiplicativeExpression"); - AddPackratMemoizedRule("ExponentiationExpression"); - AddPackratMemoizedRule("PrefixExpression"); - AddPackratMemoizedRule("CollateExpression"); - AddPackratMemoizedRule("AtTimeZoneExpression"); - AddPackratMemoizedRule("SingleExpression"); - AddPackratMemoizedRule("BaseExpression"); - AddPackratMemoizedRule("ParensExpression"); - AddPackratMemoizedRule("ParenthesisExpression"); AddPackratMemoizedRule("Identifier"); AddPackratMemoizedRule("ColId"); - AddPackratMemoizedRule("ColumnReference"); - AddPackratMemoizedRule("FunctionExpression"); + AddPackratMemoizedRule("CatalogQualification"); + AddPackratMemoizedRule("SchemaQualification"); + AddPackratMemoizedRule("ReservedSchemaQualification"); //===--------------------------------------------------------------------===// // END GENERATED PACKRAT MEMOIZED RULES //===--------------------------------------------------------------------===// diff --git a/src/duckdb/src/parser/peg/transformer/transform_expression.cpp b/src/duckdb/src/parser/peg/transformer/transform_expression.cpp index 13fed081d..28c1e195b 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_expression.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_expression.cpp @@ -1181,10 +1181,31 @@ string PEGTransformerFactory::TransformNotSimilarToOp(PEGTransformer &transforme return "!" + RegexMatchOperatorFunctionName(transformer); } +static unique_ptr TransformOperatorFunction(const string &operator_name, + vector> children) { + vector split_operator = StringUtil::Split(operator_name, "."); + string schema_name; + string function_name; + if (split_operator.size() == 1) { + function_name = std::move(split_operator[0]); + } else if (split_operator.size() == 2) { + schema_name = std::move(split_operator[0]); + function_name = std::move(split_operator[1]); + } else { + throw ParserException("Too many identifiers found, expected schema.operator or operator"); + } + + auto result = make_uniq( + QualifiedName(Identifier(), Identifier(std::move(schema_name)), Identifier(std::move(function_name))), + std::move(children)); + result->IsOperatorMutable() = true; + return std::move(result); +} + unique_ptr -PEGTransformerFactory::TransformOtherOperatorExpression(PEGTransformer &transformer, - unique_ptr bitwise_expression, - optional> other_operator_tail) { +PEGTransformerFactory::TransformInfixOtherOperatorExpression(PEGTransformer &transformer, + unique_ptr bitwise_expression, + optional> other_operator_tail) { auto expr = std::move(bitwise_expression); if (!other_operator_tail) { return expr; @@ -1259,28 +1280,20 @@ PEGTransformerFactory::TransformOtherOperatorExpression(PEGTransformer &transfor vector> children_function; children_function.push_back(std::move(expr)); children_function.push_back(std::move(right_expr)); - vector split_operator = StringUtil::Split(other_operator, "."); - string schema_name; - string func_name = ""; - if (split_operator.size() == 1) { - func_name = split_operator[0]; - } else if (split_operator.size() == 2) { - schema_name = split_operator[0]; - func_name = split_operator[1]; - } else { - throw ParserException("Too many identifiers found, expected schema.operator or operator"); - } - - auto func_expr = make_uniq( - QualifiedName(Identifier(), Identifier(std::move(schema_name)), Identifier(std::move(func_name))), - std::move(children_function)); - func_expr->IsOperatorMutable() = true; - expr = std::move(func_expr); + expr = TransformOperatorFunction(other_operator, std::move(children_function)); } } return expr; } +unique_ptr +PEGTransformerFactory::TransformCustomPrefixExpression(PEGTransformer &transformer, const string &operator_literal, + unique_ptr other_operator_expression) { + vector> children; + children.push_back(std::move(other_operator_expression)); + return TransformOperatorFunction(operator_literal, std::move(children)); +} + OtherOperatorTail PEGTransformerFactory::TransformOtherOperatorTail(PEGTransformer &transformer, ParsedOperator other_operator, unique_ptr bitwise_expression) { diff --git a/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp b/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp index bc326f193..b8eaa7e34 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp @@ -1786,6 +1786,12 @@ static const TransformFrameOps BETWEEN_CLAUSE_OPS = {"BetweenClause", static const TransformFrameOps OTHER_OPERATOR_EXPRESSION_OPS = { "OtherOperatorExpression", &PEGTransformerFactory::InitializeOtherOperatorExpressionTrampoline, &PEGTransformerFactory::FinalizeOtherOperatorExpressionTrampoline}; +static const TransformFrameOps INFIX_OTHER_OPERATOR_EXPRESSION_OPS = { + "InfixOtherOperatorExpression", &PEGTransformerFactory::InitializeInfixOtherOperatorExpressionTrampoline, + &PEGTransformerFactory::FinalizeInfixOtherOperatorExpressionTrampoline}; +static const TransformFrameOps CUSTOM_PREFIX_EXPRESSION_OPS = { + "CustomPrefixExpression", &PEGTransformerFactory::InitializeCustomPrefixExpressionTrampoline, + &PEGTransformerFactory::FinalizeCustomPrefixExpressionTrampoline}; static const TransformFrameOps OTHER_OPERATOR_TAIL_OPS = {"OtherOperatorTail", &PEGTransformerFactory::InitializeOtherOperatorTailTrampoline, &PEGTransformerFactory::FinalizeOtherOperatorTailTrampoline}; @@ -2389,6 +2395,9 @@ static const TransformFrameOps OFFSET_LIMIT_CLAUSE_OPS = {"OffsetLimitClause", static const TransformFrameOps OFFSET_FETCH_CLAUSE_OPS = {"OffsetFetchClause", &PEGTransformerFactory::InitializeOffsetFetchClauseTrampoline, &PEGTransformerFactory::FinalizeOffsetFetchClauseTrampoline}; +static const TransformFrameOps FETCH_OFFSET_CLAUSE_OPS = {"FetchOffsetClause", + &PEGTransformerFactory::InitializeFetchOffsetClauseTrampoline, + &PEGTransformerFactory::FinalizeFetchOffsetClauseTrampoline}; static const TransformFrameOps FETCH_ONLY_CLAUSE_OPS = {"FetchOnlyClause", &PEGTransformerFactory::InitializeFetchOnlyClauseTrampoline, &PEGTransformerFactory::FinalizeFetchOnlyClauseTrampoline}; @@ -2813,6 +2822,12 @@ static const TransformFrameOps LIMIT_EXPRESSION_OPS = {"LimitExpression", static const TransformFrameOps FETCH_CLAUSE_OPS = {"FetchClause", &PEGTransformerFactory::InitializeFetchClauseTrampoline, &PEGTransformerFactory::FinalizeFetchClauseTrampoline}; +static const TransformFrameOps FETCH_CLAUSE_WITHOUT_VALUE_OPS = { + "FetchClauseWithoutValue", &PEGTransformerFactory::InitializeFetchClauseWithoutValueTrampoline, + &PEGTransformerFactory::FinalizeFetchClauseWithoutValueTrampoline}; +static const TransformFrameOps FETCH_CLAUSE_WITH_VALUE_OPS = { + "FetchClauseWithValue", &PEGTransformerFactory::InitializeFetchClauseWithValueTrampoline, + &PEGTransformerFactory::FinalizeFetchClauseWithValueTrampoline}; static const TransformFrameOps FETCH_VALUE_OPS = {"FetchValue", &PEGTransformerFactory::InitializeFetchValueTrampoline, &PEGTransformerFactory::FinalizeFetchValueTrampoline}; static const TransformFrameOps ALIASED_EXPRESSION_OPS = {"AliasedExpression", @@ -3619,6 +3634,8 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"InSelectStatement", &IN_SELECT_STATEMENT_OPS}, {"BetweenClause", &BETWEEN_CLAUSE_OPS}, {"OtherOperatorExpression", &OTHER_OPERATOR_EXPRESSION_OPS}, + {"InfixOtherOperatorExpression", &INFIX_OTHER_OPERATOR_EXPRESSION_OPS}, + {"CustomPrefixExpression", &CUSTOM_PREFIX_EXPRESSION_OPS}, {"OtherOperatorTail", &OTHER_OPERATOR_TAIL_OPS}, {"OtherOperator", &OTHER_OPERATOR_OPS}, {"AnyAllParsedOperator", &ANY_ALL_PARSED_OPERATOR_OPS}, @@ -3826,6 +3843,7 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"LimitOffsetClause", &LIMIT_OFFSET_CLAUSE_OPS}, {"OffsetLimitClause", &OFFSET_LIMIT_CLAUSE_OPS}, {"OffsetFetchClause", &OFFSET_FETCH_CLAUSE_OPS}, + {"FetchOffsetClause", &FETCH_OFFSET_CLAUSE_OPS}, {"FetchOnlyClause", &FETCH_ONLY_CLAUSE_OPS}, {"TableStatement", &TABLE_STATEMENT_OPS}, {"OptionalParensSimpleSelect", &OPTIONAL_PARENS_SIMPLE_SELECT_OPS}, @@ -3979,6 +3997,8 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"LimitLiteralPercent", &LIMIT_LITERAL_PERCENT_OPS}, {"LimitExpression", &LIMIT_EXPRESSION_OPS}, {"FetchClause", &FETCH_CLAUSE_OPS}, + {"FetchClauseWithoutValue", &FETCH_CLAUSE_WITHOUT_VALUE_OPS}, + {"FetchClauseWithValue", &FETCH_CLAUSE_WITH_VALUE_OPS}, {"FetchValue", &FETCH_VALUE_OPS}, {"AliasedExpression", &ALIASED_EXPRESSION_OPS}, {"ColIdExpression", &COL_ID_EXPRESSION_OPS}, @@ -16258,6 +16278,27 @@ PEGTransformerFactory::FinalizeBetweenClauseTrampoline(PEGTransformer &transform void PEGTransformerFactory::InitializeOtherOperatorExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto &choice_result = choice_pr.GetResult(); + process.ReserveChildSlots(1); + auto child_rule = choice_result.GetRule(); + auto has_transform_process = child_rule && child_rule->transform_process; + if (!has_transform_process) { + throw InternalException("No transform process registered for rule '%s'", choice_result.name); + } + process.PushChild({*child_rule, choice_result}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeOtherOperatorExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = process.TakeResult>(0); + return make_uniq>>(std::move(result)); +} + +void PEGTransformerFactory::InitializeInfixOtherOperatorExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); auto &repeat_opt = list_pr.GetChild(1).Cast(); idx_t dynamic_child_count = 0; if (repeat_opt.HasResult()) { @@ -16277,8 +16318,8 @@ void PEGTransformerFactory::InitializeOtherOperatorExpressionTrampoline(PEGTrans } unique_ptr -PEGTransformerFactory::FinalizeOtherOperatorExpressionTrampoline(PEGTransformer &transformer, - GeneratedTransformProcess &process) { +PEGTransformerFactory::FinalizeInfixOtherOperatorExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); idx_t dynamic_child_count = 0; auto &dynamic_repeat_opt = list_pr.GetChild(1).Cast(); @@ -16296,8 +16337,25 @@ PEGTransformerFactory::FinalizeOtherOperatorExpressionTrampoline(PEGTransformer } other_operator_tail = std::move(other_operator_tail_value); } - auto result = - TransformOtherOperatorExpression(transformer, std::move(bitwise_expression), std::move(other_operator_tail)); + auto result = TransformInfixOtherOperatorExpression(transformer, std::move(bitwise_expression), + std::move(other_operator_tail)); + return make_uniq>>(std::move(result)); +} + +void PEGTransformerFactory::InitializeCustomPrefixExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("OtherOperatorExpression"), list_pr.GetChild(1)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeCustomPrefixExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + auto operator_literal = list_pr.GetChild(0).Cast().operator_token; + auto other_operator_expression = process.TakeResult>(0); + auto result = TransformCustomPrefixExpression(transformer, operator_literal, std::move(other_operator_expression)); return make_uniq>>(std::move(result)); } @@ -20555,6 +20613,23 @@ PEGTransformerFactory::FinalizeOffsetFetchClauseTrampoline(PEGTransformer &trans return make_uniq>>(std::move(result)); } +void PEGTransformerFactory::InitializeFetchOffsetClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(2); + process.PushChild({transformer.GetRule("OffsetClause"), list_pr.GetChild(1)}, 1); + process.PushChild({transformer.GetRule("FetchClause"), list_pr.GetChild(0)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeFetchOffsetClauseTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto fetch_clause = process.TakeResult(0); + auto offset_clause = process.TakeResult(1); + auto result = TransformFetchOffsetClause(transformer, std::move(fetch_clause), std::move(offset_clause)); + return make_uniq>>(std::move(result)); +} + void PEGTransformerFactory::InitializeFetchOnlyClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); @@ -23636,8 +23711,15 @@ PEGTransformerFactory::FinalizeLimitExpressionTrampoline(PEGTransformer &transfo void PEGTransformerFactory::InitializeFetchClauseTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); + auto &choice_pr = list_pr.Child(0); + auto &choice_result = choice_pr.GetResult(); process.ReserveChildSlots(1); - process.PushChild({transformer.GetRule("FetchValue"), list_pr.GetChild(2)}, 0); + auto child_rule = choice_result.GetRule(); + auto has_transform_process = child_rule && child_rule->transform_process; + if (!has_transform_process) { + throw InternalException("No transform process registered for rule '%s'", choice_result.name); + } + process.PushChild({*child_rule, choice_result}, 0); } unique_ptr @@ -23646,6 +23728,32 @@ PEGTransformerFactory::FinalizeFetchClauseTrampoline(PEGTransformer &transformer return make_uniq>(std::move(result)); } +void PEGTransformerFactory::InitializeFetchClauseWithoutValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + process.ReserveChildSlots(0); +} + +unique_ptr +PEGTransformerFactory::FinalizeFetchClauseWithoutValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = TransformFetchClauseWithoutValue(transformer); + return make_uniq>(std::move(result)); +} + +void PEGTransformerFactory::InitializeFetchClauseWithValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + process.ReserveChildSlots(1); + process.PushChild({transformer.GetRule("FetchValue"), list_pr.GetChild(2)}, 0); +} + +unique_ptr +PEGTransformerFactory::FinalizeFetchClauseWithValueTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto result = process.TakeResult(0); + return make_uniq>(std::move(result)); +} + void PEGTransformerFactory::InitializeFetchValueTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); diff --git a/src/duckdb/src/parser/peg/transformer/transform_select.cpp b/src/duckdb/src/parser/peg/transformer/transform_select.cpp index 9e869dc71..fb00b65f7 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_select.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_select.cpp @@ -1226,6 +1226,12 @@ unique_ptr PEGTransformerFactory::TransformOffsetFetchClause(PEG return VerifyLimitOffset(fetch_clause, offset_clause); } +unique_ptr PEGTransformerFactory::TransformFetchOffsetClause(PEGTransformer &transformer, + LimitPercentResult fetch_clause, + LimitPercentResult offset_clause) { + return VerifyLimitOffset(fetch_clause, offset_clause); +} + unique_ptr PEGTransformerFactory::TransformFetchOnlyClause(PEGTransformer &transformer, LimitPercentResult fetch_clause) { LimitPercentResult empty_offset; @@ -1785,6 +1791,12 @@ LimitPercentResult PEGTransformerFactory::TransformFetchValue(PEGTransformer &tr return result; } +LimitPercentResult PEGTransformerFactory::TransformFetchClauseWithoutValue(PEGTransformer &transformer) { + LimitPercentResult result; + result.expression = ConstantExpression::Integer(1); + return result; +} + unique_ptr PEGTransformerFactory::TransformColIdExpression(PEGTransformer &transformer, const Identifier &col_id, unique_ptr expression) { diff --git a/src/duckdb/src/planner/binder/tableref/bind_named_parameters.cpp b/src/duckdb/src/planner/binder/tableref/bind_named_parameters.cpp index 288c6d6e0..c1bec0bd6 100644 --- a/src/duckdb/src/planner/binder/tableref/bind_named_parameters.cpp +++ b/src/duckdb/src/planner/binder/tableref/bind_named_parameters.cpp @@ -41,7 +41,7 @@ void Binder::BindNamedParameters(named_parameter_type_map_t &types, named_parame func_name.GetIdentifierName(), error_msg); } if (entry->second.id() != LogicalTypeId::ANY) { - kv.second = kv.second.DefaultCastAs(entry->second); + kv.second = kv.second.CastAs(context, entry->second); } } } diff --git a/src/duckdb/src/planner/operator/logical_get.cpp b/src/duckdb/src/planner/operator/logical_get.cpp index 9612ea649..0e86b0d6c 100644 --- a/src/duckdb/src/planner/operator/logical_get.cpp +++ b/src/duckdb/src/planner/operator/logical_get.cpp @@ -315,7 +315,7 @@ void LogicalGet::Serialize(Serializer &serializer) const { serializer.WriteProperty(204, "projection_ids", projection_ids); serializer.WriteProperty(205, "table_filters", table_filters); FunctionSerializer::Serialize(serializer, function, bind_data.get()); - if (!function.serialize || serializer.ShouldSerialize(StorageVersion::V2_0_0)) { + if (!function.HasSerializationCallbacks() || serializer.ShouldSerialize(StorageVersion::V2_0_0)) { serializer.WriteProperty(206, "parameters", parameters); serializer.WriteProperty(207, "named_parameters", named_parameters); serializer.WriteProperty(208, "input_table_types", input_table_types); diff --git a/src/duckdb/src/storage/table/row_group_collection.cpp b/src/duckdb/src/storage/table/row_group_collection.cpp index a0ee7fcc1..c6fdd38b7 100644 --- a/src/duckdb/src/storage/table/row_group_collection.cpp +++ b/src/duckdb/src/storage/table/row_group_collection.cpp @@ -357,6 +357,16 @@ void RowGroupCollection::InitializeParallelScan(ParallelCollectionScanState &sta state.max_row = state.row_groups->GetBaseRowId() + next_row_id.load(); state.batch_index = 0; state.processed_rows = 0; + state.skipped_rows = 0; + if (state.reorderer) { + // row groups pruned by the reorderer are never scanned + idx_t total_rows = 0; + for (auto &row_group : state.row_groups->SegmentNodes()) { + total_rows += row_group.GetNode().count; + } + auto scan_rows = state.reorderer->ScanRowCount(); + state.skipped_rows = total_rows > scan_rows ? total_rows - scan_rows : 0; + } } optional_idx RowGroupCollection::NextParallelScan(ClientContext &context, ParallelCollectionScanState &state, @@ -421,6 +431,7 @@ optional_idx RowGroupCollection::NextParallelScan(ClientContext &context, Parall max_row, initialize_columns); if (!need_to_scan) { // skip this row group + state.skipped_rows.fetch_add(assignment_rows, std::memory_order_relaxed); continue; } return assignment_rows; diff --git a/src/duckdb/src/storage/table/row_group_reorderer.cpp b/src/duckdb/src/storage/table/row_group_reorderer.cpp index 4ad40d46d..315230a31 100644 --- a/src/duckdb/src/storage/table/row_group_reorderer.cpp +++ b/src/duckdb/src/storage/table/row_group_reorderer.cpp @@ -210,6 +210,15 @@ RowGroupReorderer::RowGroupReorderer(const RowGroupOrderOptions &options_p, Tran : options(options_p), transaction(transaction_p), offset(0), initialized(false) { } +idx_t RowGroupReorderer::ScanRowCount() const { + D_ASSERT(initialized); + idx_t count = 0; + for (auto &row_group : ordered_row_groups) { + count += row_group.get().GetNode().count; + } + return count; +} + optional_ptr> RowGroupReorderer::GetNextRowGroup(SegmentNode &row_group) { D_ASSERT(RefersToSameObject(ordered_row_groups[offset].get(), row_group)); if (offset >= ordered_row_groups.size() - 1) { diff --git a/src/duckdb/src/storage/table/scan_state.cpp b/src/duckdb/src/storage/table/scan_state.cpp index a967e9a9d..a879ff67c 100644 --- a/src/duckdb/src/storage/table/scan_state.cpp +++ b/src/duckdb/src/storage/table/scan_state.cpp @@ -209,7 +209,7 @@ TableScanOptions &CollectionScanState::GetOptions() { } ParallelCollectionScanState::ParallelCollectionScanState() - : collection(nullptr), current_row_group(nullptr), processed_rows(0) { + : collection(nullptr), current_row_group(nullptr), processed_rows(0), skipped_rows(0) { } void ParallelCollectionScanState::AssignRowGroup(optional_ptr> row_group) { diff --git a/src/duckdb/src/transaction/duck_transaction_manager.cpp b/src/duckdb/src/transaction/duck_transaction_manager.cpp index 4dd54f909..5dfdfe969 100644 --- a/src/duckdb/src/transaction/duck_transaction_manager.cpp +++ b/src/duckdb/src/transaction/duck_transaction_manager.cpp @@ -37,6 +37,7 @@ void DuckCleanupInfo::Cleanup() { for (auto &transaction : transactions) { if (transaction->awaiting_cleanup) { transaction->Cleanup(lowest_visibility_bound); + transaction->awaiting_cleanup = false; } } } @@ -281,18 +282,25 @@ transaction_t DuckTransactionManager::GetCommitTimestamp() { void DuckTransactionManager::CleanupTransactions() { lock_guard c_lock(cleanup_lock); while (true) { - unique_ptr top_cleanup_info; + DuckCleanupInfo *top_cleanup_info = nullptr; { lock_guard q_lock(cleanup_queue_lock); if (cleanup_queue.empty()) { // all transactions have been cleaned up - done return; } - top_cleanup_info = std::move(cleanup_queue.front()); - cleanup_queue.pop(); + top_cleanup_info = cleanup_queue.front().get(); } - if (top_cleanup_info) { + try { top_cleanup_info->Cleanup(); + } catch (FatalException &) { + throw; + } catch (std::exception &) { + return; + } + { + lock_guard q_lock(cleanup_queue_lock); + cleanup_queue.pop(); } } } From 9297d4e29516b04e48bc5b2905f865c6c07bd09c Mon Sep 17 00:00:00 2001 From: DuckLabs GitHub Bot Date: Fri, 25 Sep 2026 07:29:37 +0000 Subject: [PATCH 4/6] Update vendored DuckDB sources to 9d283094ac --- ...nerated_extension_loader_package_build.cpp | 8 +- .../multi_file/multi_file_column_mapper.cpp | 4 +- .../variant/parquet_variant_encoding.cpp | 4 +- .../scanner/string_value_scanner.cpp | 2 +- .../csv_scanner/util/csv_reader_options.cpp | 9 +- .../src/function/table/query_function.cpp | 32 +- .../function/table/version/pragma_version.cpp | 6 +- .../function/window/window_segment_tree.cpp | 4 +- .../common/multi_file/multi_file_data.hpp | 4 + .../duckdb/function/replacement_scan.hpp | 14 +- .../duckdb/parser/peg/inlined_grammar.hpp | 2400 +++++++++-------- .../peg/transformer/peg_transformer.hpp | 10 +- .../checkpoint/string_checkpoint_state.hpp | 15 +- .../chimp/algorithm/bit_reader.hpp | 69 +- .../compression/chimp/algorithm/chimp128.hpp | 23 +- .../chimp/algorithm/flag_buffer.hpp | 17 +- .../chimp/algorithm/leading_zero_buffer.hpp | 28 +- .../chimp/algorithm/packed_data.hpp | 13 +- .../storage/compression/chimp/chimp.hpp | 4 +- .../storage/compression/chimp/chimp_fetch.hpp | 6 +- .../storage/compression/chimp/chimp_scan.hpp | 203 +- .../compression_segment_reader.hpp | 25 + .../storage/compression/patas/patas_fetch.hpp | 6 +- .../storage/compression/patas/patas_scan.hpp | 152 +- .../storage/compression/patas/shared.hpp | 8 +- .../duckdb/storage/database_handle.hpp | 9 +- .../duckdb/storage/string_uncompressed.hpp | 82 +- src/duckdb/src/main/client_context.cpp | 3 +- .../optimizer/remote_pushdown_optimizer.cpp | 13 +- src/duckdb/src/parser/column_definition.cpp | 2 +- .../parser/expression/function_expression.cpp | 2 +- .../peg/transformer/peg_transformer.cpp | 2 +- .../transformer/transform_create_table.cpp | 4 +- .../peg/transformer/transform_expression.cpp | 25 +- .../transform_generated_trampoline.cpp | 64 +- .../binder/statement/bind_create_table.cpp | 2 +- .../planner/binder/statement/bind_update.cpp | 4 +- .../binder/tableref/bind_basetableref.cpp | 4 +- .../src/planner/operator/logical_get.cpp | 37 + .../write_overflow_strings_to_disk.cpp | 22 +- .../src/storage/compression/chimp/chimp.cpp | 25 + .../compression_segment_reader.cpp | 8 + src/duckdb/src/storage/compression/patas.cpp | 20 + .../compression/string_uncompressed.cpp | 322 ++- src/duckdb/src/storage/compression/zstd.cpp | 8 +- src/duckdb/src/storage/database_handle.cpp | 27 +- .../src/storage/single_file_block_manager.cpp | 4 +- 47 files changed, 2206 insertions(+), 1549 deletions(-) diff --git a/src/duckdb/generated_extension_loader_package_build.cpp b/src/duckdb/generated_extension_loader_package_build.cpp index 4d3b22962..17f4c26dd 100644 --- a/src/duckdb/generated_extension_loader_package_build.cpp +++ b/src/duckdb/generated_extension_loader_package_build.cpp @@ -41,7 +41,7 @@ int32_t duckdb_extension_core_functions_describe(duckdb_extension_descriptor *de descriptor->version = 1; descriptor->name = "core_functions"; descriptor->extension_version = EXT_VERSION_CORE_FUNCTIONS; - descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->api_version = "v2.0.0-alpha43355"; descriptor->entry_cpp = (void (*)(void))core_functions_duckdb_cpp_init; return 0; } @@ -74,7 +74,7 @@ int32_t duckdb_extension_parquet_describe(duckdb_extension_descriptor *descripto descriptor->version = 1; descriptor->name = "parquet"; descriptor->extension_version = EXT_VERSION_PARQUET; - descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->api_version = "v2.0.0-alpha43355"; descriptor->entry_cpp = (void (*)(void))parquet_duckdb_cpp_init; return 0; } @@ -107,7 +107,7 @@ int32_t duckdb_extension_icu_describe(duckdb_extension_descriptor *descriptor) { descriptor->version = 1; descriptor->name = "icu"; descriptor->extension_version = EXT_VERSION_ICU; - descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->api_version = "v2.0.0-alpha43355"; descriptor->entry_cpp = (void (*)(void))icu_duckdb_cpp_init; return 0; } @@ -140,7 +140,7 @@ int32_t duckdb_extension_json_describe(duckdb_extension_descriptor *descriptor) descriptor->version = 1; descriptor->name = "json"; descriptor->extension_version = EXT_VERSION_JSON; - descriptor->api_version = "v2.0.0-alpha43260"; + descriptor->api_version = "v2.0.0-alpha43355"; descriptor->entry_cpp = (void (*)(void))json_duckdb_cpp_init; return 0; } diff --git a/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp b/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp index b43e6b42b..a295d2490 100644 --- a/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp +++ b/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp @@ -119,7 +119,9 @@ struct FieldIdMapper : public ColumnMapper { static unique_ptr GetDefault(ClientContext &context, const MultiFileColumnDefinition &column) { auto &default_val = column.default_expression; if (!default_val) { - throw InternalException("No default expression in FieldId Map"); + throw InvalidInputException("Field \"%s\" (field id %d) is missing from the file schema and has no default " + "expression", + column.name, column.GetIdentifierFieldId()); } auto binder = Binder::CreateBinder(context); binder->SetCanContainNulls(true); diff --git a/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp b/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp index c4135b098..8a4eb21be 100644 --- a/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp +++ b/src/duckdb/src/common/types/variant/parquet_variant_encoding.cpp @@ -318,7 +318,7 @@ static idx_t AnalyzeValueData(const UnifiedVariantVectorData &variant, idx_t row case VariantLogicalType::VARCHAR: { auto string_value = VariantUtils::DecodeStringData(variant, row, values_index); total_size += string_value.GetSize(); - if (type_id == VariantLogicalType::BLOB || string_value.GetSize() > 64) { + if (type_id == VariantLogicalType::BLOB || string_value.GetSize() >= 64) { //! Save as regular string value total_size += sizeof(uint32_t); } @@ -471,7 +471,7 @@ static void WritePrimitiveValueData(const UnifiedVariantVectorData &variant, idx case VariantLogicalType::VARCHAR: { auto string_value = VariantUtils::DecodeStringData(variant, row, values_index); auto string_size = string_value.GetSize(); - if (type_id == VariantLogicalType::BLOB || string_size > 64) { + if (type_id == VariantLogicalType::BLOB || string_size >= 64) { if (type_id == VariantLogicalType::BLOB) { WritePrimitiveTypeHeader(value_data); } else { diff --git a/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp b/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp index b5d33d1f7..4853f279f 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp @@ -596,7 +596,7 @@ void StringValueResult::AddQuotedValue(StringValueResult &result, const idx_t bu void StringValueResult::AddPossiblyEscapedValue(StringValueResult &result, const idx_t buffer_pos, const char *value_ptr, const idx_t length, const bool empty) { if (result.escaped) { - if (result.projecting_columns) { + if (result.projecting_columns && result.cur_col_id < result.number_of_columns) { if (!result.projected_columns[result.cur_col_id]) { result.cur_col_id++; result.escaped = false; diff --git a/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp b/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp index 8a0e8a1c4..41ce7d6a1 100644 --- a/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp +++ b/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp @@ -3,6 +3,7 @@ #include "duckdb/common/vector_size.hpp" #include "duckdb/common/string_util.hpp" #include "duckdb/common/enum_util.hpp" +#include "duckdb/common/operator/multiply.hpp" #include "duckdb/common/multi_file/multi_file_reader.hpp" #include "duckdb/common/set.hpp" #include "duckdb/parser/keyword_helper.hpp" @@ -621,7 +622,13 @@ void CSVReaderOptions::Verify(MultiFileOptions &file_options) { } else if (maximum_line_size.IsSetByUser() && maximum_line_size.GetValue() > max_line_size_default) { // If the max line size is set by the user and bigger than we have by default, we make it part of our buffer // size decision. - buffer_size_option.Set(CSVBuffer::ROWS_PER_BUFFER * maximum_line_size.GetValue(), false); + idx_t buffer_size; + if (!TryMultiplyOperator::Operation(CSVBuffer::ROWS_PER_BUFFER, + maximum_line_size.GetValue(), buffer_size)) { + throw BinderException("MAX_LINE_SIZE option was set to %d, which is too large", + maximum_line_size.GetValue()); + } + buffer_size_option.Set(buffer_size, false); } } diff --git a/src/duckdb/src/function/table/query_function.cpp b/src/duckdb/src/function/table/query_function.cpp index 3739ac91e..a429f49c7 100644 --- a/src/duckdb/src/function/table/query_function.cpp +++ b/src/duckdb/src/function/table/query_function.cpp @@ -31,6 +31,27 @@ static unique_ptr ParseSubquery(const string &query, const ParserOp } } +//! Whether the argument is a file path or URL rather than a (qualified) table name: a path separator outside of quotes +static bool IsFilePath(const string &input) { + bool quoted = false; + for (auto c : input) { + if (c == '"') { + quoted = !quoted; + } else if (!quoted && (c == '/' || c == '\\')) { + return true; + } + } + return false; +} + +//! Renders the argument as a table reference: file paths are passed as string literals, like FROM 'file.parquet' +static string TableReference(const string &input) { + if (IsFilePath(input)) { + return SQLString::ToString(input); + } + return QualifiedName::Parse(input).ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA); +} + static string UnionTablesQuery(TableFunctionBindInput &input) { for (auto &input_val : input.inputs) { if (input_val.IsNull()) { @@ -43,9 +64,7 @@ static string UnionTablesQuery(TableFunctionBindInput &input) { ? "BY NAME " : ""; // 'by_name' variable defaults to false if (input.inputs[0].type().id() == LogicalTypeId::VARCHAR) { - auto from_path = input.inputs[0].ToString(); - auto qualified_name = QualifiedName::Parse(from_path); - result += "FROM " + qualified_name.ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA); + result += "FROM " + TableReference(input.inputs[0].ToString()); } else if (input.inputs[0].type() == LogicalType::LIST(LogicalType::VARCHAR)) { string union_all_clause = " UNION ALL " + by_name + "FROM "; const auto &children = ListValue::GetChildren(input.inputs[0]); @@ -53,12 +72,9 @@ static string UnionTablesQuery(TableFunctionBindInput &input) { if (children.empty()) { throw InvalidInputException("Input list is empty"); } - auto qualified_name = QualifiedName::Parse(children[0].ToString()); - result += "FROM " + qualified_name.ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA); + result += "FROM " + TableReference(children[0].ToString()); for (size_t i = 1; i < children.size(); ++i) { - auto child = children[i].ToString(); - auto qualified_name = QualifiedName::Parse(child); - result += union_all_clause + qualified_name.ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA); + result += union_all_clause + TableReference(children[i].ToString()); } } else { throw InvalidInputException("Expected a table or a list with tables as input"); diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index c7743cb10..c57cfe401 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "0-alpha43260" +#define DUCKDB_PATCH_VERSION "0-alpha43355" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 0 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 2 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v2.0.0-alpha43260" +#define DUCKDB_VERSION "v2.0.0-alpha43355" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "233847abfa" +#define DUCKDB_SOURCE_ID "9d283094ac" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/function/window/window_segment_tree.cpp b/src/duckdb/src/function/window/window_segment_tree.cpp index df23875e1..2f98601c4 100644 --- a/src/duckdb/src/function/window/window_segment_tree.cpp +++ b/src/duckdb/src/function/window/window_segment_tree.cpp @@ -361,7 +361,7 @@ void WindowSegmentTreeLocalState::Finalize(ExecutionContext &context, WindowAggr const auto &partition_offsets = gstate.partition_offsets; idx_t combine_width = gstate.TREE_FANOUT; idx_t combine_level = 0; - auto combine_begin = partition_offsets.rbegin(); + auto combine_begin = partition_offsets.rend(); std::greater combine_cmp; auto &levels_flat_native = gstate.levels_flat_native; @@ -395,7 +395,7 @@ void WindowSegmentTreeLocalState::Finalize(ExecutionContext &context, WindowAggr // Update the combine width to the current level. for (; combine_level < level_current; ++combine_level) { combine_width *= gstate.TREE_FANOUT; - combine_begin = partition_offsets.rbegin(); + combine_begin = partition_offsets.rend(); } // Check for crossing a partition boundary diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_data.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_data.hpp index acb8e460c..32446a4a3 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_data.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_data.hpp @@ -115,6 +115,10 @@ struct MultiFileColumnDefinition { Identifier name; LogicalType type; vector children; + //! Fallback when no file column/field matches this definition. A NULL fallback must be an explicit + //! ConstantExpression containing a typed NULL, rather than a nullptr. + //! With field-id mapping, nullptr requires a matching field; a missing field raises InvalidInputException. + //! With name mapping, nullptr rejects missing root columns but fills missing nested fields with NULL. unique_ptr default_expression; //! Either the field_id or the name to map on diff --git a/src/duckdb/src/include/duckdb/function/replacement_scan.hpp b/src/duckdb/src/include/duckdb/function/replacement_scan.hpp index 58d8d5fbd..d88521034 100644 --- a/src/duckdb/src/include/duckdb/function/replacement_scan.hpp +++ b/src/duckdb/src/include/duckdb/function/replacement_scan.hpp @@ -90,8 +90,20 @@ struct ReplacementScan { return table_name; } + //! Joins every component of the name, which can be qualified deeper than [catalog, schema] + static string GetFullPath(const QualifiedName &name) { + string table_name; + for (auto &component : name.Path()) { + if (component.empty()) { + continue; + } + table_name += (!table_name.empty() ? "." : "") + component.GetIdentifierName(); + } + return table_name; + } + static string GetFullPath(ReplacementScanInput &input) { - return GetFullPath(input.catalog_name, input.schema_name, input.table_name); + return GetFullPath(input.name); } replacement_scan_t function; diff --git a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp index c9a265465..f7b979043 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/inlined_grammar.hpp @@ -2233,1211 +2233,1213 @@ const unsigned char INLINED_PEG_GRAMMAR[] = { 97, 116, 111, 114, 67, 111, 110, 116, 101, 110, 116, 115, 32, 60, 45, 32, 67, 111, 108, 73, 100, 68, 111, 116, 42, 32, 65, 110, 121, 79, 112, 101, 114, 97, 116, 111, 114, 76, 105, 116, 101, 114, 97, 108, 10, 35, 32, 76, 69, 86, 69, 76, 32, 57, 10, 66, 105, 116, 119, 105, - 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 100, 100, 105, - 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 66, 105, 116, 119, 105, - 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 66, 105, - 116, 119, 105, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, - 60, 45, 32, 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 65, 100, 100, 105, 116, - 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 66, 105, 116, 79, 112, 101, - 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 38, 39, 32, 47, 32, 39, 124, 39, 32, 47, - 32, 39, 60, 60, 39, 32, 47, 32, 39, 62, 62, 39, 10, 35, 32, 76, 69, 86, 69, 76, - 32, 49, 48, 10, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, 100, 100, 105, 116, 105, 118, 101, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 100, 100, 105, 116, - 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, - 32, 84, 101, 114, 109, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 101, 114, 109, 32, 60, 45, 32, 39, - 43, 39, 32, 47, 32, 39, 45, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 49, 10, - 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, - 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 77, 117, 108, 116, 105, 112, 108, - 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, - 108, 42, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 70, 97, 99, 116, 111, - 114, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 70, 97, 99, 116, 111, 114, 32, 60, 45, 32, 39, 42, 39, - 32, 47, 32, 39, 47, 39, 32, 47, 32, 39, 47, 47, 39, 32, 47, 32, 39, 37, 39, 10, - 35, 32, 76, 69, 86, 69, 76, 32, 49, 50, 10, 69, 120, 112, 111, 110, 101, 110, 116, 105, - 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, - 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 69, 120, 112, - 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 84, 97, 105, 108, 42, 10, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, - 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 69, - 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 67, 111, 108, 108, - 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, 120, 112, 111, 110, 101, - 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 94, 39, 32, 47, 32, - 39, 42, 42, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 51, 10, 67, 111, 108, 108, - 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 65, 116, 84, - 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 67, 111, - 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, - 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, - 105, 108, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, 116, 111, - 114, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 10, 67, 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, - 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, - 49, 52, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 65, 116, - 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 80, 114, 101, - 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 84, 105, 109, 101, - 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 65, 84, 39, - 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 10, 35, 32, 76, 69, 86, - 69, 76, 32, 49, 53, 10, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, - 42, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 114, 101, - 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 81, 117, 97, 108, 105, - 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 77, 105, 110, 117, 115, - 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 80, 108, 117, - 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 84, 105, - 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 10, 77, 105, - 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, - 32, 39, 45, 39, 10, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, - 116, 111, 114, 32, 60, 45, 32, 39, 43, 39, 10, 84, 105, 108, 100, 101, 80, 114, 101, 102, - 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 126, 39, 10, 35, 32, - 76, 69, 86, 69, 76, 32, 49, 54, 32, 40, 72, 105, 103, 104, 101, 115, 116, 41, 10, 66, - 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 105, 110, - 103, 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 110, 100, 105, 114, 101, - 99, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, - 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, - 110, 43, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, - 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, 116, 79, 112, 101, 114, - 97, 116, 111, 114, 32, 47, 32, 83, 108, 105, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 47, 32, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, - 10, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 58, 58, - 39, 32, 84, 121, 112, 101, 10, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, - 45, 32, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, - 47, 32, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, 111, 114, 10, - 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, - 32, 39, 46, 39, 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, 111, 114, 32, - 60, 45, 32, 39, 46, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 10, 77, 101, 116, 104, - 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 76, - 97, 98, 101, 108, 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 10, 77, 101, 116, 104, 111, 100, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, - 80, 97, 114, 101, 110, 115, 40, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 41, 10, 77, 101, 116, - 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, - 116, 76, 105, 115, 116, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, - 108, 108, 63, 32, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, - 103, 117, 109, 101, 110, 116, 115, 63, 32, 79, 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, - 115, 101, 63, 32, 73, 103, 110, 111, 114, 101, 79, 114, 82, 101, 115, 112, 101, 99, 116, 78, - 117, 108, 108, 115, 63, 10, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, 110, - 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 76, 105, 115, 116, 40, 70, 117, - 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 10, 83, 108, 105, 99, - 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 91, 39, 32, 83, - 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 39, 93, 39, 10, 83, 108, 105, 99, 101, 66, - 111, 117, 110, 100, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, - 69, 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 32, 83, 116, 101, 112, 83, - 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 66, - 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 110, 100, 83, 108, 105, 99, 101, - 86, 97, 108, 117, 101, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, 108, 117, 101, - 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 110, 100, - 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 10, 69, 110, 100, 83, 108, 105, 99, 101, 77, - 105, 110, 117, 115, 32, 60, 45, 32, 39, 45, 39, 10, 83, 116, 101, 112, 83, 108, 105, 99, - 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 63, 10, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, - 114, 32, 60, 45, 32, 39, 33, 39, 10, 83, 112, 101, 99, 105, 97, 108, 70, 117, 110, 99, - 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, - 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 85, - 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, 114, - 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 67, 111, 108, 117, 109, 110, - 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 116, 114, 97, 99, - 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 76, 97, 109, 98, 100, 97, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 78, 117, 108, 108, 73, 102, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 82, 111, 119, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, 114, 105, 109, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 65, 76, 69, 83, 67, 69, 39, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 41, 41, 10, 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 39, 85, 78, 80, 65, 67, 75, 39, 32, 80, 97, 114, 101, 110, 115, 40, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 121, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 89, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 67, 111, 108, 117, 109, 110, - 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 83, - 121, 109, 98, 111, 108, 63, 32, 39, 67, 79, 76, 85, 77, 78, 83, 39, 32, 80, 97, 114, - 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, - 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 69, 88, - 84, 82, 65, 67, 84, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 116, 114, 97, 99, - 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, - 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 65, - 114, 103, 117, 109, 101, 110, 116, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 60, 45, 32, 39, 76, 65, 77, 66, 68, 65, 39, 32, 76, 105, 115, 116, 40, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 32, 39, 58, 39, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 117, 108, 108, 73, 102, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 78, 85, 76, 76, 73, 70, 39, 32, 80, - 97, 114, 101, 110, 115, 40, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, - 115, 41, 10, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, - 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 44, 39, 32, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 10, 80, 111, 115, 105, 116, 105, 111, 110, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, - 32, 80, 97, 114, 101, 110, 115, 40, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, 103, 117, - 109, 101, 110, 116, 115, 41, 10, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, 103, 117, 109, - 101, 110, 116, 115, 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, 97, 116, 111, - 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 10, 82, 111, 119, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, - 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 83, 117, 98, - 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, - 39, 83, 85, 66, 83, 84, 82, 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, - 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 83, - 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, - 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, - 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 76, 105, 115, 116, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, - 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, - 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, 114, 32, 60, - 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, 116, 105, 111, - 110, 97, 108, 70, 111, 114, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, - 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, 116, 105, 111, - 110, 97, 108, 70, 111, 114, 32, 60, 45, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, - 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, 114, 32, 60, 45, 32, 70, 111, 114, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 114, 105, 109, 69, 120, 112, 114, 101, 115, - 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 73, 77, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 84, 114, 105, - 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 84, 114, 105, 109, 68, 105, - 114, 101, 99, 116, 105, 111, 110, 63, 32, 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 63, - 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, - 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 114, 105, 109, 66, - 111, 116, 104, 32, 47, 32, 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, 32, 47, 32, - 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, 10, 84, 114, 105, 109, 66, 111, 116, - 104, 32, 60, 45, 32, 39, 66, 79, 84, 72, 39, 10, 84, 114, 105, 109, 76, 101, 97, 100, - 105, 110, 103, 32, 60, 45, 32, 39, 76, 69, 65, 68, 73, 78, 71, 39, 10, 84, 114, 105, - 109, 84, 114, 97, 105, 108, 105, 110, 103, 32, 60, 45, 32, 39, 84, 82, 65, 73, 76, 73, - 78, 71, 39, 10, 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 70, 82, 79, 77, 39, 10, 79, 118, 101, - 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 79, - 86, 69, 82, 76, 65, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 118, 101, 114, 108, - 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 79, 118, 101, 114, 108, 97, 121, - 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 118, 101, 114, 108, 97, 121, - 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 79, 118, 101, 114, 108, - 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 39, 80, 76, 65, 67, 73, 78, 71, 39, 32, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 10, 70, 114, - 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 70, 82, 79, - 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 111, 114, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 10, 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, - 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, - 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, 120, 116, 114, 97, - 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, 116, - 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, 114, 103, 117, - 109, 101, 110, 116, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, + 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 84, 105, 108, 100, + 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 66, 105, 116, 119, 105, 115, 101, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 66, 105, 116, 119, 105, + 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, + 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 84, 105, 108, 100, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 66, 105, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, + 60, 45, 32, 39, 38, 39, 32, 47, 32, 39, 124, 39, 32, 47, 32, 39, 60, 60, 39, 32, + 47, 32, 39, 62, 62, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 57, 46, 53, 10, 84, + 105, 108, 100, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 84, 105, + 108, 100, 101, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 42, 32, 65, + 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 35, 32, + 76, 69, 86, 69, 76, 32, 49, 48, 10, 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, + 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, 100, 100, 105, + 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, + 65, 100, 100, 105, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, + 105, 108, 32, 60, 45, 32, 84, 101, 114, 109, 32, 77, 117, 108, 116, 105, 112, 108, 105, 99, + 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 101, 114, 109, + 32, 60, 45, 32, 39, 43, 39, 32, 47, 32, 39, 45, 39, 10, 35, 32, 76, 69, 86, 69, + 76, 32, 49, 49, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, + 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 77, 117, + 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 84, 97, 105, 108, 42, 10, 77, 117, 108, 116, 105, 112, 108, 105, 99, 97, 116, 105, + 118, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, + 70, 97, 99, 116, 111, 114, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, + 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 97, 99, 116, 111, 114, 32, 60, + 45, 32, 39, 42, 39, 32, 47, 32, 39, 47, 39, 32, 47, 32, 39, 47, 47, 39, 32, 47, + 32, 39, 37, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 50, 10, 69, 120, 112, 111, + 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 69, 120, 112, 111, 110, 101, 110, 116, 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 69, 120, 112, 111, 110, 101, 110, 116, + 105, 97, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, + 32, 60, 45, 32, 69, 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, + 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 69, + 120, 112, 111, 110, 101, 110, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, + 94, 39, 32, 47, 32, 39, 42, 42, 39, 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 51, + 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, + 45, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 84, 97, 105, 108, 42, 10, 67, 111, 108, 108, 97, 116, 101, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 84, 97, 105, 108, 32, 60, 45, 32, 67, 111, 108, 108, 97, 116, 101, 79, 112, + 101, 114, 97, 116, 111, 114, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 108, 108, 97, 116, 101, 79, 112, 101, 114, 97, + 116, 111, 114, 32, 60, 45, 32, 39, 67, 79, 76, 76, 65, 84, 69, 39, 10, 35, 32, 76, + 69, 86, 69, 76, 32, 49, 52, 10, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 42, 10, 65, 116, 84, 105, 109, + 101, 90, 111, 110, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 105, 108, 32, + 60, 45, 32, 65, 116, 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 80, 114, 101, 102, 105, 120, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, + 116, 84, 105, 109, 101, 90, 111, 110, 101, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, + 32, 39, 65, 84, 39, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 10, + 35, 32, 76, 69, 86, 69, 76, 32, 49, 53, 10, 80, 114, 101, 102, 105, 120, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 80, 114, 101, 102, 105, 120, 79, 112, 101, + 114, 97, 116, 111, 114, 42, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, + 81, 117, 97, 108, 105, 102, 105, 101, 100, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, + 77, 105, 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, + 47, 32, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, + 10, 77, 105, 110, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, + 32, 60, 45, 32, 39, 45, 39, 10, 80, 108, 117, 115, 80, 114, 101, 102, 105, 120, 79, 112, + 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 43, 39, 10, 84, 105, 108, 100, 101, 80, + 114, 101, 102, 105, 120, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, 39, 126, 39, + 10, 35, 32, 76, 69, 86, 69, 76, 32, 49, 54, 32, 40, 72, 105, 103, 104, 101, 115, 116, + 41, 10, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, + 83, 105, 110, 103, 108, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 110, 100, + 105, 114, 101, 99, 116, 105, 111, 110, 76, 105, 115, 116, 63, 10, 73, 110, 100, 105, 114, 101, + 99, 116, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 100, 105, 114, 101, 99, + 116, 105, 111, 110, 43, 10, 73, 110, 100, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, + 32, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 68, 111, 116, 79, + 112, 101, 114, 97, 116, 111, 114, 32, 47, 32, 83, 108, 105, 99, 101, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, 97, + 116, 111, 114, 10, 67, 97, 115, 116, 79, 112, 101, 114, 97, 116, 111, 114, 32, 60, 45, 32, + 39, 58, 58, 39, 32, 84, 121, 112, 101, 10, 68, 111, 116, 79, 112, 101, 114, 97, 116, 111, + 114, 32, 60, 45, 32, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, + 111, 114, 32, 47, 32, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, + 111, 114, 10, 68, 111, 116, 77, 101, 116, 104, 111, 100, 79, 112, 101, 114, 97, 116, 111, 114, + 32, 60, 45, 32, 39, 46, 39, 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 10, 68, 111, 116, 67, 111, 108, 117, 109, 110, 79, 112, 101, 114, 97, 116, + 111, 114, 32, 60, 45, 32, 39, 46, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 10, 77, + 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, + 111, 108, 76, 97, 98, 101, 108, 32, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 10, 77, 101, 116, 104, 111, 100, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, + 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 76, 105, 115, 116, 41, 10, + 77, 101, 116, 104, 111, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 114, 103, 117, + 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, + 79, 114, 65, 108, 108, 63, 32, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, 105, 111, + 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 63, 32, 79, 114, 100, 101, 114, 66, 121, 67, + 108, 97, 117, 115, 101, 63, 32, 73, 103, 110, 111, 114, 101, 79, 114, 82, 101, 115, 112, 101, + 99, 116, 78, 117, 108, 108, 115, 63, 10, 77, 101, 116, 104, 111, 100, 70, 117, 110, 99, 116, + 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 76, 105, 115, 116, + 40, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 10, 83, + 108, 105, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 91, + 39, 32, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 39, 93, 39, 10, 83, 108, 105, + 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 63, 32, 69, 110, 100, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 32, 83, 116, + 101, 112, 83, 108, 105, 99, 101, 66, 111, 117, 110, 100, 63, 10, 69, 110, 100, 83, 108, 105, + 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 110, 100, 83, 108, + 105, 99, 101, 86, 97, 108, 117, 101, 63, 10, 69, 110, 100, 83, 108, 105, 99, 101, 86, 97, + 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, + 69, 110, 100, 83, 108, 105, 99, 101, 77, 105, 110, 117, 115, 10, 69, 110, 100, 83, 108, 105, + 99, 101, 77, 105, 110, 117, 115, 32, 60, 45, 32, 39, 45, 39, 10, 83, 116, 101, 112, 83, + 108, 105, 99, 101, 66, 111, 117, 110, 100, 32, 60, 45, 32, 39, 58, 39, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 63, 10, 80, 111, 115, 116, 102, 105, 120, 79, 112, 101, 114, + 97, 116, 111, 114, 32, 60, 45, 32, 39, 33, 39, 10, 83, 112, 101, 99, 105, 97, 108, 70, + 117, 110, 99, 116, 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, + 32, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 47, 32, 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, + 32, 84, 114, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 67, 111, 108, + 117, 109, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 116, + 114, 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 76, 97, 109, + 98, 100, 97, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 78, 117, 108, 108, + 73, 102, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 80, 111, 115, 105, 116, + 105, 111, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 82, 111, 119, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, + 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 84, 114, 105, 109, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 79, 118, 101, 114, 108, 97, 121, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 10, 67, 111, 97, 108, 101, 115, 99, 101, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 67, 79, 65, 76, 69, 83, 67, 69, + 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 41, 41, 10, 85, 110, 112, 97, 99, 107, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 60, 45, 32, 39, 85, 78, 80, 65, 67, 75, 39, 32, 80, 97, 114, 101, + 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 121, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 89, 39, 32, 80, 97, + 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 67, 111, 108, + 117, 109, 110, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 83, 116, + 97, 114, 83, 121, 109, 98, 111, 108, 63, 32, 39, 67, 79, 76, 85, 77, 78, 83, 39, 32, + 80, 97, 114, 101, 110, 115, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, + 120, 116, 114, 97, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, + 39, 69, 88, 84, 82, 65, 67, 84, 39, 32, 80, 97, 114, 101, 110, 115, 40, 69, 120, 116, + 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 69, 120, 116, 114, 97, + 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 69, 120, 116, 114, 97, + 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, 97, 109, 98, 100, 97, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 76, 65, 77, 66, 68, 65, 39, 32, 76, 105, + 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 41, 32, 39, 58, + 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 117, 108, 108, 73, 102, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 78, 85, 76, 76, 73, 70, + 39, 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, + 101, 110, 116, 115, 41, 10, 78, 117, 108, 108, 73, 102, 65, 114, 103, 117, 109, 101, 110, 116, + 115, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 44, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 111, 115, 105, 116, 105, 111, 110, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, + 79, 78, 39, 32, 80, 97, 114, 101, 110, 115, 40, 80, 111, 115, 105, 116, 105, 111, 110, 65, + 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 80, 111, 115, 105, 116, 105, 111, 110, 65, 114, + 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 116, 104, 101, 114, 79, 112, 101, 114, + 97, 116, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 82, 111, 119, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 80, 97, 114, 101, 110, 115, + 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, + 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 39, 83, 85, 66, 83, 84, 82, 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, + 115, 40, 83, 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, + 41, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 115, + 32, 60, 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, + 101, 114, 115, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, + 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 83, 117, 98, 115, 116, 114, + 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, + 109, 70, 111, 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 70, 111, + 114, 32, 60, 45, 32, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, + 116, 105, 111, 110, 97, 108, 70, 111, 114, 32, 47, 32, 83, 117, 98, 115, 116, 114, 105, 110, + 103, 70, 111, 114, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 114, 111, 109, 79, 112, + 116, 105, 111, 110, 97, 108, 70, 111, 114, 32, 60, 45, 32, 70, 114, 111, 109, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 63, 10, 83, 117, 98, 115, 116, 114, 105, 110, 103, 70, 111, 114, 32, 60, 45, 32, 70, + 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 84, 114, 105, 109, 69, 120, 112, + 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 84, 82, 73, 77, 39, 32, 80, 97, + 114, 101, 110, 115, 40, 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, + 84, 114, 105, 109, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 84, 114, 105, + 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 63, 32, 84, 114, 105, 109, 83, 111, 117, 114, + 99, 101, 63, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, + 10, 84, 114, 105, 109, 68, 105, 114, 101, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 114, + 105, 109, 66, 111, 116, 104, 32, 47, 32, 84, 114, 105, 109, 76, 101, 97, 100, 105, 110, 103, + 32, 47, 32, 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, 10, 84, 114, 105, 109, + 66, 111, 116, 104, 32, 60, 45, 32, 39, 66, 79, 84, 72, 39, 10, 84, 114, 105, 109, 76, + 101, 97, 100, 105, 110, 103, 32, 60, 45, 32, 39, 76, 69, 65, 68, 73, 78, 71, 39, 10, + 84, 114, 105, 109, 84, 114, 97, 105, 108, 105, 110, 103, 32, 60, 45, 32, 39, 84, 82, 65, + 73, 76, 73, 78, 71, 39, 10, 84, 114, 105, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, + 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 70, 82, 79, 77, 39, 10, + 79, 118, 101, 114, 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, + 32, 39, 79, 86, 69, 82, 76, 65, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 79, 118, + 101, 114, 108, 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 41, 10, 79, 118, 101, 114, + 108, 97, 121, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 60, 45, 32, 79, 118, 101, 114, + 108, 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 47, 32, 79, 118, 101, 114, + 108, 97, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 10, 79, 118, + 101, 114, 108, 97, 121, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 32, 60, 45, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 80, 76, 65, 67, 73, 78, 71, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 70, 114, 111, 109, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 32, 70, 111, 114, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, + 10, 70, 114, 111, 109, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, + 70, 82, 79, 77, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 70, 111, 114, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 39, 70, 79, 82, 39, 32, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 79, 118, 101, 114, 108, 97, 121, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, + 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 69, 120, 116, 114, 97, 99, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, 99, 116, 68, - 97, 116, 101, 80, 97, 114, 116, 10, 69, 120, 116, 114, 97, 99, 116, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 10, 69, 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, - 103, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, - 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, 97, - 114, 116, 32, 60, 45, 10, 32, 32, 32, 32, 89, 101, 97, 114, 75, 101, 121, 119, 111, 114, - 100, 32, 47, 32, 77, 111, 110, 116, 104, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, - 97, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 72, 111, 117, 114, 75, 101, 121, 119, - 111, 114, 100, 32, 47, 32, 77, 105, 110, 117, 116, 101, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 83, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, 32, - 32, 32, 77, 105, 108, 108, 105, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, - 32, 47, 32, 77, 105, 99, 114, 111, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, - 100, 32, 47, 32, 87, 101, 101, 107, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 81, 117, - 97, 114, 116, 101, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, 101, 99, 97, 100, - 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 67, 101, 110, 116, 117, - 114, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 108, 108, 101, 110, 110, 105, - 117, 109, 75, 101, 121, 119, 111, 114, 100, 10, 35, 32, 69, 118, 101, 114, 121, 32, 115, 116, - 97, 116, 101, 109, 101, 110, 116, 32, 97, 98, 111, 117, 116, 32, 101, 120, 116, 101, 114, 110, - 97, 108, 32, 114, 101, 115, 111, 117, 114, 99, 101, 115, 44, 32, 115, 111, 32, 116, 104, 101, - 32, 116, 111, 112, 45, 108, 101, 118, 101, 108, 32, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 99, 104, 111, 105, 99, 101, 32, 99, 97, 114, 114, 105, 101, 115, 32, 111, 110, 101, 32, - 101, 110, 116, 114, 121, 10, 35, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, - 111, 110, 101, 32, 112, 101, 114, 32, 102, 111, 114, 109, 46, 10, 69, 120, 116, 101, 114, 110, - 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, - 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 82, 101, 103, 105, 115, 116, 101, 114, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, - 32, 47, 32, 68, 101, 115, 116, 114, 111, 121, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, - 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 83, 104, 111, 119, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 115, 83, 116, 109, 116, 32, 47, - 32, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, - 111, 117, 114, 99, 101, 32, 47, 32, 67, 111, 110, 110, 101, 99, 116, 84, 111, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 10, 67, 114, 101, 97, 116, 101, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, - 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 69, 120, 116, 101, 114, 110, 97, - 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 83, 116, 114, - 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, - 97, 115, 63, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, - 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, 82, 101, 103, - 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, - 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 82, 69, 71, 73, 83, 84, 69, 82, 39, 32, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, - 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, 116, - 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 39, 70, 82, 79, 77, 39, 32, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 101, 115, 116, 114, 111, 121, 69, 120, 116, 101, - 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, - 39, 68, 69, 83, 84, 82, 79, 89, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, - 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, - 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, - 115, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 72, 79, 87, 39, 32, 83, 104, 111, 119, - 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 63, 32, 39, 69, 88, 84, 69, 82, 78, - 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 83, 39, 10, 83, 104, 111, 119, - 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 65, 76, 76, 39, - 10, 35, 32, 83, 121, 110, 116, 97, 120, 32, 111, 110, 108, 121, 58, 32, 116, 104, 101, 32, - 107, 101, 121, 119, 111, 114, 100, 32, 112, 97, 105, 114, 32, 101, 118, 101, 114, 121, 32, 115, - 105, 110, 103, 117, 108, 97, 114, 32, 102, 111, 114, 109, 32, 114, 101, 112, 101, 97, 116, 115, - 46, 32, 84, 104, 101, 32, 112, 108, 117, 114, 97, 108, 32, 105, 110, 32, 83, 72, 79, 87, - 32, 99, 97, 110, 110, 111, 116, 32, 115, 104, 97, 114, 101, 32, 105, 116, 46, 10, 69, 120, - 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, - 100, 32, 60, 45, 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, - 79, 85, 82, 67, 69, 39, 10, 35, 32, 84, 104, 101, 32, 114, 101, 99, 105, 112, 101, 39, - 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 46, 32, 73, 116, 115, - 32, 111, 119, 110, 32, 114, 117, 108, 101, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, 97, - 110, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 58, 32, 116, 104, 101, - 32, 116, 119, 111, 32, 111, 112, 116, 105, 111, 110, 32, 98, 97, 103, 115, 32, 97, 114, 101, - 10, 35, 32, 100, 105, 115, 116, 105, 110, 99, 116, 44, 32, 97, 110, 100, 32, 97, 32, 115, - 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 97, 110, 32, 99, 97, 114, 114, 121, 32, 98, - 111, 116, 104, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, - 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, - 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, 76, 105, 115, - 116, 10, 35, 32, 84, 104, 101, 32, 97, 116, 116, 97, 99, 104, 32, 97, 108, 105, 97, 115, - 32, 105, 115, 32, 109, 97, 110, 100, 97, 116, 111, 114, 121, 58, 32, 105, 116, 32, 115, 101, - 112, 97, 114, 97, 116, 101, 115, 32, 116, 104, 101, 32, 114, 101, 99, 105, 112, 101, 39, 115, - 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 44, 32, 119, 104, 105, 99, - 104, 32, 112, 114, 101, 99, 101, 100, 101, 32, 105, 116, 44, 32, 102, 114, 111, 109, 32, 116, - 104, 101, 10, 35, 32, 97, 116, 116, 97, 99, 104, 109, 101, 110, 116, 39, 115, 32, 111, 119, - 110, 32, 111, 112, 116, 105, 111, 110, 115, 44, 32, 119, 104, 105, 99, 104, 32, 102, 111, 108, - 108, 111, 119, 46, 32, 87, 105, 116, 104, 111, 117, 116, 32, 105, 116, 32, 97, 32, 115, 105, - 110, 103, 108, 101, 32, 111, 112, 116, 105, 111, 110, 32, 108, 105, 115, 116, 32, 119, 111, 117, - 108, 100, 32, 98, 101, 32, 97, 109, 98, 105, 103, 117, 111, 117, 115, 46, 10, 35, 32, 67, - 79, 78, 78, 69, 67, 84, 32, 104, 97, 115, 32, 110, 111, 32, 115, 117, 99, 104, 32, 115, - 101, 112, 97, 114, 97, 116, 111, 114, 46, 32, 66, 111, 114, 114, 111, 119, 105, 110, 103, 32, - 97, 32, 114, 101, 103, 105, 115, 116, 101, 114, 101, 100, 32, 114, 101, 115, 111, 117, 114, 99, - 101, 32, 104, 97, 115, 32, 110, 111, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, - 109, 115, 32, 116, 111, 32, 98, 101, 32, 99, 111, 110, 102, 117, 115, 101, 100, 10, 35, 32, - 119, 105, 116, 104, 44, 32, 115, 111, 32, 97, 32, 108, 105, 115, 116, 32, 116, 104, 101, 114, - 101, 32, 105, 115, 32, 116, 104, 101, 32, 99, 111, 110, 110, 101, 99, 116, 105, 111, 110, 39, - 115, 59, 32, 112, 114, 111, 118, 105, 115, 105, 111, 110, 105, 110, 103, 32, 100, 111, 101, 115, - 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 101, - 114, 32, 114, 101, 106, 101, 99, 116, 115, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, - 10, 35, 32, 108, 105, 115, 116, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, - 108, 101, 116, 32, 112, 111, 115, 105, 116, 105, 111, 110, 32, 100, 101, 99, 105, 100, 101, 46, - 10, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, - 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 65, 84, 84, 65, 67, 72, 39, 32, 39, 84, - 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, - 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 32, 65, 116, - 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 67, 111, 110, 110, 101, 99, 116, - 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 32, 60, - 45, 32, 39, 67, 79, 78, 78, 69, 67, 84, 39, 32, 39, 84, 79, 39, 32, 69, 120, 116, - 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, 32, - 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, - 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, 32, 60, 45, - 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, - 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 47, 32, 69, 120, 116, 101, 114, 110, 97, 108, - 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, 97, - 117, 115, 101, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, - 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 78, 69, 87, - 39, 32, 39, 84, 69, 77, 80, 79, 82, 65, 82, 89, 39, 32, 69, 120, 116, 101, 114, 110, - 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 83, 116, - 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 69, 120, 116, 101, 114, 110, 97, 108, - 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, - 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, - 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, - 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, - 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, 73, 110, 115, 101, 114, 116, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, - 32, 39, 73, 78, 83, 69, 82, 84, 39, 32, 79, 114, 65, 99, 116, 105, 111, 110, 63, 32, - 39, 73, 78, 84, 79, 39, 32, 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, - 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 63, 32, 73, 110, - 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 73, 110, 115, 101, - 114, 116, 86, 97, 108, 117, 101, 115, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 67, - 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 63, 10, 79, 114, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, 115, 101, - 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, 47, 32, 73, 110, 115, 101, 114, 116, - 79, 114, 73, 103, 110, 111, 114, 101, 10, 73, 110, 115, 101, 114, 116, 79, 114, 82, 101, 112, - 108, 97, 99, 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 82, 69, 80, 76, 65, 67, - 69, 39, 10, 73, 110, 115, 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, 32, 60, 45, - 32, 39, 79, 82, 39, 32, 39, 73, 71, 78, 79, 82, 69, 39, 10, 66, 121, 78, 97, 109, - 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, 115, 101, 114, - 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 47, 32, 73, 110, 115, 101, 114, - 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 10, 73, 110, 115, - 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 66, - 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 10, 73, 110, 115, 101, - 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 32, 60, 45, - 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, - 111, 110, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 32, 60, 45, 32, 39, - 78, 65, 77, 69, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, - 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, 10, 73, 110, 115, - 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, - 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 63, 10, - 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, - 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 117, 109, 110, 76, 105, 115, - 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 41, 10, 73, 110, 115, - 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, 10, 73, 110, 115, 101, - 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 73, 110, - 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 68, 101, 102, 97, 117, 108, 116, - 86, 97, 108, 117, 101, 115, 10, 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, 114, 116, 86, - 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 68, 101, 102, 97, 117, 108, 116, - 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, - 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 67, - 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, 78, 70, 76, - 73, 67, 84, 39, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, - 116, 63, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, 111, 110, 10, - 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, - 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 84, 97, 114, 103, 101, 116, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 73, - 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, - 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, - 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 32, 87, 104, 101, 114, 101, 67, - 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 73, 110, 100, - 101, 120, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, - 78, 83, 84, 82, 65, 73, 78, 84, 39, 32, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, - 78, 97, 109, 101, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, 111, - 110, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, - 101, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, 116, 104, 105, 110, - 103, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, 101, 32, 60, - 45, 32, 39, 68, 79, 39, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 83, 69, 84, - 39, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 87, 104, - 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, - 116, 78, 111, 116, 104, 105, 110, 103, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, - 84, 72, 73, 78, 71, 39, 10, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 82, 69, 84, 85, 82, 78, 73, 78, 71, 39, 32, 84, 97, - 114, 103, 101, 116, 76, 105, 115, 116, 10, 76, 111, 97, 100, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 60, 45, 32, 39, 76, 79, 65, 68, 39, 32, 67, 111, 108, 73, 100, 79, 114, - 83, 116, 114, 105, 110, 103, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 63, 32, 69, - 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 63, 10, 69, 120, 116, 101, 110, - 115, 105, 111, 110, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 10, 73, 110, 115, 116, 97, 108, 108, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 63, 32, 39, 73, - 78, 83, 84, 65, 76, 76, 39, 32, 73, 110, 115, 116, 97, 108, 108, 65, 110, 100, 76, 111, - 97, 100, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, 116, 114, 105, - 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, - 63, 32, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 63, 10, 73, 110, 115, - 116, 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 32, 60, 45, 32, 39, 65, 78, 68, 39, - 32, 39, 76, 79, 65, 68, 39, 10, 85, 112, 100, 97, 116, 101, 69, 120, 116, 101, 110, 115, - 105, 111, 110, 115, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 85, 80, - 68, 65, 84, 69, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 83, 39, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, 100, 101, 110, 116, 105, 102, 105, 101, - 114, 41, 41, 63, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 70, - 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, - 47, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, 10, 70, - 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, - 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, 32, 60, 45, - 32, 39, 70, 82, 79, 77, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, - 108, 10, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 32, 60, 45, 32, 39, - 86, 69, 82, 83, 73, 79, 78, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, - 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 101, 110, - 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 97, 116, 101, 109, - 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, - 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 47, 32, 68, - 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, - 114, 121, 83, 116, 109, 116, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 110, 115, 105, - 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, - 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, 101, 63, 32, + 97, 116, 101, 80, 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 69, 120, + 116, 114, 97, 99, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, + 101, 110, 116, 32, 47, 32, 69, 120, 116, 114, 97, 99, 116, 83, 116, 114, 105, 110, 103, 65, + 114, 103, 117, 109, 101, 110, 116, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, 101, 80, + 97, 114, 116, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 116, 114, 97, + 99, 116, 68, 97, 116, 101, 80, 97, 114, 116, 10, 69, 120, 116, 114, 97, 99, 116, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 69, 120, 116, 114, 97, 99, 116, 83, 116, + 114, 105, 110, 103, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 83, 116, 114, 105, + 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, 116, 114, 97, 99, 116, 68, 97, 116, + 101, 80, 97, 114, 116, 32, 60, 45, 10, 32, 32, 32, 32, 89, 101, 97, 114, 75, 101, 121, + 119, 111, 114, 100, 32, 47, 32, 77, 111, 110, 116, 104, 75, 101, 121, 119, 111, 114, 100, 32, + 47, 32, 68, 97, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 72, 111, 117, 114, 75, + 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 110, 117, 116, 101, 75, 101, 121, 119, 111, + 114, 100, 32, 47, 32, 83, 101, 99, 111, 110, 100, 75, 101, 121, 119, 111, 114, 100, 32, 47, + 10, 32, 32, 32, 32, 77, 105, 108, 108, 105, 115, 101, 99, 111, 110, 100, 75, 101, 121, 119, + 111, 114, 100, 32, 47, 32, 77, 105, 99, 114, 111, 115, 101, 99, 111, 110, 100, 75, 101, 121, + 119, 111, 114, 100, 32, 47, 32, 87, 101, 101, 107, 75, 101, 121, 119, 111, 114, 100, 32, 47, + 32, 81, 117, 97, 114, 116, 101, 114, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 68, 101, + 99, 97, 100, 101, 75, 101, 121, 119, 111, 114, 100, 32, 47, 10, 32, 32, 32, 32, 67, 101, + 110, 116, 117, 114, 121, 75, 101, 121, 119, 111, 114, 100, 32, 47, 32, 77, 105, 108, 108, 101, + 110, 110, 105, 117, 109, 75, 101, 121, 119, 111, 114, 100, 10, 35, 32, 69, 118, 101, 114, 121, + 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 97, 98, 111, 117, 116, 32, 101, 120, 116, + 101, 114, 110, 97, 108, 32, 114, 101, 115, 111, 117, 114, 99, 101, 115, 44, 32, 115, 111, 32, + 116, 104, 101, 32, 116, 111, 112, 45, 108, 101, 118, 101, 108, 32, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 32, 99, 104, 111, 105, 99, 101, 32, 99, 97, 114, 114, 105, 101, 115, 32, 111, + 110, 101, 32, 101, 110, 116, 114, 121, 10, 35, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, + 97, 110, 32, 111, 110, 101, 32, 112, 101, 114, 32, 102, 111, 114, 109, 46, 10, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 82, 101, 103, 105, 115, + 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, + 116, 109, 116, 32, 47, 32, 68, 101, 115, 116, 114, 111, 121, 69, 120, 116, 101, 114, 110, 97, + 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, 47, 32, 83, 104, 111, 119, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 115, 83, 116, 109, + 116, 32, 47, 32, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 32, 47, 32, 67, 111, 110, 110, 101, 99, 116, 84, 111, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 10, 67, 114, 101, + 97, 116, 101, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, + 116, 109, 116, 32, 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 69, 120, 116, 101, + 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, + 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 65, 116, 116, 97, 99, 104, + 65, 108, 105, 97, 115, 63, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, + 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 63, 10, + 82, 101, 103, 105, 115, 116, 101, 114, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 83, 116, 109, 116, 32, 60, 45, 32, 39, 82, 69, 71, 73, 83, 84, 69, + 82, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, + 101, 121, 119, 111, 114, 100, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, 63, 32, 39, 70, 82, 79, 77, 39, + 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 68, 101, 115, 116, 114, 111, 121, 69, + 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 116, 109, 116, 32, + 60, 45, 32, 39, 68, 69, 83, 84, 82, 79, 89, 39, 32, 69, 120, 116, 101, 114, 110, 97, + 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, 32, 67, 111, 108, + 73, 100, 10, 83, 104, 111, 119, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, + 114, 99, 101, 115, 83, 116, 109, 116, 32, 60, 45, 32, 39, 83, 72, 79, 87, 39, 32, 83, + 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 63, 32, 39, 69, 88, 84, + 69, 82, 78, 65, 76, 39, 32, 39, 82, 69, 83, 79, 85, 82, 67, 69, 83, 39, 10, 83, + 104, 111, 119, 65, 108, 108, 77, 111, 100, 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 65, + 76, 76, 39, 10, 35, 32, 83, 121, 110, 116, 97, 120, 32, 111, 110, 108, 121, 58, 32, 116, + 104, 101, 32, 107, 101, 121, 119, 111, 114, 100, 32, 112, 97, 105, 114, 32, 101, 118, 101, 114, + 121, 32, 115, 105, 110, 103, 117, 108, 97, 114, 32, 102, 111, 114, 109, 32, 114, 101, 112, 101, + 97, 116, 115, 46, 32, 84, 104, 101, 32, 112, 108, 117, 114, 97, 108, 32, 105, 110, 32, 83, + 72, 79, 87, 32, 99, 97, 110, 110, 111, 116, 32, 115, 104, 97, 114, 101, 32, 105, 116, 46, + 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, + 119, 111, 114, 100, 32, 60, 45, 32, 39, 69, 88, 84, 69, 82, 78, 65, 76, 39, 32, 39, + 82, 69, 83, 79, 85, 82, 67, 69, 39, 10, 35, 32, 84, 104, 101, 32, 114, 101, 99, 105, + 112, 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 46, 32, + 73, 116, 115, 32, 111, 119, 110, 32, 114, 117, 108, 101, 32, 114, 97, 116, 104, 101, 114, 32, + 116, 104, 97, 110, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 58, 32, + 116, 104, 101, 32, 116, 119, 111, 32, 111, 112, 116, 105, 111, 110, 32, 98, 97, 103, 115, 32, + 97, 114, 101, 10, 35, 32, 100, 105, 115, 116, 105, 110, 99, 116, 44, 32, 97, 110, 100, 32, + 97, 32, 115, 116, 97, 116, 101, 109, 101, 110, 116, 32, 99, 97, 110, 32, 99, 97, 114, 114, + 121, 32, 98, 111, 116, 104, 46, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, 112, 116, 105, 111, 110, 115, 32, + 60, 45, 32, 71, 101, 110, 101, 114, 105, 99, 67, 111, 112, 121, 79, 112, 116, 105, 111, 110, + 76, 105, 115, 116, 10, 35, 32, 84, 104, 101, 32, 97, 116, 116, 97, 99, 104, 32, 97, 108, + 105, 97, 115, 32, 105, 115, 32, 109, 97, 110, 100, 97, 116, 111, 114, 121, 58, 32, 105, 116, + 32, 115, 101, 112, 97, 114, 97, 116, 101, 115, 32, 116, 104, 101, 32, 114, 101, 99, 105, 112, + 101, 39, 115, 32, 99, 114, 101, 97, 116, 101, 32, 112, 97, 114, 97, 109, 115, 44, 32, 119, + 104, 105, 99, 104, 32, 112, 114, 101, 99, 101, 100, 101, 32, 105, 116, 44, 32, 102, 114, 111, + 109, 32, 116, 104, 101, 10, 35, 32, 97, 116, 116, 97, 99, 104, 109, 101, 110, 116, 39, 115, + 32, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 115, 44, 32, 119, 104, 105, 99, 104, 32, + 102, 111, 108, 108, 111, 119, 46, 32, 87, 105, 116, 104, 111, 117, 116, 32, 105, 116, 32, 97, + 32, 115, 105, 110, 103, 108, 101, 32, 111, 112, 116, 105, 111, 110, 32, 108, 105, 115, 116, 32, + 119, 111, 117, 108, 100, 32, 98, 101, 32, 97, 109, 98, 105, 103, 117, 111, 117, 115, 46, 10, + 35, 32, 67, 79, 78, 78, 69, 67, 84, 32, 104, 97, 115, 32, 110, 111, 32, 115, 117, 99, + 104, 32, 115, 101, 112, 97, 114, 97, 116, 111, 114, 46, 32, 66, 111, 114, 114, 111, 119, 105, + 110, 103, 32, 97, 32, 114, 101, 103, 105, 115, 116, 101, 114, 101, 100, 32, 114, 101, 115, 111, + 117, 114, 99, 101, 32, 104, 97, 115, 32, 110, 111, 32, 99, 114, 101, 97, 116, 101, 32, 112, + 97, 114, 97, 109, 115, 32, 116, 111, 32, 98, 101, 32, 99, 111, 110, 102, 117, 115, 101, 100, + 10, 35, 32, 119, 105, 116, 104, 44, 32, 115, 111, 32, 97, 32, 108, 105, 115, 116, 32, 116, + 104, 101, 114, 101, 32, 105, 115, 32, 116, 104, 101, 32, 99, 111, 110, 110, 101, 99, 116, 105, + 111, 110, 39, 115, 59, 32, 112, 114, 111, 118, 105, 115, 105, 111, 110, 105, 110, 103, 32, 100, + 111, 101, 115, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 116, 114, 97, 110, 115, 102, 111, + 114, 109, 101, 114, 32, 114, 101, 106, 101, 99, 116, 115, 32, 116, 104, 101, 32, 115, 101, 99, + 111, 110, 100, 10, 35, 32, 108, 105, 115, 116, 32, 114, 97, 116, 104, 101, 114, 32, 116, 104, + 97, 110, 32, 108, 101, 116, 32, 112, 111, 115, 105, 116, 105, 111, 110, 32, 100, 101, 99, 105, + 100, 101, 46, 10, 65, 116, 116, 97, 99, 104, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, + 82, 101, 115, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 65, 84, 84, 65, 67, 72, 39, + 32, 39, 84, 79, 39, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, + 99, 101, 83, 111, 117, 114, 99, 101, 32, 65, 116, 116, 97, 99, 104, 65, 108, 105, 97, 115, + 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 67, 111, 110, 110, + 101, 99, 116, 84, 111, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, + 101, 32, 60, 45, 32, 39, 67, 79, 78, 78, 69, 67, 84, 39, 32, 39, 84, 79, 39, 32, + 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, + 99, 101, 32, 65, 116, 116, 97, 99, 104, 79, 112, 116, 105, 111, 110, 115, 63, 10, 69, 120, + 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 83, 111, 117, 114, 99, 101, + 32, 60, 45, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, + 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 47, 32, 69, 120, 116, 101, 114, + 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, + 67, 108, 97, 117, 115, 101, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, + 114, 99, 101, 67, 114, 101, 97, 116, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, + 78, 69, 87, 39, 32, 39, 84, 69, 77, 80, 79, 82, 65, 82, 89, 39, 32, 69, 120, 116, + 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, 101, 121, 119, 111, 114, 100, + 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 69, 120, 116, 101, 114, + 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 67, 114, 101, 97, 116, 105, 111, 110, 79, + 112, 116, 105, 111, 110, 115, 63, 10, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, + 117, 114, 99, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 67, 108, 97, 117, 115, 101, 32, + 60, 45, 32, 69, 120, 116, 101, 114, 110, 97, 108, 82, 101, 115, 111, 117, 114, 99, 101, 75, + 101, 121, 119, 111, 114, 100, 32, 67, 111, 108, 73, 100, 10, 73, 110, 115, 101, 114, 116, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, + 115, 101, 63, 32, 39, 73, 78, 83, 69, 82, 84, 39, 32, 79, 114, 65, 99, 116, 105, 111, + 110, 63, 32, 39, 73, 78, 84, 79, 39, 32, 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, + 101, 116, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 63, + 32, 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 73, + 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 79, 110, 67, 111, 110, 102, 108, 105, + 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, + 108, 97, 117, 115, 101, 63, 10, 79, 114, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 73, + 110, 115, 101, 114, 116, 79, 114, 82, 101, 112, 108, 97, 99, 101, 32, 47, 32, 73, 110, 115, + 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, 10, 73, 110, 115, 101, 114, 116, 79, 114, + 82, 101, 112, 108, 97, 99, 101, 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 82, 69, 80, + 76, 65, 67, 69, 39, 10, 73, 110, 115, 101, 114, 116, 79, 114, 73, 103, 110, 111, 114, 101, + 32, 60, 45, 32, 39, 79, 82, 39, 32, 39, 73, 71, 78, 79, 82, 69, 39, 10, 66, 121, + 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, 110, + 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 47, 32, 73, 110, + 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, 10, + 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 100, 101, 114, 32, 60, 45, + 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 10, 73, + 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, 105, 116, 105, 111, 110, 79, 114, 100, 101, 114, + 32, 60, 45, 32, 39, 66, 89, 39, 32, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, + 105, 116, 105, 111, 110, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 32, 60, + 45, 32, 39, 78, 65, 77, 69, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 80, 111, 115, + 105, 116, 105, 111, 110, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 39, 10, + 73, 110, 115, 101, 114, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, + 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, + 115, 63, 10, 73, 110, 115, 101, 114, 116, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, + 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 67, 111, 108, 117, 109, 110, + 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 41, 10, + 73, 110, 115, 101, 114, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 41, 10, 73, + 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, + 116, 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 68, 101, 102, 97, + 117, 108, 116, 86, 97, 108, 117, 101, 115, 10, 83, 101, 108, 101, 99, 116, 73, 110, 115, 101, + 114, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 68, 101, 102, 97, + 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, + 84, 39, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 110, 67, 111, 110, 102, 108, 105, + 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, 39, 67, 79, + 78, 70, 76, 73, 67, 84, 39, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, + 114, 103, 101, 116, 63, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, 116, 105, + 111, 110, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 84, 97, 114, 103, 101, 116, 32, + 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 84, 97, 114, 103, 101, 116, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, + 99, 116, 73, 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 10, 79, 110, 67, 111, 110, 102, + 108, 105, 99, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 84, 97, 114, 103, 101, 116, + 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 73, 100, 76, 105, 115, 116, 32, 87, 104, 101, + 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, + 73, 110, 100, 101, 120, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 79, 78, 39, 32, + 39, 67, 79, 78, 83, 84, 82, 65, 73, 78, 84, 39, 32, 67, 111, 110, 115, 116, 114, 97, + 105, 110, 116, 78, 97, 109, 101, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 65, 99, + 116, 105, 111, 110, 32, 60, 45, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, + 100, 97, 116, 101, 32, 47, 32, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 78, 111, 116, + 104, 105, 110, 103, 10, 79, 110, 67, 111, 110, 102, 108, 105, 99, 116, 85, 112, 100, 97, 116, + 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, + 83, 69, 84, 39, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, + 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 10, 79, 110, 67, 111, 110, 102, + 108, 105, 99, 116, 78, 111, 116, 104, 105, 110, 103, 32, 60, 45, 32, 39, 68, 79, 39, 32, + 39, 78, 79, 84, 72, 73, 78, 71, 39, 10, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 82, 69, 84, 85, 82, 78, 73, 78, 71, 39, + 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 76, 111, 97, 100, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 76, 79, 65, 68, 39, 32, 67, 111, 108, 73, + 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, + 63, 32, 69, 120, 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 63, 10, 69, 120, + 116, 101, 110, 115, 105, 111, 110, 65, 108, 105, 97, 115, 32, 60, 45, 32, 39, 65, 83, 39, + 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 73, 110, 115, 116, 97, 108, 108, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 70, 79, 82, 67, 69, 39, 63, + 32, 39, 73, 78, 83, 84, 65, 76, 76, 39, 32, 73, 110, 115, 116, 97, 108, 108, 65, 110, + 100, 76, 111, 97, 100, 63, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 79, 114, 83, + 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 70, 114, 111, 109, 83, 111, 117, + 114, 99, 101, 63, 32, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 63, 10, + 73, 110, 115, 116, 97, 108, 108, 65, 110, 100, 76, 111, 97, 100, 32, 60, 45, 32, 39, 65, + 78, 68, 39, 32, 39, 76, 79, 65, 68, 39, 10, 85, 112, 100, 97, 116, 101, 69, 120, 116, + 101, 110, 115, 105, 111, 110, 115, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, + 39, 85, 80, 68, 65, 84, 69, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 83, + 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 73, 100, 101, 110, 116, 105, + 102, 105, 101, 114, 41, 41, 63, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 32, 60, + 45, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 32, 47, 32, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, + 103, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 10, 70, 114, 111, 109, 83, 111, 117, 114, 99, 101, 83, 116, 114, 105, 110, 103, + 32, 60, 45, 32, 39, 70, 82, 79, 77, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, + 101, 114, 97, 108, 10, 86, 101, 114, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 32, 60, + 45, 32, 39, 86, 69, 82, 83, 73, 79, 78, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 69, 120, + 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 97, + 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, + 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, + 47, 32, 68, 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, + 105, 116, 111, 114, 121, 83, 116, 109, 116, 10, 67, 114, 101, 97, 116, 101, 69, 120, 116, 101, + 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, + 60, 45, 32, 39, 67, 82, 69, 65, 84, 69, 39, 32, 79, 114, 82, 101, 112, 108, 97, 99, + 101, 63, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, + 83, 73, 84, 79, 82, 89, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, + 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 82, 101, 112, 111, 115, + 105, 116, 111, 114, 121, 80, 114, 101, 102, 105, 120, 32, 82, 101, 112, 111, 115, 105, 116, 111, + 114, 121, 80, 117, 98, 108, 105, 99, 75, 101, 121, 63, 10, 82, 101, 112, 111, 115, 105, 116, + 111, 114, 121, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 63, + 32, 39, 80, 82, 69, 70, 73, 88, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, + 114, 97, 108, 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, 105, 99, + 75, 101, 121, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 63, 32, 39, 80, 85, 66, + 76, 73, 67, 39, 32, 40, 39, 75, 69, 89, 83, 39, 32, 47, 32, 39, 75, 69, 89, 39, + 41, 32, 76, 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, + 41, 10, 68, 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, + 105, 116, 111, 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 39, 69, 88, 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, 83, 73, 84, - 79, 82, 89, 39, 32, 73, 102, 78, 111, 116, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, - 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 82, 101, 112, 111, 115, 105, 116, 111, - 114, 121, 80, 114, 101, 102, 105, 120, 32, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, - 117, 98, 108, 105, 99, 75, 101, 121, 63, 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, - 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 63, 32, 39, 80, - 82, 69, 70, 73, 88, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, - 10, 82, 101, 112, 111, 115, 105, 116, 111, 114, 121, 80, 117, 98, 108, 105, 99, 75, 101, 121, - 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 63, 32, 39, 80, 85, 66, 76, 73, 67, - 39, 32, 40, 39, 75, 69, 89, 83, 39, 32, 47, 32, 39, 75, 69, 89, 39, 41, 32, 76, - 105, 115, 116, 40, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 41, 10, 68, - 114, 111, 112, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 112, 111, 115, 105, 116, 111, - 114, 121, 83, 116, 109, 116, 32, 60, 45, 32, 39, 68, 82, 79, 80, 39, 32, 39, 69, 88, - 84, 69, 78, 83, 73, 79, 78, 39, 32, 39, 82, 69, 80, 79, 83, 73, 84, 79, 82, 89, - 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, 79, 114, 83, - 116, 114, 105, 110, 103, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, - 39, 77, 69, 82, 71, 69, 39, 32, 39, 73, 78, 84, 79, 39, 32, 84, 97, 114, 103, 101, - 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 77, 101, 114, 103, 101, 73, 110, 116, 111, 85, - 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, - 102, 105, 101, 114, 32, 77, 101, 114, 103, 101, 77, 97, 116, 99, 104, 43, 32, 82, 101, 116, - 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 77, 101, 114, 103, 101, 73, - 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, - 83, 73, 78, 71, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 10, 77, 101, 114, 103, 101, - 77, 97, 116, 99, 104, 32, 60, 45, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, - 115, 101, 32, 47, 32, 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, - 101, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, - 87, 72, 69, 78, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, 65, 110, 100, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, 32, 77, 97, - 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 10, 77, 97, - 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 32, 60, 45, - 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, - 32, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, - 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, - 32, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, - 101, 32, 47, 32, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, - 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, - 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, - 99, 104, 73, 110, 102, 111, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 73, - 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, - 116, 65, 99, 116, 105, 111, 110, 32, 47, 32, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, - 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 77, - 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, 85, 112, 100, - 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, 10, 85, 112, - 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, - 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, - 10, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, - 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 73, 110, 115, 101, 114, 116, 77, 97, 116, - 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, 83, 69, 82, 84, 39, - 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, 10, 73, 110, - 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, 73, 110, 115, - 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 47, 32, 73, 110, 115, 101, - 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 47, 32, 73, 110, - 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, - 10, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, - 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, 76, 85, 69, - 83, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, - 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, - 105, 116, 105, 111, 110, 63, 32, 39, 42, 39, 63, 10, 73, 110, 115, 101, 114, 116, 86, 97, - 108, 117, 101, 115, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 115, 101, 114, 116, 67, 111, - 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 41, 41, 10, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, 84, 72, 73, 78, - 71, 39, 10, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 69, 82, 82, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 85, 112, 100, 97, 116, 101, 77, - 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 10, 85, 112, 100, 97, 116, 101, 77, 97, - 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, - 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 83, 116, 97, 114, 83, 121, 109, 98, - 111, 108, 10, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, - 39, 65, 78, 68, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 111, 116, - 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, - 69, 78, 39, 32, 39, 78, 79, 84, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, - 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 63, 32, 65, 110, - 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, 32, - 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, 10, - 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, - 66, 121, 83, 111, 117, 114, 99, 101, 32, 47, 32, 66, 121, 84, 97, 114, 103, 101, 116, 10, - 66, 121, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 83, 79, - 85, 82, 67, 69, 39, 10, 66, 121, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 39, 66, - 89, 39, 32, 39, 84, 65, 82, 71, 69, 84, 39, 10, 80, 105, 118, 111, 116, 83, 116, 97, - 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 75, 101, 121, 119, 111, - 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 80, 105, 118, 111, 116, 79, 110, 63, - 32, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 63, 32, 80, 105, 118, 111, 116, 71, 114, - 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 79, 110, 32, 60, - 45, 32, 39, 79, 78, 39, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 76, 105, - 115, 116, 10, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 32, 60, 45, 32, 39, 85, 83, - 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, - 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, - 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 41, 10, 80, 105, - 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 32, 60, 45, 32, 80, 105, - 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, - 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 47, 32, 80, 105, 118, - 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, - 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, 118, 111, 116, - 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 66, 97, - 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, 32, 80, 97, - 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 80, 105, 118, 111, 116, 75, 101, 121, 119, 111, - 114, 100, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 47, 32, 39, 80, 73, 86, - 79, 84, 95, 87, 73, 68, 69, 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, 75, 101, 121, - 119, 111, 114, 100, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, 47, 32, - 39, 80, 73, 86, 79, 84, 95, 76, 79, 78, 71, 69, 82, 39, 10, 85, 110, 112, 105, 118, - 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, - 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 39, - 79, 78, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 73, 110, 116, 111, 78, - 97, 109, 101, 86, 97, 108, 117, 101, 115, 63, 10, 73, 110, 116, 111, 78, 97, 109, 101, 86, - 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 73, 78, 84, 79, 39, 32, 39, 78, 65, 77, - 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 86, 97, 108, - 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, - 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 10, 86, 97, 108, 117, 101, 79, - 114, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, 39, 32, 47, - 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, - 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, - 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 47, 32, - 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, 10, 80, 97, 114, 101, 110, 116, 104, - 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, - 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, - 105, 110, 103, 41, 41, 10, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, - 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, - 41, 10, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, - 108, 108, 115, 32, 60, 45, 32, 73, 110, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, - 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 10, 73, 110, 99, 108, 117, - 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 73, 78, 67, 76, 85, 68, 69, 39, - 32, 39, 78, 85, 76, 76, 83, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, - 115, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 39, 78, 85, 76, 76, - 83, 39, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 60, 45, 32, - 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, 108, 101, 32, - 47, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 10, - 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, 108, 101, 32, - 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, 85, 110, 112, - 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, - 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, - 105, 110, 103, 41, 41, 10, 80, 114, 97, 103, 109, 97, 83, 116, 97, 116, 101, 109, 101, 110, - 116, 32, 60, 45, 32, 39, 80, 82, 65, 71, 77, 65, 39, 32, 80, 114, 97, 103, 109, 97, - 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, - 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 32, - 60, 45, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 32, 47, 32, 80, 114, - 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, 103, 109, 97, 65, - 115, 115, 105, 103, 110, 32, 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, 101, - 32, 39, 61, 39, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, 10, 80, 114, - 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 80, 114, 97, 103, - 109, 97, 78, 97, 109, 101, 32, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, 116, - 101, 114, 115, 63, 10, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, 116, 101, 114, - 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 80, 114, 101, 112, 97, 114, 101, 83, 116, 97, - 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 69, 80, 65, 82, 69, 39, 32, - 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 84, 121, 112, 101, 76, 105, - 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 84, - 121, 112, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, - 115, 116, 40, 84, 121, 112, 101, 41, 41, 10, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, - 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 83, 101, 108, 101, 99, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 32, 60, 45, 32, - 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 83, 101, 108, 101, 99, 116, 83, 101, - 116, 79, 112, 67, 104, 97, 105, 110, 32, 82, 101, 115, 117, 108, 116, 77, 111, 100, 105, 102, - 105, 101, 114, 115, 63, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, - 105, 110, 32, 60, 45, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, - 32, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 84, 97, 105, - 108, 42, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 84, - 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, 32, 73, - 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 10, 73, 110, 116, 101, 114, 115, - 101, 99, 116, 67, 104, 97, 105, 110, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 65, 116, - 111, 109, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 84, 97, 105, - 108, 42, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 84, 97, 105, - 108, 32, 60, 45, 32, 83, 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, - 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 10, 83, 101, 116, 73, 110, - 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, - 84, 69, 82, 83, 69, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, - 108, 108, 63, 10, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 32, 60, 45, 32, 83, 101, - 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, 32, 83, 101, 108, 101, 99, 116, 83, - 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, 10, 83, 101, 108, 101, 99, 116, 80, - 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, - 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, - 10, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, 101, 116, 111, - 112, 84, 121, 112, 101, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, 108, 108, 63, - 32, 66, 121, 78, 97, 109, 101, 63, 10, 83, 101, 116, 111, 112, 84, 121, 112, 101, 32, 60, - 45, 32, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, 32, 47, 32, 83, 101, 116, 111, 112, - 69, 120, 99, 101, 112, 116, 10, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, 32, 60, 45, - 32, 39, 85, 78, 73, 79, 78, 39, 10, 83, 101, 116, 111, 112, 69, 120, 99, 101, 112, 116, - 32, 60, 45, 32, 39, 69, 88, 67, 69, 80, 84, 39, 10, 66, 121, 78, 97, 109, 101, 32, - 60, 45, 32, 39, 66, 89, 39, 32, 39, 78, 65, 77, 69, 39, 10, 83, 101, 108, 101, 99, - 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, 32, 60, 45, 32, 79, 112, - 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, - 108, 101, 99, 116, 32, 47, 32, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, - 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, - 47, 32, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 80, - 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 85, 110, 112, 105, - 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 82, 101, 115, 117, 108, 116, 77, - 111, 100, 105, 102, 105, 101, 114, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 67, - 108, 97, 117, 115, 101, 63, 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 63, 10, - 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 32, 60, 45, 32, 76, 105, 109, 105, 116, - 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, 102, 115, 101, - 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, 102, 115, 101, - 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, 116, 99, 104, - 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, 116, 99, 104, - 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 10, 76, 105, 109, 105, 116, 79, 102, 102, 115, - 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 67, 108, 97, - 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 63, 10, 79, 102, - 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 79, - 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 76, 105, 109, 105, 116, 67, 108, 97, - 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 70, - 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 70, 101, 116, 99, 104, 79, 102, 102, 115, - 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, 104, 67, 108, 97, - 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 10, 70, 101, 116, - 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, - 104, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 66, 97, 115, 101, 84, 97, - 98, 108, 101, 78, 97, 109, 101, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, - 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 105, - 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, 32, 83, - 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 10, 83, 105, 109, 112, 108, 101, 83, 101, - 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, - 40, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 41, 10, 83, 105, 109, 112, 108, - 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, - 109, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 71, 114, 111, 117, 112, - 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 63, 32, 87, 105, 110, 100, 111, 119, 67, 108, 97, 117, 115, 101, 63, 32, 81, 117, - 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, - 108, 97, 117, 115, 101, 63, 10, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 32, 60, 45, - 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 47, 32, - 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 10, 83, 101, 108, - 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, 101, 108, - 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, - 63, 10, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, - 45, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 67, - 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, 110, 116, - 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 67, 111, - 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 32, 85, 115, 105, 110, 103, 75, 101, - 121, 63, 32, 39, 65, 83, 39, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, 122, 101, 100, - 63, 32, 67, 84, 69, 66, 111, 100, 121, 10, 67, 84, 69, 66, 111, 100, 121, 32, 60, 45, - 32, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, 121, 32, 47, 32, 67, 84, 69, - 68, 77, 76, 66, 111, 100, 121, 10, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, - 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 67, 84, 69, - 68, 77, 76, 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 116, - 97, 116, 101, 109, 101, 110, 116, 41, 10, 85, 115, 105, 110, 103, 75, 101, 121, 32, 60, 45, - 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 75, 69, 89, 39, 32, 80, 97, 114, 101, 110, - 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 77, 97, 116, 101, 114, 105, - 97, 108, 105, 122, 101, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 63, 32, 39, 77, 65, - 84, 69, 82, 73, 65, 76, 73, 90, 69, 68, 39, 10, 87, 105, 116, 104, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 99, 117, 114, 115, 105, - 118, 101, 63, 32, 76, 105, 115, 116, 40, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, 101, - 110, 116, 41, 10, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, 45, 32, 39, 82, 69, - 67, 85, 82, 83, 73, 86, 69, 39, 10, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, - 101, 32, 60, 45, 32, 39, 83, 69, 76, 69, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, - 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, - 63, 10, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, - 40, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, - 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, - 110, 103, 41, 41, 10, 68, 105, 115, 116, 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, 47, 32, 68, 105, 115, 116, - 105, 110, 99, 116, 65, 108, 108, 10, 68, 105, 115, 116, 105, 110, 99, 116, 65, 108, 108, 32, - 60, 45, 32, 39, 65, 76, 76, 39, 10, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, - 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, - 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 63, 10, 68, 105, 115, 116, 105, 110, 99, - 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 32, 60, 45, 32, 39, 79, 78, 39, 32, 80, - 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 41, 41, 10, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, - 32, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 47, 32, 84, 97, 98, 108, 101, 70, 117, - 110, 99, 116, 105, 111, 110, 32, 47, 32, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, 101, - 114, 121, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, - 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 84, 97, 98, 108, 101, - 82, 101, 102, 32, 60, 45, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, - 32, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 42, 10, 84, 97, 98, 108, 101, 83, - 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 67, 111, 108, 111, 110, 63, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, 98, - 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 84, 97, 98, 108, 101, - 65, 108, 105, 97, 115, 63, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 79, 82, 89, 39, 32, 73, 102, 69, 120, 105, 115, 116, 115, 63, 32, 67, 111, 108, 73, 100, + 79, 114, 83, 116, 114, 105, 110, 103, 10, 77, 101, 114, 103, 101, 73, 110, 116, 111, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, + 101, 63, 32, 39, 77, 69, 82, 71, 69, 39, 32, 39, 73, 78, 84, 79, 39, 32, 84, 97, + 114, 103, 101, 116, 79, 112, 116, 65, 108, 105, 97, 115, 32, 77, 101, 114, 103, 101, 73, 110, + 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 74, 111, 105, 110, 81, 117, + 97, 108, 105, 102, 105, 101, 114, 32, 77, 101, 114, 103, 101, 77, 97, 116, 99, 104, 43, 32, + 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, 97, 117, 115, 101, 63, 10, 77, 101, 114, + 103, 101, 73, 110, 116, 111, 85, 115, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, + 32, 39, 85, 83, 73, 78, 71, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 10, 77, 101, + 114, 103, 101, 77, 97, 116, 99, 104, 32, 60, 45, 32, 77, 97, 116, 99, 104, 101, 100, 67, + 108, 97, 117, 115, 101, 32, 47, 32, 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, + 97, 117, 115, 101, 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, + 45, 32, 39, 87, 72, 69, 78, 39, 32, 39, 77, 65, 84, 67, 72, 69, 68, 39, 32, 65, + 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, 78, 39, + 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, + 10, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, 111, 110, + 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, + 101, 32, 47, 32, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, 104, 67, 108, + 97, 117, 115, 101, 32, 47, 32, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, + 117, 115, 101, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, 101, + 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, + 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, + 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 47, 32, 85, 112, 100, 97, 116, 101, 66, + 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, 105, 111, 110, 10, 85, 112, 100, 97, + 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 65, 99, 116, 105, 111, 110, 32, 60, 45, 32, + 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 67, 108, 97, 117, 115, 101, + 10, 85, 112, 100, 97, 116, 101, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, + 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, + 105, 111, 110, 10, 68, 101, 108, 101, 116, 101, 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 39, 68, 69, 76, 69, 84, 69, 39, 10, 73, 110, 115, 101, 114, 116, + 77, 97, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 73, 78, 83, 69, + 82, 84, 39, 32, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 63, + 10, 73, 110, 115, 101, 114, 116, 77, 97, 116, 99, 104, 73, 110, 102, 111, 32, 60, 45, 32, + 73, 110, 115, 101, 114, 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 47, 32, 73, + 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, 117, 101, 115, 32, 47, + 32, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, 80, 111, 115, 105, 116, + 105, 111, 110, 10, 73, 110, 115, 101, 114, 116, 68, 101, 102, 97, 117, 108, 116, 86, 97, 108, + 117, 101, 115, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 32, 39, 86, 65, + 76, 85, 69, 83, 39, 10, 73, 110, 115, 101, 114, 116, 66, 121, 78, 97, 109, 101, 79, 114, + 80, 111, 115, 105, 116, 105, 111, 110, 32, 60, 45, 32, 66, 121, 78, 97, 109, 101, 79, 114, + 80, 111, 115, 105, 116, 105, 111, 110, 63, 32, 39, 42, 39, 63, 10, 73, 110, 115, 101, 114, + 116, 86, 97, 108, 117, 101, 115, 76, 105, 115, 116, 32, 60, 45, 32, 73, 110, 115, 101, 114, + 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 63, 32, 39, 86, 65, 76, 85, 69, 83, + 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 41, 41, 10, 68, 111, 78, 111, 116, 104, 105, 110, 103, 77, 97, 116, 99, + 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 68, 79, 39, 32, 39, 78, 79, 84, + 72, 73, 78, 71, 39, 10, 69, 114, 114, 111, 114, 77, 97, 116, 99, 104, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 69, 82, 82, 79, 82, 39, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 63, 10, 85, 112, 100, 97, 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 84, 39, 32, 85, 112, 100, 97, + 116, 101, 77, 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 10, 85, 112, 100, 97, 116, + 101, 77, 97, 116, 99, 104, 83, 101, 116, 73, 110, 102, 111, 32, 60, 45, 32, 85, 112, 100, + 97, 116, 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 83, 116, 97, 114, 83, + 121, 109, 98, 111, 108, 10, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 60, 45, 32, 39, 65, 78, 68, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, + 78, 111, 116, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 39, 87, 72, 69, 78, 39, 32, 39, 78, 79, 84, 39, 32, 39, 77, 65, 84, 67, 72, 69, + 68, 39, 32, 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 63, + 32, 65, 110, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 63, 32, 39, 84, 72, 69, + 78, 39, 32, 77, 97, 116, 99, 104, 101, 100, 67, 108, 97, 117, 115, 101, 65, 99, 116, 105, + 111, 110, 10, 66, 121, 83, 111, 117, 114, 99, 101, 79, 114, 84, 97, 114, 103, 101, 116, 32, + 60, 45, 32, 66, 121, 83, 111, 117, 114, 99, 101, 32, 47, 32, 66, 121, 84, 97, 114, 103, + 101, 116, 10, 66, 121, 83, 111, 117, 114, 99, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, + 39, 83, 79, 85, 82, 67, 69, 39, 10, 66, 121, 84, 97, 114, 103, 101, 116, 32, 60, 45, + 32, 39, 66, 89, 39, 32, 39, 84, 65, 82, 71, 69, 84, 39, 10, 80, 105, 118, 111, 116, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 75, 101, + 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 80, 105, 118, 111, 116, + 79, 110, 63, 32, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 63, 32, 80, 105, 118, 111, + 116, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 79, + 110, 32, 60, 45, 32, 39, 79, 78, 39, 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, + 110, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 85, 115, 105, 110, 103, 32, 60, 45, 32, + 39, 85, 83, 73, 78, 71, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 80, + 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, + 115, 116, 40, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 41, + 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 110, 116, 114, 121, 32, 60, 45, + 32, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, + 32, 47, 32, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 47, 32, + 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 80, 105, 118, 111, 116, 67, 111, 108, 117, 109, 110, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, + 118, 111, 116, 67, 111, 108, 117, 109, 110, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, + 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 73, 78, 39, + 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 80, 105, 118, 111, 116, 75, 101, + 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 47, 32, 39, + 80, 73, 86, 79, 84, 95, 87, 73, 68, 69, 82, 39, 10, 85, 110, 112, 105, 118, 111, 116, + 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, + 32, 47, 32, 39, 80, 73, 86, 79, 84, 95, 76, 79, 78, 71, 69, 82, 39, 10, 85, 110, + 112, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 110, + 112, 105, 118, 111, 116, 75, 101, 121, 119, 111, 114, 100, 32, 84, 97, 98, 108, 101, 82, 101, + 102, 32, 39, 79, 78, 39, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 73, 110, + 116, 111, 78, 97, 109, 101, 86, 97, 108, 117, 101, 115, 63, 10, 73, 110, 116, 111, 78, 97, + 109, 101, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 73, 78, 84, 79, 39, 32, 39, + 78, 65, 77, 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, + 86, 97, 108, 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 79, 112, 116, 105, 111, 110, + 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 10, 86, 97, 108, + 117, 101, 79, 114, 86, 97, 108, 117, 101, 115, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, + 39, 32, 47, 32, 39, 86, 65, 76, 85, 69, 83, 39, 10, 79, 112, 116, 105, 111, 110, 97, + 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, + 97, 114, 101, 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, + 32, 47, 32, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, 116, 10, 80, 97, 114, 101, + 110, 116, 104, 101, 115, 105, 122, 101, 100, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, + 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, + 83, 116, 114, 105, 110, 103, 41, 41, 10, 66, 97, 114, 101, 78, 97, 109, 101, 76, 105, 115, + 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, + 105, 110, 103, 41, 10, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, + 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 73, 110, 99, 108, 117, 100, 101, 78, 117, 108, + 108, 115, 32, 47, 32, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 10, 73, 110, + 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 32, 60, 45, 32, 39, 73, 78, 67, 76, 85, + 68, 69, 39, 32, 39, 78, 85, 76, 76, 83, 39, 10, 69, 120, 99, 108, 117, 100, 101, 78, + 117, 108, 108, 115, 32, 60, 45, 32, 39, 69, 88, 67, 76, 85, 68, 69, 39, 32, 39, 78, + 85, 76, 76, 83, 39, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, + 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, + 108, 101, 32, 47, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, + 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 83, 105, 110, 103, + 108, 101, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 10, + 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 76, 105, 115, 116, 32, 60, 45, + 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, + 83, 116, 114, 105, 110, 103, 41, 41, 10, 80, 114, 97, 103, 109, 97, 83, 116, 97, 116, 101, + 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 65, 71, 77, 65, 39, 32, 80, 114, 97, + 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, 111, 110, 10, + 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 79, 114, 70, 117, 110, 99, 116, 105, + 111, 110, 32, 60, 45, 32, 80, 114, 97, 103, 109, 97, 65, 115, 115, 105, 103, 110, 32, 47, + 32, 80, 114, 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 10, 80, 114, 97, 103, + 109, 97, 65, 115, 115, 105, 103, 110, 32, 60, 45, 32, 83, 101, 116, 116, 105, 110, 103, 78, + 97, 109, 101, 32, 39, 61, 39, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, 115, 116, + 10, 80, 114, 97, 103, 109, 97, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 80, + 114, 97, 103, 109, 97, 78, 97, 109, 101, 32, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, + 109, 101, 116, 101, 114, 115, 63, 10, 80, 114, 97, 103, 109, 97, 80, 97, 114, 97, 109, 101, + 116, 101, 114, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 80, 114, 101, 112, 97, 114, 101, + 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 80, 82, 69, 80, 65, 82, + 69, 39, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, 32, 84, 121, 112, + 101, 76, 105, 115, 116, 63, 32, 39, 65, 83, 39, 32, 83, 116, 97, 116, 101, 109, 101, 110, + 116, 10, 84, 121, 112, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, + 40, 76, 105, 115, 116, 40, 84, 121, 112, 101, 41, 41, 10, 83, 101, 108, 101, 99, 116, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 83, 116, + 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 10, 83, 101, 108, 101, + 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 32, + 60, 45, 32, 87, 105, 116, 104, 67, 108, 97, 117, 115, 101, 63, 32, 83, 101, 108, 101, 99, + 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, 32, 82, 101, 115, 117, 108, 116, 77, 111, + 100, 105, 102, 105, 101, 114, 115, 63, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, + 67, 104, 97, 105, 110, 32, 60, 45, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, + 97, 105, 110, 32, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, 105, 110, + 84, 97, 105, 108, 42, 10, 83, 101, 108, 101, 99, 116, 83, 101, 116, 79, 112, 67, 104, 97, + 105, 110, 84, 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, + 101, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 10, 73, 110, 116, + 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, 32, 60, 45, 32, 83, 101, 108, 101, 99, + 116, 65, 116, 111, 109, 32, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, + 84, 97, 105, 108, 42, 10, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 104, 97, 105, 110, + 84, 97, 105, 108, 32, 60, 45, 32, 83, 101, 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, + 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 10, 83, 101, + 116, 73, 110, 116, 101, 114, 115, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 39, 73, 78, 84, 69, 82, 83, 69, 67, 84, 39, 32, 68, 105, 115, 116, 105, 110, 99, 116, + 79, 114, 65, 108, 108, 63, 10, 83, 101, 108, 101, 99, 116, 65, 116, 111, 109, 32, 60, 45, + 32, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 47, 32, 83, 101, 108, 101, + 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, 10, 83, 101, 108, 101, + 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, + 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, + 97, 108, 41, 10, 83, 101, 116, 111, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 83, + 101, 116, 111, 112, 84, 121, 112, 101, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 114, 65, + 108, 108, 63, 32, 66, 121, 78, 97, 109, 101, 63, 10, 83, 101, 116, 111, 112, 84, 121, 112, + 101, 32, 60, 45, 32, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, 32, 47, 32, 83, 101, + 116, 111, 112, 69, 120, 99, 101, 112, 116, 10, 83, 101, 116, 111, 112, 85, 110, 105, 111, 110, + 32, 60, 45, 32, 39, 85, 78, 73, 79, 78, 39, 10, 83, 101, 116, 111, 112, 69, 120, 99, + 101, 112, 116, 32, 60, 45, 32, 39, 69, 88, 67, 69, 80, 84, 39, 10, 66, 121, 78, 97, + 109, 101, 32, 60, 45, 32, 39, 66, 89, 39, 32, 39, 78, 65, 77, 69, 39, 10, 83, 101, + 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 84, 121, 112, 101, 32, 60, 45, + 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 83, 105, 109, 112, 108, + 101, 83, 101, 108, 101, 99, 116, 32, 47, 32, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, + 115, 101, 32, 47, 32, 68, 101, 115, 99, 114, 105, 98, 101, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 32, 47, 32, 84, 97, 98, 108, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 47, 32, 80, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 47, 32, 85, + 110, 112, 105, 118, 111, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 10, 82, 101, 115, 117, + 108, 116, 77, 111, 100, 105, 102, 105, 101, 114, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, + 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, + 116, 63, 10, 76, 105, 109, 105, 116, 79, 102, 102, 115, 101, 116, 32, 60, 45, 32, 76, 105, + 109, 105, 116, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, + 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 47, 32, 79, 102, + 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, + 116, 99, 104, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 70, 101, + 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 10, 76, 105, 109, 105, 116, 79, + 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, + 67, 108, 97, 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 63, + 10, 79, 102, 102, 115, 101, 116, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, + 45, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 76, 105, 109, 105, 116, + 67, 108, 97, 117, 115, 101, 63, 10, 79, 102, 102, 115, 101, 116, 70, 101, 116, 99, 104, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, + 101, 32, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 70, 101, 116, 99, 104, 79, + 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, 104, + 67, 108, 97, 117, 115, 101, 32, 79, 102, 102, 115, 101, 116, 67, 108, 97, 117, 115, 101, 10, + 70, 101, 116, 99, 104, 79, 110, 108, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, + 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 84, 65, 66, 76, 69, 39, 32, 66, 97, 115, + 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 79, 112, 116, 105, 111, 110, 97, 108, 80, + 97, 114, 101, 110, 115, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, + 32, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, + 47, 32, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 10, 83, 105, 109, 112, 108, + 101, 83, 101, 108, 101, 99, 116, 80, 97, 114, 101, 110, 115, 32, 60, 45, 32, 80, 97, 114, + 101, 110, 115, 40, 83, 105, 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 41, 10, 83, 105, + 109, 112, 108, 101, 83, 101, 108, 101, 99, 116, 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, + 70, 114, 111, 109, 32, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 71, 114, + 111, 117, 112, 66, 121, 67, 108, 97, 117, 115, 101, 63, 32, 72, 97, 118, 105, 110, 103, 67, + 108, 97, 117, 115, 101, 63, 32, 87, 105, 110, 100, 111, 119, 67, 108, 97, 117, 115, 101, 63, + 32, 81, 117, 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, + 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, + 32, 60, 45, 32, 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, + 32, 47, 32, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 10, + 83, 101, 108, 101, 99, 116, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, + 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, + 117, 115, 101, 63, 10, 70, 114, 111, 109, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, + 101, 32, 60, 45, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 83, 101, 108, 101, + 99, 116, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 83, 116, 97, 116, 101, 109, + 101, 110, 116, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, + 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 32, 85, 115, 105, 110, + 103, 75, 101, 121, 63, 32, 39, 65, 83, 39, 32, 77, 97, 116, 101, 114, 105, 97, 108, 105, + 122, 101, 100, 63, 32, 67, 84, 69, 66, 111, 100, 121, 10, 67, 84, 69, 66, 111, 100, 121, + 32, 60, 45, 32, 67, 84, 69, 83, 101, 108, 101, 99, 116, 66, 111, 100, 121, 32, 47, 32, + 67, 84, 69, 68, 77, 76, 66, 111, 100, 121, 10, 67, 84, 69, 83, 101, 108, 101, 99, 116, + 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, + 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, + 67, 84, 69, 68, 77, 76, 66, 111, 100, 121, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, + 40, 83, 116, 97, 116, 101, 109, 101, 110, 116, 41, 10, 85, 115, 105, 110, 103, 75, 101, 121, + 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 75, 69, 89, 39, 32, 80, 97, + 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 41, 10, 77, 97, 116, + 101, 114, 105, 97, 108, 105, 122, 101, 100, 32, 60, 45, 32, 39, 78, 79, 84, 39, 63, 32, + 39, 77, 65, 84, 69, 82, 73, 65, 76, 73, 90, 69, 68, 39, 10, 87, 105, 116, 104, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 82, 101, 99, 117, + 114, 115, 105, 118, 101, 63, 32, 76, 105, 115, 116, 40, 87, 105, 116, 104, 83, 116, 97, 116, + 101, 109, 101, 110, 116, 41, 10, 82, 101, 99, 117, 114, 115, 105, 118, 101, 32, 60, 45, 32, + 39, 82, 69, 67, 85, 82, 83, 73, 86, 69, 39, 10, 83, 101, 108, 101, 99, 116, 67, 108, + 97, 117, 115, 101, 32, 60, 45, 32, 39, 83, 69, 76, 69, 67, 84, 39, 32, 68, 105, 115, + 116, 105, 110, 99, 116, 67, 108, 97, 117, 115, 101, 63, 32, 84, 97, 114, 103, 101, 116, 76, + 105, 115, 116, 63, 10, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, + 105, 115, 116, 40, 65, 108, 105, 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 41, 10, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, + 116, 114, 105, 110, 103, 41, 41, 10, 68, 105, 115, 116, 105, 110, 99, 116, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 68, 105, 115, 116, 105, 110, 99, 116, 79, 110, 32, 47, 32, 68, + 105, 115, 116, 105, 110, 99, 116, 65, 108, 108, 10, 68, 105, 115, 116, 105, 110, 99, 116, 65, + 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 68, 105, 115, 116, 105, 110, 99, 116, + 79, 110, 32, 60, 45, 32, 39, 68, 73, 83, 84, 73, 78, 67, 84, 39, 32, 68, 105, 115, + 116, 105, 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 63, 10, 68, 105, 115, 116, + 105, 110, 99, 116, 79, 110, 84, 97, 114, 103, 101, 116, 115, 32, 60, 45, 32, 39, 79, 78, + 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 41, 41, 10, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, 101, 102, + 32, 60, 45, 32, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 47, 32, 84, 97, 98, 108, + 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 84, 97, 98, 108, 101, 83, 117, 98, + 113, 117, 101, 114, 121, 32, 47, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, + 32, 47, 32, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 84, 97, + 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, + 82, 101, 102, 32, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 42, 10, 84, 97, 98, + 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, + 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, + 83, 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 84, 97, + 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, + 101, 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, + 110, 63, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 84, 97, 98, + 108, 101, 65, 108, 105, 97, 115, 63, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, 32, 83, + 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 84, 97, 98, 108, 101, 65, 108, + 105, 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, + 116, 114, 105, 110, 103, 32, 39, 58, 39, 10, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, - 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 84, 97, 98, 108, 101, 65, - 108, 105, 97, 115, 63, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, 32, 83, 97, 109, 112, - 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, - 67, 111, 108, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, - 110, 103, 32, 39, 58, 39, 10, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, - 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 86, 97, 108, - 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, - 63, 10, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, - 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, 80, 97, 114, - 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 84, 97, 98, 108, 101, 65, - 108, 105, 97, 115, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, - 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 32, 60, 45, 32, 74, 111, 105, 110, 67, - 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, - 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, - 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 80, 97, 114, 101, 110, 115, - 40, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, - 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, - 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 84, - 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 39, 70, 79, 82, 39, 32, 80, 105, 118, 111, - 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 32, 80, 105, 118, 111, 116, 71, 114, 111, - 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 71, 114, 111, 117, 112, - 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, - 89, 39, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, 78, 97, 109, - 101, 76, 105, 115, 116, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, 32, 73, 110, - 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, 108, 115, 63, - 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, - 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, - 97, 115, 63, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, 108, 97, 117, - 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, - 100, 101, 114, 32, 39, 70, 79, 82, 39, 32, 85, 110, 112, 105, 118, 111, 116, 86, 97, 108, - 117, 101, 76, 105, 115, 116, 43, 10, 80, 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, - 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 80, 105, - 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 105, 118, 111, - 116, 72, 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 80, 105, 118, 111, 116, 86, 97, - 108, 117, 101, 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, - 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, - 97, 114, 103, 101, 116, 32, 47, 32, 80, 105, 118, 111, 116, 76, 105, 115, 116, 84, 97, 114, - 103, 101, 116, 10, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, 97, 114, 103, 101, 116, 32, - 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 105, 118, 111, 116, 76, - 105, 115, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 84, 97, - 114, 103, 101, 116, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 86, 97, 108, 117, - 101, 76, 105, 115, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, 101, 97, 100, - 101, 114, 32, 39, 73, 78, 39, 32, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, - 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, - 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, - 115, 116, 41, 10, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, - 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, 116, 76, 105, - 115, 116, 41, 10, 76, 97, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 76, 65, 84, 69, - 82, 65, 76, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, - 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, - 32, 47, 32, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, 97, 115, 101, 84, 97, - 98, 108, 101, 78, 97, 109, 101, 10, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, - 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 84, 97, 98, 108, - 101, 78, 97, 109, 101, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, - 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, - 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 32, 47, 32, 83, 99, 104, - 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 10, 83, 99, 104, - 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 32, 60, 45, 32, - 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, - 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 67, 97, - 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, - 97, 98, 108, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, - 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, - 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, 32, 82, 101, - 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 84, 97, 98, 108, - 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, 101, 70, 117, - 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, 47, 32, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, - 111, 110, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, - 114, 97, 108, 79, 112, 116, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 81, + 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, 84, 97, 98, 108, 101, 65, 108, + 105, 97, 115, 63, 10, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 63, 32, + 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 84, 97, 98, + 108, 101, 65, 108, 105, 97, 115, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, + 101, 63, 10, 74, 111, 105, 110, 79, 114, 80, 105, 118, 111, 116, 32, 60, 45, 32, 74, 111, + 105, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 80, 105, 118, 111, + 116, 67, 108, 97, 117, 115, 101, 32, 47, 32, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, + 111, 116, 67, 108, 97, 117, 115, 101, 10, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 80, 73, 86, 79, 84, 39, 32, 80, 97, 114, + 101, 110, 115, 40, 84, 97, 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, + 66, 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, + 98, 108, 101, 80, 105, 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, + 45, 32, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 32, 39, 70, 79, 82, 39, 32, 80, + 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 32, 80, 105, 118, 111, 116, + 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 63, 10, 80, 105, 118, 111, 116, 71, 114, + 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, + 32, 39, 66, 89, 39, 32, 79, 112, 116, 105, 111, 110, 97, 108, 80, 97, 114, 101, 110, 115, + 78, 97, 109, 101, 76, 105, 115, 116, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, + 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 78, 80, 73, 86, 79, 84, 39, + 32, 73, 110, 99, 108, 117, 100, 101, 79, 114, 69, 120, 99, 108, 117, 100, 101, 78, 117, 108, + 108, 115, 63, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 85, 110, 112, 105, + 118, 111, 116, 67, 108, 97, 117, 115, 101, 66, 111, 100, 121, 41, 32, 84, 97, 98, 108, 101, + 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, 85, 110, 112, 105, 118, 111, 116, 67, + 108, 97, 117, 115, 101, 66, 111, 100, 121, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, + 72, 101, 97, 100, 101, 114, 32, 39, 70, 79, 82, 39, 32, 85, 110, 112, 105, 118, 111, 116, + 86, 97, 108, 117, 101, 76, 105, 115, 116, 43, 10, 80, 105, 118, 111, 116, 72, 101, 97, 100, + 101, 114, 32, 60, 45, 32, 66, 97, 115, 101, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 10, 80, 105, 118, 111, 116, 86, 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, + 105, 118, 111, 116, 72, 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 80, 105, 118, 111, + 116, 86, 97, 108, 117, 101, 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 86, 97, + 108, 117, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, 116, 69, 110, + 117, 109, 84, 97, 114, 103, 101, 116, 32, 47, 32, 80, 105, 118, 111, 116, 76, 105, 115, 116, + 84, 97, 114, 103, 101, 116, 10, 80, 105, 118, 111, 116, 69, 110, 117, 109, 84, 97, 114, 103, + 101, 116, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 80, 105, 118, + 111, 116, 76, 105, 115, 116, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 80, 105, 118, 111, + 116, 84, 97, 114, 103, 101, 116, 76, 105, 115, 116, 10, 85, 110, 112, 105, 118, 111, 116, 86, + 97, 108, 117, 101, 76, 105, 115, 116, 32, 60, 45, 32, 85, 110, 112, 105, 118, 111, 116, 72, + 101, 97, 100, 101, 114, 32, 39, 73, 78, 39, 32, 85, 110, 112, 105, 118, 111, 116, 84, 97, + 114, 103, 101, 116, 76, 105, 115, 116, 10, 80, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, + 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, + 116, 76, 105, 115, 116, 41, 10, 85, 110, 112, 105, 118, 111, 116, 84, 97, 114, 103, 101, 116, + 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 114, 103, 101, + 116, 76, 105, 115, 116, 41, 10, 76, 97, 116, 101, 114, 97, 108, 32, 60, 45, 32, 39, 76, + 65, 84, 69, 82, 65, 76, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, + 101, 32, 60, 45, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 78, + 97, 109, 101, 32, 47, 32, 85, 110, 113, 117, 97, 108, 105, 102, 105, 101, 100, 66, 97, 115, + 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 85, 110, 113, 117, 97, 108, 105, 102, 105, + 101, 100, 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 84, + 97, 98, 108, 101, 78, 97, 109, 101, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, + 98, 108, 101, 78, 97, 109, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 82, 101, + 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 84, 97, 98, 108, 101, 32, 47, 32, + 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 10, + 83, 99, 104, 101, 109, 97, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 32, + 60, 45, 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, + 10, 67, 97, 116, 97, 108, 111, 103, 82, 101, 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, + 109, 97, 84, 97, 98, 108, 101, 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 81, 117, + 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 32, 82, 101, 115, 101, 114, 118, 101, 100, + 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 43, + 32, 82, 101, 115, 101, 114, 118, 101, 100, 84, 97, 98, 108, 101, 78, 97, 109, 101, 10, 84, + 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 84, 97, 98, 108, + 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, + 47, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, + 67, 111, 108, 111, 110, 10, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 76, + 97, 116, 101, 114, 97, 108, 79, 112, 116, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, + 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, + 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, + 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, + 116, 121, 63, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, + 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, + 60, 45, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, - 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 63, 10, 84, 97, 98, 108, 101, 70, 117, - 110, 99, 116, 105, 111, 110, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 60, 45, 32, - 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 67, 111, 108, 111, 110, 32, 81, 117, 97, 108, - 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, - 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, 121, 63, 32, 83, 97, - 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 79, 114, 100, 105, - 110, 97, 108, 105, 116, 121, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, 39, 79, 82, - 68, 73, 78, 65, 76, 73, 84, 89, 39, 10, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, 97, 116, 97, - 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, 32, 83, 99, - 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 42, 32, 84, - 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, 84, 97, 98, - 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, - 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 70, 117, 110, 99, 116, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 63, 41, 10, 70, 117, 110, 99, 116, - 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, - 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 47, 32, 80, - 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, - 117, 109, 101, 110, 116, 10, 78, 97, 109, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, - 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, - 109, 101, 116, 101, 114, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, - 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, - 114, 32, 60, 45, 32, 84, 121, 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, 32, 84, 121, - 112, 101, 63, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, - 115, 105, 103, 110, 109, 101, 110, 116, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, - 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, 115, 105, 103, 110, - 109, 101, 110, 116, 32, 60, 45, 32, 39, 58, 61, 39, 32, 47, 32, 39, 61, 62, 39, 10, - 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, 84, 97, 98, 108, 101, 65, - 108, 105, 97, 115, 65, 115, 32, 47, 32, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 87, - 105, 116, 104, 111, 117, 116, 65, 115, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 65, - 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 67, 111, 108, 117, - 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, - 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, - 102, 105, 101, 114, 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, - 65, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 65, 84, 39, 32, 80, 97, 114, - 101, 110, 115, 40, 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 41, 10, 65, 116, 83, - 112, 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 65, 116, 85, 110, 105, 116, 32, 39, - 61, 62, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, 85, 110, 105, - 116, 32, 60, 45, 32, 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 47, - 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 10, 86, 101, 114, - 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 39, 86, 69, 82, 83, 73, - 79, 78, 39, 10, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 32, - 60, 45, 32, 39, 84, 73, 77, 69, 83, 84, 65, 77, 80, 39, 10, 74, 111, 105, 110, 67, - 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, - 101, 32, 47, 32, 82, 101, 103, 117, 108, 97, 114, 74, 111, 105, 110, 67, 108, 97, 117, 115, - 101, 32, 47, 32, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, 110, 67, 108, 97, - 117, 115, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, 108, 97, - 117, 115, 101, 10, 35, 32, 78, 69, 65, 82, 69, 83, 84, 32, 66, 89, 32, 104, 97, 115, - 32, 116, 119, 111, 32, 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 115, 32, 115, 111, - 32, 80, 69, 71, 32, 99, 97, 110, 32, 98, 97, 99, 107, 116, 114, 97, 99, 107, 58, 32, - 116, 104, 101, 32, 98, 97, 114, 101, 32, 102, 111, 114, 109, 32, 117, 115, 101, 115, 32, 97, - 108, 105, 97, 115, 45, 108, 101, 115, 115, 32, 116, 97, 114, 103, 101, 116, 32, 109, 105, 114, - 114, 111, 114, 115, 32, 40, 116, 114, 105, 101, 100, 10, 35, 32, 102, 105, 114, 115, 116, 44, - 32, 115, 111, 32, 97, 110, 32, 117, 110, 97, 108, 105, 97, 115, 101, 100, 32, 116, 97, 114, - 103, 101, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 103, 114, 101, 101, 100, 105, 108, - 121, 32, 99, 111, 110, 115, 117, 109, 101, 32, 78, 69, 65, 82, 69, 83, 84, 47, 65, 80, - 80, 82, 79, 88, 47, 69, 88, 65, 67, 84, 32, 97, 115, 32, 97, 110, 32, 97, 108, 105, - 97, 115, 41, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 97, 108, 105, 97, 115, 101, 100, - 10, 35, 32, 102, 111, 114, 109, 32, 102, 97, 108, 108, 115, 32, 98, 97, 99, 107, 32, 116, - 111, 32, 97, 32, 102, 117, 108, 108, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 119, 104, - 101, 110, 32, 97, 32, 114, 101, 97, 108, 32, 97, 108, 105, 97, 115, 32, 105, 100, 101, 110, - 116, 105, 102, 105, 101, 114, 32, 102, 111, 108, 108, 111, 119, 115, 32, 116, 104, 101, 32, 116, - 97, 114, 103, 101, 116, 46, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 66, - 97, 114, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, 105, - 97, 115, 101, 100, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, 108, 105, 97, - 115, 101, 100, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, - 73, 78, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, - 114, 69, 120, 97, 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, - 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, - 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, - 110, 66, 97, 114, 101, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, - 74, 79, 73, 78, 39, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, - 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, 99, 116, 63, - 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, - 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, 115, 116, 97, 110, 99, 101, 79, - 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, 108, 101, 82, - 101, 102, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, - 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 70, 117, 110, - 99, 116, 105, 111, 110, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, - 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, - 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, - 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 78, 101, 97, 114, 101, - 115, 116, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 86, 97, 108, 117, 101, - 115, 67, 108, 97, 117, 115, 101, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, - 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, - 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, - 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, - 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, 108, 105, 116, - 121, 63, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 83, 117, 98, 113, 117, - 101, 114, 121, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, 117, 98, 113, - 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 78, 101, 97, 114, 101, 115, - 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, 66, 97, 115, - 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 65, 116, 67, 108, 97, 117, 115, 101, 63, - 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 78, 101, 97, 114, 101, - 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, - 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, 83, 97, 109, - 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 65, 112, 112, 114, 111, 120, 79, 114, 69, - 120, 97, 99, 116, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, - 120, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 10, 78, 101, 97, - 114, 101, 115, 116, 65, 112, 112, 114, 111, 120, 32, 60, 45, 32, 39, 65, 80, 80, 82, 79, - 88, 39, 10, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 32, 60, 45, 32, 39, - 69, 88, 65, 67, 84, 39, 10, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, - 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 68, 105, - 115, 116, 97, 110, 99, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, - 108, 97, 114, 105, 116, 121, 10, 78, 101, 97, 114, 101, 115, 116, 68, 105, 115, 116, 97, 110, - 99, 101, 32, 60, 45, 32, 39, 68, 73, 83, 84, 65, 78, 67, 69, 39, 10, 78, 101, 97, - 114, 101, 115, 116, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 39, 83, - 73, 77, 73, 76, 65, 82, 73, 84, 89, 39, 10, 82, 101, 103, 117, 108, 97, 114, 74, 111, - 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 65, 115, 111, 102, 63, 32, 74, 111, - 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, - 82, 101, 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 74, 111, - 105, 110, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 74, 79, 73, 78, 39, - 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 39, 84, 89, 80, 69, 39, 32, - 67, 111, 108, 76, 97, 98, 101, 108, 41, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 74, - 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 65, 115, 111, 102, 32, 60, 45, - 32, 39, 65, 83, 79, 70, 39, 10, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, - 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 80, 114, 101, 102, 105, - 120, 32, 39, 74, 79, 73, 78, 39, 32, 73, 110, 110, 101, 114, 84, 97, 98, 108, 101, 82, - 101, 102, 10, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, 60, 45, 32, - 79, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 85, 115, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 10, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 78, 39, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 115, 105, 110, 103, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 80, 97, 114, 101, 110, 115, - 40, 76, 105, 115, 116, 40, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, 109, - 101, 41, 41, 10, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, - 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, 83, 116, 114, 105, - 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, - 74, 111, 105, 110, 84, 121, 112, 101, 32, 60, 45, 32, 70, 117, 108, 108, 74, 111, 105, 110, - 32, 47, 32, 76, 101, 102, 116, 74, 111, 105, 110, 32, 47, 32, 82, 105, 103, 104, 116, 74, - 111, 105, 110, 32, 47, 32, 83, 101, 109, 105, 74, 111, 105, 110, 32, 47, 32, 65, 110, 116, - 105, 74, 111, 105, 110, 32, 47, 32, 73, 110, 110, 101, 114, 74, 111, 105, 110, 10, 74, 111, - 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 67, 114, 111, 115, 115, 74, 111, 105, - 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, - 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, - 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 10, 67, 114, 111, 115, 115, 74, 111, 105, 110, - 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 67, 82, 79, 83, 83, 39, 10, 78, 97, - 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, - 78, 65, 84, 85, 82, 65, 76, 39, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 10, 80, - 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, - 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 65, 76, 39, 10, 70, 117, 108, 108, - 74, 111, 105, 110, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 32, 39, 79, 85, 84, 69, - 82, 39, 63, 10, 76, 101, 102, 116, 74, 111, 105, 110, 32, 60, 45, 32, 39, 76, 69, 70, - 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 82, 105, 103, 104, 116, 74, 111, 105, - 110, 32, 60, 45, 32, 39, 82, 73, 71, 72, 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, - 63, 10, 83, 101, 109, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 83, 69, 77, 73, 39, - 10, 65, 110, 116, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 65, 78, 84, 73, 39, 10, - 73, 110, 110, 101, 114, 74, 111, 105, 110, 32, 60, 45, 32, 39, 73, 78, 78, 69, 82, 39, - 10, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, 82, 79, 77, - 39, 32, 76, 105, 115, 116, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, 87, 104, 101, - 114, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 82, 69, 39, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 67, 108, - 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, 66, 89, 39, - 32, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 10, - 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 72, 65, 86, - 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 81, 117, 97, 108, - 105, 102, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 81, 85, 65, 76, 73, 70, - 89, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 97, 109, 112, 108, 101, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 40, 84, 97, 98, 108, 101, 83, 97, 109, 112, - 108, 101, 32, 47, 32, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, 101, 41, 32, 83, 97, - 109, 112, 108, 101, 69, 110, 116, 114, 121, 10, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, - 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 83, 65, 77, 80, 76, 69, - 39, 10, 84, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 84, 65, - 66, 76, 69, 83, 65, 77, 80, 76, 69, 39, 10, 87, 105, 110, 100, 111, 119, 67, 108, 97, - 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 78, 68, 79, 87, 39, 32, 76, 105, 115, 116, - 40, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 41, 10, 87, - 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, 45, 32, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 65, 83, 39, 32, 87, 105, 110, 100, 111, - 119, 70, 114, 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 10, 83, 97, 109, - 112, 108, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 69, 110, - 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 83, 97, 109, 112, 108, 101, - 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, - 114, 121, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 67, 111, 117, - 110, 116, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 80, 114, 111, 112, - 101, 114, 116, 105, 101, 115, 41, 63, 10, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, - 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 70, 117, - 110, 99, 116, 105, 111, 110, 63, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, - 101, 67, 111, 117, 110, 116, 41, 32, 82, 101, 112, 101, 97, 116, 97, 98, 108, 101, 83, 97, - 109, 112, 108, 101, 63, 10, 83, 97, 109, 112, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, - 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 83, 97, 109, 112, 108, 101, 80, 114, 111, 112, - 101, 114, 116, 105, 101, 115, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 40, 39, 44, 39, - 32, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 41, 63, 10, 82, 101, 112, 101, 97, 116, - 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 82, 69, 80, 69, 65, - 84, 65, 66, 76, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, - 83, 101, 101, 100, 41, 10, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 32, 60, 45, 32, - 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 83, 97, 109, 112, 108, 101, - 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 86, 97, 108, 117, 101, - 32, 83, 97, 109, 112, 108, 101, 85, 110, 105, 116, 63, 10, 83, 97, 109, 112, 108, 101, 86, - 97, 108, 117, 101, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, - 108, 32, 47, 32, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 83, 97, 109, 112, 108, 101, - 85, 110, 105, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, - 116, 97, 103, 101, 32, 47, 32, 83, 97, 109, 112, 108, 101, 82, 111, 119, 115, 10, 83, 97, - 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, 116, 97, 103, 101, 32, 60, 45, 32, 39, 37, - 39, 32, 47, 32, 39, 80, 69, 82, 67, 69, 78, 84, 39, 10, 83, 97, 109, 112, 108, 101, - 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, 79, 87, 83, 39, 10, 71, 114, 111, 117, 112, - 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 71, 114, 111, - 117, 112, 66, 121, 76, 105, 115, 116, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 65, 108, - 108, 10, 71, 114, 111, 117, 112, 66, 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, - 39, 10, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, - 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, - 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, - 45, 32, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, 109, 32, - 47, 32, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, - 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, 97, 117, 115, - 101, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, 114, 101, - 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, - 110, 10, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, 101, 109, 32, - 60, 45, 32, 39, 40, 39, 32, 39, 41, 39, 10, 67, 117, 98, 101, 79, 114, 82, 111, 108, - 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 67, 117, 98, 101, 79, 114, 82, - 111, 108, 108, 117, 112, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, - 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 67, 117, 98, 101, 79, 114, 82, 111, - 108, 108, 117, 112, 32, 60, 45, 32, 67, 117, 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, - 47, 32, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 10, 67, 117, 98, 101, - 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 85, 66, 69, 39, 10, 82, 111, - 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 82, 79, 76, 76, - 85, 80, 39, 10, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, 97, 117, - 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 32, 39, 83, 69, - 84, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 71, 114, 111, 117, - 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, 117, 98, 113, - 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 73, - 110, 116, 101, 114, 110, 97, 108, 41, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, - 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, - 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 68, 101, 115, 99, 79, 114, 65, 115, 99, 32, - 60, 45, 32, 68, 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 47, - 32, 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 10, 68, 101, 115, 99, - 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 68, 69, 83, 67, - 39, 32, 47, 32, 39, 68, 69, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 65, 115, 99, - 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 65, 83, 67, 39, - 32, 47, 32, 39, 65, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 78, 117, 108, 108, 115, - 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 32, 60, 45, 32, 78, 117, 108, 108, 115, - 70, 105, 114, 115, 116, 32, 47, 32, 78, 117, 108, 108, 115, 76, 97, 115, 116, 10, 78, 117, - 108, 108, 115, 70, 105, 114, 115, 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, - 39, 70, 73, 82, 83, 84, 39, 10, 78, 117, 108, 108, 115, 76, 97, 115, 116, 32, 60, 45, - 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, 76, 65, 83, 84, 39, 10, 79, 114, 100, 101, - 114, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 82, 68, 69, 82, 39, - 32, 39, 66, 89, 39, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 115, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, - 111, 110, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 65, 108, 108, 32, 47, 32, - 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, 105, 115, - 116, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 76, - 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 79, 114, 100, 101, 114, 66, 121, 69, - 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 79, 114, 100, 101, 114, 66, 121, 65, 108, - 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, - 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, - 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 76, 73, 77, 73, - 84, 39, 32, 76, 105, 109, 105, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, - 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 70, 70, 83, 69, 84, 39, 32, 79, - 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, 86, 97, 108, - 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 82, 111, 119, - 79, 114, 82, 111, 119, 115, 63, 10, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 60, 45, - 32, 39, 82, 79, 87, 39, 32, 47, 32, 39, 82, 79, 87, 83, 39, 10, 76, 105, 109, 105, - 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 65, 108, 108, 32, 47, - 32, 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, - 32, 47, 32, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 76, - 105, 109, 105, 116, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, 76, 105, 109, - 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, 32, 60, 45, 32, - 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 39, 80, 69, 82, 67, 69, - 78, 84, 39, 10, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, - 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 37, 39, 63, 10, 70, - 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, 99, 104, 67, - 108, 97, 117, 115, 101, 87, 105, 116, 104, 111, 117, 116, 86, 97, 108, 117, 101, 32, 47, 32, - 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 86, 97, 108, 117, 101, - 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 111, 117, 116, 86, - 97, 108, 117, 101, 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, 70, 105, 114, 115, - 116, 79, 114, 78, 101, 120, 116, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, - 78, 76, 89, 39, 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, - 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, 70, 105, 114, - 115, 116, 79, 114, 78, 101, 120, 116, 32, 70, 101, 116, 99, 104, 86, 97, 108, 117, 101, 32, - 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, 78, 76, 89, 39, 10, 70, 105, 114, - 115, 116, 79, 114, 78, 101, 120, 116, 32, 60, 45, 32, 39, 70, 73, 82, 83, 84, 39, 32, - 47, 32, 39, 78, 69, 88, 84, 39, 10, 70, 101, 116, 99, 104, 86, 97, 108, 117, 101, 32, - 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 108, 105, 97, 115, 101, - 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, 32, 47, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, - 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, - 111, 108, 73, 100, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, - 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 65, 83, 39, 32, - 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, 116, 114, 105, 110, 103, 10, 69, 120, 112, - 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 100, 101, 110, 116, - 105, 102, 105, 101, 114, 63, 10, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 32, - 60, 45, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 76, 105, 115, 116, 40, 86, 97, 108, - 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 41, 10, 86, 97, 108, 117, - 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 80, 97, 114, - 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, - 41, 10, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 83, - 69, 84, 39, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 79, 114, 84, - 105, 109, 101, 90, 111, 110, 101, 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, - 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 83, 101, 116, 83, 99, - 104, 101, 109, 97, 32, 47, 32, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, - 110, 109, 101, 110, 116, 32, 47, 32, 83, 101, 116, 84, 105, 109, 101, 90, 111, 110, 101, 10, - 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 82, - 69, 83, 69, 84, 39, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, - 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, - 39, 83, 67, 72, 69, 77, 65, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, - 97, 108, 10, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, 110, 109, 101, 110, - 116, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, - 116, 116, 105, 110, 103, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 10, - 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, 105, 110, 103, - 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 47, 32, 83, 101, - 116, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 84, 105, 109, 101, 90, 111, 110, 101, - 32, 60, 45, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, 32, 90, 111, - 110, 101, 86, 97, 108, 117, 101, 10, 90, 111, 110, 101, 86, 97, 108, 117, 101, 32, 60, 45, - 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 80, 114, 101, - 99, 105, 115, 105, 111, 110, 32, 47, 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, - 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, 32, 47, 32, 90, 111, 110, 101, - 76, 111, 99, 97, 108, 32, 47, 32, 90, 111, 110, 101, 68, 101, 102, 97, 117, 108, 116, 32, - 47, 32, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, - 47, 32, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 47, 32, 78, - 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, 76, 111, 99, - 97, 108, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, 90, 111, 110, 101, 68, 101, - 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, 39, 10, 90, - 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 60, 45, 32, - 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, 73, 100, - 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, 73, - 110, 116, 101, 114, 118, 97, 108, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, 86, 65, 76, - 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 73, 110, 116, 101, - 114, 118, 97, 108, 63, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, - 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 60, 45, 32, 39, 73, 78, 84, 69, - 82, 86, 65, 76, 39, 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 109, 98, 101, 114, 76, - 105, 116, 101, 114, 97, 108, 41, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, - 108, 10, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, 101, 116, 116, - 105, 110, 103, 83, 99, 111, 112, 101, 63, 32, 83, 101, 116, 116, 105, 110, 103, 78, 97, 109, - 101, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 60, 45, 32, 86, 97, 114, - 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, - 114, 10, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, - 86, 65, 82, 73, 65, 66, 76, 69, 39, 10, 83, 101, 116, 116, 105, 110, 103, 83, 99, 111, - 112, 101, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, 47, 32, 83, - 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, 32, 47, 32, 71, 108, 111, 98, 97, 108, - 83, 99, 111, 112, 101, 10, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, 60, 45, 32, - 39, 76, 79, 67, 65, 76, 39, 10, 83, 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, - 32, 60, 45, 32, 39, 83, 69, 83, 83, 73, 79, 78, 39, 10, 71, 108, 111, 98, 97, 108, - 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 71, 76, 79, 66, 65, 76, 39, 10, 83, 101, - 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 86, 97, 114, 105, 97, - 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 86, 97, 114, 105, 97, 98, 108, 101, 76, 105, - 115, 116, 10, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 60, 45, - 32, 39, 61, 39, 32, 47, 32, 39, 84, 79, 39, 10, 86, 97, 114, 105, 97, 98, 108, 101, - 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, - 105, 111, 110, 41, 10, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 83, 116, 97, 116, - 101, 109, 101, 110, 116, 32, 60, 45, 32, 66, 101, 103, 105, 110, 84, 114, 97, 110, 115, 97, - 99, 116, 105, 111, 110, 32, 47, 32, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, 97, 110, - 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 67, 111, 109, 109, 105, 116, 84, 114, 97, 110, - 115, 97, 99, 116, 105, 111, 110, 10, 66, 101, 103, 105, 110, 84, 114, 97, 110, 115, 97, 99, - 116, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, - 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 32, 82, 101, 97, 100, 79, 114, - 87, 114, 105, 116, 101, 63, 10, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, 97, 110, 115, - 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, - 108, 98, 97, 99, 107, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 10, 67, - 111, 109, 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, - 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 84, 114, 97, 110, 115, 97, 99, 116, - 105, 111, 110, 63, 10, 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, 32, 60, 45, - 32, 39, 83, 84, 65, 82, 84, 39, 32, 47, 32, 39, 66, 69, 71, 73, 78, 39, 10, 84, - 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 87, 79, 82, 75, 39, - 32, 47, 32, 39, 84, 82, 65, 78, 83, 65, 67, 84, 73, 79, 78, 39, 10, 82, 101, 97, - 100, 79, 114, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 82, 69, 65, 68, 39, 32, 82, - 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, 101, 10, 82, - 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, - 45, 32, 82, 101, 97, 100, 79, 110, 108, 121, 32, 47, 32, 82, 101, 97, 100, 87, 114, 105, - 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 32, 60, 45, 32, 39, 79, 78, 76, 89, - 39, 10, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 87, 82, 73, 84, - 69, 39, 10, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, 107, 32, 60, - 45, 32, 39, 65, 66, 79, 82, 84, 39, 32, 47, 32, 39, 82, 79, 76, 76, 66, 65, 67, - 75, 39, 10, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 60, 45, 32, 39, 67, - 79, 77, 77, 73, 84, 39, 32, 47, 32, 39, 69, 78, 68, 39, 10, 85, 112, 100, 97, 116, - 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, 104, 67, 108, - 97, 117, 115, 101, 63, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, 100, 97, 116, - 101, 84, 97, 114, 103, 101, 116, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, 67, 108, 97, - 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 63, 32, 87, 104, 101, 114, - 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, 103, 67, 108, - 97, 117, 115, 101, 63, 10, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, 101, 116, 32, 60, - 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 47, 32, 66, 97, 115, - 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, 116, 10, 66, 97, 115, 101, 84, - 97, 98, 108, 101, 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, - 78, 97, 109, 101, 32, 39, 83, 69, 84, 39, 10, 66, 97, 115, 101, 84, 97, 98, 108, 101, - 65, 108, 105, 97, 115, 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, - 101, 78, 97, 109, 101, 32, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 63, 32, 39, - 83, 69, 84, 39, 10, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, - 39, 65, 83, 39, 63, 32, 67, 111, 108, 73, 100, 10, 85, 112, 100, 97, 116, 101, 83, 101, - 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, - 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 47, 32, 85, 112, 100, 97, 116, 101, - 83, 101, 116, 84, 117, 112, 108, 101, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 84, 117, - 112, 108, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, - 111, 108, 117, 109, 110, 78, 97, 109, 101, 41, 41, 32, 39, 61, 39, 32, 69, 120, 112, 114, - 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, - 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 85, 112, 100, 97, - 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 41, 10, 85, 112, 100, 97, 116, 101, - 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, - 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 39, 61, 39, 32, - 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, - 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, 111, 108, 117, - 109, 110, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 42, 10, 85, 115, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 39, 85, - 83, 69, 39, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 10, 85, 115, 101, 84, 97, 114, - 103, 101, 116, 32, 60, 45, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, 97, 116, 97, - 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, 99, 104, 101, 109, 97, 78, 97, - 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 47, 32, 67, 97, 116, 97, - 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 10, 83, - 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, - 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 10, 67, 97, 116, 97, 108, - 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 60, 45, - 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 10, 85, 115, 101, 84, 97, 114, 103, - 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 60, 45, 32, 67, - 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 46, 39, 32, 82, 101, 115, 101, 114, - 118, 101, 100, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, - 110, 116, 105, 102, 105, 101, 114, 42, 10, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, 105, - 101, 114, 32, 60, 45, 32, 39, 46, 39, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, - 10, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, - 39, 86, 65, 67, 85, 85, 77, 39, 32, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, - 110, 115, 63, 32, 65, 110, 97, 108, 121, 122, 101, 84, 97, 114, 103, 101, 116, 63, 10, 86, - 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 86, 97, 99, 117, - 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 47, 32, 86, 97, - 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, 10, 86, 97, - 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, - 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 86, 97, 99, 117, 117, 109, 79, - 112, 116, 105, 111, 110, 41, 41, 10, 86, 97, 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, - 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 79, 112, 116, 70, 117, 108, 108, 63, 32, - 79, 112, 116, 70, 114, 101, 101, 122, 101, 63, 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, - 101, 63, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, 63, 10, 86, 97, 99, 117, 117, - 109, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, - 101, 32, 47, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, 32, 47, 32, 79, 112, 116, 70, - 117, 108, 108, 32, 47, 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 47, 32, 73, - 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, - 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, 100, 10, 79, - 112, 116, 70, 117, 108, 108, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 10, 79, 112, 116, - 70, 114, 101, 101, 122, 101, 32, 60, 45, 32, 39, 70, 82, 69, 69, 90, 69, 39, 10, 79, - 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 60, 45, 32, 39, 86, 69, 82, 66, 79, 83, - 69, 39, 10, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, 114, 101, 110, - 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, 105, 110, 103, - 41, 41, 10, 0, + 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 87, 105, 116, 104, 79, + 114, 100, 105, 110, 97, 108, 105, 116, 121, 32, 60, 45, 32, 39, 87, 73, 84, 72, 39, 32, + 39, 79, 82, 68, 73, 78, 65, 76, 73, 84, 89, 39, 10, 81, 117, 97, 108, 105, 102, 105, + 101, 100, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 67, + 97, 116, 97, 108, 111, 103, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, 63, + 32, 83, 99, 104, 101, 109, 97, 81, 117, 97, 108, 105, 102, 105, 99, 97, 116, 105, 111, 110, + 42, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 78, 97, 109, 101, 10, + 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, + 116, 115, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 70, 117, + 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 41, 63, 41, 10, 70, 117, + 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, + 109, 101, 100, 70, 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, + 47, 32, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, 117, 110, 99, 116, 105, 111, 110, + 65, 114, 103, 117, 109, 101, 110, 116, 10, 78, 97, 109, 101, 100, 70, 117, 110, 99, 116, 105, + 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 78, 97, 109, 101, 100, 80, + 97, 114, 97, 109, 101, 116, 101, 114, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 70, + 117, 110, 99, 116, 105, 111, 110, 65, 114, 103, 117, 109, 101, 110, 116, 32, 60, 45, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, + 101, 116, 101, 114, 32, 60, 45, 32, 84, 121, 112, 101, 70, 117, 110, 99, 78, 97, 109, 101, + 32, 84, 121, 112, 101, 63, 32, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, + 114, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 78, 97, 109, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 65, 115, 115, + 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 39, 58, 61, 39, 32, 47, 32, 39, 61, + 62, 39, 10, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 32, 60, 45, 32, 84, 97, 98, + 108, 101, 65, 108, 105, 97, 115, 65, 115, 32, 47, 32, 84, 97, 98, 108, 101, 65, 108, 105, + 97, 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 10, 84, 97, 98, 108, 101, 65, 108, 105, + 97, 115, 65, 115, 32, 60, 45, 32, 39, 65, 83, 39, 32, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 79, 114, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 67, + 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, 115, 63, 10, 84, 97, 98, 108, 101, 65, + 108, 105, 97, 115, 87, 105, 116, 104, 111, 117, 116, 65, 115, 32, 60, 45, 32, 73, 100, 101, + 110, 116, 105, 102, 105, 101, 114, 32, 67, 111, 108, 117, 109, 110, 65, 108, 105, 97, 115, 101, + 115, 63, 10, 65, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 65, 84, 39, 32, + 80, 97, 114, 101, 110, 115, 40, 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 41, 10, + 65, 116, 83, 112, 101, 99, 105, 102, 105, 101, 114, 32, 60, 45, 32, 65, 116, 85, 110, 105, + 116, 32, 39, 61, 62, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 116, + 85, 110, 105, 116, 32, 60, 45, 32, 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, + 116, 32, 47, 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, 105, 116, 10, + 86, 101, 114, 115, 105, 111, 110, 65, 116, 85, 110, 105, 116, 32, 60, 45, 32, 39, 86, 69, + 82, 83, 73, 79, 78, 39, 10, 84, 105, 109, 101, 115, 116, 97, 109, 112, 65, 116, 85, 110, + 105, 116, 32, 60, 45, 32, 39, 84, 73, 77, 69, 83, 84, 65, 77, 80, 39, 10, 74, 111, + 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 66, 121, 67, 108, + 97, 117, 115, 101, 32, 47, 32, 82, 101, 103, 117, 108, 97, 114, 74, 111, 105, 110, 67, 108, + 97, 117, 115, 101, 32, 47, 32, 74, 111, 105, 110, 87, 105, 116, 104, 111, 117, 116, 79, 110, + 67, 108, 97, 117, 115, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, + 67, 108, 97, 117, 115, 101, 10, 35, 32, 78, 69, 65, 82, 69, 83, 84, 32, 66, 89, 32, + 104, 97, 115, 32, 116, 119, 111, 32, 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 115, + 32, 115, 111, 32, 80, 69, 71, 32, 99, 97, 110, 32, 98, 97, 99, 107, 116, 114, 97, 99, + 107, 58, 32, 116, 104, 101, 32, 98, 97, 114, 101, 32, 102, 111, 114, 109, 32, 117, 115, 101, + 115, 32, 97, 108, 105, 97, 115, 45, 108, 101, 115, 115, 32, 116, 97, 114, 103, 101, 116, 32, + 109, 105, 114, 114, 111, 114, 115, 32, 40, 116, 114, 105, 101, 100, 10, 35, 32, 102, 105, 114, + 115, 116, 44, 32, 115, 111, 32, 97, 110, 32, 117, 110, 97, 108, 105, 97, 115, 101, 100, 32, + 116, 97, 114, 103, 101, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 103, 114, 101, 101, + 100, 105, 108, 121, 32, 99, 111, 110, 115, 117, 109, 101, 32, 78, 69, 65, 82, 69, 83, 84, + 47, 65, 80, 80, 82, 79, 88, 47, 69, 88, 65, 67, 84, 32, 97, 115, 32, 97, 110, 32, + 97, 108, 105, 97, 115, 41, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 97, 108, 105, 97, + 115, 101, 100, 10, 35, 32, 102, 111, 114, 109, 32, 102, 97, 108, 108, 115, 32, 98, 97, 99, + 107, 32, 116, 111, 32, 97, 32, 102, 117, 108, 108, 32, 84, 97, 98, 108, 101, 82, 101, 102, + 32, 119, 104, 101, 110, 32, 97, 32, 114, 101, 97, 108, 32, 97, 108, 105, 97, 115, 32, 105, + 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 102, 111, 108, 108, 111, 119, 115, 32, 116, 104, + 101, 32, 116, 97, 114, 103, 101, 116, 46, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, + 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, + 105, 110, 66, 97, 114, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, + 65, 108, 105, 97, 115, 101, 100, 10, 78, 101, 97, 114, 101, 115, 116, 74, 111, 105, 110, 65, + 108, 105, 97, 115, 101, 100, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, + 39, 74, 79, 73, 78, 39, 32, 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, + 111, 120, 79, 114, 69, 120, 97, 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, + 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, + 32, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, + 121, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, + 74, 111, 105, 110, 66, 97, 114, 101, 32, 60, 45, 32, 74, 111, 105, 110, 84, 121, 112, 101, + 63, 32, 39, 74, 79, 73, 78, 39, 32, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, + 84, 97, 98, 108, 101, 82, 101, 102, 32, 65, 112, 112, 114, 111, 120, 79, 114, 69, 120, 97, + 99, 116, 63, 32, 39, 78, 69, 65, 82, 69, 83, 84, 39, 32, 78, 117, 109, 98, 101, 114, + 76, 105, 116, 101, 114, 97, 108, 63, 32, 39, 66, 89, 39, 32, 68, 105, 115, 116, 97, 110, + 99, 101, 79, 114, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 10, 78, 101, 97, 114, 101, 115, 116, 66, 97, 114, 101, 84, 97, 98, + 108, 101, 82, 101, 102, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 86, 97, 108, 117, + 101, 115, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, + 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 84, 97, + 98, 108, 101, 83, 117, 98, 113, 117, 101, 114, 121, 32, 47, 32, 78, 101, 97, 114, 101, 115, + 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 47, 32, 78, 101, 97, 114, + 101, 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 10, 78, 101, + 97, 114, 101, 115, 116, 86, 97, 108, 117, 101, 115, 82, 101, 102, 32, 60, 45, 32, 86, 97, + 108, 117, 101, 115, 67, 108, 97, 117, 115, 101, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, + 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 76, 97, 116, 101, 114, + 97, 108, 63, 32, 81, 117, 97, 108, 105, 102, 105, 101, 100, 84, 97, 98, 108, 101, 70, 117, + 110, 99, 116, 105, 111, 110, 32, 84, 97, 98, 108, 101, 70, 117, 110, 99, 116, 105, 111, 110, + 65, 114, 103, 117, 109, 101, 110, 116, 115, 32, 87, 105, 116, 104, 79, 114, 100, 105, 110, 97, + 108, 105, 116, 121, 63, 10, 78, 101, 97, 114, 101, 115, 116, 84, 97, 98, 108, 101, 83, 117, + 98, 113, 117, 101, 114, 121, 32, 60, 45, 32, 76, 97, 116, 101, 114, 97, 108, 63, 32, 83, + 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 10, 78, 101, 97, + 114, 101, 115, 116, 66, 97, 115, 101, 84, 97, 98, 108, 101, 82, 101, 102, 32, 60, 45, 32, + 66, 97, 115, 101, 84, 97, 98, 108, 101, 78, 97, 109, 101, 32, 65, 116, 67, 108, 97, 117, + 115, 101, 63, 32, 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 78, 101, + 97, 114, 101, 115, 116, 80, 97, 114, 101, 110, 115, 84, 97, 98, 108, 101, 82, 101, 102, 32, + 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 32, + 83, 97, 109, 112, 108, 101, 67, 108, 97, 117, 115, 101, 63, 10, 65, 112, 112, 114, 111, 120, + 79, 114, 69, 120, 97, 99, 116, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, 116, 65, 112, + 112, 114, 111, 120, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 10, + 78, 101, 97, 114, 101, 115, 116, 65, 112, 112, 114, 111, 120, 32, 60, 45, 32, 39, 65, 80, + 80, 82, 79, 88, 39, 10, 78, 101, 97, 114, 101, 115, 116, 69, 120, 97, 99, 116, 32, 60, + 45, 32, 39, 69, 88, 65, 67, 84, 39, 10, 68, 105, 115, 116, 97, 110, 99, 101, 79, 114, + 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, 32, 78, 101, 97, 114, 101, 115, + 116, 68, 105, 115, 116, 97, 110, 99, 101, 32, 47, 32, 78, 101, 97, 114, 101, 115, 116, 83, + 105, 109, 105, 108, 97, 114, 105, 116, 121, 10, 78, 101, 97, 114, 101, 115, 116, 68, 105, 115, + 116, 97, 110, 99, 101, 32, 60, 45, 32, 39, 68, 73, 83, 84, 65, 78, 67, 69, 39, 10, + 78, 101, 97, 114, 101, 115, 116, 83, 105, 109, 105, 108, 97, 114, 105, 116, 121, 32, 60, 45, + 32, 39, 83, 73, 77, 73, 76, 65, 82, 73, 84, 89, 39, 10, 82, 101, 103, 117, 108, 97, + 114, 74, 111, 105, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 65, 115, 111, 102, 63, + 32, 74, 111, 105, 110, 84, 121, 112, 101, 63, 32, 39, 74, 79, 73, 78, 39, 32, 84, 97, + 98, 108, 101, 82, 101, 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, + 10, 74, 111, 105, 110, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 74, 79, + 73, 78, 39, 32, 39, 66, 89, 39, 32, 80, 97, 114, 101, 110, 115, 40, 39, 84, 89, 80, + 69, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 41, 32, 84, 97, 98, 108, 101, 82, 101, + 102, 32, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 10, 65, 115, 111, 102, + 32, 60, 45, 32, 39, 65, 83, 79, 70, 39, 10, 74, 111, 105, 110, 87, 105, 116, 104, 111, + 117, 116, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 74, 111, 105, 110, 80, 114, + 101, 102, 105, 120, 32, 39, 74, 79, 73, 78, 39, 32, 73, 110, 110, 101, 114, 84, 97, 98, + 108, 101, 82, 101, 102, 10, 74, 111, 105, 110, 81, 117, 97, 108, 105, 102, 105, 101, 114, 32, + 60, 45, 32, 79, 110, 67, 108, 97, 117, 115, 101, 32, 47, 32, 85, 115, 105, 110, 103, 67, + 108, 97, 117, 115, 101, 10, 79, 110, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, + 78, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 115, 105, 110, 103, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 80, 97, 114, + 101, 110, 115, 40, 76, 105, 115, 116, 40, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, + 78, 97, 109, 101, 41, 41, 10, 85, 115, 105, 110, 103, 67, 111, 108, 117, 109, 110, 78, 97, + 109, 101, 32, 60, 45, 32, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 47, 32, 83, + 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 10, 74, 111, 105, 110, 84, 121, 112, 101, 32, 60, 45, 32, 70, 117, 108, 108, 74, + 111, 105, 110, 32, 47, 32, 76, 101, 102, 116, 74, 111, 105, 110, 32, 47, 32, 82, 105, 103, + 104, 116, 74, 111, 105, 110, 32, 47, 32, 83, 101, 109, 105, 74, 111, 105, 110, 32, 47, 32, + 65, 110, 116, 105, 74, 111, 105, 110, 32, 47, 32, 73, 110, 110, 101, 114, 74, 111, 105, 110, + 10, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 67, 114, 111, 115, 115, + 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 78, 97, 116, 117, 114, 97, 108, + 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 47, 32, 80, 111, 115, 105, 116, 105, 111, + 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 10, 67, 114, 111, 115, 115, 74, + 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, 45, 32, 39, 67, 82, 79, 83, 83, 39, + 10, 78, 97, 116, 117, 114, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, 105, 120, 32, 60, + 45, 32, 39, 78, 65, 84, 85, 82, 65, 76, 39, 32, 74, 111, 105, 110, 84, 121, 112, 101, + 63, 10, 80, 111, 115, 105, 116, 105, 111, 110, 97, 108, 74, 111, 105, 110, 80, 114, 101, 102, + 105, 120, 32, 60, 45, 32, 39, 80, 79, 83, 73, 84, 73, 79, 78, 65, 76, 39, 10, 70, + 117, 108, 108, 74, 111, 105, 110, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 32, 39, 79, + 85, 84, 69, 82, 39, 63, 10, 76, 101, 102, 116, 74, 111, 105, 110, 32, 60, 45, 32, 39, + 76, 69, 70, 84, 39, 32, 39, 79, 85, 84, 69, 82, 39, 63, 10, 82, 105, 103, 104, 116, + 74, 111, 105, 110, 32, 60, 45, 32, 39, 82, 73, 71, 72, 84, 39, 32, 39, 79, 85, 84, + 69, 82, 39, 63, 10, 83, 101, 109, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 83, 69, + 77, 73, 39, 10, 65, 110, 116, 105, 74, 111, 105, 110, 32, 60, 45, 32, 39, 65, 78, 84, + 73, 39, 10, 73, 110, 110, 101, 114, 74, 111, 105, 110, 32, 60, 45, 32, 39, 73, 78, 78, + 69, 82, 39, 10, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 70, + 82, 79, 77, 39, 32, 76, 105, 115, 116, 40, 84, 97, 98, 108, 101, 82, 101, 102, 41, 10, + 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 72, 69, 82, + 69, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, + 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 39, 32, 39, + 66, 89, 39, 32, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 115, 10, 72, 97, 118, 105, 110, 103, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, + 72, 65, 86, 73, 78, 71, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 81, + 117, 97, 108, 105, 102, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 81, 85, 65, + 76, 73, 70, 89, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 83, 97, 109, + 112, 108, 101, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 40, 84, 97, 98, 108, 101, 83, + 97, 109, 112, 108, 101, 32, 47, 32, 85, 115, 105, 110, 103, 83, 97, 109, 112, 108, 101, 41, + 32, 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 10, 85, 115, 105, 110, 103, 83, 97, + 109, 112, 108, 101, 32, 60, 45, 32, 39, 85, 83, 73, 78, 71, 39, 32, 39, 83, 65, 77, + 80, 76, 69, 39, 10, 84, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, + 39, 84, 65, 66, 76, 69, 83, 65, 77, 80, 76, 69, 39, 10, 87, 105, 110, 100, 111, 119, + 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 87, 73, 78, 68, 79, 87, 39, 32, 76, + 105, 115, 116, 40, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, + 41, 10, 87, 105, 110, 100, 111, 119, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 32, 60, + 45, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 39, 65, 83, 39, 32, 87, 105, + 110, 100, 111, 119, 70, 114, 97, 109, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 10, + 83, 97, 109, 112, 108, 101, 69, 110, 116, 114, 121, 32, 60, 45, 32, 83, 97, 109, 112, 108, + 101, 69, 110, 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 47, 32, 83, 97, 109, + 112, 108, 101, 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 10, 83, 97, 109, 112, 108, 101, + 69, 110, 116, 114, 121, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, + 67, 111, 117, 110, 116, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, 112, 108, 101, 80, + 114, 111, 112, 101, 114, 116, 105, 101, 115, 41, 63, 10, 83, 97, 109, 112, 108, 101, 69, 110, + 116, 114, 121, 70, 117, 110, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 97, 109, 112, 108, + 101, 70, 117, 110, 99, 116, 105, 111, 110, 63, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, + 109, 112, 108, 101, 67, 111, 117, 110, 116, 41, 32, 82, 101, 112, 101, 97, 116, 97, 98, 108, + 101, 83, 97, 109, 112, 108, 101, 63, 10, 83, 97, 109, 112, 108, 101, 70, 117, 110, 99, 116, + 105, 111, 110, 32, 60, 45, 32, 67, 111, 108, 73, 100, 10, 83, 97, 109, 112, 108, 101, 80, + 114, 111, 112, 101, 114, 116, 105, 101, 115, 32, 60, 45, 32, 67, 111, 108, 73, 100, 32, 40, + 39, 44, 39, 32, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 41, 63, 10, 82, 101, 112, + 101, 97, 116, 97, 98, 108, 101, 83, 97, 109, 112, 108, 101, 32, 60, 45, 32, 39, 82, 69, + 80, 69, 65, 84, 65, 66, 76, 69, 39, 32, 80, 97, 114, 101, 110, 115, 40, 83, 97, 109, + 112, 108, 101, 83, 101, 101, 100, 41, 10, 83, 97, 109, 112, 108, 101, 83, 101, 101, 100, 32, + 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 83, 97, 109, + 112, 108, 101, 67, 111, 117, 110, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 86, 97, + 108, 117, 101, 32, 83, 97, 109, 112, 108, 101, 85, 110, 105, 116, 63, 10, 83, 97, 109, 112, + 108, 101, 86, 97, 108, 117, 101, 32, 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, + 101, 114, 97, 108, 32, 47, 32, 80, 97, 114, 97, 109, 101, 116, 101, 114, 10, 83, 97, 109, + 112, 108, 101, 85, 110, 105, 116, 32, 60, 45, 32, 83, 97, 109, 112, 108, 101, 80, 101, 114, + 99, 101, 110, 116, 97, 103, 101, 32, 47, 32, 83, 97, 109, 112, 108, 101, 82, 111, 119, 115, + 10, 83, 97, 109, 112, 108, 101, 80, 101, 114, 99, 101, 110, 116, 97, 103, 101, 32, 60, 45, + 32, 39, 37, 39, 32, 47, 32, 39, 80, 69, 82, 67, 69, 78, 84, 39, 10, 83, 97, 109, + 112, 108, 101, 82, 111, 119, 115, 32, 60, 45, 32, 39, 82, 79, 87, 83, 39, 10, 71, 114, + 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, + 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 47, 32, 71, 114, 111, 117, 112, 66, + 121, 65, 108, 108, 10, 71, 114, 111, 117, 112, 66, 121, 65, 108, 108, 32, 60, 45, 32, 39, + 65, 76, 76, 39, 10, 71, 114, 111, 117, 112, 66, 121, 76, 105, 115, 116, 32, 60, 45, 32, + 76, 105, 115, 116, 40, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 41, 10, 71, 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 32, 60, 45, 32, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, + 101, 109, 32, 47, 32, 67, 117, 98, 101, 79, 114, 82, 111, 108, 108, 117, 112, 67, 108, 97, + 117, 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, 108, + 97, 117, 115, 101, 32, 47, 32, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, 69, 120, + 112, 114, 101, 115, 115, 105, 111, 110, 10, 71, 114, 111, 117, 112, 66, 121, 66, 97, 115, 101, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, + 115, 105, 111, 110, 10, 69, 109, 112, 116, 121, 71, 114, 111, 117, 112, 105, 110, 103, 73, 116, + 101, 109, 32, 60, 45, 32, 39, 40, 39, 32, 39, 41, 39, 10, 67, 117, 98, 101, 79, 114, + 82, 111, 108, 108, 117, 112, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 67, 117, 98, 101, + 79, 114, 82, 111, 108, 108, 117, 112, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, + 40, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 63, 41, 10, 67, 117, 98, 101, 79, + 114, 82, 111, 108, 108, 117, 112, 32, 60, 45, 32, 67, 117, 98, 101, 75, 101, 121, 119, 111, + 114, 100, 32, 47, 32, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 10, 67, + 117, 98, 101, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 67, 85, 66, 69, 39, + 10, 82, 111, 108, 108, 117, 112, 75, 101, 121, 119, 111, 114, 100, 32, 60, 45, 32, 39, 82, + 79, 76, 76, 85, 80, 39, 10, 71, 114, 111, 117, 112, 105, 110, 103, 83, 101, 116, 115, 67, + 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 71, 82, 79, 85, 80, 73, 78, 71, 39, 32, + 39, 83, 69, 84, 83, 39, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 71, + 114, 111, 117, 112, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 41, 10, 83, + 117, 98, 113, 117, 101, 114, 121, 82, 101, 102, 101, 114, 101, 110, 99, 101, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 83, 101, 108, 101, 99, 116, 83, 116, 97, 116, 101, 109, 101, + 110, 116, 73, 110, 116, 101, 114, 110, 97, 108, 41, 10, 79, 114, 100, 101, 114, 66, 121, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, + 105, 111, 110, 32, 68, 101, 115, 99, 79, 114, 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, + 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 63, 10, 68, 101, 115, 99, 79, 114, 65, + 115, 99, 32, 60, 45, 32, 68, 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, + 114, 32, 47, 32, 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 10, 68, + 101, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 68, + 69, 83, 67, 39, 32, 47, 32, 39, 68, 69, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, + 65, 115, 99, 101, 110, 100, 105, 110, 103, 79, 114, 100, 101, 114, 32, 60, 45, 32, 39, 65, + 83, 67, 39, 32, 47, 32, 39, 65, 83, 67, 69, 78, 68, 73, 78, 71, 39, 10, 78, 117, + 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, 116, 32, 60, 45, 32, 78, 117, + 108, 108, 115, 70, 105, 114, 115, 116, 32, 47, 32, 78, 117, 108, 108, 115, 76, 97, 115, 116, + 10, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 32, 60, 45, 32, 39, 78, 85, 76, 76, + 83, 39, 32, 39, 70, 73, 82, 83, 84, 39, 10, 78, 117, 108, 108, 115, 76, 97, 115, 116, + 32, 60, 45, 32, 39, 78, 85, 76, 76, 83, 39, 32, 39, 76, 65, 83, 84, 39, 10, 79, + 114, 100, 101, 114, 66, 121, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 82, 68, + 69, 82, 39, 32, 39, 66, 89, 39, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 115, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, + 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, 79, 114, 100, 101, 114, 66, 121, 65, 108, 108, + 32, 47, 32, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, + 76, 105, 115, 116, 10, 79, 114, 100, 101, 114, 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 79, 114, 100, 101, 114, + 66, 121, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 41, 10, 79, 114, 100, 101, 114, 66, + 121, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 32, 68, 101, 115, 99, 79, 114, + 65, 115, 99, 63, 32, 78, 117, 108, 108, 115, 70, 105, 114, 115, 116, 79, 114, 76, 97, 115, + 116, 63, 10, 76, 105, 109, 105, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 76, + 73, 77, 73, 84, 39, 32, 76, 105, 109, 105, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, + 115, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 39, 79, 70, 70, 83, 69, 84, + 39, 32, 79, 102, 102, 115, 101, 116, 86, 97, 108, 117, 101, 10, 79, 102, 102, 115, 101, 116, + 86, 97, 108, 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, + 82, 111, 119, 79, 114, 82, 111, 119, 115, 63, 10, 82, 111, 119, 79, 114, 82, 111, 119, 115, + 32, 60, 45, 32, 39, 82, 79, 87, 39, 32, 47, 32, 39, 82, 79, 87, 83, 39, 10, 76, + 105, 109, 105, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 76, 105, 109, 105, 116, 65, 108, + 108, 32, 47, 32, 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, + 101, 110, 116, 32, 47, 32, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, 111, + 110, 10, 76, 105, 109, 105, 116, 65, 108, 108, 32, 60, 45, 32, 39, 65, 76, 76, 39, 10, + 76, 105, 109, 105, 116, 76, 105, 116, 101, 114, 97, 108, 80, 101, 114, 99, 101, 110, 116, 32, + 60, 45, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 32, 39, 80, 69, + 82, 67, 69, 78, 84, 39, 10, 76, 105, 109, 105, 116, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 37, 39, + 63, 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 70, 101, 116, + 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 111, 117, 116, 86, 97, 108, 117, 101, + 32, 47, 32, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 86, 97, + 108, 117, 101, 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, 105, 116, 104, 111, + 117, 116, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, 70, + 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, + 32, 39, 79, 78, 76, 89, 39, 10, 70, 101, 116, 99, 104, 67, 108, 97, 117, 115, 101, 87, + 105, 116, 104, 86, 97, 108, 117, 101, 32, 60, 45, 32, 39, 70, 69, 84, 67, 72, 39, 32, + 70, 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 70, 101, 116, 99, 104, 86, 97, 108, + 117, 101, 32, 82, 111, 119, 79, 114, 82, 111, 119, 115, 32, 39, 79, 78, 76, 89, 39, 10, + 70, 105, 114, 115, 116, 79, 114, 78, 101, 120, 116, 32, 60, 45, 32, 39, 70, 73, 82, 83, + 84, 39, 32, 47, 32, 39, 78, 69, 88, 84, 39, 10, 70, 101, 116, 99, 104, 86, 97, 108, + 117, 101, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 65, 108, 105, + 97, 115, 101, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, 45, 32, 67, 111, + 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 47, 32, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, 98, 101, 108, 32, 47, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, 105, + 101, 114, 10, 67, 111, 108, 73, 100, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 60, + 45, 32, 67, 111, 108, 73, 100, 32, 39, 58, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 10, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 65, 115, 67, 111, 108, 108, 97, + 98, 101, 108, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 39, 65, + 83, 39, 32, 67, 111, 108, 76, 97, 98, 101, 108, 79, 114, 83, 116, 114, 105, 110, 103, 10, + 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 79, 112, 116, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 32, 60, 45, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 32, 73, 100, + 101, 110, 116, 105, 102, 105, 101, 114, 63, 10, 86, 97, 108, 117, 101, 115, 67, 108, 97, 117, + 115, 101, 32, 60, 45, 32, 39, 86, 65, 76, 85, 69, 83, 39, 32, 76, 105, 115, 116, 40, + 86, 97, 108, 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 41, 10, 86, + 97, 108, 117, 101, 115, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 115, 32, 60, 45, 32, + 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 69, 120, 112, 114, 101, 115, 115, 105, + 111, 110, 41, 41, 10, 83, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 39, 83, 69, 84, 39, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, + 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, + 109, 101, 110, 116, 79, 114, 84, 105, 109, 101, 90, 111, 110, 101, 32, 60, 45, 32, 83, 101, + 116, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, + 115, 105, 103, 110, 109, 101, 110, 116, 32, 47, 32, 83, 101, 116, 84, 105, 109, 101, 90, 111, + 110, 101, 10, 82, 101, 115, 101, 116, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 39, 82, 69, 83, 69, 84, 39, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, + 79, 114, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 83, 99, 104, 101, 109, 97, 32, + 60, 45, 32, 39, 83, 67, 72, 69, 77, 65, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, + 116, 101, 114, 97, 108, 10, 83, 116, 97, 110, 100, 97, 114, 100, 65, 115, 115, 105, 103, 110, + 109, 101, 110, 116, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, + 114, 83, 101, 116, 116, 105, 110, 103, 32, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, + 110, 116, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 79, 114, 83, 101, 116, 116, + 105, 110, 103, 32, 60, 45, 32, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 47, + 32, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 10, 83, 101, 116, 84, 105, 109, 101, 90, + 111, 110, 101, 32, 60, 45, 32, 39, 84, 73, 77, 69, 39, 32, 39, 90, 79, 78, 69, 39, + 32, 90, 111, 110, 101, 86, 97, 108, 117, 101, 10, 90, 111, 110, 101, 86, 97, 108, 117, 101, + 32, 60, 45, 32, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, 116, 104, + 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 47, 32, 90, 111, 110, 101, 73, 110, 116, 101, + 114, 118, 97, 108, 87, 105, 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, 32, 47, 32, 90, + 111, 110, 101, 76, 111, 99, 97, 108, 32, 47, 32, 90, 111, 110, 101, 68, 101, 102, 97, 117, + 108, 116, 32, 47, 32, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, + 97, 108, 32, 47, 32, 90, 111, 110, 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, + 47, 32, 78, 117, 109, 98, 101, 114, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, 101, + 76, 111, 99, 97, 108, 32, 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, 90, 111, 110, + 101, 68, 101, 102, 97, 117, 108, 116, 32, 60, 45, 32, 39, 68, 69, 70, 65, 85, 76, 84, + 39, 10, 90, 111, 110, 101, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, + 60, 45, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 10, 90, 111, 110, + 101, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 60, 45, 32, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, 108, 87, 105, + 116, 104, 73, 110, 116, 101, 114, 118, 97, 108, 32, 60, 45, 32, 39, 73, 78, 84, 69, 82, + 86, 65, 76, 39, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, 101, 114, 97, 108, 32, 73, + 110, 116, 101, 114, 118, 97, 108, 63, 10, 90, 111, 110, 101, 73, 110, 116, 101, 114, 118, 97, + 108, 87, 105, 116, 104, 80, 114, 101, 99, 105, 115, 105, 111, 110, 32, 60, 45, 32, 39, 73, + 78, 84, 69, 82, 86, 65, 76, 39, 32, 80, 97, 114, 101, 110, 115, 40, 78, 117, 109, 98, + 101, 114, 76, 105, 116, 101, 114, 97, 108, 41, 32, 83, 116, 114, 105, 110, 103, 76, 105, 116, + 101, 114, 97, 108, 10, 83, 101, 116, 83, 101, 116, 116, 105, 110, 103, 32, 60, 45, 32, 83, + 101, 116, 116, 105, 110, 103, 83, 99, 111, 112, 101, 63, 32, 83, 101, 116, 116, 105, 110, 103, + 78, 97, 109, 101, 10, 83, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 32, 60, 45, 32, + 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 73, 100, 101, 110, 116, 105, + 102, 105, 101, 114, 10, 86, 97, 114, 105, 97, 98, 108, 101, 83, 99, 111, 112, 101, 32, 60, + 45, 32, 39, 86, 65, 82, 73, 65, 66, 76, 69, 39, 10, 83, 101, 116, 116, 105, 110, 103, + 83, 99, 111, 112, 101, 32, 60, 45, 32, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, + 47, 32, 83, 101, 115, 115, 105, 111, 110, 83, 99, 111, 112, 101, 32, 47, 32, 71, 108, 111, + 98, 97, 108, 83, 99, 111, 112, 101, 10, 76, 111, 99, 97, 108, 83, 99, 111, 112, 101, 32, + 60, 45, 32, 39, 76, 79, 67, 65, 76, 39, 10, 83, 101, 115, 115, 105, 111, 110, 83, 99, + 111, 112, 101, 32, 60, 45, 32, 39, 83, 69, 83, 83, 73, 79, 78, 39, 10, 71, 108, 111, + 98, 97, 108, 83, 99, 111, 112, 101, 32, 60, 45, 32, 39, 71, 76, 79, 66, 65, 76, 39, + 10, 83, 101, 116, 65, 115, 115, 105, 103, 110, 109, 101, 110, 116, 32, 60, 45, 32, 86, 97, + 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, 32, 86, 97, 114, 105, 97, 98, 108, + 101, 76, 105, 115, 116, 10, 86, 97, 114, 105, 97, 98, 108, 101, 65, 115, 115, 105, 103, 110, + 32, 60, 45, 32, 39, 61, 39, 32, 47, 32, 39, 84, 79, 39, 10, 86, 97, 114, 105, 97, + 98, 108, 101, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 69, 120, 112, 114, + 101, 115, 115, 105, 111, 110, 41, 10, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 83, + 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 66, 101, 103, 105, 110, 84, 114, 97, + 110, 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 82, 111, 108, 108, 98, 97, 99, 107, 84, + 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 47, 32, 67, 111, 109, 109, 105, 116, 84, + 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 10, 66, 101, 103, 105, 110, 84, 114, 97, 110, + 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 83, 116, 97, 114, 116, 79, 114, 66, 101, + 103, 105, 110, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 63, 32, 82, 101, 97, + 100, 79, 114, 87, 114, 105, 116, 101, 63, 10, 82, 111, 108, 108, 98, 97, 99, 107, 84, 114, + 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 65, 98, 111, 114, 116, 79, 114, + 82, 111, 108, 108, 98, 97, 99, 107, 32, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, + 63, 10, 67, 111, 109, 109, 105, 116, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, + 60, 45, 32, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 84, 114, 97, 110, 115, + 97, 99, 116, 105, 111, 110, 63, 10, 83, 116, 97, 114, 116, 79, 114, 66, 101, 103, 105, 110, + 32, 60, 45, 32, 39, 83, 84, 65, 82, 84, 39, 32, 47, 32, 39, 66, 69, 71, 73, 78, + 39, 10, 84, 114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 32, 60, 45, 32, 39, 87, 79, + 82, 75, 39, 32, 47, 32, 39, 84, 82, 65, 78, 83, 65, 67, 84, 73, 79, 78, 39, 10, + 82, 101, 97, 100, 79, 114, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 82, 69, 65, 68, + 39, 32, 82, 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, + 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 79, 114, 82, 101, 97, 100, 87, 114, 105, 116, + 101, 32, 60, 45, 32, 82, 101, 97, 100, 79, 110, 108, 121, 32, 47, 32, 82, 101, 97, 100, + 87, 114, 105, 116, 101, 10, 82, 101, 97, 100, 79, 110, 108, 121, 32, 60, 45, 32, 39, 79, + 78, 76, 89, 39, 10, 82, 101, 97, 100, 87, 114, 105, 116, 101, 32, 60, 45, 32, 39, 87, + 82, 73, 84, 69, 39, 10, 65, 98, 111, 114, 116, 79, 114, 82, 111, 108, 108, 98, 97, 99, + 107, 32, 60, 45, 32, 39, 65, 66, 79, 82, 84, 39, 32, 47, 32, 39, 82, 79, 76, 76, + 66, 65, 67, 75, 39, 10, 67, 111, 109, 109, 105, 116, 79, 114, 69, 110, 100, 32, 60, 45, + 32, 39, 67, 79, 77, 77, 73, 84, 39, 32, 47, 32, 39, 69, 78, 68, 39, 10, 85, 112, + 100, 97, 116, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, 32, 87, 105, 116, + 104, 67, 108, 97, 117, 115, 101, 63, 32, 39, 85, 80, 68, 65, 84, 69, 39, 32, 85, 112, + 100, 97, 116, 101, 84, 97, 114, 103, 101, 116, 32, 85, 112, 100, 97, 116, 101, 83, 101, 116, + 67, 108, 97, 117, 115, 101, 32, 70, 114, 111, 109, 67, 108, 97, 117, 115, 101, 63, 32, 87, + 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 63, 32, 82, 101, 116, 117, 114, 110, 105, 110, + 103, 67, 108, 97, 117, 115, 101, 63, 10, 85, 112, 100, 97, 116, 101, 84, 97, 114, 103, 101, + 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 47, 32, + 66, 97, 115, 101, 84, 97, 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, 116, 10, 66, 97, + 115, 101, 84, 97, 98, 108, 101, 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, 97, + 98, 108, 101, 78, 97, 109, 101, 32, 39, 83, 69, 84, 39, 10, 66, 97, 115, 101, 84, 97, + 98, 108, 101, 65, 108, 105, 97, 115, 83, 101, 116, 32, 60, 45, 32, 66, 97, 115, 101, 84, + 97, 98, 108, 101, 78, 97, 109, 101, 32, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, + 63, 32, 39, 83, 69, 84, 39, 10, 85, 112, 100, 97, 116, 101, 65, 108, 105, 97, 115, 32, + 60, 45, 32, 39, 65, 83, 39, 63, 32, 67, 111, 108, 73, 100, 10, 85, 112, 100, 97, 116, + 101, 83, 101, 116, 67, 108, 97, 117, 115, 101, 32, 60, 45, 32, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 47, 32, 85, 112, 100, + 97, 116, 101, 83, 101, 116, 84, 117, 112, 108, 101, 10, 85, 112, 100, 97, 116, 101, 83, 101, + 116, 84, 117, 112, 108, 101, 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, + 116, 40, 67, 111, 108, 117, 109, 110, 78, 97, 109, 101, 41, 41, 32, 39, 61, 39, 32, 69, + 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, 83, 101, 116, 69, + 108, 101, 109, 101, 110, 116, 76, 105, 115, 116, 32, 60, 45, 32, 76, 105, 115, 116, 40, 85, + 112, 100, 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 41, 10, 85, 112, 100, + 97, 116, 101, 83, 101, 116, 69, 108, 101, 109, 101, 110, 116, 32, 60, 45, 32, 85, 112, 100, + 97, 116, 101, 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 39, + 61, 39, 32, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 10, 85, 112, 100, 97, 116, 101, + 83, 101, 116, 67, 111, 108, 117, 109, 110, 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 67, + 111, 108, 117, 109, 110, 78, 97, 109, 101, 32, 68, 111, 116, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 42, 10, 85, 115, 101, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, 60, 45, + 32, 39, 85, 83, 69, 39, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 10, 85, 115, 101, + 84, 97, 114, 103, 101, 116, 32, 60, 45, 32, 85, 115, 101, 84, 97, 114, 103, 101, 116, 67, + 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 47, 32, 83, 99, 104, 101, 109, + 97, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, 32, 47, 32, 67, + 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, + 116, 10, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, + 103, 101, 116, 32, 60, 45, 32, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 10, 67, 97, + 116, 97, 108, 111, 103, 78, 97, 109, 101, 65, 115, 85, 115, 101, 84, 97, 114, 103, 101, 116, + 32, 60, 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 10, 85, 115, 101, 84, + 97, 114, 103, 101, 116, 67, 97, 116, 97, 108, 111, 103, 83, 99, 104, 101, 109, 97, 32, 60, + 45, 32, 67, 97, 116, 97, 108, 111, 103, 78, 97, 109, 101, 32, 39, 46, 39, 32, 82, 101, + 115, 101, 114, 118, 101, 100, 83, 99, 104, 101, 109, 97, 78, 97, 109, 101, 32, 68, 111, 116, + 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 42, 10, 68, 111, 116, 73, 100, 101, 110, 116, + 105, 102, 105, 101, 114, 32, 60, 45, 32, 39, 46, 39, 32, 73, 100, 101, 110, 116, 105, 102, + 105, 101, 114, 10, 86, 97, 99, 117, 117, 109, 83, 116, 97, 116, 101, 109, 101, 110, 116, 32, + 60, 45, 32, 39, 86, 65, 67, 85, 85, 77, 39, 32, 86, 97, 99, 117, 117, 109, 79, 112, + 116, 105, 111, 110, 115, 63, 32, 65, 110, 97, 108, 121, 122, 101, 84, 97, 114, 103, 101, 116, + 63, 10, 86, 97, 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 86, + 97, 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, 32, 47, + 32, 86, 97, 99, 117, 117, 109, 76, 101, 103, 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, + 10, 86, 97, 99, 117, 117, 109, 80, 97, 114, 101, 110, 115, 79, 112, 116, 105, 111, 110, 115, + 32, 60, 45, 32, 80, 97, 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 86, 97, 99, 117, + 117, 109, 79, 112, 116, 105, 111, 110, 41, 41, 10, 86, 97, 99, 117, 117, 109, 76, 101, 103, + 97, 99, 121, 79, 112, 116, 105, 111, 110, 115, 32, 60, 45, 32, 79, 112, 116, 70, 117, 108, + 108, 63, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, 63, 32, 79, 112, 116, 86, 101, 114, + 98, 111, 115, 101, 63, 32, 79, 112, 116, 65, 110, 97, 108, 121, 122, 101, 63, 10, 86, 97, + 99, 117, 117, 109, 79, 112, 116, 105, 111, 110, 32, 60, 45, 32, 79, 112, 116, 65, 110, 97, + 108, 121, 122, 101, 32, 47, 32, 79, 112, 116, 70, 114, 101, 101, 122, 101, 32, 47, 32, 79, + 112, 116, 70, 117, 108, 108, 32, 47, 32, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, + 47, 32, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 10, 79, 112, 116, 65, 110, 97, 108, + 121, 122, 101, 32, 60, 45, 32, 65, 110, 97, 108, 121, 122, 101, 75, 101, 121, 119, 111, 114, + 100, 10, 79, 112, 116, 70, 117, 108, 108, 32, 60, 45, 32, 39, 70, 85, 76, 76, 39, 10, + 79, 112, 116, 70, 114, 101, 101, 122, 101, 32, 60, 45, 32, 39, 70, 82, 69, 69, 90, 69, + 39, 10, 79, 112, 116, 86, 101, 114, 98, 111, 115, 101, 32, 60, 45, 32, 39, 86, 69, 82, + 66, 79, 83, 69, 39, 10, 78, 97, 109, 101, 76, 105, 115, 116, 32, 60, 45, 32, 80, 97, + 114, 101, 110, 115, 40, 76, 105, 115, 116, 40, 67, 111, 108, 73, 100, 79, 114, 83, 116, 114, + 105, 110, 103, 41, 41, 10, 0, }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp index 639eeb6f2..512b7352a 100644 --- a/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp +++ b/src/duckdb/src/include/duckdb/parser/peg/transformer/peg_transformer.hpp @@ -2747,6 +2747,9 @@ class PEGTransformerFactory { static void InitializeBitOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeBitOperatorTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static void InitializeTildeExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); + static unique_ptr FinalizeTildeExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process); static void InitializeAdditiveExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); static unique_ptr FinalizeAdditiveExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process); @@ -5071,10 +5074,13 @@ class PEGTransformerFactory { const optional> &col_id_dot, const string &any_operator_literal); static unique_ptr - TransformBitwiseExpression(PEGTransformer &transformer, unique_ptr additive_expression, + TransformBitwiseExpression(PEGTransformer &transformer, unique_ptr tilde_expression, optional> bitwise_expression_tail); static BinaryExpressionTail TransformBitwiseExpressionTail(PEGTransformer &transformer, const string &bit_operator, - unique_ptr additive_expression); + unique_ptr tilde_expression); + static unique_ptr TransformTildeExpression(PEGTransformer &transformer, + optional> tilde_prefix_operator, + unique_ptr additive_expression); static unique_ptr TransformAdditiveExpression(PEGTransformer &transformer, unique_ptr multiplicative_expression, optional> additive_expression_tail); diff --git a/src/duckdb/src/include/duckdb/storage/checkpoint/string_checkpoint_state.hpp b/src/duckdb/src/include/duckdb/storage/checkpoint/string_checkpoint_state.hpp index a598e74a9..594ad9112 100644 --- a/src/duckdb/src/include/duckdb/storage/checkpoint/string_checkpoint_state.hpp +++ b/src/duckdb/src/include/duckdb/storage/checkpoint/string_checkpoint_state.hpp @@ -9,6 +9,7 @@ #pragma once #include "duckdb/common/common.hpp" +#include "duckdb/common/unordered_set.hpp" #include "duckdb/storage/storage_info.hpp" #include "duckdb/storage/buffer/block_handle.hpp" #include "duckdb/function/compression_function.hpp" @@ -45,10 +46,15 @@ struct UncompressedStringSegmentState : public CompressedSegmentState { unique_ptr overflow_writer; //! The block manager with which to write optional_ptr block_manager; - //! The set of overflow blocks written to disk (if any) - vector on_disk_blocks; public: + void InitializeOnDiskBlocks(vector blocks); + + const vector &GetOnDiskBlocks() const { + D_ASSERT(on_disk_blocks.size() == on_disk_block_set.size()); + return on_disk_blocks; + } + shared_ptr GetHandle(BlockManager &manager, block_id_t block_id); void RegisterBlock(BlockManager &manager, block_id_t block_id); @@ -59,6 +65,11 @@ struct UncompressedStringSegmentState : public CompressedSegmentState { reference FindOverflowBlock(block_id_t block_id); private: + //! Overflow block IDs in write order, preserved for serialization. + vector on_disk_blocks; + //! Membership index for on_disk_blocks. + unordered_set on_disk_block_set; + mutex block_lock; unordered_map> handles; diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/bit_reader.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/bit_reader.hpp index 901fb0e68..28f943c21 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/bit_reader.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/bit_reader.hpp @@ -8,6 +8,9 @@ #pragma once +#include "duckdb/common/array_ptr.hpp" +#include "duckdb/common/assert.hpp" +#include "duckdb/common/likely.hpp" #include "duckdb/common/numeric_utils.hpp" namespace duckdb { @@ -51,28 +54,41 @@ struct BitReader { }; public: -public: - BitReader() : input(nullptr), index(0) { + explicit BitReader(unsafe_array_ptr input, uint8_t bit_offset = 0) + : input(input), index(bit_offset) { + D_ASSERT(bit_offset < 8); } - uint8_t *input; - uint32_t index; -public: - void SetStream(uint8_t *input) { - this->input = input; - index = 0; + template + inline T ReadValue() { + static_assert(SIZE <= sizeof(T) * 8, "Bit width exceeds the result type"); + constexpr uint8_t BYTES = (SIZE >> 3); + constexpr uint8_t REMAINDER = (SIZE & 7); + return ReadBytes(REMAINDER); + } + + template + inline T ReadValue(const uint8_t &size) { + D_ASSERT(size <= sizeof(T) * 8); + const uint8_t bytes = size >> 3; // divide by 8; + const uint8_t remainder = size & 7; + return ReadBytes(bytes, remainder); } +private: inline uint8_t BitIndex() const { return (index & 7); } - inline uint64_t ByteIndex() const { + inline idx_t ByteIndex() const { return (index >> 3); } inline uint8_t InnerReadByte(const uint8_t &offset) { - uint8_t result = static_cast(input[ByteIndex() + offset] << BitIndex()) | - ((input[ByteIndex() + offset + 1] & REMAINDER_MASKS[8 + BitIndex()]) >> (8 - BitIndex())); + const auto bit_index = BitIndex(); + const bool spill_to_next_byte = bit_index != 0; + uint8_t result = + static_cast(input[ByteIndex() + offset] << bit_index) | + ((input[ByteIndex() + offset + spill_to_next_byte] & REMAINDER_MASKS[8 + bit_index]) >> (8 - bit_index)); return result; } @@ -96,14 +112,14 @@ struct BitReader { // Right-shift this result (the most significant bits) // Sometimes we will need to read from the second byte - // But to make this branchless, we will perform what is basically a no-op if this condition is not true - // SPILL = (index + size >= 8) + // But to make this branchless, we will read from the current byte as a no-op if this condition is not true + // SPILL = (index + size > 8) // // If SPILL is true: // The REMAINDER_MASKS gives us the mask for the bits we're interested in // We bit-wise AND these together (no need to shift anything because the index is essentially zero for this new // byte) And we then right-shift these bits in place (to the right of the previous bits) - const bool spill_to_next_byte = (size + BitIndex() >= 8); + const bool spill_to_next_byte = (size + BitIndex() > 8); uint8_t result = ((input[ByteIndex() + offset] << BitIndex()) & MASKS[size]) >> right_shift | ((input[ByteIndex() + offset + spill_to_next_byte] & REMAINDER_MASKS[size + BitIndex()]) >> bit_remainder); @@ -137,7 +153,9 @@ struct BitReader { if (BYTES > 7) { result = UnsafeNumericCast(result << 8 | InnerReadByte(7)); } - result = UnsafeNumericCast(result << remainder | InnerRead(remainder, BYTES)); + if (remainder > 0) { + result = UnsafeNumericCast(result << remainder | InnerRead(remainder, BYTES)); + } index += (BYTES << 3) + remainder; return result; } @@ -148,24 +166,15 @@ struct BitReader { for (uint8_t i = 0; i < bytes; i++) { result = result << 8 | InnerReadByte(i); } - result = result << remainder | InnerRead(remainder, bytes); - index += static_cast(bytes << 3) + remainder; + if (DUCKDB_LIKELY(remainder > 0)) { + result = result << remainder | InnerRead(remainder, bytes); + } + index += static_cast(bytes << 3) + remainder; return result; } - template - inline T ReadValue() { - constexpr uint8_t BYTES = (SIZE >> 3); - constexpr uint8_t REMAINDER = (SIZE & 7); - return ReadBytes(REMAINDER); - } - - template - inline T ReadValue(const uint8_t &size) { - const uint8_t bytes = size >> 3; // divide by 8; - const uint8_t remainder = size & 7; - return ReadBytes(bytes, remainder); - } + unsafe_array_ptr input; + idx_t index; }; } // namespace duckdb diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/chimp128.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/chimp128.hpp index 4dc8aaff4..6985a86e7 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/chimp128.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/chimp128.hpp @@ -207,7 +207,6 @@ struct Chimp128DecompressionState { return trailing_zeros; } - BitReader input; uint8_t leading_zeros; uint8_t trailing_zeros; CHIMP_TYPE reference_value = 0; @@ -229,16 +228,18 @@ struct Chimp128Decompression { } static inline CHIMP_TYPE Load(ChimpConstants::Flags flag, uint8_t leading_zeros[], uint32_t &leading_zero_index, - UnpackedData unpacked_data[], uint32_t &unpacked_index, DecompressState &state) { + UnpackedData unpacked_data[], uint32_t &unpacked_index, DecompressState &state, + BitReader &input) { if (DUCKDB_UNLIKELY(state.first)) { - return LoadFirst(state); + return LoadFirst(state, input); } else { - return DecompressValue(flag, leading_zeros, leading_zero_index, unpacked_data, unpacked_index, state); + return DecompressValue(flag, leading_zeros, leading_zero_index, unpacked_data, unpacked_index, state, + input); } } - static inline CHIMP_TYPE LoadFirst(DecompressState &state) { - CHIMP_TYPE result = state.input.template ReadValue(); + static inline CHIMP_TYPE LoadFirst(DecompressState &state, BitReader &input) { + CHIMP_TYPE result = input.ReadValue(); state.ring_buffer.template InsertScan(result); state.first = false; state.reference_value = result; @@ -247,12 +248,12 @@ struct Chimp128Decompression { static inline CHIMP_TYPE DecompressValue(ChimpConstants::Flags flag, uint8_t leading_zeros[], uint32_t &leading_zero_index, UnpackedData unpacked_data[], - uint32_t &unpacked_index, DecompressState &state) { + uint32_t &unpacked_index, DecompressState &state, BitReader &input) { CHIMP_TYPE result; switch (flag) { case ChimpConstants::Flags::VALUE_IDENTICAL: { //! Value is identical to previous value - auto index = state.input.template ReadValue(); + auto index = input.ReadValue(); result = UnsafeNumericCast(state.ring_buffer.Value(index)); break; } @@ -260,20 +261,20 @@ struct Chimp128Decompression { const UnpackedData &unpacked = unpacked_data[unpacked_index++]; state.leading_zeros = unpacked.leading_zero; state.trailing_zeros = BIT_SIZE - unpacked.significant_bits - state.leading_zeros; - result = state.input.template ReadValue(unpacked.significant_bits); + result = input.ReadValue(unpacked.significant_bits); result <<= state.trailing_zeros; result ^= state.ring_buffer.Value(unpacked.index); break; } case ChimpConstants::Flags::LEADING_ZERO_EQUALITY: { - result = state.input.template ReadValue(BIT_SIZE - state.leading_zeros); + result = input.ReadValue(BIT_SIZE - state.leading_zeros); result ^= state.reference_value; break; } case ChimpConstants::Flags::LEADING_ZERO_LOAD: { state.leading_zeros = leading_zeros[leading_zero_index++]; D_ASSERT(state.leading_zeros <= BIT_SIZE); - result = state.input.template ReadValue(BIT_SIZE - state.leading_zeros); + result = input.ReadValue(BIT_SIZE - state.leading_zeros); result ^= state.reference_value; break; } diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/flag_buffer.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/flag_buffer.hpp index a31eac7ad..fd193e9b8 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/flag_buffer.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/flag_buffer.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/array_ptr.hpp" #include "duckdb/storage/compression/chimp/algorithm/chimp_utils.hpp" #ifdef DEBUG #include "duckdb/common/vector.hpp" @@ -34,12 +35,13 @@ struct FlagBufferConstants { template class FlagBuffer { public: - FlagBuffer() : counter(0), buffer(nullptr) { + explicit FlagBuffer(unsafe_array_ptr buffer) + : counter(0), read_buffer(buffer), write_buffer(nullptr) { } public: void SetBuffer(uint8_t *buffer) { - this->buffer = buffer; + write_buffer = buffer; this->counter = 0; } void Reset() { @@ -63,7 +65,7 @@ class FlagBuffer { if (!EMPTY) { if ((counter & 3) == 0) { // Start the new byte fresh - buffer[counter >> 2] = 0; + write_buffer[counter >> 2] = 0; #ifdef DEBUG flags.clear(); #endif @@ -71,16 +73,16 @@ class FlagBuffer { #ifdef DEBUG flags.push_back((uint8_t)value); #endif - buffer[counter >> 2] |= (((uint8_t)value & 3) << FlagBufferConstants::SHIFTS[counter & 3]); + write_buffer[counter >> 2] |= (((uint8_t)value & 3) << FlagBufferConstants::SHIFTS[counter & 3]); #ifdef DEBUG // Verify that the bits are serialized correctly - D_ASSERT(flags[counter & 3] == ExtractValue(buffer[counter >> 2], counter & 3)); + D_ASSERT(flags[counter & 3] == ExtractValue(write_buffer[counter >> 2], counter & 3)); #endif } counter++; } inline uint8_t Extract() { - const uint8_t result = (buffer[counter >> 2] & FlagBufferConstants::MASKS[counter & 3]) >> + const uint8_t result = (read_buffer[counter >> 2] & FlagBufferConstants::MASKS[counter & 3]) >> FlagBufferConstants::SHIFTS[counter & 3]; counter++; return result; @@ -97,7 +99,8 @@ class FlagBuffer { private: private: uint32_t counter = 0; - uint8_t *buffer; + unsafe_array_ptr read_buffer; + uint8_t *write_buffer; #ifdef DEBUG vector flags; #endif diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/leading_zero_buffer.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/leading_zero_buffer.hpp index 04dc130a7..b1f3aead8 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/leading_zero_buffer.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/leading_zero_buffer.hpp @@ -8,6 +8,7 @@ #pragma once +#include "duckdb/common/array_ptr.hpp" #include "duckdb/common/helper.hpp" #include "duckdb/common/numeric_utils.hpp" #ifdef DEBUG @@ -47,25 +48,16 @@ class LeadingZeroBuffer { static constexpr uint32_t MAX_LEADING_ZERO_BLOCKS = CHIMP_GROUP_SIZE / LEADING_ZERO_BLOCK_SIZE; static constexpr uint32_t MAX_BITS_USED_BY_ZERO_BLOCKS = MAX_LEADING_ZERO_BLOCKS * LEADING_ZERO_BLOCK_BIT_SIZE; static constexpr uint32_t MAX_BYTES_USED_BY_ZERO_BLOCKS = MAX_BITS_USED_BY_ZERO_BLOCKS / 8; - - // Add an extra byte to prevent heap buffer overflow on the last group, because we'll be addressing 4 bytes each - static constexpr uint32_t BUFFER_SIZE = - MAX_BYTES_USED_BY_ZERO_BLOCKS + (sizeof(uint32_t) - (LEADING_ZERO_BLOCK_BIT_SIZE / 8)); - - template - const T Load(const uint8_t *ptr) { - T ret; - memcpy(&ret, ptr, sizeof(ret)); - return ret; - } + static constexpr uint32_t BUFFER_SIZE = MAX_BYTES_USED_BY_ZERO_BLOCKS; public: - LeadingZeroBuffer() : current(0), counter(0), buffer(nullptr) { + explicit LeadingZeroBuffer(unsafe_array_ptr buffer) + : current(0), counter(0), read_buffer(buffer), write_buffer(nullptr) { } void SetBuffer(uint8_t *buffer) { // Set the internal buffer, when inserting this should be BUFFER_SIZE bytes in length // This buffer does not need to be zero-initialized for inserting - this->buffer = buffer; + write_buffer = buffer; this->counter = 0; } void Flush() { @@ -104,12 +96,12 @@ class LeadingZeroBuffer { return; } const auto buffer_idx = BlockIndex(); - memcpy((void *)(buffer + buffer_idx), (uint8_t *)¤t, 3); + memcpy((void *)(write_buffer + buffer_idx), (uint8_t *)¤t, 3); #ifdef DEBUG // Verify that the bits are copied correctly uint32_t temp_value = 0; - memcpy(reinterpret_cast(&temp_value), (void *)(buffer + buffer_idx), 3); + memcpy(reinterpret_cast(&temp_value), (void *)(write_buffer + buffer_idx), 3); for (idx_t i = 0; i < flags.size(); i++) { D_ASSERT(flags[i] == ExtractValue(temp_value, i)); } @@ -138,7 +130,8 @@ class LeadingZeroBuffer { inline uint8_t Extract() { const auto buffer_idx = BlockIndex(); - auto const temp = Load(buffer + buffer_idx); + uint32_t temp = 0; + memcpy(&temp, read_buffer.data() + buffer_idx, 3); const uint8_t result = UnsafeNumericCast((temp & LeadingZeroBufferConstants::MASKS[counter & 7]) >> LeadingZeroBufferConstants::SHIFTS[counter & 7]); @@ -156,7 +149,8 @@ class LeadingZeroBuffer { private: uint32_t current; uint32_t counter = 0; // block_index * 8 - uint8_t *buffer; + unsafe_array_ptr read_buffer; + uint8_t *write_buffer; #ifdef DEBUG vector flags; #endif diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/packed_data.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/packed_data.hpp index b2d432d5d..eaa896852 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/packed_data.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/packed_data.hpp @@ -39,10 +39,17 @@ struct PackedDataUtils { // IIIIIII //! Index (7 bits, shifted by 9) // LLL //! LeadingZeros (3 bits, shifted by 6) // SSSSSS //! SignificantBits (6 bits) + static inline UnpackedData Unpack(uint16_t packed_data) { + UnpackedData result; + result.index = packed_data >> INDEX_SHIFT_AMOUNT & INDEX_MASK; + result.leading_zero = packed_data >> LEADING_SHIFT_AMOUNT & LEADING_MASK; + result.significant_bits = packed_data & SignificantBits::mask; + return result; + } + + // FIXME: remove once chimp has been moved over to the above. static inline void Unpack(uint16_t packed_data, UnpackedData &dest) { - dest.index = packed_data >> INDEX_SHIFT_AMOUNT & INDEX_MASK; - dest.leading_zero = packed_data >> LEADING_SHIFT_AMOUNT & LEADING_MASK; - dest.significant_bits = packed_data & SignificantBits::mask; + dest = Unpack(packed_data); // Verify that combined, this is not bigger than the full size of the type D_ASSERT(dest.significant_bits + dest.leading_zero <= (sizeof(CHIMP_TYPE) * 8)); } diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp.hpp index 85bcb6ea3..70653c998 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp.hpp @@ -29,9 +29,11 @@ struct ChimpType { class ChimpPrimitives { public: + using METADATA_POINTER_TYPE = uint32_t; + static constexpr uint32_t CHIMP_SEQUENCE_SIZE = 1024; static constexpr uint8_t MAX_BYTES_PER_VALUE = sizeof(double) + 1; // extra wiggle room - static constexpr uint8_t HEADER_SIZE = sizeof(uint32_t); + static constexpr uint8_t HEADER_SIZE = sizeof(METADATA_POINTER_TYPE); static constexpr uint8_t FLAG_BIT_SIZE = 2; static constexpr uint32_t LEADING_ZERO_BLOCK_BUFFERSIZE = 1 + (CHIMP_SEQUENCE_SIZE / 8) * 3; }; diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_fetch.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_fetch.hpp index e52089b10..6898f1ebb 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_fetch.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_fetch.hpp @@ -19,8 +19,12 @@ namespace duckdb { template void ChimpFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) { using INTERNAL_TYPE = typename ChimpType::TYPE; + D_ASSERT(row_id >= 0); + D_ASSERT(UnsafeNumericCast(row_id) < segment.count); - ChimpScanState scan_state(segment); + auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); + auto handle = buffer_manager.Pin(state.context, segment.GetBlockHandle()); + ChimpScanState scan_state(std::move(handle), segment); scan_state.Skip(segment, UnsafeNumericCast(row_id)); auto result_data = FlatVector::GetDataMutableUnsafe(result); diff --git a/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_scan.hpp b/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_scan.hpp index 2e87685bd..829b00981 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_scan.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_scan.hpp @@ -16,6 +16,7 @@ #include "duckdb/common/vector/flat_vector.hpp" #include "duckdb/function/compression_function.hpp" #include "duckdb/storage/buffer_manager.hpp" +#include "duckdb/storage/compression/compression_segment_reader.hpp" #include "duckdb/storage/table/column_segment.hpp" @@ -25,14 +26,15 @@ namespace duckdb { +[[noreturn]] void ThrowChimpMetadataBeforeHeader(); +[[noreturn]] void ThrowChimpLeadingZeroBlockCountOutOfBounds(uint8_t block_count); +[[noreturn]] void ThrowChimpLeadingZeroCountMismatch(idx_t stored_count, idx_t required_count); +[[noreturn]] void ThrowChimpPackedDataExceedsType(uint8_t leading_zero, uint8_t significant_bits, idx_t bit_width); +[[noreturn]] void ThrowChimpLeadingZeroStateMissing(); + template struct ChimpGroupState { public: - void Init(uint8_t *data) { - chimp_state.input.SetStream(data); - Reset(); - } - void Reset() { chimp_state.Reset(); index = 0; @@ -52,33 +54,22 @@ struct ChimpGroupState { index += count; } - void LoadFlags(uint8_t *packed_data, idx_t group_size) { - FlagBuffer flag_buffer; - flag_buffer.SetBuffer(packed_data); + void LoadFlags(unsafe_array_ptr packed_data, idx_t group_size) { + FlagBuffer flag_buffer(packed_data); flags[0] = ChimpConstants::Flags::VALUE_IDENTICAL; // First value doesn't require a flag for (idx_t i = 0; i < group_size; i++) { - flags[1 + i] = (ChimpConstants::Flags)flag_buffer.Extract(); + flags[1 + i] = static_cast(flag_buffer.Extract()); } max_flags_to_read = group_size; index = 0; } - void LoadLeadingZeros(uint8_t *packed_data, idx_t leading_zero_block_size) { -#ifdef DEBUG - idx_t flag_one_count = 0; - for (idx_t i = 0; i < max_flags_to_read; i++) { - flag_one_count += flags[1 + i] == ChimpConstants::Flags::LEADING_ZERO_LOAD; - } - // There are 8 leading zero values packed in one block, the block could be partially filled - flag_one_count = AlignValue(flag_one_count); - D_ASSERT(flag_one_count == leading_zero_block_size); -#endif - LeadingZeroBuffer leading_zero_buffer; - leading_zero_buffer.SetBuffer(packed_data); - for (idx_t i = 0; i < leading_zero_block_size; i++) { + void LoadLeadingZeros(unsafe_array_ptr packed_data, idx_t leading_zero_count) { + LeadingZeroBuffer leading_zero_buffer(packed_data); + for (idx_t i = 0; i < leading_zero_count; i++) { leading_zeros[i] = ChimpConstants::Decompression::LEADING_REPRESENTATION[leading_zero_buffer.Extract()]; } - max_leading_zeros_to_read = leading_zero_block_size; + max_leading_zeros_to_read = leading_zero_count; leading_zero_index = 0; } @@ -90,23 +81,80 @@ struct ChimpGroupState { return count; } - void LoadPackedData(uint16_t *packed_data, idx_t packed_data_block_count) { + idx_t CalculateLeadingZeroCount() const { + idx_t count = 0; + for (idx_t i = 0; i < max_flags_to_read; i++) { + count += flags[1 + i] == ChimpConstants::Flags::LEADING_ZERO_LOAD; + } + return AlignValue(count); + } + + void LoadPackedData(unsafe_array_ptr packed_data) { + auto packed_data_block_count = packed_data.size(); for (idx_t i = 0; i < packed_data_block_count; i++) { - PackedDataUtils::Unpack(packed_data[i], unpacked_data_blocks[i]); - if (unpacked_data_blocks[i].significant_bits == 0) { - unpacked_data_blocks[i].significant_bits = 64; + auto unpacked = PackedDataUtils::Unpack(packed_data[i]); + if (unpacked.significant_bits == 0) { + unpacked.significant_bits = 64; } - unpacked_data_blocks[i].leading_zero = - ChimpConstants::Decompression::LEADING_REPRESENTATION[unpacked_data_blocks[i].leading_zero]; + unpacked.leading_zero = ChimpConstants::Decompression::LEADING_REPRESENTATION[unpacked.leading_zero]; + unpacked_data_blocks[i] = unpacked; } unpacked_index = 0; max_packed_data_to_read = packed_data_block_count; } - void LoadValues(CHIMP_TYPE *result, idx_t count) { + // Count how many bits the decoder should read based on the metadata. + // LoadGroup checks the resulting range through CompressionSegmentReader before the BitReader reads any values. + idx_t ValidateAndCalculateDataBitCount(idx_t group_size) const { + using Decompression = Chimp128Decompression; + D_ASSERT(group_size == max_flags_to_read + 1); + + // The first value is stored at full width and has no flag. + idx_t data_bit_count = Decompression::BIT_SIZE; + idx_t leading_zero_position = 0; + idx_t packed_data_position = 0; + uint8_t leading_zero = NumericLimits::Maximum(); + for (idx_t i = 1; i < group_size; i++) { + switch (flags[i]) { + case ChimpConstants::Flags::VALUE_IDENTICAL: + // Identical values still read a ring-buffer index from the bitstream. + data_bit_count += Decompression::INDEX_BITS_SIZE; + break; + case ChimpConstants::Flags::TRAILING_EXCEEDS_THRESHOLD: { + D_ASSERT(packed_data_position < max_packed_data_to_read); + auto &unpacked = unpacked_data_blocks[packed_data_position++]; + // The decoder derives its left shift as BIT_SIZE - significant_bits - leading_zero. + if (unpacked.leading_zero > Decompression::BIT_SIZE || + unpacked.significant_bits > Decompression::BIT_SIZE - unpacked.leading_zero) { + ThrowChimpPackedDataExceedsType(unpacked.leading_zero, unpacked.significant_bits, + Decompression::BIT_SIZE); + } + leading_zero = unpacked.leading_zero; + data_bit_count += unpacked.significant_bits; + break; + } + case ChimpConstants::Flags::LEADING_ZERO_EQUALITY: + // Equality reuses the decoder's leading-zero count, the initial value of 255 is invalid. + if (leading_zero > Decompression::BIT_SIZE) { + ThrowChimpLeadingZeroStateMissing(); + } + data_bit_count += Decompression::BIT_SIZE - leading_zero; + break; + case ChimpConstants::Flags::LEADING_ZERO_LOAD: + D_ASSERT(leading_zero_position < max_leading_zeros_to_read); + leading_zero = leading_zeros[leading_zero_position++]; + data_bit_count += Decompression::BIT_SIZE - leading_zero; + break; + } + } + D_ASSERT(packed_data_position == max_packed_data_to_read); + return data_bit_count; + } + + void LoadValues(BitReader &input, CHIMP_TYPE *result, idx_t count) { for (idx_t i = 0; i < count; i++) { - result[i] = Chimp128Decompression::Load(flags[i], leading_zeros, leading_zero_index, - unpacked_data_blocks, unpacked_index, chimp_state); + result[i] = Chimp128Decompression::Load( + flags[i], leading_zeros, leading_zero_index, unpacked_data_blocks, unpacked_index, chimp_state, input); } } @@ -121,7 +169,7 @@ struct ChimpGroupState { CHIMP_TYPE values[ChimpPrimitives::CHIMP_SEQUENCE_SIZE]; private: - idx_t index; + idx_t index = 0; idx_t max_leading_zeros_to_read; idx_t max_flags_to_read; idx_t max_packed_data_to_read; @@ -133,22 +181,23 @@ struct ChimpScanState : public SegmentScanState { public: using CHIMP_TYPE = typename ChimpType::TYPE; - explicit ChimpScanState(ColumnSegment &segment) : segment(segment), segment_count(segment.count) { - auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); - - handle = buffer_manager.Pin(segment.GetBlockHandle()); - auto dataptr = handle.GetDataMutable(); - // ScanStates never exceed the boundaries of a Segment, - // but are not guaranteed to start at the beginning of the Block - auto start_of_data_segment = dataptr + segment.GetBlockOffset() + ChimpPrimitives::HEADER_SIZE; - group_state.Init(start_of_data_segment); - auto metadata_offset = Load(dataptr + segment.GetBlockOffset()); - metadata_ptr = dataptr + segment.GetBlockOffset() + metadata_offset; + explicit ChimpScanState(BufferHandle handle_p, ColumnSegment &segment) + : handle(std::move(handle_p)), + metadata(CompressionSegmentReader::FromSegment(handle, segment, "Chimp segment")), segment(segment), + segment_count(segment.count) { + auto metadata_end = metadata.template Read(); + if (metadata_end < ChimpPrimitives::HEADER_SIZE) { + ThrowChimpMetadataBeforeHeader(); + } + metadata = metadata.GetSubReader(0, metadata_end, "Chimp segment"); + + metadata.SetPosition(metadata_end); } BufferHandle handle; - data_ptr_t metadata_ptr; + CompressionSegmentReader metadata; idx_t total_value_count = 0; + idx_t data_bit_position = 0; ChimpGroupState group_state; ColumnSegment &segment; @@ -181,25 +230,24 @@ struct ChimpScanState : public SegmentScanState { } void LoadGroup(CHIMP_TYPE *value_buffer) { + D_ASSERT(GroupFinished()); + D_ASSERT(total_value_count < segment_count); + //! FIXME: If we change the order of this to flag -> leading_zero_blocks -> packed_data //! We can leave out the leading zero block count as well, because it can be derived from //! Extracting all the flags and counting the 3's - // Load the offset indicating where a groups data starts - metadata_ptr -= sizeof(uint32_t); - auto data_byte_offset = Load(metadata_ptr); - D_ASSERT(data_byte_offset < segment.GetBlockSize()); - // Only used for point queries - (void)data_byte_offset; + // The stored group data offset is unused by scan and fetch + (void)metadata.ReadBackward(); // Load how many blocks of leading zero bits we have - metadata_ptr -= sizeof(uint8_t); - auto leading_zero_block_count = Load(metadata_ptr); - D_ASSERT(leading_zero_block_count <= ChimpPrimitives::CHIMP_SEQUENCE_SIZE / 8); + auto leading_zero_block_count = metadata.ReadBackward(); + if (leading_zero_block_count > ChimpPrimitives::CHIMP_SEQUENCE_SIZE / 8) { + ThrowChimpLeadingZeroBlockCountOutOfBounds(leading_zero_block_count); + } - // Load the leading zero block count - metadata_ptr -= 3ULL * leading_zero_block_count; - const auto leading_zero_block_ptr = metadata_ptr; + // Load the leading zero blocks + auto leading_zero_blocks = metadata.ReadBytesBackward(3ULL * leading_zero_block_count); // Figure out how many flags there are D_ASSERT(segment_count >= total_value_count); @@ -209,26 +257,37 @@ struct ChimpScanState : public SegmentScanState { uint16_t flag_byte_count = AlignValue(UnsafeNumericCast(flag_count)) / 4; // Load the flags - metadata_ptr -= flag_byte_count; - auto flags = metadata_ptr; + auto flags = metadata.ReadBytesBackward(flag_byte_count); group_state.LoadFlags(flags, flag_count); // Load the leading zero blocks - group_state.LoadLeadingZeros(leading_zero_block_ptr, (uint32_t)leading_zero_block_count * 8); + auto leading_zero_count = static_cast(leading_zero_block_count) * 8; + auto required_leading_zero_count = group_state.CalculateLeadingZeroCount(); + if (leading_zero_count != required_leading_zero_count) { + ThrowChimpLeadingZeroCountMismatch(leading_zero_count, required_leading_zero_count); + } + group_state.LoadLeadingZeros(leading_zero_blocks, leading_zero_count); // Load packed data blocks auto packed_data_block_count = group_state.CalculatePackedDataCount(); - metadata_ptr -= packed_data_block_count * 2; - if ((uint64_t)metadata_ptr & 1) { - // Align on a two-byte boundary - metadata_ptr--; - } - group_state.LoadPackedData((uint16_t *)metadata_ptr, packed_data_block_count); - + // Align (backwards) on a two-byte boundary + metadata.AlignBackward(sizeof(uint16_t)); + auto packed_data = metadata.ReadArrayBackward(packed_data_block_count); + group_state.LoadPackedData(packed_data); + + // Validate the full group data range before using the unchecked bit reader + auto data_bit_count = group_state.ValidateAndCalculateDataBitCount(group_size); + auto bit_offset = UnsafeNumericCast(data_bit_position & 7); + auto data_byte_position = data_bit_position >> 3; + auto data_byte_count = (static_cast(bit_offset) + data_bit_count + 7) / 8; + auto data = metadata.GetSubReader(ChimpPrimitives::HEADER_SIZE, metadata.Size() - ChimpPrimitives::HEADER_SIZE, + "Chimp data"); + BitReader input(data.GetBytes(data_byte_position, data_byte_count), bit_offset); group_state.Reset(); // Load all values for the group - group_state.LoadValues(value_buffer, group_size); + group_state.LoadValues(input, value_buffer, group_size); + data_bit_position += data_bit_count; } public: @@ -237,6 +296,8 @@ struct ChimpScanState : public SegmentScanState { void Skip(ColumnSegment &segment, idx_t skip_count) { using INTERNAL_TYPE = typename ChimpType::TYPE; INTERNAL_TYPE buffer[ChimpPrimitives::CHIMP_SEQUENCE_SIZE]; + D_ASSERT(total_value_count <= segment_count); + D_ASSERT(skip_count <= segment_count - total_value_count); while (skip_count) { auto skip_size = MinValue(skip_count, LeftInGroup()); @@ -248,7 +309,9 @@ struct ChimpScanState : public SegmentScanState { template unique_ptr ChimpInitScan(const QueryContext &context, ColumnSegment &segment) { - auto result = make_uniq_base>(segment); + auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); + auto handle = buffer_manager.Pin(context, segment.GetBlockHandle()); + auto result = make_uniq_base>(std::move(handle), segment); return result; } @@ -260,6 +323,8 @@ void ChimpScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t scan idx_t result_offset) { using INTERNAL_TYPE = typename ChimpType::TYPE; auto &scan_state = state.scan_state->Cast>(); + D_ASSERT(scan_state.total_value_count <= scan_state.segment_count); + D_ASSERT(scan_count <= scan_state.segment_count - scan_state.total_value_count); T *result_data = FlatVector::GetDataMutable(result); result.SetVectorType(VectorType::FLAT_VECTOR); diff --git a/src/duckdb/src/include/duckdb/storage/compression/compression_segment_reader.hpp b/src/duckdb/src/include/duckdb/storage/compression/compression_segment_reader.hpp index 8bdfa894d..ab7be12db 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/compression_segment_reader.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/compression_segment_reader.hpp @@ -80,6 +80,27 @@ class CompressionSegmentReader { return result; } + //! Returns a view over the preceding length bytes and moves the position backward. + unsafe_array_ptr ReadBytesBackward(idx_t length) { + CheckBackwardRead(length); + position -= length; + return unsafe_array_ptr(data + position, length); + } + + //! Returns a view over the preceding count aligned elements and moves the position backward. + template + unsafe_array_ptr ReadArrayBackward(idx_t count) { + static_assert(std::is_trivially_copyable_v, + "ReadArrayBackward element must be a trivially copyable data type"); + if (DUCKDB_UNLIKELY(count > position / sizeof(T))) { + ThrowBackwardReadOutOfBounds(); + } + auto offset = position - count * sizeof(T); + auto result = GetArray(offset, count); + position = offset; + return result; + } + //! Copies the next length bytes into destination and advances the position. //! The caller must ensure destination has capacity for length bytes. void ReadBytesInto(data_ptr_t destination, idx_t length) { @@ -203,6 +224,10 @@ class CompressionSegmentReader { //! Throws if alignment is zero or the padding exceeds the range. void Align(idx_t alignment); + //! Aligns the position backward relative to this reader's origin. + //! Throws if alignment is zero. + void AlignBackward(idx_t alignment); + private: void CheckForwardRead(idx_t length) const { if (DUCKDB_UNLIKELY(length > size - position)) { diff --git a/src/duckdb/src/include/duckdb/storage/compression/patas/patas_fetch.hpp b/src/duckdb/src/include/duckdb/storage/compression/patas/patas_fetch.hpp index 594cfb8ae..a343452de 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/patas/patas_fetch.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/patas/patas_fetch.hpp @@ -19,8 +19,12 @@ namespace duckdb { template void PatasFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) { using EXACT_TYPE = typename FloatingToExact::TYPE; + D_ASSERT(row_id >= 0); + D_ASSERT(UnsafeNumericCast(row_id) < segment.count); - PatasScanState scan_state(segment); + auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); + auto handle = buffer_manager.Pin(state.context, segment.GetBlockHandle()); + PatasScanState scan_state(std::move(handle), segment); scan_state.Skip(segment, UnsafeNumericCast(row_id)); auto result_data = FlatVector::GetDataMutableUnsafe(result); result_data[result_idx] = (EXACT_TYPE)0; diff --git a/src/duckdb/src/include/duckdb/storage/compression/patas/patas_scan.hpp b/src/duckdb/src/include/duckdb/storage/compression/patas/patas_scan.hpp index e41c3aced..eda924e65 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/patas/patas_scan.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/patas/patas_scan.hpp @@ -18,12 +18,19 @@ #include "duckdb/common/vector/flat_vector.hpp" #include "duckdb/function/compression_function.hpp" #include "duckdb/storage/buffer_manager.hpp" +#include "duckdb/storage/compression/compression_segment_reader.hpp" #include "duckdb/storage/table/column_segment.hpp" #include "duckdb/storage/table/scan_state.hpp" namespace duckdb { +[[noreturn]] void ThrowPatasInvalidBackwardReference(); +[[noreturn]] void ThrowPatasInvalidPackedValueMetadata(); +[[noreturn]] void ThrowPatasMetadataBeforeHeader(); +[[noreturn]] void ThrowPatasMetadataTableOutOfBounds(); +[[noreturn]] void ThrowPatasGroupDataOutOfBounds(); + //! Do not change order of these variables struct PatasUnpackedValueStats { uint8_t significant_bytes; @@ -34,7 +41,7 @@ struct PatasUnpackedValueStats { template struct PatasGroupState { public: - void Init(uint8_t *data) { + void Init(const uint8_t *data) { byte_reader.SetStream(data); } @@ -46,11 +53,33 @@ struct PatasGroupState { index = 0; } - void LoadPackedData(uint16_t *packed_data, idx_t count) { + // Calculate the bytes ByteReader will consume so LoadGroup can check the full span before decoding. + idx_t LoadPackedData(const PatasPrimitives::PACKED_DATA_TYPE *packed_data, idx_t count) { + idx_t data_size = 0; for (idx_t i = 0; i < count; i++) { auto &unpacked = unpacked_data[i]; - PackedDataUtils::Unpack(packed_data[i], (UnpackedData &)unpacked); + unpacked = Unpack(packed_data[i]); + // LoadValues initializes value_buffer[0] to zero, all later references must point to earlier values. + if (unpacked.index_diff > i || (i > 0 && unpacked.index_diff == 0)) { + ThrowPatasInvalidBackwardReference(); + } + // Keep reads within EXACT_TYPE and the left shift during decoding below its bit width. + if (unpacked.significant_bytes > sizeof(EXACT_TYPE) || unpacked.trailing_zeros >= sizeof(EXACT_TYPE) * 8) { + ThrowPatasInvalidPackedValueMetadata(); + } + // ByteReader treats zero bytes with fewer than eight trailing zeros as a full-width read. + if (unpacked.significant_bytes == 0 && unpacked.trailing_zeros < 8) { + data_size += sizeof(EXACT_TYPE); + } else { + data_size += unpacked.significant_bytes; + } } + return data_size; + } + + static PatasUnpackedValueStats Unpack(PatasPrimitives::PACKED_DATA_TYPE packed_data) { + auto unpacked = PackedDataUtils::Unpack(packed_data); + return {unpacked.leading_zero, unpacked.significant_bits, unpacked.index}; } template @@ -68,14 +97,6 @@ struct PatasGroupState { } value_buffer[0] = (EXACT_TYPE)0; for (idx_t i = 0; i < count; i++) { - if (unpacked_data[i].index_diff > i) { - throw DataCorruptionException("Corrupted Patas segment: invalid backward reference"); - } - if (unpacked_data[i].significant_bytes > sizeof(EXACT_TYPE) || - unpacked_data[i].trailing_zeros >= sizeof(EXACT_TYPE) * 8) { - throw DataCorruptionException("Corrupted Patas segment: invalid packed value metadata"); - } - value_buffer[i] = patas::PatasDecompression::DecompressValue( byte_reader, unpacked_data[i].significant_bytes, unpacked_data[i].trailing_zeros, value_buffer[i - unpacked_data[i].index_diff]); @@ -96,30 +117,49 @@ struct PatasScanState : public SegmentScanState { public: using EXACT_TYPE = typename FloatingToExact::TYPE; - explicit PatasScanState(ColumnSegment &segment) : segment(segment), count(segment.count) { - auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); - - handle = buffer_manager.Pin(segment.GetBlockHandle()); - // ScanStates never exceed the boundaries of a Segment, - // but are not guaranteed to start at the beginning of the Block - segment_data = handle.GetDataMutable() + segment.GetBlockOffset(); - auto metadata_offset = Load(segment_data); - if (segment.GetBlockOffset() + metadata_offset > segment.GetBlockSize()) { - throw DataCorruptionException( - "Corrupted Patas segment: metadata_offset reaches outside of the blocks memory"); + struct SegmentLayout { + CompressionSegmentReader data; + CompressionSegmentReader metadata; + }; + + static SegmentLayout ReadSegmentLayout(const BufferHandle &handle, ColumnSegment &segment, idx_t count) { + auto reader = CompressionSegmentReader::FromSegment(handle, segment, "Patas segment"); + auto metadata_end = reader.template Read(); + if (metadata_end < PatasPrimitives::HEADER_SIZE) { + ThrowPatasMetadataBeforeHeader(); + } + reader = reader.GetSubReader(0, metadata_end, "Patas segment"); + + auto group_count = count / PatasPrimitives::PATAS_GROUP_SIZE + (count % PatasPrimitives::PATAS_GROUP_SIZE != 0); + auto metadata_capacity = metadata_end - PatasPrimitives::HEADER_SIZE; + if (group_count > metadata_capacity / PatasPrimitives::GROUP_OFFSET_SIZE) { + ThrowPatasMetadataTableOutOfBounds(); } - metadata_ptr = segment_data + metadata_offset; + auto group_offsets_size = group_count * PatasPrimitives::GROUP_OFFSET_SIZE; + metadata_capacity -= group_offsets_size; + if (count > metadata_capacity / PatasPrimitives::PACKED_DATA_SIZE) { + ThrowPatasMetadataTableOutOfBounds(); + } + auto metadata_size = group_offsets_size + count * PatasPrimitives::PACKED_DATA_SIZE; + auto metadata_start = metadata_end - metadata_size; + auto data = reader.GetSubReader(PatasPrimitives::HEADER_SIZE, metadata_start - PatasPrimitives::HEADER_SIZE, + "Patas data"); + auto metadata = reader.GetSubReader(metadata_start, metadata_size, "Patas metadata"); + return {data, metadata}; + } + + explicit PatasScanState(BufferHandle handle_p, ColumnSegment &segment) + : handle(std::move(handle_p)), count(segment.count), layout(ReadSegmentLayout(handle, segment, count)), + metadata_position(layout.metadata.Size()) { } BufferHandle handle; - data_ptr_t metadata_ptr; - data_ptr_t segment_data; + idx_t count; + SegmentLayout layout; + idx_t metadata_position; idx_t total_value_count = 0; PatasGroupState group_state; - ColumnSegment &segment; - idx_t count; - idx_t LeftInGroup() const { return PatasPrimitives::PATAS_GROUP_SIZE - (total_value_count % PatasPrimitives::PATAS_GROUP_SIZE); } @@ -151,35 +191,41 @@ struct PatasScanState : public SegmentScanState { // Using the metadata, we can avoid loading any of the data if we don't care about the group at all void SkipGroup() { - // Skip the offset indicating where the data starts - metadata_ptr -= sizeof(uint32_t); + D_ASSERT(GroupFinished()); + D_ASSERT(total_value_count < count); idx_t group_size = MinValue((idx_t)PatasPrimitives::PATAS_GROUP_SIZE, count - total_value_count); - // Skip the blocks of packed data - metadata_ptr -= sizeof(uint16_t) * group_size; - + auto group_metadata_size = PatasPrimitives::GROUP_OFFSET_SIZE + PatasPrimitives::PACKED_DATA_SIZE * group_size; + D_ASSERT(group_metadata_size <= metadata_position); + metadata_position -= group_metadata_size; total_value_count += group_size; } template void LoadGroup(EXACT_TYPE *value_buffer) { + D_ASSERT(GroupFinished()); + D_ASSERT(total_value_count < count); group_state.Reset(); - // Load the offset indicating where a groups data starts - metadata_ptr -= sizeof(uint32_t); - auto data_byte_offset = Load(metadata_ptr); - if (segment.GetBlockOffset() + data_byte_offset >= segment.GetBlockSize()) { - throw DataCorruptionException( - "Corrupted Patas segment: data_byte_offset would reach outside of the blocks memory"); + idx_t group_size = MinValue((idx_t)PatasPrimitives::PATAS_GROUP_SIZE, count - total_value_count); + auto group_metadata_size = PatasPrimitives::GROUP_OFFSET_SIZE + PatasPrimitives::PACKED_DATA_SIZE * group_size; + D_ASSERT(group_metadata_size <= metadata_position); + metadata_position -= group_metadata_size; + auto metadata = layout.metadata.GetSubReader(metadata_position, group_metadata_size, "Patas group metadata"); + metadata.SetPosition(metadata.Size()); + auto data_byte_offset = metadata.template ReadBackward(); + if (data_byte_offset < PatasPrimitives::HEADER_SIZE || + data_byte_offset - PatasPrimitives::HEADER_SIZE > layout.data.Size()) { + ThrowPatasGroupDataOutOfBounds(); } - // Initialize the byte_reader with the data values for the group - group_state.Init(segment_data + data_byte_offset); - - idx_t group_size = MinValue((idx_t)PatasPrimitives::PATAS_GROUP_SIZE, (count - total_value_count)); - - // Read the compacted blocks of (7 + 6 + 3 bits) value stats - metadata_ptr -= sizeof(uint16_t) * group_size; - group_state.LoadPackedData((uint16_t *)metadata_ptr, group_size); + auto packed_data = metadata.template GetArray(0, group_size); + auto data_size = group_state.LoadPackedData(packed_data.data(), group_size); + auto data_offset = data_byte_offset - PatasPrimitives::HEADER_SIZE; + if (data_size > layout.data.Size() - data_offset) { + ThrowPatasGroupDataOutOfBounds(); + } + auto data = layout.data.GetSubReader(data_offset, data_size, "Patas group data"); + group_state.Init(data.GetBytes(0, data.Size()).data()); // Read all the values to the specified 'value_buffer' group_state.template LoadValues(value_buffer, group_size); @@ -189,12 +235,14 @@ struct PatasScanState : public SegmentScanState { //! Skip the next 'skip_count' values, we don't store the values void Skip(ColumnSegment &segment, idx_t skip_count) { using EXACT_TYPE = typename FloatingToExact::TYPE; + D_ASSERT(total_value_count <= count); + D_ASSERT(skip_count <= count - total_value_count); if (total_value_count != 0 && !GroupFinished()) { // Finish skipping the current group - idx_t to_skip = LeftInGroup(); - skip_count -= to_skip; + idx_t to_skip = MinValue(skip_count, LeftInGroup()); ScanGroup(nullptr, to_skip); + skip_count -= to_skip; } // Figure out how many entire groups we can skip // For these groups, we don't even need to process the metadata or values @@ -214,7 +262,9 @@ struct PatasScanState : public SegmentScanState { template unique_ptr PatasInitScan(const QueryContext &context, ColumnSegment &segment) { - auto result = make_uniq_base>(segment); + auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); + auto handle = buffer_manager.Pin(context, segment.GetBlockHandle()); + auto result = make_uniq_base>(std::move(handle), segment); return result; } @@ -226,6 +276,8 @@ void PatasScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t scan idx_t result_offset) { using EXACT_TYPE = typename FloatingToExact::TYPE; auto &scan_state = (PatasScanState &)*state.scan_state; + D_ASSERT(scan_state.total_value_count <= scan_state.count); + D_ASSERT(scan_count <= scan_state.count - scan_state.total_value_count); // Get the pointer to the result values auto current_result_ptr = FlatVector::GetDataMutableUnsafe(result); diff --git a/src/duckdb/src/include/duckdb/storage/compression/patas/shared.hpp b/src/duckdb/src/include/duckdb/storage/compression/patas/shared.hpp index a26143aea..9a59a0ea5 100644 --- a/src/duckdb/src/include/duckdb/storage/compression/patas/shared.hpp +++ b/src/duckdb/src/include/duckdb/storage/compression/patas/shared.hpp @@ -4,8 +4,14 @@ namespace duckdb { class PatasPrimitives { public: + using METADATA_POINTER_TYPE = uint32_t; + using GROUP_OFFSET_TYPE = uint32_t; + using PACKED_DATA_TYPE = uint16_t; + static constexpr uint32_t PATAS_GROUP_SIZE = 1024; - static constexpr uint8_t HEADER_SIZE = sizeof(uint32_t); + static constexpr uint8_t HEADER_SIZE = sizeof(METADATA_POINTER_TYPE); + static constexpr uint8_t GROUP_OFFSET_SIZE = sizeof(GROUP_OFFSET_TYPE); + static constexpr uint8_t PACKED_DATA_SIZE = sizeof(PACKED_DATA_TYPE); static constexpr uint8_t BYTECOUNT_BITSIZE = 3; static constexpr uint8_t INDEX_BITSIZE = 7; }; diff --git a/src/duckdb/src/include/duckdb/storage/database_handle.hpp b/src/duckdb/src/include/duckdb/storage/database_handle.hpp index 119f4505f..6e01838c6 100644 --- a/src/duckdb/src/include/duckdb/storage/database_handle.hpp +++ b/src/duckdb/src/include/duckdb/storage/database_handle.hpp @@ -23,8 +23,9 @@ struct DatabaseHandle { explicit DatabaseHandle(unique_ptr mmap_handle); //! Open a fresh handle for the database file. A header prefix in `options.prefetched` (from file-type - //! detection) is adopted to serve the initial header reads from memory. - static unique_ptr Open(AttachedDatabase &db, const string &path, + //! detection) is adopted to serve the initial header reads from memory. With a client in `context`, the file + //! is opened through that client's file system, so the handle uses its settings and logger. + static unique_ptr Open(QueryContext context, AttachedDatabase &db, const string &path, const StorageManagerOptions &options, DatabaseOpenMode open_mode); bool OnDiskFile() const; @@ -42,9 +43,9 @@ struct DatabaseHandle { //! Throws if a write at [required_size] would exceed the mmap reserve. No-op otherwise. void EnsureMappedSize(idx_t required_size) const; - static unique_ptr OpenMemoryMap(AttachedDatabase &db, const string &path, + static unique_ptr OpenMemoryMap(QueryContext context, AttachedDatabase &db, const string &path, const StorageManagerOptions &options, DatabaseOpenMode open_mode); - static unique_ptr OpenFile(AttachedDatabase &db, const string &path, + static unique_ptr OpenFile(QueryContext context, AttachedDatabase &db, const string &path, const StorageManagerOptions &options, DatabaseOpenMode open_mode); private: diff --git a/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp b/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp index b14aeb5a8..2befc2e99 100644 --- a/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp +++ b/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp @@ -12,6 +12,7 @@ #include "duckdb/common/types/vector.hpp" #include "duckdb/function/compression_function.hpp" #include "duckdb/storage/buffer_manager.hpp" +#include "duckdb/storage/compression/compression_segment_reader.hpp" #include "duckdb/storage/segment/uncompressed.hpp" #include "duckdb/storage/table/column_segment.hpp" #include "duckdb/storage/table/scan_state.hpp" @@ -31,7 +32,59 @@ struct StringDictionaryContainer { } }; +struct StringDictionaryEntry { + unsafe_array_ptr data; + bool is_overflow; +}; + +struct ValidatedStringRange { +public: + StringDictionaryEntry GetEntry(idx_t index) const { + D_ASSERT(index < offsets.size()); + const auto current_offset = offsets[index]; + const auto dictionary_offset = UnsafeNumericCast(AbsValue(current_offset)); + const auto previous_offset = index > 0 ? UnsafeNumericCast(AbsValue(offsets[index - 1])) + : preceding_dictionary_offset; + const auto string_length = dictionary_offset - previous_offset; + return {dictionary_data.SubArray(dictionary_data.size() - dictionary_offset, string_length), + current_offset < 0 && string_length > 0}; + } + +private: + friend struct StringSegmentLayout; + ValidatedStringRange(unsafe_array_ptr dictionary_data_p, unsafe_array_ptr offsets_p, + uint32_t preceding_dictionary_offset_p) + : dictionary_data(dictionary_data_p), offsets(offsets_p), + preceding_dictionary_offset(preceding_dictionary_offset_p) { + } + + unsafe_array_ptr dictionary_data; + unsafe_array_ptr offsets; + uint32_t preceding_dictionary_offset; +}; + +struct StringSegmentLayout { +public: + static StringSegmentLayout Read(const BufferHandle &handle, const ColumnSegment &segment); + StringDictionaryEntry ValidateAndGetEntry(idx_t row_index) const; + ValidatedStringRange ValidateRange(idx_t start, idx_t count) const; + +private: + StringSegmentLayout(const unsafe_array_ptr dictionary_data_p, + const unsafe_array_ptr offsets_p) + : dictionary_data(dictionary_data_p), offsets(offsets_p) { + } + + //! Dictionary bytes [DICTIONARY_HEADER_SIZE + segment.count * sizeof(int32_t), dictionary end) + unsafe_array_ptr dictionary_data; + //! Dictionary offsets read from the segment after validating the array's byte range. + unsafe_array_ptr offsets; +}; + struct StringScanState : public SegmentScanState { +public: + explicit StringScanState(BufferHandle handle); + BufferHandle handle; }; @@ -224,18 +277,16 @@ struct UncompressedStringStorage { public: static void SetDictionary(ColumnSegment &segment, BufferHandle &handle, StringDictionaryContainer dict); static StringDictionaryContainer GetDictionary(ColumnSegment &segment, BufferHandle &handle); - static uint32_t GetDictionaryEnd(ColumnSegment &segment, BufferHandle &handle); static idx_t RemainingSpace(ColumnSegment &segment, BufferHandle &handle); static void WriteString(ColumnSegment &segment, string_t string, block_id_t &result_block, int32_t &result_offset); static void WriteStringMemory(ColumnSegment &segment, string_t string, block_id_t &result_block, int32_t &result_offset); static string_t ReadOverflowString(const QueryContext &context, ColumnSegment &segment, Vector &result, block_id_t block, int32_t offset); - static string_t ReadString(data_ptr_t target, int32_t offset, uint32_t string_length); - static string_t ReadStringWithLength(data_ptr_t target, int32_t offset); + static string_t ReadStringWithLength(CompressionSegmentReader reader, int32_t offset); static void WriteStringMarker(data_ptr_t target, block_id_t block_id, int32_t offset); - static void ReadStringMarker(data_ptr_t target, block_id_t &block_id, int32_t &offset); + // FIXME: Remove this raw pointer helper once FSST no longer needs it. inline static string_t FetchStringFromDict(const QueryContext &context, ColumnSegment &segment, uint32_t dict_end_offset, Vector &result, data_ptr_t base_ptr, int32_t dict_offset, uint32_t string_length) { @@ -244,7 +295,6 @@ struct UncompressedStringStorage { // regular string - fetch from dictionary auto dict_end = base_ptr + dict_end_offset; auto dict_pos = dict_end - dict_offset; - auto str_ptr = char_ptr_cast(dict_pos); return string_t(str_ptr, string_length); } else if (string_length == 0) { @@ -258,9 +308,25 @@ struct UncompressedStringStorage { return string_t(char_ptr_cast(base_ptr), 0); } else { // read overflow string - block_id_t block_id; - int32_t offset; - ReadStringMarker(base_ptr + dict_end_offset - AbsValue(dict_offset), block_id, offset); + auto marker = base_ptr + dict_end_offset - AbsValue(dict_offset); + block_id_t block_id = Load(marker); + int32_t offset = Load(marker + sizeof(block_id_t)); + + return ReadOverflowString(context, segment, result, block_id, offset); + } + } + + inline static string_t FetchStringFromEntry(const QueryContext &context, ColumnSegment &segment, Vector &result, + const StringDictionaryEntry &entry) { + if (DUCKDB_LIKELY(!entry.is_overflow)) { + // regular string - fetch from dictionary + auto str_ptr = const_char_ptr_cast(entry.data.data()); + return string_t(str_ptr, NumericCast(entry.data.size())); + } else { + // read overflow string + D_ASSERT(entry.data.size() == BIG_STRING_MARKER_SIZE); + auto block_id = Load(entry.data.data()); + auto offset = Load(entry.data.data() + sizeof(block_id_t)); return ReadOverflowString(context, segment, result, block_id, offset); } diff --git a/src/duckdb/src/main/client_context.cpp b/src/duckdb/src/main/client_context.cpp index c09f111d0..8cbb81d22 100644 --- a/src/duckdb/src/main/client_context.cpp +++ b/src/duckdb/src/main/client_context.cpp @@ -753,7 +753,8 @@ QueryResultState ClientContext::ExecuteTaskInternal(ClientContextLock &lock, Bas try { // Surface a pending interrupt even when this thread runs no task that reaches InterruptCheck. // IsInterrupted() rather than InterruptCheck(): we must not enforce query_deadline here. - if (IsInterrupted()) { + // Skip when the executor already has an error: ExecuteTask rethrows that with its original type. + if (IsInterrupted() && !active_query->executor->HasError()) { throw InterruptException(); } auto state = active_query->executor->ExecuteTask(); diff --git a/src/duckdb/src/optimizer/remote_pushdown_optimizer.cpp b/src/duckdb/src/optimizer/remote_pushdown_optimizer.cpp index 287b4f1ea..92ed5436f 100644 --- a/src/duckdb/src/optimizer/remote_pushdown_optimizer.cpp +++ b/src/duckdb/src/optimizer/remote_pushdown_optimizer.cpp @@ -1360,15 +1360,16 @@ void RemotePushdownOptimizer::StripCatalogName(TableRef &ref, const Identifier & void RemotePushdownOptimizer::StripCatalogName(ParsedExpression &expr, const Identifier &catalog_name) { if (expr.GetExpressionClass() == ExpressionClass::COLUMN_REF) { auto &col_ref = expr.Cast(); - // Strip catalog prefix from qualified column references, normalising to exactly table.col (2 parts). + // Strip the catalog prefix from qualified column references, keeping everything after it. // Require at least 3 names: a 2-part ref like "rpc.field" is either table.col or struct-column.field — // not catalog-qualified — so stripping would be wrong. - // For 3-part catalog.table.col → table.col (one level stripped) - // For 4-part catalog.schema.table.col → table.col (catalog + schema stripped) + // For 3-part catalog.table.col → table.col + // For 4-part catalog.schema.table.col → schema.table.col + // Only the catalog is dropped: the parser keeps arbitrarily deep refs in a single ColumnRef, so trailing + // names may be struct fields (catalog.table.s.a.b → table.s.a.b) and must be preserved. if (col_ref.ColumnNames().size() >= 3 && col_ref.ColumnNames()[0] == catalog_name) { - Identifier table_name = col_ref.ColumnNames()[col_ref.ColumnNames().size() - 2]; - Identifier col_name = col_ref.ColumnNames()[col_ref.ColumnNames().size() - 1]; - col_ref.ColumnNamesMutable() = {std::move(table_name), std::move(col_name)}; + auto &names = col_ref.ColumnNamesMutable(); + names.erase(names.begin()); } return; } diff --git a/src/duckdb/src/parser/column_definition.cpp b/src/duckdb/src/parser/column_definition.cpp index 0c92d0cb2..08e38e0e8 100644 --- a/src/duckdb/src/parser/column_definition.cpp +++ b/src/duckdb/src/parser/column_definition.cpp @@ -212,7 +212,7 @@ void ColumnDefinition::SetGeneratedExpression(unique_ptr new_e category = TableColumnType::GENERATED; if (new_expr->HasSubquery()) { - throw ParserException("Expression of generated column \"%s\" contains a subquery, which isn't allowed", name); + throw ParserException("Expression of generated column %s contains a subquery, which isn't allowed", name); } VerifyColumnRefs(*new_expr); diff --git a/src/duckdb/src/parser/expression/function_expression.cpp b/src/duckdb/src/parser/expression/function_expression.cpp index 7ff0b9373..8ae9eafd8 100644 --- a/src/duckdb/src/parser/expression/function_expression.cpp +++ b/src/duckdb/src/parser/expression/function_expression.cpp @@ -66,7 +66,7 @@ string FunctionExpression::ToString() const { return "((" + arguments[0].ToString() + ")" + StringUtil::Replace(qualified_name.Name().GetIdentifierName(), "__postfix", "") + ")"; } - return qualified_name.Name().GetIdentifierName() + "(" + arguments[0].ToString() + ")"; + return "(" + qualified_name.Name().GetIdentifierName() + "(" + arguments[0].ToString() + "))"; } if (arguments.size() == 2) { return StringUtil::Format("(%s %s %s)", arguments[0].ToString(), qualified_name.Name().GetIdentifierName(), diff --git a/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp b/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp index e5793b850..4118abf06 100644 --- a/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp +++ b/src/duckdb/src/parser/peg/transformer/peg_transformer.cpp @@ -370,7 +370,7 @@ bool PEGTransformer::IsWindowFrameDefault(WindowBoundary start, WindowBoundary e unique_ptr PEGTransformer::GetWindowClause(const Identifier &window_name) { auto it = window_clauses.find(window_name); if (it == window_clauses.end()) { - throw ParserException("window \"%s\" does not exist", window_name); + throw ParserException("window %s does not exist", window_name); } return unique_ptr_cast(it->second->Copy()); } diff --git a/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp b/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp index 7e243482d..7b5182571 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_create_table.cpp @@ -291,14 +291,14 @@ ConstraintColumnDefinition PEGTransformerFactory::TransformColumnDefinition( if (has_generated) { auto generated = std::move(*generated_column); if (generated.expr->HasSubquery()) { - throw ParserException("Expression of generated column \"%s\" contains a subquery, which isn't allowed", + throw ParserException("Expression of generated column %s contains a subquery, which isn't allowed", qualified_name.Name()); } if (column_type != LogicalType::ANY) { generated.expr = make_uniq(column_type, std::move(generated.expr)); } if (generated.expr->HasSubquery()) { - throw ParserException("Expression of generated column \"%s\" contains a subquery, which isn't allowed", + throw ParserException("Expression of generated column %s contains a subquery, which isn't allowed", qualified_name.Name()); } diff --git a/src/duckdb/src/parser/peg/transformer/transform_expression.cpp b/src/duckdb/src/parser/peg/transformer/transform_expression.cpp index 28c1e195b..dc43055e5 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_expression.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_expression.cpp @@ -1350,9 +1350,9 @@ bool PEGTransformerFactory::TransformSubqueryAll(PEGTransformer &transformer) { unique_ptr PEGTransformerFactory::TransformBitwiseExpression(PEGTransformer &transformer, - unique_ptr additive_expression, + unique_ptr tilde_expression, optional> bitwise_expression_tail) { - auto expr = std::move(additive_expression); + auto expr = std::move(tilde_expression); if (!bitwise_expression_tail) { return expr; } @@ -1435,8 +1435,25 @@ unique_ptr PEGTransformerFactory::TransformExponentiationExpre BinaryExpressionTail PEGTransformerFactory::TransformBitwiseExpressionTail(PEGTransformer &transformer, const string &bit_operator, - unique_ptr additive_expression) { - return {bit_operator, std::move(additive_expression), optional_idx()}; + unique_ptr tilde_expression) { + return {bit_operator, std::move(tilde_expression), optional_idx()}; +} + +unique_ptr +PEGTransformerFactory::TransformTildeExpression(PEGTransformer &transformer, + optional> tilde_prefix_operator, + unique_ptr additive_expression) { + auto expr = std::move(additive_expression); + if (!tilde_prefix_operator) { + return expr; + } + auto tilde_depth_guard = transformer.StackCheck(tilde_prefix_operator->size()); + for (const auto &prefix : *tilde_prefix_operator) { + vector> children; + children.push_back(std::move(expr)); + expr = TransformOperatorFunction(prefix, std::move(children)); + } + return expr; } BinaryExpressionTail diff --git a/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp b/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp index b8eaa7e34..f602dc9c1 100644 --- a/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp +++ b/src/duckdb/src/parser/peg/transformer/transform_generated_trampoline.cpp @@ -1836,6 +1836,9 @@ static const TransformFrameOps BITWISE_EXPRESSION_TAIL_OPS = { static const TransformFrameOps BIT_OPERATOR_OPS = {"BitOperator", &PEGTransformerFactory::InitializeBitOperatorTrampoline, &PEGTransformerFactory::FinalizeBitOperatorTrampoline}; +static const TransformFrameOps TILDE_EXPRESSION_OPS = {"TildeExpression", + &PEGTransformerFactory::InitializeTildeExpressionTrampoline, + &PEGTransformerFactory::FinalizeTildeExpressionTrampoline}; static const TransformFrameOps ADDITIVE_EXPRESSION_OPS = { "AdditiveExpression", &PEGTransformerFactory::InitializeAdditiveExpressionTrampoline, &PEGTransformerFactory::FinalizeAdditiveExpressionTrampoline}; @@ -3651,6 +3654,7 @@ const case_insensitive_map_t &PEGTransformerFactory:: {"BitwiseExpression", &BITWISE_EXPRESSION_OPS}, {"BitwiseExpressionTail", &BITWISE_EXPRESSION_TAIL_OPS}, {"BitOperator", &BIT_OPERATOR_OPS}, + {"TildeExpression", &TILDE_EXPRESSION_OPS}, {"AdditiveExpression", &ADDITIVE_EXPRESSION_OPS}, {"AdditiveExpressionTail", &ADDITIVE_EXPRESSION_TAIL_OPS}, {"Term", &TERM_OPS}, @@ -16617,7 +16621,7 @@ void PEGTransformerFactory::InitializeBitwiseExpressionTrampoline(PEGTransformer } else { process.ReserveChildSlots(2 - 1); } - process.PushChild({transformer.GetRule("AdditiveExpression"), list_pr.GetChild(0)}, 0); + process.PushChild({transformer.GetRule("TildeExpression"), list_pr.GetChild(0)}, 0); } unique_ptr @@ -16631,7 +16635,7 @@ PEGTransformerFactory::FinalizeBitwiseExpressionTrampoline(PEGTransformer &trans auto dynamic_repeat_children = dynamic_repeat_pr.GetChildren(); dynamic_child_count = dynamic_repeat_children.size(); } - auto additive_expression = process.TakeResult>(0); + auto tilde_expression = process.TakeResult>(0); optional> bitwise_expression_tail {}; if (dynamic_child_count > 0) { vector bitwise_expression_tail_value; @@ -16641,7 +16645,7 @@ PEGTransformerFactory::FinalizeBitwiseExpressionTrampoline(PEGTransformer &trans bitwise_expression_tail = std::move(bitwise_expression_tail_value); } auto result = - TransformBitwiseExpression(transformer, std::move(additive_expression), std::move(bitwise_expression_tail)); + TransformBitwiseExpression(transformer, std::move(tilde_expression), std::move(bitwise_expression_tail)); return make_uniq>>(std::move(result)); } @@ -16649,7 +16653,7 @@ void PEGTransformerFactory::InitializeBitwiseExpressionTailTrampoline(PEGTransfo GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); process.ReserveChildSlots(2); - process.PushChild({transformer.GetRule("AdditiveExpression"), list_pr.GetChild(1)}, 1); + process.PushChild({transformer.GetRule("TildeExpression"), list_pr.GetChild(1)}, 1); process.PushChild({transformer.GetRule("BitOperator"), list_pr.GetChild(0)}, 0); } @@ -16657,8 +16661,8 @@ unique_ptr PEGTransformerFactory::FinalizeBitwiseExpressionTailTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto bit_operator = process.TakeResult(0); - auto additive_expression = process.TakeResult>(1); - auto result = TransformBitwiseExpressionTail(transformer, bit_operator, std::move(additive_expression)); + auto tilde_expression = process.TakeResult>(1); + auto result = TransformBitwiseExpressionTail(transformer, bit_operator, std::move(tilde_expression)); return make_uniq>(std::move(result)); } @@ -16675,6 +16679,54 @@ PEGTransformerFactory::FinalizeBitOperatorTrampoline(PEGTransformer &transformer return make_uniq>(result); } +void PEGTransformerFactory::InitializeTildeExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + auto &repeat_opt = list_pr.GetChild(0).Cast(); + idx_t dynamic_child_count = 0; + if (repeat_opt.HasResult()) { + auto &repeat_pr = repeat_opt.GetResult().Cast(); + auto repeat_children = repeat_pr.GetChildren(); + dynamic_child_count = repeat_children.size(); + process.ReserveChildSlots(2 + dynamic_child_count - 1); + process.PushChild({transformer.GetRule("AdditiveExpression"), list_pr.GetChild(1)}, + 1 + dynamic_child_count - 1); + for (idx_t i = repeat_children.size(); i > 0; i--) { + auto child_idx = i - 1; + process.PushChild({transformer.GetRule("TildePrefixOperator"), repeat_children[child_idx].get()}, + 0 + child_idx); + } + } else { + process.ReserveChildSlots(2 - 1); + process.PushChild({transformer.GetRule("AdditiveExpression"), list_pr.GetChild(1)}, + 1 + dynamic_child_count - 1); + } +} + +unique_ptr +PEGTransformerFactory::FinalizeTildeExpressionTrampoline(PEGTransformer &transformer, + GeneratedTransformProcess &process) { + auto &list_pr = process.parse_result.Cast(); + idx_t dynamic_child_count = 0; + auto &dynamic_repeat_opt = list_pr.GetChild(0).Cast(); + if (dynamic_repeat_opt.HasResult()) { + auto &dynamic_repeat_pr = dynamic_repeat_opt.GetResult().Cast(); + auto dynamic_repeat_children = dynamic_repeat_pr.GetChildren(); + dynamic_child_count = dynamic_repeat_children.size(); + } + optional> tilde_prefix_operator {}; + if (dynamic_child_count > 0) { + vector tilde_prefix_operator_value; + for (idx_t i = 0; i < 0 + dynamic_child_count; i++) { + tilde_prefix_operator_value.push_back(process.TakeResult(i)); + } + tilde_prefix_operator = std::move(tilde_prefix_operator_value); + } + auto additive_expression = process.TakeResult>(1 + dynamic_child_count - 1); + auto result = TransformTildeExpression(transformer, tilde_prefix_operator, std::move(additive_expression)); + return make_uniq>>(std::move(result)); +} + void PEGTransformerFactory::InitializeAdditiveExpressionTrampoline(PEGTransformer &transformer, GeneratedTransformProcess &process) { auto &list_pr = process.parse_result.Cast(); diff --git a/src/duckdb/src/planner/binder/statement/bind_create_table.cpp b/src/duckdb/src/planner/binder/statement/bind_create_table.cpp index 02c26da6c..d1ab54c8a 100644 --- a/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +++ b/src/duckdb/src/planner/binder/statement/bind_create_table.cpp @@ -447,7 +447,7 @@ static void FindForeignKeyIndexes(const ColumnList &columns, const vector &r } auto &column = table.GetColumn(colname); if (column.Generated()) { - throw BinderException("Cant update column \"%s\" because it is a generated column!", column.Name()); + throw BinderException("Cant update column %s because it is a generated column!", column.Name()); } if (std::find(columns.begin(), columns.end(), column.Physical()) != columns.end()) { - throw BinderException("Multiple assignments to same column \"%s\"", colname); + throw BinderException("Multiple assignments to same column %s", colname); } columns.push_back(column.Physical()); if (expr->GetExpressionType() == ExpressionType::VALUE_DEFAULT) { diff --git a/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp b/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp index efec48b5c..bffa396db 100644 --- a/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +++ b/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp @@ -213,9 +213,7 @@ BoundStatement Binder::Bind(BaseTableRef &ref) { } // Try autoloading an extension, then retry the replacement scan bind - auto full_path = ReplacementScan::GetFullPath(ref.GetQualifiedName().Catalog().GetIdentifierName(), - ref.GetQualifiedName().Schema().GetIdentifierName(), - ref.Table().GetIdentifierName()); + auto full_path = ReplacementScan::GetFullPath(ref.GetQualifiedName()); auto extension_loaded = TryLoadExtensionForReplacementScan(context, full_path); if (extension_loaded) { replacement_scan_bind_result = BindWithReplacementScan(context, ref); diff --git a/src/duckdb/src/planner/operator/logical_get.cpp b/src/duckdb/src/planner/operator/logical_get.cpp index 0e86b0d6c..9515d9ceb 100644 --- a/src/duckdb/src/planner/operator/logical_get.cpp +++ b/src/duckdb/src/planner/operator/logical_get.cpp @@ -34,6 +34,37 @@ static void ConvertLegacyTableFilters(LogicalGet &get) { } } +//! Pre-v2.0.0 versions key their table filters by table column index. Map each key to the scanned column it names. +static void MapLegacyTableFilterKeys(LogicalGet &get) { + if (get.table_filters.HasMultiColumnFilters()) { + throw SerializationException( + "LogicalGet::Deserialize - unexpected multi-column filters in legacy table filters"); + } + auto &column_ids = get.GetColumnIds(); + vector>> filters; + for (auto &entry : get.table_filters) { + auto table_column = entry.GetIndex().GetIndex(); + optional_idx projection_index; + for (idx_t i = 0; i < column_ids.size(); i++) { + auto &column_index = column_ids[i]; + if (column_index.HasPrimaryIndex() && !column_index.IsPushdownExtract() && + column_index.GetPrimaryIndex() == table_column) { + projection_index = i; + break; + } + } + if (!projection_index.IsValid()) { + throw SerializationException("LogicalGet::Deserialize - table filter on column %llu that is not scanned", + table_column); + } + filters.emplace_back(ProjectionIndex(projection_index.GetIndex()), entry.TakeFilter()); + } + get.table_filters.ClearFilters(); + for (auto &filter : filters) { + get.table_filters.SetFilterByColumnIndex(filter.first, std::move(filter.second)); + } +} + LogicalGet::LogicalGet() : LogicalOperator(LogicalOperatorType::LOGICAL_GET) { } @@ -330,6 +361,7 @@ void LogicalGet::Serialize(Serializer &serializer) const { serializer.WritePropertyWithDefault(215, "scan_partition_indices", scan_partition_indices, vector()); serializer.WritePropertyWithDefault(216, "source_ordinality", source_ordinality, OrdinalityType::WITHOUT_ORDINALITY); + serializer.WriteProperty(217, "table_filters_by_projection", true); } unique_ptr LogicalGet::Deserialize(Deserializer &deserializer) { @@ -365,6 +397,8 @@ unique_ptr LogicalGet::Deserialize(Deserializer &deserializer) deserializer.ReadPropertyWithExplicitDefault>(215, "scan_partition_indices", vector()); result->source_ordinality = deserializer.ReadPropertyWithExplicitDefault( 216, "source_ordinality", OrdinalityType::WITHOUT_ORDINALITY); + auto table_filters_by_projection = + deserializer.ReadPropertyWithExplicitDefault(217, "table_filters_by_projection", false); if (!legacy_column_ids.empty()) { if (!result->column_ids.empty()) { throw SerializationException( @@ -374,6 +408,9 @@ unique_ptr LogicalGet::Deserialize(Deserializer &deserializer) result->column_ids.emplace_back(col_id); } } + if (!table_filters_by_projection) { + MapLegacyTableFilterKeys(*result); + } auto &context = deserializer.Get(); virtual_column_map_t virtual_columns; if (!has_serialize) { diff --git a/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp b/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp index 3c7a9426f..854cb30cb 100644 --- a/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp +++ b/src/duckdb/src/storage/checkpoint/write_overflow_strings_to_disk.cpp @@ -14,6 +14,18 @@ WriteOverflowStringsToDisk::~WriteOverflowStringsToDisk() { D_ASSERT(Exception::UncaughtException() || offset == 0); } +void UncompressedStringSegmentState::InitializeOnDiskBlocks(vector blocks) { + D_ASSERT(on_disk_blocks.empty()); + D_ASSERT(on_disk_block_set.empty()); + D_ASSERT(handles.empty()); + on_disk_block_set.reserve(blocks.size()); + on_disk_block_set.insert(blocks.begin(), blocks.end()); + if (on_disk_block_set.size() != blocks.size()) { + throw DataCorruptionException("Corrupted string segment: duplicate overflow block IDs"); + } + on_disk_blocks = std::move(blocks); +} + shared_ptr UncompressedStringSegmentState::GetHandle(BlockManager &manager_p, block_id_t block_id) { lock_guard lock(block_lock); auto entry = handles.find(block_id); @@ -21,6 +33,10 @@ shared_ptr UncompressedStringSegmentState::GetHandle(BlockManager & return entry->second; } auto &manager = block_manager ? *block_manager : manager_p; + if (on_disk_block_set.find(block_id) == on_disk_block_set.end()) { + throw DataCorruptionException( + "Corrupted uncompressed string segment: overflow string block is not owned by the segment"); + } auto result = manager.RegisterBlock(block_id); handles.insert(make_pair(block_id, result)); return result; @@ -37,6 +53,7 @@ void UncompressedStringSegmentState::RegisterBlock(BlockManager &manager_p, bloc auto result = manager.RegisterBlock(block_id); handles.insert(make_pair(block_id, std::move(result))); on_disk_blocks.push_back(block_id); + on_disk_block_set.insert(block_id); } string UncompressedStringSegmentState::GetSegmentInfo() const { @@ -56,7 +73,10 @@ void UncompressedStringSegmentState::InsertOverflowBlock(block_id_t block_id, re reference UncompressedStringSegmentState::FindOverflowBlock(block_id_t block_id) { auto read_lock = overflow_blocks_lock.GetSharedLock(); auto entry = overflow_blocks.find(block_id); - D_ASSERT(entry != overflow_blocks.end()); + if (entry == overflow_blocks.end()) { + throw DataCorruptionException( + "Corrupted uncompressed string segment: overflow string block is not owned by the segment"); + } return entry->second; } diff --git a/src/duckdb/src/storage/compression/chimp/chimp.cpp b/src/duckdb/src/storage/compression/chimp/chimp.cpp index 088c6dbdc..1c13d684a 100644 --- a/src/duckdb/src/storage/compression/chimp/chimp.cpp +++ b/src/duckdb/src/storage/compression/chimp/chimp.cpp @@ -7,6 +7,31 @@ namespace duckdb { +void ThrowChimpMetadataBeforeHeader() { + throw DataCorruptionException("Corrupted Chimp segment: metadata ends before the segment header"); +} + +void ThrowChimpLeadingZeroBlockCountOutOfBounds(uint8_t block_count) { + throw DataCorruptionException("Corrupted Chimp segment: leading-zero block count %d exceeds %d", block_count, + ChimpPrimitives::CHIMP_SEQUENCE_SIZE / 8); +} + +void ThrowChimpLeadingZeroCountMismatch(idx_t stored_count, idx_t required_count) { + throw DataCorruptionException( + "Corrupted Chimp segment: leading-zero metadata contains %d values but %d are required", stored_count, + required_count); +} + +void ThrowChimpPackedDataExceedsType(uint8_t leading_zero, uint8_t significant_bits, idx_t bit_width) { + throw DataCorruptionException( + "Corrupted Chimp segment: packed data uses %d leading-zero and %d significant bits for a %d-bit value", + leading_zero, significant_bits, bit_width); +} + +void ThrowChimpLeadingZeroStateMissing() { + throw DataCorruptionException("Corrupted Chimp segment: leading-zero equality has no preceding leading-zero value"); +} + template CompressionFunction GetChimpFunction(PhysicalType data_type) { return CompressionFunction(CompressionType::COMPRESSION_CHIMP, data_type, ChimpInitAnalyze, ChimpAnalyze, diff --git a/src/duckdb/src/storage/compression/compression_segment_reader.cpp b/src/duckdb/src/storage/compression/compression_segment_reader.cpp index d43c1e1ae..a20f1eff9 100644 --- a/src/duckdb/src/storage/compression/compression_segment_reader.cpp +++ b/src/duckdb/src/storage/compression/compression_segment_reader.cpp @@ -73,4 +73,12 @@ void CompressionSegmentReader::Align(idx_t alignment) { position += padding; } +void CompressionSegmentReader::AlignBackward(idx_t alignment) { + if (alignment == 0) { + throw InternalException("CompressionSegmentReader::AlignBackward called with a zero alignment"); + } + auto padding = position % alignment; + position -= padding; +} + } // namespace duckdb diff --git a/src/duckdb/src/storage/compression/patas.cpp b/src/duckdb/src/storage/compression/patas.cpp index 14f82d598..f272fca3a 100644 --- a/src/duckdb/src/storage/compression/patas.cpp +++ b/src/duckdb/src/storage/compression/patas.cpp @@ -7,6 +7,26 @@ namespace duckdb { +void ThrowPatasInvalidBackwardReference() { + throw DataCorruptionException("Corrupted Patas segment: invalid backward reference"); +} + +void ThrowPatasInvalidPackedValueMetadata() { + throw DataCorruptionException("Corrupted Patas segment: invalid packed value metadata"); +} + +void ThrowPatasMetadataBeforeHeader() { + throw DataCorruptionException("Corrupted Patas segment: metadata ends before the segment header"); +} + +void ThrowPatasMetadataTableOutOfBounds() { + throw DataCorruptionException("Corrupted Patas segment: metadata table exceeds the segment"); +} + +void ThrowPatasGroupDataOutOfBounds() { + throw DataCorruptionException("Corrupted Patas segment: group data is outside the data region"); +} + template CompressionFunction GetPatasFunction(PhysicalType data_type) { throw NotImplementedException("GetPatasFunction not implemented for the given datatype"); diff --git a/src/duckdb/src/storage/compression/string_uncompressed.cpp b/src/duckdb/src/storage/compression/string_uncompressed.cpp index 5ae47949c..7348b0934 100644 --- a/src/duckdb/src/storage/compression/string_uncompressed.cpp +++ b/src/duckdb/src/storage/compression/string_uncompressed.cpp @@ -9,6 +9,46 @@ namespace duckdb { +//===--------------------------------------------------------------------===// +// Error Helpers +//===--------------------------------------------------------------------===// +[[noreturn]] static void ThrowInvalidStringDictionary() { + throw DataCorruptionException("Corrupted uncompressed string segment: dictionary is outside the segment"); +} + +[[noreturn]] static void ThrowStringOffsetTableOutOfBounds() { + throw DataCorruptionException("Corrupted uncompressed string segment: offset table overlaps the dictionary"); +} + +[[noreturn]] static void ThrowDictionaryOffsetMinimumValue() { + throw DataCorruptionException("Corrupted uncompressed string segment: dictionary offset is INT32_MIN"); +} + +[[noreturn]] static void ThrowDictionaryOffsetOutOfBounds(uint32_t offset, uint32_t dictionary_size) { + throw DataCorruptionException( + "Corrupted uncompressed string segment: dictionary offset %u exceeds dictionary size %u", offset, + dictionary_size); +} + +[[noreturn]] static void ThrowDecreasingDictionaryOffset(uint32_t offset, uint32_t previous_offset) { + throw DataCorruptionException( + "Corrupted uncompressed string segment: dictionary offset %u is smaller than preceding offset %u", offset, + previous_offset); +} + +[[noreturn]] static void ThrowInvalidDictionaryEntryMarker() { + throw DataCorruptionException( + "Corrupted uncompressed string segment: negative dictionary offset does not describe an overflow marker"); +} + +[[noreturn]] static void ThrowInvalidOverflowStringBlock() { + throw DataCorruptionException("Corrupted uncompressed string segment: invalid overflow string block ID"); +} + +[[noreturn]] static void ThrowOverflowStringOffsetOutOfBounds() { + throw DataCorruptionException("Corrupted uncompressed string segment: overflow string offset is outside its block"); +} + //===--------------------------------------------------------------------===// // Storage Class //===--------------------------------------------------------------------===// @@ -65,13 +105,16 @@ idx_t UncompressedStringStorage::StringFinalAnalyze(AnalyzeState &state_p) { //===--------------------------------------------------------------------===// // Scan //===--------------------------------------------------------------------===// +StringScanState::StringScanState(BufferHandle handle_p) : handle(std::move(handle_p)) { +} + void UncompressedStringInitPrefetch(ColumnSegment &segment, PrefetchState &prefetch_state) { prefetch_state.AddBlock(segment.GetBlockHandle()); auto segment_state = segment.GetSegmentState(); if (segment_state) { auto &state = segment_state->Cast(); auto &block_manager = segment.GetBlockHandle()->GetBlockManager(); - for (auto &block_id : state.on_disk_blocks) { + for (auto &block_id : state.GetOnDiskBlocks()) { auto block_handle = state.GetHandle(block_manager, block_id); prefetch_state.AddBlock(block_handle); } @@ -80,10 +123,9 @@ void UncompressedStringInitPrefetch(ColumnSegment &segment, PrefetchState &prefe unique_ptr UncompressedStringStorage::StringInitScan(const QueryContext &context, ColumnSegment &segment) { - auto result = make_uniq(); auto &buffer_manager = BufferManager::GetBufferManager(segment.GetDatabase()); - result->handle = buffer_manager.Pin(context, segment.GetBlockHandle()); - return std::move(result); + auto handle = buffer_manager.Pin(context, segment.GetBlockHandle()); + return make_uniq(std::move(handle)); } //===--------------------------------------------------------------------===// @@ -93,22 +135,17 @@ void UncompressedStringStorage::StringScanPartial(ColumnSegment &segment, Column Vector &result, idx_t result_offset) { // clear any previously locked buffers and get the primary buffer handle auto &scan_state = state.scan_state->Cast(); + auto layout = StringSegmentLayout::Read(scan_state.handle, segment); auto start = state.GetPositionInSegment(); + D_ASSERT(start <= segment.count.load()); + D_ASSERT(scan_count <= segment.count.load() - start); - auto baseptr = scan_state.handle.GetDataMutable() + segment.GetBlockOffset(); - auto dict_end = GetDictionaryEnd(segment, scan_state.handle); - auto base_data = reinterpret_cast(baseptr + DICTIONARY_HEADER_SIZE); auto result_data = FlatVector::GetDataMutable(result); - - int32_t previous_offset = start > 0 ? base_data[start - 1] : 0; + auto strings = layout.ValidateRange(start, scan_count); for (idx_t i = 0; i < scan_count; i++) { - // std::abs used since offsets can be negative to indicate big strings - auto current_offset = base_data[start + i]; - auto string_length = UnsafeNumericCast(std::abs(current_offset) - std::abs(previous_offset)); - result_data[result_offset + i] = - FetchStringFromDict(state.context, segment, dict_end, result, baseptr, current_offset, string_length); - previous_offset = base_data[start + i]; + auto entry = strings.GetEntry(i); + result_data[result_offset + i] = FetchStringFromEntry(state.context, segment, result, entry); } } @@ -124,20 +161,20 @@ void UncompressedStringStorage::Select(ColumnSegment &segment, ColumnScanState & Vector &result, const SelectionVector &sel, idx_t sel_count) { // clear any previously locked buffers and get the primary buffer handle auto &scan_state = state.scan_state->Cast(); + auto layout = StringSegmentLayout::Read(scan_state.handle, segment); auto start = state.GetPositionInSegment(); + D_ASSERT(start <= segment.count.load()); + D_ASSERT(vector_count <= segment.count.load() - start); + D_ASSERT(sel_count <= vector_count); - auto baseptr = scan_state.handle.GetDataMutable() + segment.GetBlockOffset(); - auto dict_end = GetDictionaryEnd(segment, scan_state.handle); - auto base_data = reinterpret_cast(baseptr + DICTIONARY_HEADER_SIZE); auto result_data = FlatVector::GetDataMutable(result); + auto strings = layout.ValidateRange(start, vector_count); for (idx_t i = 0; i < sel_count; i++) { - idx_t index = start + sel.get_index(i); - auto current_offset = base_data[index]; - auto prev_offset = index > 0 ? base_data[index - 1] : 0; - auto string_length = UnsafeNumericCast(std::abs(current_offset) - std::abs(prev_offset)); - result_data[i] = - FetchStringFromDict(state.context, segment, dict_end, result, baseptr, current_offset, string_length); + auto selection_index = sel.get_index(i); + D_ASSERT(selection_index < vector_count); + auto entry = strings.GetEntry(selection_index); + result_data[i] = FetchStringFromEntry(state.context, segment, result, entry); } } @@ -162,25 +199,19 @@ BufferHandle &ColumnFetchState::GetOrInsertHandle(ColumnSegment &segment) { void UncompressedStringStorage::StringFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx) { + D_ASSERT(row_id >= 0); + auto row_index = NumericCast(row_id); + D_ASSERT(row_index < segment.count.load()); + // fetch a single row from the string segment // first pin the main buffer if it is not already pinned auto &handle = state.GetOrInsertHandle(segment); + auto layout = StringSegmentLayout::Read(handle, segment); - auto baseptr = handle.GetDataMutable() + segment.GetBlockOffset(); - auto dict_end = GetDictionaryEnd(segment, handle); - auto base_data = reinterpret_cast(baseptr + DICTIONARY_HEADER_SIZE); auto result_data = FlatVector::GetDataMutable(result); - auto dict_offset = base_data[row_id]; - uint32_t string_length; - if (DUCKDB_UNLIKELY(row_id == 0LL)) { - // edge case where this is the first string in the dict - string_length = NumericCast(std::abs(dict_offset)); - } else { - string_length = NumericCast(std::abs(dict_offset) - std::abs(base_data[row_id - 1])); - } - result_data[result_idx] = - FetchStringFromDict(state.context, segment, dict_end, result, baseptr, dict_offset, string_length); + auto entry = layout.ValidateAndGetEntry(row_index); + result_data[result_idx] = FetchStringFromEntry(state.context, segment, result, entry); } //===--------------------------------------------------------------------===// @@ -211,7 +242,7 @@ UncompressedStringStorage::StringInitSegment(ColumnSegment &segment, block_id_t auto result = make_uniq(); if (segment_state) { auto &serialized_state = segment_state->Cast(); - result->on_disk_blocks = std::move(serialized_state.blocks); + result->InitializeOnDiskBlocks(std::move(serialized_state.blocks)); } return std::move(result); } @@ -248,11 +279,11 @@ idx_t UncompressedStringStorage::FinalizeAppend(ColumnSegment &segment, BaseStat //===--------------------------------------------------------------------===// unique_ptr UncompressedStringStorage::SerializeState(ColumnSegment &segment) { auto &state = segment.GetSegmentState()->Cast(); - if (state.on_disk_blocks.empty()) { + if (state.GetOnDiskBlocks().empty()) { // no on-disk blocks - nothing to write return nullptr; } - return make_uniq(state.on_disk_blocks); + return make_uniq(state.GetOnDiskBlocks()); } unique_ptr UncompressedStringStorage::DeserializeState(Deserializer &deserializer) { @@ -263,7 +294,7 @@ unique_ptr UncompressedStringStorage::DeserializeState(Deser void UncompressedStringStorage::VisitBlockIds(const ColumnSegment &segment, BlockIdVisitor &visitor) { auto &state = segment.GetSegmentState()->Cast(); - for (auto &block_id : state.on_disk_blocks) { + for (auto &block_id : state.GetOnDiskBlocks()) { visitor.Visit(block_id); } } @@ -287,6 +318,150 @@ CompressionFunction StringUncompressed::GetFunction(PhysicalType data_type) { UncompressedStringStorage::Select); } +//===--------------------------------------------------------------------===// +// Dictionary Validation +//===--------------------------------------------------------------------===// +//! Returns the absolute offset without validating it. +static inline uint32_t GetDictionaryOffset(const int32_t encoded_offset) { + // Widen first so taking the absolute value of INT32_MIN does not overflow. + return UnsafeNumericCast(AbsValue(encoded_offset)); +} + +static uint32_t ValidateAndGetDictionaryOffset(const int32_t encoded_offset, const uint32_t dictionary_size) { + if (encoded_offset == NumericLimits::Minimum()) { + ThrowDictionaryOffsetMinimumValue(); + } + + const auto dictionary_offset = GetDictionaryOffset(encoded_offset); + if (dictionary_offset > dictionary_size) { + ThrowDictionaryOffsetOutOfBounds(dictionary_offset, dictionary_size); + } + return dictionary_offset; +} + +//! SIMD friendly version of ValidateDictionaryEntry that avoids early exits. +//! Returns 1 if ValidateDictionaryEntry would accept the offsets, otherwise 0. +static uint32_t ValidateDictionaryEntryFast(const int32_t current_offset, const int32_t previous_offset, + const uint32_t dictionary_size) { + const auto current_dictionary_offset = GetDictionaryOffset(current_offset); + const auto previous_dictionary_offset = GetDictionaryOffset(previous_offset); + // Offsets store the cumulative number of dictionary bytes used. + const auto string_length = current_dictionary_offset - previous_dictionary_offset; + uint32_t invalid = current_offset == NumericLimits::Minimum(); + invalid |= current_dictionary_offset > dictionary_size; + // Dictionary offsets must not decrease. + invalid |= current_dictionary_offset < previous_dictionary_offset; + + // If the offset is negative, the entry is either NULL or an overflow string. + const uint32_t is_negative = current_offset < 0; + const uint32_t has_zero_length = string_length == 0; + const uint32_t has_bytes = string_length != 0; + const uint32_t offset_changed = current_offset != previous_offset; + const uint32_t wrong_marker_size = string_length != UncompressedStringStorage::BIG_STRING_MARKER_SIZE; + + // If it is NULL, the current offset must be inherited unchanged from the previous entry. + const auto invalid_null = has_zero_length & offset_changed; + // If it is an overflow string, the entry's length must match the marker's length. + const auto invalid_overflow = has_bytes & wrong_marker_size; + invalid |= is_negative & (invalid_null | invalid_overflow); + + return invalid == 0; +} + +//! Validates both offsets and their entry, throwing on invalid data. +static void ValidateDictionaryEntry(const int32_t current_offset, const int32_t previous_offset, + const uint32_t dictionary_size) { + const auto previous_dictionary_offset = ValidateAndGetDictionaryOffset(previous_offset, dictionary_size); + const auto current_dictionary_offset = ValidateAndGetDictionaryOffset(current_offset, dictionary_size); + + // Dictionary offsets must not decrease. + if (current_dictionary_offset < previous_dictionary_offset) { + D_ASSERT(!ValidateDictionaryEntryFast(current_offset, previous_offset, dictionary_size)); + ThrowDecreasingDictionaryOffset(current_dictionary_offset, previous_dictionary_offset); + } + + // Offsets store the cumulative number of dictionary bytes used. + const auto string_length = current_dictionary_offset - previous_dictionary_offset; + + // If the offset is negative, the entry is either NULL or an overflow string. + if (current_offset < 0) { + // If it is NULL, the current offset must be inherited unchanged from the previous entry. + if (string_length == 0 && current_offset != previous_offset) { + D_ASSERT(!ValidateDictionaryEntryFast(current_offset, previous_offset, dictionary_size)); + ThrowInvalidDictionaryEntryMarker(); + } + + // If it is an overflow string, the entry's length must match the marker's length. + if (string_length > 0 && string_length != UncompressedStringStorage::BIG_STRING_MARKER_SIZE) { + D_ASSERT(!ValidateDictionaryEntryFast(current_offset, previous_offset, dictionary_size)); + ThrowInvalidDictionaryEntryMarker(); + } + } + + D_ASSERT(ValidateDictionaryEntryFast(current_offset, previous_offset, dictionary_size)); +} + +StringSegmentLayout StringSegmentLayout::Read(const BufferHandle &handle, const ColumnSegment &segment) { + auto reader = CompressionSegmentReader::FromSegment(handle, segment, "uncompressed string segment"); + // Appends change the dictionary size, so reading it during a scan would race. + // The dictionary end does not change during appends, so use that instead. + auto dictionary_end = NumericCast(reader.Get(sizeof(uint32_t))); + if (dictionary_end > reader.Size()) { + ThrowInvalidStringDictionary(); + } + auto offset_count = segment.count.load(); + if (dictionary_end < UncompressedStringStorage::DICTIONARY_HEADER_SIZE || + offset_count > (dictionary_end - UncompressedStringStorage::DICTIONARY_HEADER_SIZE) / sizeof(int32_t)) { + ThrowStringOffsetTableOutOfBounds(); + } + // Dictionary bytes do not overlap the offsets table, so use the end of the table + // as the lower bound instead of reading the dictionary size. + auto dictionary_start = UncompressedStringStorage::DICTIONARY_HEADER_SIZE + offset_count * sizeof(int32_t); + auto dictionary_data = reader.GetBytes(dictionary_start, dictionary_end - dictionary_start); + auto offsets = reader.GetArray(UncompressedStringStorage::DICTIONARY_HEADER_SIZE, offset_count); + return {dictionary_data, offsets}; +} + +ValidatedStringRange StringSegmentLayout::ValidateRange(const idx_t start, const idx_t count) const { + D_ASSERT(start <= offsets.size()); + D_ASSERT(count <= offsets.size() - start); + auto range_offsets = offsets.SubArray(start, count); + const auto previous_offset = start > 0 ? offsets[start - 1] : 0; + const auto dictionary_size = NumericCast(dictionary_data.size()); + const auto preceding_dictionary_offset = ValidateAndGetDictionaryOffset(previous_offset, dictionary_size); + if (DUCKDB_UNLIKELY(count == 0)) { + return ValidatedStringRange(dictionary_data, range_offsets, preceding_dictionary_offset); + } + + uint32_t valid = ValidateDictionaryEntryFast(range_offsets[0], previous_offset, dictionary_size); + // Hot path assumes no errors, so accumulate and later deal with them. + for (idx_t i = 1; i < count; i++) { + valid &= ValidateDictionaryEntryFast(range_offsets[i], range_offsets[i - 1], dictionary_size); + } + + // If we have an error, find it and report it. + if (DUCKDB_UNLIKELY(!valid)) { + for (idx_t i = 0; i < count; i++) { + ValidateDictionaryEntry(range_offsets[i], i > 0 ? range_offsets[i - 1] : previous_offset, dictionary_size); + } + throw InternalException("ValidateDictionaryEntryFast and ValidateDictionaryEntry disagree"); + } + + return ValidatedStringRange(dictionary_data, range_offsets, preceding_dictionary_offset); +} + +StringDictionaryEntry StringSegmentLayout::ValidateAndGetEntry(const idx_t row_index) const { + D_ASSERT(row_index < offsets.size()); + const auto current_offset = offsets[row_index]; + const auto previous_offset = row_index > 0 ? offsets[row_index - 1] : 0; + ValidateDictionaryEntry(current_offset, previous_offset, NumericCast(dictionary_data.size())); + const auto previous_dictionary_offset = GetDictionaryOffset(previous_offset); + const auto current_dictionary_offset = GetDictionaryOffset(current_offset); + const auto string_length = current_dictionary_offset - previous_dictionary_offset; + const auto is_overflow = current_offset < 0 && string_length > 0; + return {dictionary_data.SubArray(dictionary_data.size() - current_dictionary_offset, string_length), is_overflow}; +} + //===--------------------------------------------------------------------===// // Helper Functions //===--------------------------------------------------------------------===// @@ -298,18 +473,13 @@ void UncompressedStringStorage::SetDictionary(ColumnSegment &segment, BufferHand } StringDictionaryContainer UncompressedStringStorage::GetDictionary(ColumnSegment &segment, BufferHandle &handle) { - auto startptr = handle.GetDataMutable() + segment.GetBlockOffset(); + auto startptr = handle.Ptr() + segment.GetBlockOffset(); StringDictionaryContainer container; container.size = Load(startptr); container.end = Load(startptr + sizeof(uint32_t)); return container; } -uint32_t UncompressedStringStorage::GetDictionaryEnd(ColumnSegment &segment, BufferHandle &handle) { - auto startptr = handle.GetDataMutable() + segment.GetBlockOffset(); - return Load(startptr + sizeof(uint32_t)); -} - idx_t UncompressedStringStorage::RemainingSpace(ColumnSegment &segment, BufferHandle &handle) { auto dictionary = GetDictionary(segment, handle); D_ASSERT(dictionary.end == segment.SegmentSize()); @@ -374,8 +544,12 @@ string_t UncompressedStringStorage::ReadOverflowString(const QueryContext &conte auto &buffer_manager = segment.GetBlockHandle()->GetMemory().GetBufferManager(); auto &state = segment.GetSegmentState()->Cast(); - D_ASSERT(block != INVALID_BLOCK); - D_ASSERT(offset < NumericCast(segment.GetBlockSize())); + if (block < 0) { + ThrowInvalidOverflowStringBlock(); + } + if (offset < 0) { + ThrowOverflowStringOffsetOutOfBounds(); + } if (block < MAXIMUM_BLOCK) { // read the overflow string from disk @@ -384,9 +558,13 @@ string_t UncompressedStringStorage::ReadOverflowString(const QueryContext &conte auto handle = buffer_manager.Pin(context, block_handle); // read header - uint32_t length = Load(handle.GetDataMutable() + offset); + auto block_size = segment.GetBlockSize(); + auto string_space = block_size - sizeof(block_id_t); + CompressionSegmentReader block_reader(handle.Ptr(), block_size, "overflow string block"); + auto reader = block_reader.GetSubReader(0, string_space, "overflow string data"); + reader.SetPosition(NumericCast(offset)); + uint32_t length = reader.Read(); uint32_t remaining = length; - offset += sizeof(uint32_t); BufferHandle target_handle; string_t overflow_string; @@ -404,24 +582,23 @@ string_t UncompressedStringStorage::ReadOverflowString(const QueryContext &conte // now append the string to the single buffer while (remaining > 0) { - idx_t to_write = MinValue(remaining, segment.GetBlockSize() - sizeof(block_id_t) - - UnsafeNumericCast(offset)); - memcpy(target_ptr, handle.GetDataMutable() + offset, to_write); + idx_t to_write = MinValue(remaining, reader.Remaining()); + reader.ReadBytesInto(target_ptr, to_write); remaining -= to_write; - offset += UnsafeNumericCast(to_write); target_ptr += to_write; if (remaining > 0) { // read the next block - block_id_t next_block = Load(handle.GetDataMutable() + offset); + block_id_t next_block = block_reader.Get(string_space); block_handle = state.GetHandle(segment.GetBlockHandle()->GetBlockManager(), next_block); handle = buffer_manager.Pin(context, block_handle); - offset = 0; + block_reader = CompressionSegmentReader(handle.Ptr(), block_size, "overflow string block"); + reader = block_reader.GetSubReader(0, string_space, "overflow string data"); } } if (allocate_block) { - auto final_buffer = target_handle.GetDataMutable(); + auto final_buffer = target_handle.Ptr(); StringVector::AddHandle(result, std::move(target_handle)); - return ReadString(final_buffer, 0, length); + return string_t(const_char_ptr_cast(final_buffer), length); } else { overflow_string.Finalize(); return overflow_string; @@ -432,22 +609,17 @@ string_t UncompressedStringStorage::ReadOverflowString(const QueryContext &conte // first pin the handle, if it is not pinned yet auto string_block = state.FindOverflowBlock(block); auto handle = buffer_manager.Pin(context, string_block.get().block); - auto final_buffer = handle.GetDataMutable(); + auto final_buffer = handle.Ptr(); StringVector::AddHandle(result, std::move(handle)); - return ReadStringWithLength(final_buffer, offset); + CompressionSegmentReader reader(final_buffer, string_block.get().size, "in-memory overflow string block"); + return ReadStringWithLength(reader, offset); } -string_t UncompressedStringStorage::ReadString(data_ptr_t target, int32_t offset, uint32_t string_length) { - auto ptr = target + offset; - auto str_ptr = char_ptr_cast(ptr); - return string_t(str_ptr, string_length); -} - -string_t UncompressedStringStorage::ReadStringWithLength(data_ptr_t target, int32_t offset) { - auto ptr = target + offset; - auto str_length = Load(ptr); - auto str_ptr = char_ptr_cast(ptr + sizeof(uint32_t)); - return string_t(str_ptr, str_length); +string_t UncompressedStringStorage::ReadStringWithLength(CompressionSegmentReader reader, int32_t offset) { + reader.SetPosition(NumericCast(offset)); + auto string_length = reader.Read(); + auto string_data = reader.ReadBytes(string_length); + return string_t(const_char_ptr_cast(string_data.data()), string_length); } void UncompressedStringStorage::WriteStringMarker(data_ptr_t target, block_id_t block_id, int32_t offset) { @@ -456,10 +628,4 @@ void UncompressedStringStorage::WriteStringMarker(data_ptr_t target, block_id_t memcpy(target, &offset, sizeof(int32_t)); } -void UncompressedStringStorage::ReadStringMarker(data_ptr_t target, block_id_t &block_id, int32_t &offset) { - memcpy(&block_id, target, sizeof(block_id_t)); - target += sizeof(block_id_t); - memcpy(&offset, target, sizeof(int32_t)); -} - } // namespace duckdb diff --git a/src/duckdb/src/storage/compression/zstd.cpp b/src/duckdb/src/storage/compression/zstd.cpp index 099c4765d..b60ae6c81 100644 --- a/src/duckdb/src/storage/compression/zstd.cpp +++ b/src/duckdb/src/storage/compression/zstd.cpp @@ -1035,18 +1035,18 @@ unique_ptr ZSTDStorage::StringInitSegment(ColumnSegment auto result = make_uniq(); if (segment_state) { auto &serialized_state = segment_state->Cast(); - result->on_disk_blocks = std::move(serialized_state.blocks); + result->InitializeOnDiskBlocks(std::move(serialized_state.blocks)); } return std::move(result); } unique_ptr ZSTDStorage::SerializeState(ColumnSegment &segment) { auto &state = segment.GetSegmentState()->Cast(); - if (state.on_disk_blocks.empty()) { + if (state.GetOnDiskBlocks().empty()) { // no on-disk blocks - nothing to write return nullptr; } - return make_uniq(state.on_disk_blocks); + return make_uniq(state.GetOnDiskBlocks()); } unique_ptr ZSTDStorage::DeserializeState(Deserializer &deserializer) { @@ -1057,7 +1057,7 @@ unique_ptr ZSTDStorage::DeserializeState(Deserializer &deser void ZSTDStorage::VisitBlockIds(const ColumnSegment &segment, BlockIdVisitor &visitor) { auto &state = segment.GetSegmentState()->Cast(); - for (auto &block_id : state.on_disk_blocks) { + for (auto &block_id : state.GetOnDiskBlocks()) { visitor.Visit(block_id); } } diff --git a/src/duckdb/src/storage/database_handle.cpp b/src/duckdb/src/storage/database_handle.cpp index cb4542bd7..c484225cf 100644 --- a/src/duckdb/src/storage/database_handle.cpp +++ b/src/duckdb/src/storage/database_handle.cpp @@ -1,5 +1,6 @@ #include "duckdb/storage/database_handle.hpp" #include "duckdb/storage/single_file_block_manager.hpp" +#include "duckdb/common/query_context.hpp" #include @@ -10,17 +11,29 @@ DatabaseHandle::DatabaseHandle(unique_ptr handle_p) : handle(std::mo DatabaseHandle::DatabaseHandle(unique_ptr mmap_handle_p) : mmap_handle(std::move(mmap_handle_p)) { } -unique_ptr DatabaseHandle::Open(AttachedDatabase &db, const string &path, +//! The file system to open the database file with. The handle outlives the statement that opens it, but file systems +//! take what they need from the opener when the file is opened: through the client's file system, a remote database +//! file uses the settings of the session that attached it (http_proxy, ca_cert_file, ...) and reports its requests to +//! that session's logger. Without a client, the database-wide file system only sees global settings. +static FileSystem &GetDatabaseFileSystem(QueryContext context, AttachedDatabase &db) { + auto client_context = context.GetClientContext(); + if (client_context) { + return FileSystem::GetFileSystem(*client_context); + } + return FileSystem::Get(db); +} + +unique_ptr DatabaseHandle::Open(QueryContext context, AttachedDatabase &db, const string &path, const StorageManagerOptions &options, DatabaseOpenMode open_mode) { if (options.io_mode == FileIOMode::MMAP) { // mmap reads are zero-copy from the mapping, so the prefetched header is not needed here. - return OpenMemoryMap(db, path, options, open_mode); + return OpenMemoryMap(context, db, path, options, open_mode); } else { - return OpenFile(db, path, options, open_mode); + return OpenFile(context, db, path, options, open_mode); } } -unique_ptr DatabaseHandle::OpenFile(AttachedDatabase &db, const string &path, +unique_ptr DatabaseHandle::OpenFile(QueryContext context, AttachedDatabase &db, const string &path, const StorageManagerOptions &options, DatabaseOpenMode open_mode) { FileOpenFlags file_flags; if (options.read_only) { @@ -39,7 +52,7 @@ unique_ptr DatabaseHandle::OpenFile(AttachedDatabase &db, const file_flags |= FileFlags::FILE_FLAGS_PARALLEL_ACCESS; file_flags |= FileFlags::FILE_FLAGS_MULTI_CLIENT_ACCESS; - auto &fs = FileSystem::Get(db); + auto &fs = GetDatabaseFileSystem(context, db); auto file_handle = fs.OpenFile(path, file_flags); if (!file_handle) { // this can only happen in read-only mode - as that is when we set FILE_FLAGS_NULL_IF_NOT_EXISTS @@ -54,7 +67,7 @@ unique_ptr DatabaseHandle::OpenFile(AttachedDatabase &db, const return result; } -unique_ptr DatabaseHandle::OpenMemoryMap(AttachedDatabase &db, const string &path, +unique_ptr DatabaseHandle::OpenMemoryMap(QueryContext context, AttachedDatabase &db, const string &path, const StorageManagerOptions &options, DatabaseOpenMode open_mode) { if (options.encryption_options.encryption_enabled) { @@ -76,7 +89,7 @@ unique_ptr DatabaseHandle::OpenMemoryMap(AttachedDatabase &db, c mmap_flags |= FileFlags::FILE_FLAGS_FILE_CREATE; } } - auto &fs = FileSystem::Get(db); + auto &fs = GetDatabaseFileSystem(context, db); auto mmap_handle = fs.MemoryMapFile(path, mmap_flags, mmap_options); if (!mmap_handle) { // Only happens in read-only mode, where FILE_FLAGS_NULL_IF_NOT_EXISTS is set. diff --git a/src/duckdb/src/storage/single_file_block_manager.cpp b/src/duckdb/src/storage/single_file_block_manager.cpp index 37f49faff..6640a76b6 100644 --- a/src/duckdb/src/storage/single_file_block_manager.cpp +++ b/src/duckdb/src/storage/single_file_block_manager.cpp @@ -529,7 +529,7 @@ void SingleFileBlockManager::CreateNewDatabase(QueryContext context) { } // MAP mode opens only the mmap; other modes open the FileHandle. - handle = DatabaseHandle::Open(db, path, options, DatabaseOpenMode::CREATE_NEW_FILE); + handle = DatabaseHandle::Open(context, db, path, options, DatabaseOpenMode::CREATE_NEW_FILE); header_buffer.Clear(); if (options.storage_version == StorageVersion::INVALID) { @@ -631,7 +631,7 @@ void SingleFileBlockManager::CreateNewDatabase(QueryContext context) { } void SingleFileBlockManager::LoadExistingDatabase(QueryContext context) { - handle = DatabaseHandle::Open(db, path, options, DatabaseOpenMode::OPEN_EXISTING_FILE); + handle = DatabaseHandle::Open(context, db, path, options, DatabaseOpenMode::OPEN_EXISTING_FILE); handle->CheckMagicBytes(context); // otherwise, we check the metadata of the file From d6efeadfd58f0deb2b7bf673238b957cfd6e8f50 Mon Sep 17 00:00:00 2001 From: DuckLabs GitHub Bot Date: Fri, 25 Sep 2026 11:28:01 +0000 Subject: [PATCH 5/6] Update vendored DuckDB sources to ca15f79c32 --- ...nerated_extension_loader_package_build.cpp | 8 +++---- .../function/table/version/pragma_version.cpp | 6 +++--- .../common/multi_file/multi_file_function.hpp | 21 ++++++++++++++----- .../common/multi_file/multi_file_states.hpp | 3 +++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/duckdb/generated_extension_loader_package_build.cpp b/src/duckdb/generated_extension_loader_package_build.cpp index 17f4c26dd..a2dfed398 100644 --- a/src/duckdb/generated_extension_loader_package_build.cpp +++ b/src/duckdb/generated_extension_loader_package_build.cpp @@ -41,7 +41,7 @@ int32_t duckdb_extension_core_functions_describe(duckdb_extension_descriptor *de descriptor->version = 1; descriptor->name = "core_functions"; descriptor->extension_version = EXT_VERSION_CORE_FUNCTIONS; - descriptor->api_version = "v2.0.0-alpha43355"; + descriptor->api_version = "v2.0.0-alpha43385"; descriptor->entry_cpp = (void (*)(void))core_functions_duckdb_cpp_init; return 0; } @@ -74,7 +74,7 @@ int32_t duckdb_extension_parquet_describe(duckdb_extension_descriptor *descripto descriptor->version = 1; descriptor->name = "parquet"; descriptor->extension_version = EXT_VERSION_PARQUET; - descriptor->api_version = "v2.0.0-alpha43355"; + descriptor->api_version = "v2.0.0-alpha43385"; descriptor->entry_cpp = (void (*)(void))parquet_duckdb_cpp_init; return 0; } @@ -107,7 +107,7 @@ int32_t duckdb_extension_icu_describe(duckdb_extension_descriptor *descriptor) { descriptor->version = 1; descriptor->name = "icu"; descriptor->extension_version = EXT_VERSION_ICU; - descriptor->api_version = "v2.0.0-alpha43355"; + descriptor->api_version = "v2.0.0-alpha43385"; descriptor->entry_cpp = (void (*)(void))icu_duckdb_cpp_init; return 0; } @@ -140,7 +140,7 @@ int32_t duckdb_extension_json_describe(duckdb_extension_descriptor *descriptor) descriptor->version = 1; descriptor->name = "json"; descriptor->extension_version = EXT_VERSION_JSON; - descriptor->api_version = "v2.0.0-alpha43355"; + descriptor->api_version = "v2.0.0-alpha43385"; descriptor->entry_cpp = (void (*)(void))json_duckdb_cpp_init; return 0; } diff --git a/src/duckdb/src/function/table/version/pragma_version.cpp b/src/duckdb/src/function/table/version/pragma_version.cpp index c57cfe401..e9e27542c 100644 --- a/src/duckdb/src/function/table/version/pragma_version.cpp +++ b/src/duckdb/src/function/table/version/pragma_version.cpp @@ -1,5 +1,5 @@ #ifndef DUCKDB_PATCH_VERSION -#define DUCKDB_PATCH_VERSION "0-alpha43355" +#define DUCKDB_PATCH_VERSION "0-alpha43385" #endif #ifndef DUCKDB_MINOR_VERSION #define DUCKDB_MINOR_VERSION 0 @@ -8,10 +8,10 @@ #define DUCKDB_MAJOR_VERSION 2 #endif #ifndef DUCKDB_VERSION -#define DUCKDB_VERSION "v2.0.0-alpha43355" +#define DUCKDB_VERSION "v2.0.0-alpha43385" #endif #ifndef DUCKDB_SOURCE_ID -#define DUCKDB_SOURCE_ID "9d283094ac" +#define DUCKDB_SOURCE_ID "ca15f79c32" #endif #include "duckdb/function/table/system_functions.hpp" #include "duckdb/main/database.hpp" diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp index adca4434d..4a7503e52 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_function.hpp @@ -435,6 +435,7 @@ class MultiFileFunction : public TableFunction { } PushAsyncOpenError(gstate, ErrorData("Unknown exception while opening a file")); } // LCOV_EXCL_STOP + gstate.async_open_settled.notify_all(); } //! Schedule async opens for upcoming unopened files on the async pool, ahead of decoding. Lock held on entry. @@ -466,6 +467,7 @@ class MultiFileFunction : public TableFunction { [&gstate]() { // the reader stays in OPENING, so tell every waiter to stop instead of polling forever gstate.error_opening_file = true; + gstate.async_open_settled.notify_all(); }); } progress_guaranteed = true; @@ -549,14 +551,23 @@ class MultiFileFunction : public TableFunction { unique_lock ¶llel_lock) { D_ASSERT(parallel_lock.owns_lock()); auto &read_ahead = *gstate.read_ahead; - while (HasFilesToRead(gstate, parallel_lock) && !gstate.error_opening_file && - gstate.readers[gstate.file_index]->file_state == MultiFileFileState::OPENING) { + auto still_opening = [&]() { + return HasFilesToRead(gstate, parallel_lock) && !gstate.error_opening_file && + gstate.readers[gstate.file_index]->file_state == MultiFileFileState::OPENING; + }; + while (still_opening()) { parallel_lock.unlock(); // the open may be queued behind other async work or the async pool may be gone, so run tasks inline - if (!read_ahead.TryRunPendingTask()) { - context.InterruptCheck(); - TaskScheduler::YieldThread(); + const bool ran_task = read_ahead.TryRunPendingTask(); + parallel_lock.lock(); + if (ran_task || !still_opening()) { + continue; } + // the open is in flight: sleep until it settles; the timeout bounds interrupt latency and + // covers a cancellation that signals without the lock + gstate.async_open_settled.wait_for(parallel_lock, std::chrono::milliseconds(10)); + parallel_lock.unlock(); + context.InterruptCheck(); parallel_lock.lock(); } } diff --git a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp index 7fad141be..4c44f359b 100644 --- a/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp +++ b/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp @@ -10,6 +10,7 @@ #include "duckdb/common/multi_file/multi_file_data.hpp" #include "duckdb/common/atomic.hpp" +#include "duckdb/common/condition_variable.hpp" #include "duckdb/common/multi_file/multi_file_options.hpp" #include "duckdb/common/multi_file/base_file_reader.hpp" #include "duckdb/common/multi_file/multi_file_list.hpp" @@ -170,6 +171,8 @@ struct MultiFileGlobalState : public GlobalTableFunctionState { //! Signal to other threads that a file failed to open, letting every thread abort. //! Atomic because a cancelled file open settles it while the scheduling thread may hold the lock. atomic error_opening_file {false}; + //! Signalled when an async file open settles, waking the threads waiting for the front file + condition_variable async_open_settled; //! Index of file currently up for scanning atomic file_index; From 3d0fe11ec1f35421c973db302e347c562908697f Mon Sep 17 00:00:00 2001 From: Alex Kasko Date: Sun, 27 Sep 2026 08:30:29 +0100 Subject: [PATCH 6/6] Implement query execution over QueryResultStream --- CMakeLists.txt | 5 + CMakeLists.txt.in | 5 + src/jni/duckdb_java.cpp | 170 +++++++++++++++++----- src/jni/holders.hpp | 4 +- src/test/java/org/duckdb/TestResults.java | 28 +++- src/test/java/org/duckdb/TestVariant.java | 25 +--- 6 files changed, 179 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d50919e..a9b5997ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -703,6 +703,11 @@ target_compile_definitions(duckdb_java PRIVATE -DDUCKDB_EXTENSION_AUTOLOAD_DEFAULT -DDUCKDB_EXTENSION_AUTOINSTALL_DEFAULT) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(duckdb_java PRIVATE + -DD_ASSERT_IS_ENABLED) +endif() + if(JEMALLOC_ENABLED) target_compile_definitions(duckdb_java PRIVATE -DDUCKDB_ENABLE_JEMALLOC) diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index 00f5eda26..73ceaf49f 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -189,6 +189,11 @@ target_compile_definitions(duckdb_java PRIVATE -DDUCKDB_EXTENSION_AUTOLOAD_DEFAULT -DDUCKDB_EXTENSION_AUTOINSTALL_DEFAULT) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(duckdb_java PRIVATE + -DD_ASSERT_IS_ENABLED) +endif() + if(JEMALLOC_ENABLED) target_compile_definitions(duckdb_java PRIVATE -DDUCKDB_ENABLE_JEMALLOC) diff --git a/src/jni/duckdb_java.cpp b/src/jni/duckdb_java.cpp index 4a3f1f623..77bc0330e 100644 --- a/src/jni/duckdb_java.cpp +++ b/src/jni/duckdb_java.cpp @@ -262,16 +262,22 @@ jobject _duckdb_jdbc_pending_query(JNIEnv *env, jclass, jobject conn_ref_buf, jb Value result; bool stream_results = conn_ref->context->TryGetCurrentSetting("jdbc_stream_results", result) ? result.GetValue() : false; - QueryParameters query_parameters; - query_parameters.output_type = - stream_results ? QueryResultOutputType::ALLOW_STREAMING : QueryResultOutputType::FORCE_MATERIALIZED; auto pending_ref = make_uniq(); - pending_ref->pending = conn_ref->PendingQuery(std::move(statements.back()), query_parameters); + pending_ref->pending = conn_ref->Submit(std::move(statements.back())); + pending_ref->streaming = stream_results; return env->NewDirectByteBuffer(pending_ref.release(), 0); } +template +static void throw_execution_java_error(JNIEnv *env, T *res) { + std::string error_msg = std::string(res->GetError()); + duckdb::ExceptionType error_type = res->GetErrorType(); + jclass exc_type = duckdb::ExceptionType::INTERRUPT == error_type ? J_SQLTimeoutException : J_SQLException; + env->ThrowNew(exc_type, error_msg.c_str()); +} + static duckdb::unique_ptr execute_prepared_statement(JNIEnv *env, jobject stmt_ref_buf, jobjectArray params, bool stream_results) { auto stmt_ref = reinterpret_cast(env->GetDirectBufferAddress(stmt_ref_buf)); @@ -301,17 +307,41 @@ static duckdb::unique_ptr execute_prepared_statement(JNIEnv *env, j } } - auto res = stmt_ref->stmt->Execute(duckdb_params, stream_results); + duckdb::unique_ptr res; + if (stream_results) { + res = stmt_ref->stmt->Submit(duckdb_params); + } else { + res = stmt_ref->stmt->Execute(duckdb_params); + } + if (res->HasError()) { - std::string error_msg = std::string(res->GetError()); - duckdb::ExceptionType error_type = res->GetErrorType(); - jclass exc_type = duckdb::ExceptionType::INTERRUPT == error_type ? J_SQLTimeoutException : J_SQLException; - env->ThrowNew(exc_type, error_msg.c_str()); + throw_execution_java_error(env, res.get()); return nullptr; } + return res; } +duckdb::unique_ptr complete_query_streaming(JNIEnv *env, duckdb::unique_ptr pending) { + auto stream = make_uniq(std::move(pending)); + while (!duckdb::IsObservable(stream->ExecuteTask())) { + if (stream->HasError()) { + throw_execution_java_error(env, stream.get()); + return nullptr; + } + } + return stream; +} + +duckdb::unique_ptr complete_query_materialized(JNIEnv *env, duckdb::unique_ptr pending) { + pending->Complete(); + if (pending->HasError()) { + throw_execution_java_error(env, pending.get()); + return nullptr; + } + return pending; +} + jobject _duckdb_jdbc_execute(JNIEnv *env, jclass, jobject stmt_ref_buf, jobjectArray params) { auto stmt_ref = reinterpret_cast(env->GetDirectBufferAddress(stmt_ref_buf)); if (!stmt_ref || !stmt_ref->stmt) { @@ -322,42 +352,91 @@ jobject _duckdb_jdbc_execute(JNIEnv *env, jclass, jobject stmt_ref_buf, jobjectA throw InvalidInputException("Attempting to execute a prepared statement after its connection was closed!"); } Value result; - bool stream_results = + bool stream_results_user = context->TryGetCurrentSetting("jdbc_stream_results", result) ? result.GetValue() : false; - auto res_ref = make_uniq(); - res_ref->res = execute_prepared_statement(env, stmt_ref_buf, params, stream_results); - if (res_ref->res == nullptr) { + + auto pending = execute_prepared_statement(env, stmt_ref_buf, params, stream_results_user); + if (pending == nullptr) { return nullptr; } + + bool stream_results_stmt = pending->GetStatementProperties().result_eagerness != ResultEagerness::FORCED; + bool stream_results = stream_results_user && stream_results_stmt; + + auto res_ref = make_uniq(); + + if (stream_results) { + auto stream = complete_query_streaming(env, std::move(pending)); + if (!stream) { + return nullptr; + } + res_ref->stream = std::move(stream); + } else { + auto res = complete_query_materialized(env, std::move(pending)); + if (!res) { + return nullptr; + } + res_ref->res = std::move(res); + } + return env->NewDirectByteBuffer(res_ref.release(), 0); } jobject _duckdb_jdbc_execute_capi(JNIEnv *env, jclass, jobject stmt_ref_buf, jobjectArray params) { - auto res_ptr = execute_prepared_statement(env, stmt_ref_buf, params, true); - if (!res_ptr) { + auto pending = execute_prepared_statement(env, stmt_ref_buf, params, true); + if (!pending) { return nullptr; } + + bool stream_results = pending->GetStatementProperties().result_eagerness != ResultEagerness::FORCED; auto out = make_uniq(); - DuckDBTranslateResult(std::move(res_ptr), out.get()); + + if (stream_results) { + auto stream = complete_query_streaming(env, std::move(pending)); + if (!stream) { + return nullptr; + } + DuckDBTranslateStreamResult(std::move(stream), out.get()); + } else { + auto res = complete_query_materialized(env, std::move(pending)); + if (!res) { + return nullptr; + } + DuckDBTranslateResult(std::move(res), out.get()); + } + return env->NewDirectByteBuffer(out.release(), 0); } jobject _duckdb_jdbc_execute_pending(JNIEnv *env, jclass, jobject pending_ref_buf) { auto pending_ref = reinterpret_cast(env->GetDirectBufferAddress(pending_ref_buf)); - if (!pending_ref) { + if (!pending_ref || !pending_ref->pending) { throw InvalidInputException("Invalid pending query"); } - auto res_ref = make_uniq(); - res_ref->res = pending_ref->pending->Execute(); - if (res_ref->res->HasError()) { - std::string error_msg = std::string(res_ref->res->GetError()); - duckdb::ExceptionType error_type = res_ref->res->GetErrorType(); - res_ref->res = nullptr; - jclass exc_type = duckdb::ExceptionType::INTERRUPT == error_type ? J_SQLTimeoutException : J_SQLException; - env->ThrowNew(exc_type, error_msg.c_str()); + if (pending_ref->pending->HasError()) { + throw_execution_java_error(env, pending_ref->pending.get()); + pending_ref->pending = nullptr; return nullptr; } + + bool stream_results = pending_ref->pending->GetStatementProperties().result_eagerness != ResultEagerness::FORCED; + auto res_ref = make_uniq(); + + if (pending_ref->streaming && stream_results) { + auto stream = complete_query_streaming(env, std::move(pending_ref->pending)); + if (!stream) { + return nullptr; + } + res_ref->stream = std::move(stream); + } else { + auto res = complete_query_materialized(env, std::move(pending_ref->pending)); + if (!res) { + return nullptr; + } + res_ref->res = std::move(res); + } + return env->NewDirectByteBuffer(res_ref.release(), 0); } @@ -452,16 +531,24 @@ static jobject build_meta(JNIEnv *env, size_t column_count, size_t n_param, cons jobject _duckdb_jdbc_query_result_meta(JNIEnv *env, jclass, jobject res_ref_buf) { auto res_ref = (ResultHolder *)env->GetDirectBufferAddress(res_ref_buf); - if (!res_ref || !res_ref->res || res_ref->res->HasError()) { + if (!res_ref || (!res_ref->res && !res_ref->stream) || (res_ref->res && res_ref->res->HasError()) || + (res_ref->stream && res_ref->stream->HasError())) { throw InvalidInputException("Invalid result set"); } - auto &result = res_ref->res; - auto n_param = 0; // no params now duckdb::vector param_types(n_param); - return build_meta(env, result->ColumnCount(), n_param, result->GetNames(), result->GetTypes(), - result->GetStatementProperties(), param_types); + if (res_ref->res) { + auto &res = res_ref->res; + return build_meta(env, res->ColumnCount(), n_param, res->GetNames(), res->GetTypes(), + res->GetStatementProperties(), param_types); + } else if (res_ref->stream) { + auto &res = res_ref->stream; + return build_meta(env, res->ColumnCount(), n_param, res->GetNames(), res->GetTypes(), + res->GetStatementProperties(), param_types); + } else { + throw InvalidInputException("Invalid result set"); + } } jobject _duckdb_jdbc_prepared_statement_meta(JNIEnv *env, jclass, jobject stmt_ref_buf) { @@ -491,7 +578,8 @@ jobject ProcessVector(JNIEnv *env, Connection *conn_ref, Vector &vec, idx_t row_ jobjectArray _duckdb_jdbc_fetch(JNIEnv *env, jclass, jobject res_ref_buf, jobject conn_ref_buf) { auto res_ref = reinterpret_cast(env->GetDirectBufferAddress(res_ref_buf)); - if (!res_ref || !res_ref->res || res_ref->res->HasError()) { + if (!res_ref || (!res_ref->res && !res_ref->stream) || (res_ref->res && res_ref->res->HasError()) || + (res_ref->stream && res_ref->stream->HasError())) { throw InvalidInputException("Invalid result set"); } @@ -500,7 +588,22 @@ jobjectArray _duckdb_jdbc_fetch(JNIEnv *env, jclass, jobject res_ref_buf, jobjec return nullptr; } - res_ref->chunk = res_ref->res->Fetch(); + if (res_ref->res) { + res_ref->chunk = res_ref->res->Fetch(); + if (res_ref->res->HasError()) { + throw_execution_java_error(env, res_ref->res.get()); + return nullptr; + } + } else if (res_ref->stream) { + res_ref->chunk = res_ref->stream->Fetch(); + if (res_ref->stream->HasError()) { + throw_execution_java_error(env, res_ref->stream.get()); + return nullptr; + } + } else { + throw InvalidInputException("Invalid result set"); + } + if (!res_ref->chunk) { res_ref->chunk = make_uniq(); } @@ -523,7 +626,8 @@ jobjectArray _duckdb_jdbc_fetch(JNIEnv *env, jclass, jobject res_ref_buf, jobjec jobjectArray _duckdb_jdbc_cast_result_to_strings(JNIEnv *env, jclass, jobject res_ref_buf, jobject conn_ref_buf, jlong col_idx) { auto res_ref = reinterpret_cast(env->GetDirectBufferAddress(res_ref_buf)); - if (!res_ref || !res_ref->res || res_ref->res->HasError()) { + if (!res_ref || (!res_ref->res && !res_ref->stream) || (res_ref->res && res_ref->res->HasError()) || + (res_ref->stream && res_ref->stream->HasError())) { throw InvalidInputException("Invalid result set"); } diff --git a/src/jni/holders.hpp b/src/jni/holders.hpp index 4da96efec..b47381343 100644 --- a/src/jni/holders.hpp +++ b/src/jni/holders.hpp @@ -47,11 +47,13 @@ struct StatementHolder { }; struct PendingHolder { - duckdb::unique_ptr pending; + duckdb::unique_ptr pending; + bool streaming = false; }; struct ResultHolder { duckdb::unique_ptr res; + duckdb::unique_ptr stream; duckdb::unique_ptr chunk; }; diff --git a/src/test/java/org/duckdb/TestResults.java b/src/test/java/org/duckdb/TestResults.java index 7efa24324..0303abcef 100644 --- a/src/test/java/org/duckdb/TestResults.java +++ b/src/test/java/org/duckdb/TestResults.java @@ -232,9 +232,17 @@ public static void test_result_streaming() throws Exception { Properties props = new Properties(); props.setProperty(JDBC_STREAM_RESULTS, String.valueOf(true)); + try (Connection conn = DriverManager.getConnection(JDBC_URL, props); Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM range(100000)")) { + while (rs.next()) { + rs.getInt(1); + } + assertFalse(rs.next()); // is exhausted + } + try (Connection conn = DriverManager.getConnection(JDBC_URL, props); - PreparedStatement stmt1 = conn.prepareStatement("SELECT * FROM range(100000)"); - ResultSet rs = stmt1.executeQuery()) { + PreparedStatement ps = conn.prepareStatement("SELECT * FROM range(100000)"); + ResultSet rs = ps.executeQuery()) { while (rs.next()) { rs.getInt(1); } @@ -242,6 +250,22 @@ public static void test_result_streaming() throws Exception { } } + public static void test_result_streaming_ddl() throws Exception { + Properties props = new Properties(); + props.setProperty(JDBC_STREAM_RESULTS, String.valueOf(true)); + + try (Connection conn = DriverManager.getConnection(JDBC_URL, props); Statement stmt = conn.createStatement()) { + boolean hasResultSet = stmt.execute("CREATE TABLE tab1 (col1 INT)"); + assertFalse(hasResultSet); + } + + try (Connection conn = DriverManager.getConnection(JDBC_URL, props); + PreparedStatement ps = conn.prepareStatement("CREATE TABLE tab1 (col1 INT)")) { + boolean hasResultSet = ps.execute(); + assertFalse(hasResultSet); + } + } + public static void test_stream_multiple_open_results() throws Exception { Properties props = new Properties(); props.setProperty(JDBC_STREAM_RESULTS, String.valueOf(true)); diff --git a/src/test/java/org/duckdb/TestVariant.java b/src/test/java/org/duckdb/TestVariant.java index 8c7465a7e..de88e0e7a 100644 --- a/src/test/java/org/duckdb/TestVariant.java +++ b/src/test/java/org/duckdb/TestVariant.java @@ -278,22 +278,8 @@ public static void test_variant_nested_struct_json() throws Exception { + " )"); String testData = "{\n" - + " \"id\": \"72869b95-ab13-4405-9371-546b6dcc443e\",\n" - + " \"isSimulation\": false,\n" - + " \"workOrderSchedules\": [\n" - + " {\n" - + " \"workOrderId\": \"e10c064f-6280-41f7-be75-b0075234754b\",\n" - + " \"scheduledStart\": \"2026-06-02T22:56:00\",\n" - + " \"scheduledEnd\": \"2026-06-03T05:01:00\",\n" - + " \"scheduledResourceIds\": [\n" - + " \"a49f8503-f2db-43aa-9d7c-711fc78d8dc9\"\n" - + " ],\n" - + " \"batchId\": null,\n" - + " \"batchSequence\": null\n" - + " }\n" - + " ],\n" - + " \"simulationResultType\": null\n" - + " }"; + + "\"id\": \"72869b95-ab13-4405-9371-546b6dcc443e\"" + + "}"; try (PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO events (globalSequence, data) VALUES (?, json(?)::VARIANT)")) { @@ -304,12 +290,7 @@ public static void test_variant_nested_struct_json() throws Exception { try (ResultSet rs = stmt.executeQuery("SELECT globalSequence, data FROM events")) { assertTrue(rs.next()); assertEquals(rs.getLong(1), 100L); - assertEquals(rs.getString(2), - "{id=72869b95-ab13-4405-9371-546b6dcc443e, isSimulation=false, " - + "workOrderSchedules=[{workOrderId=e10c064f-6280-41f7-be75-b0075234754b, " - + "scheduledStart=2026-06-02T22:56:00, scheduledEnd=2026-06-03T05:01:00, " - + "scheduledResourceIds=[a49f8503-f2db-43aa-9d7c-711fc78d8dc9], batchId=null, " - + "batchSequence=null}], simulationResultType=null}"); + assertEquals(rs.getString(2), "{id=72869b95-ab13-4405-9371-546b6dcc443e}"); assertFalse(rs.next()); } }