Repository: AfterShip/clickhouse-sql-parser Branch: master Commit: 1930f34593d4 Files: 918 Total size: 2.1 MB Directory structure: gitextract_22vvr93l/ ├── .github/ │ └── workflows/ │ └── ci.yaml ├── .gitignore ├── .golangci.yml ├── AGENTS.md ├── LICENSE ├── Makefile ├── README.md ├── go.mod ├── go.sum ├── main.go └── parser/ ├── ast.go ├── ast_visitor.go ├── benchmark_test.go ├── format.go ├── format_test.go ├── helper.go ├── keyword.go ├── lexer.go ├── lexer_test.go ├── parse_system.go ├── parser_alter.go ├── parser_column.go ├── parser_common.go ├── parser_drop.go ├── parser_query.go ├── parser_table.go ├── parser_test.go ├── parser_view.go ├── set.go ├── set_test.go ├── testdata/ │ ├── basic/ │ │ ├── format/ │ │ │ ├── beautify/ │ │ │ │ ├── quantile_functions.sql │ │ │ │ ├── set_statement.sql │ │ │ │ ├── settings_statement.sql │ │ │ │ └── use_database.sql │ │ │ ├── quantile_functions.sql │ │ │ ├── set_statement.sql │ │ │ ├── settings_statement.sql │ │ │ └── use_database.sql │ │ ├── output/ │ │ │ ├── quantile_functions.sql.golden.json │ │ │ ├── set_statement.sql.golden.json │ │ │ ├── settings_statement.sql.golden.json │ │ │ └── use_database.sql.golden.json │ │ ├── quantile_functions.sql │ │ ├── set_statement.sql │ │ ├── settings_statement.sql │ │ └── use_database.sql │ ├── benchdata/ │ │ ├── posthog_huge_0.sql │ │ └── posthog_huge_1.sql │ ├── ddl/ │ │ ├── alter_role.sql │ │ ├── alter_table_add_column.sql │ │ ├── alter_table_add_index.sql │ │ ├── alter_table_add_projection.sql │ │ ├── alter_table_add_projection_group_by_only.sql │ │ ├── alter_table_attach_partition.sql │ │ ├── alter_table_clear_column.sql │ │ ├── alter_table_clear_index.sql │ │ ├── alter_table_clear_projection.sql │ │ ├── alter_table_delete.sql │ │ ├── alter_table_delete_with_cluster.sql │ │ ├── alter_table_detach_partition.sql │ │ ├── alter_table_drop_column.sql │ │ ├── alter_table_drop_detach_partition.sql │ │ ├── alter_table_drop_index.sql │ │ ├── alter_table_drop_partition.sql │ │ ├── alter_table_drop_projection.sql │ │ ├── alter_table_freeze_no_specify_partition.sql │ │ ├── alter_table_freeze_partition.sql │ │ ├── alter_table_materialize_index.sql │ │ ├── alter_table_materialize_projection.sql │ │ ├── alter_table_modify_column.sql │ │ ├── alter_table_modify_column_remove.sql │ │ ├── alter_table_modify_setting.sql │ │ ├── alter_table_remove_ttl.sql │ │ ├── alter_table_rename_column.sql │ │ ├── alter_table_replace_partition.sql │ │ ├── alter_table_reset_multiple_settings.sql │ │ ├── alter_table_reset_setting.sql │ │ ├── alter_table_update.sql │ │ ├── alter_table_update_in_partition.sql │ │ ├── alter_table_update_with_cluster.sql │ │ ├── attach_table_basic.sql │ │ ├── bug_001.sql │ │ ├── check.sql │ │ ├── create_database.sql │ │ ├── create_database_replicated.sql │ │ ├── create_dictionary_basic.sql │ │ ├── create_dictionary_comprehensive.sql │ │ ├── create_dictionary_with_comment.sql │ │ ├── create_distributed_table.sql │ │ ├── create_function_simple.sql │ │ ├── create_live_view_basic.sql │ │ ├── create_materialized_view_basic.sql │ │ ├── create_materialized_view_with_comment_before_as.sql │ │ ├── create_materialized_view_with_definer.sql │ │ ├── create_materialized_view_with_empty_table_schema.sql │ │ ├── create_materialized_view_with_gcs.sql │ │ ├── create_materialized_view_with_refresh.sql │ │ ├── create_mv_with_not_op.sql │ │ ├── create_mv_with_order_by.sql │ │ ├── create_named_collection_basic.sql │ │ ├── create_named_collection_simple.sql │ │ ├── create_named_collection_with_cluster.sql │ │ ├── create_named_collection_with_overridable.sql │ │ ├── create_or_replace.sql │ │ ├── create_role.sql │ │ ├── create_table_as_remote_function.sql │ │ ├── create_table_basic.sql │ │ ├── create_table_codec_no_args.sql │ │ ├── create_table_json_typehints.sql │ │ ├── create_table_with_codec_delta.sql │ │ ├── create_table_with_enum_fields.sql │ │ ├── create_table_with_index.sql │ │ ├── create_table_with_keyword_partition_by.sql │ │ ├── create_table_with_null_engine.sql │ │ ├── create_table_with_nullable.sql │ │ ├── create_table_with_on_clsuter.sql │ │ ├── create_table_with_projection.sql │ │ ├── create_table_with_projection_group_by_only.sql │ │ ├── create_table_with_qbit.sql │ │ ├── create_table_with_sample_by.sql │ │ ├── create_table_with_ttl_policy.sql │ │ ├── create_table_with_tuple_fields.sql │ │ ├── create_table_with_uuid.sql │ │ ├── create_user.sql │ │ ├── create_view_basic.sql │ │ ├── create_view_on_cluster_with_uuid.sql │ │ ├── create_view_with_comment.sql │ │ ├── create_with_time_zone.sql │ │ ├── desc_table_with_table_keyword.sql │ │ ├── desc_table_without_table_keyword.sql │ │ ├── describe_table_with_table_keyword.sql │ │ ├── describe_table_without_table_keyword.sql │ │ ├── drop_database.sql │ │ ├── drop_role.sql │ │ ├── drop_table_basic.sql │ │ ├── drop_table_with_no_delay.sql │ │ ├── drop_table_with_on_clsuter.sql │ │ ├── format/ │ │ │ ├── alter_role.sql │ │ │ ├── alter_table_add_column.sql │ │ │ ├── alter_table_add_index.sql │ │ │ ├── alter_table_add_projection.sql │ │ │ ├── alter_table_add_projection_group_by_only.sql │ │ │ ├── alter_table_attach_partition.sql │ │ │ ├── alter_table_clear_column.sql │ │ │ ├── alter_table_clear_index.sql │ │ │ ├── alter_table_clear_projection.sql │ │ │ ├── alter_table_delete.sql │ │ │ ├── alter_table_delete_with_cluster.sql │ │ │ ├── alter_table_detach_partition.sql │ │ │ ├── alter_table_drop_column.sql │ │ │ ├── alter_table_drop_detach_partition.sql │ │ │ ├── alter_table_drop_index.sql │ │ │ ├── alter_table_drop_partition.sql │ │ │ ├── alter_table_drop_projection.sql │ │ │ ├── alter_table_freeze_no_specify_partition.sql │ │ │ ├── alter_table_freeze_partition.sql │ │ │ ├── alter_table_materialize_index.sql │ │ │ ├── alter_table_materialize_projection.sql │ │ │ ├── alter_table_modify_column.sql │ │ │ ├── alter_table_modify_column_remove.sql │ │ │ ├── alter_table_modify_setting.sql │ │ │ ├── alter_table_remove_ttl.sql │ │ │ ├── alter_table_rename_column.sql │ │ │ ├── alter_table_replace_partition.sql │ │ │ ├── alter_table_reset_multiple_settings.sql │ │ │ ├── alter_table_reset_setting.sql │ │ │ ├── alter_table_update.sql │ │ │ ├── alter_table_update_in_partition.sql │ │ │ ├── alter_table_update_with_cluster.sql │ │ │ ├── attach_table_basic.sql │ │ │ ├── beautify/ │ │ │ │ ├── alter_role.sql │ │ │ │ ├── alter_table_add_column.sql │ │ │ │ ├── alter_table_add_index.sql │ │ │ │ ├── alter_table_add_projection.sql │ │ │ │ ├── alter_table_add_projection_group_by_only.sql │ │ │ │ ├── alter_table_attach_partition.sql │ │ │ │ ├── alter_table_clear_column.sql │ │ │ │ ├── alter_table_clear_index.sql │ │ │ │ ├── alter_table_clear_projection.sql │ │ │ │ ├── alter_table_delete.sql │ │ │ │ ├── alter_table_delete_with_cluster.sql │ │ │ │ ├── alter_table_detach_partition.sql │ │ │ │ ├── alter_table_drop_column.sql │ │ │ │ ├── alter_table_drop_detach_partition.sql │ │ │ │ ├── alter_table_drop_index.sql │ │ │ │ ├── alter_table_drop_partition.sql │ │ │ │ ├── alter_table_drop_projection.sql │ │ │ │ ├── alter_table_freeze_no_specify_partition.sql │ │ │ │ ├── alter_table_freeze_partition.sql │ │ │ │ ├── alter_table_materialize_index.sql │ │ │ │ ├── alter_table_materialize_projection.sql │ │ │ │ ├── alter_table_modify_column.sql │ │ │ │ ├── alter_table_modify_column_remove.sql │ │ │ │ ├── alter_table_modify_setting.sql │ │ │ │ ├── alter_table_remove_ttl.sql │ │ │ │ ├── alter_table_rename_column.sql │ │ │ │ ├── alter_table_replace_partition.sql │ │ │ │ ├── alter_table_reset_multiple_settings.sql │ │ │ │ ├── alter_table_reset_setting.sql │ │ │ │ ├── alter_table_update.sql │ │ │ │ ├── alter_table_update_in_partition.sql │ │ │ │ ├── alter_table_update_with_cluster.sql │ │ │ │ ├── attach_table_basic.sql │ │ │ │ ├── bug_001.sql │ │ │ │ ├── check.sql │ │ │ │ ├── create_database.sql │ │ │ │ ├── create_database_replicated.sql │ │ │ │ ├── create_dictionary_basic.sql │ │ │ │ ├── create_dictionary_comprehensive.sql │ │ │ │ ├── create_dictionary_with_comment.sql │ │ │ │ ├── create_distributed_table.sql │ │ │ │ ├── create_function_simple.sql │ │ │ │ ├── create_live_view_basic.sql │ │ │ │ ├── create_materialized_view_basic.sql │ │ │ │ ├── create_materialized_view_with_comment_before_as.sql │ │ │ │ ├── create_materialized_view_with_definer.sql │ │ │ │ ├── create_materialized_view_with_empty_table_schema.sql │ │ │ │ ├── create_materialized_view_with_gcs.sql │ │ │ │ ├── create_materialized_view_with_refresh.sql │ │ │ │ ├── create_mv_with_not_op.sql │ │ │ │ ├── create_mv_with_order_by.sql │ │ │ │ ├── create_named_collection_basic.sql │ │ │ │ ├── create_named_collection_simple.sql │ │ │ │ ├── create_named_collection_with_cluster.sql │ │ │ │ ├── create_named_collection_with_overridable.sql │ │ │ │ ├── create_or_replace.sql │ │ │ │ ├── create_role.sql │ │ │ │ ├── create_table_as_remote_function.sql │ │ │ │ ├── create_table_basic.sql │ │ │ │ ├── create_table_codec_no_args.sql │ │ │ │ ├── create_table_json_typehints.sql │ │ │ │ ├── create_table_with_codec_delta.sql │ │ │ │ ├── create_table_with_enum_fields.sql │ │ │ │ ├── create_table_with_index.sql │ │ │ │ ├── create_table_with_keyword_partition_by.sql │ │ │ │ ├── create_table_with_null_engine.sql │ │ │ │ ├── create_table_with_nullable.sql │ │ │ │ ├── create_table_with_on_clsuter.sql │ │ │ │ ├── create_table_with_projection.sql │ │ │ │ ├── create_table_with_projection_group_by_only.sql │ │ │ │ ├── create_table_with_qbit.sql │ │ │ │ ├── create_table_with_sample_by.sql │ │ │ │ ├── create_table_with_ttl_policy.sql │ │ │ │ ├── create_table_with_tuple_fields.sql │ │ │ │ ├── create_table_with_uuid.sql │ │ │ │ ├── create_user.sql │ │ │ │ ├── create_view_basic.sql │ │ │ │ ├── create_view_on_cluster_with_uuid.sql │ │ │ │ ├── create_view_with_comment.sql │ │ │ │ ├── create_with_time_zone.sql │ │ │ │ ├── desc_table_with_table_keyword.sql │ │ │ │ ├── desc_table_without_table_keyword.sql │ │ │ │ ├── describe_table_with_table_keyword.sql │ │ │ │ ├── describe_table_without_table_keyword.sql │ │ │ │ ├── drop_database.sql │ │ │ │ ├── drop_role.sql │ │ │ │ ├── drop_table_basic.sql │ │ │ │ ├── drop_table_with_no_delay.sql │ │ │ │ ├── drop_table_with_on_clsuter.sql │ │ │ │ ├── grant_privilege.sql │ │ │ │ ├── optimize.sql │ │ │ │ ├── rename.sql │ │ │ │ ├── show_create_table.sql │ │ │ │ ├── show_databases.sql │ │ │ │ ├── show_databases_comprehensive.sql │ │ │ │ ├── show_databases_format.sql │ │ │ │ ├── show_databases_format_string.sql │ │ │ │ ├── show_databases_ilike.sql │ │ │ │ ├── show_databases_like.sql │ │ │ │ ├── show_databases_limit.sql │ │ │ │ ├── show_databases_not_ilike.sql │ │ │ │ ├── show_databases_not_like.sql │ │ │ │ ├── show_databases_outfile.sql │ │ │ │ ├── show_tables.sql │ │ │ │ ├── systems.sql │ │ │ │ ├── truncate_table_basic.sql │ │ │ │ └── truncate_temporary_table_on_clsuter.sql │ │ │ ├── bug_001.sql │ │ │ ├── check.sql │ │ │ ├── create_database.sql │ │ │ ├── create_database_replicated.sql │ │ │ ├── create_dictionary_basic.sql │ │ │ ├── create_dictionary_comprehensive.sql │ │ │ ├── create_dictionary_with_comment.sql │ │ │ ├── create_distributed_table.sql │ │ │ ├── create_function_simple.sql │ │ │ ├── create_live_view_basic.sql │ │ │ ├── create_materialized_view_basic.sql │ │ │ ├── create_materialized_view_with_comment_before_as.sql │ │ │ ├── create_materialized_view_with_definer.sql │ │ │ ├── create_materialized_view_with_empty_table_schema.sql │ │ │ ├── create_materialized_view_with_gcs.sql │ │ │ ├── create_materialized_view_with_refresh.sql │ │ │ ├── create_mv_with_not_op.sql │ │ │ ├── create_mv_with_order_by.sql │ │ │ ├── create_named_collection_basic.sql │ │ │ ├── create_named_collection_simple.sql │ │ │ ├── create_named_collection_with_cluster.sql │ │ │ ├── create_named_collection_with_overridable.sql │ │ │ ├── create_or_replace.sql │ │ │ ├── create_role.sql │ │ │ ├── create_table_as_remote_function.sql │ │ │ ├── create_table_basic.sql │ │ │ ├── create_table_codec_no_args.sql │ │ │ ├── create_table_json_typehints.sql │ │ │ ├── create_table_with_codec_delta.sql │ │ │ ├── create_table_with_enum_fields.sql │ │ │ ├── create_table_with_index.sql │ │ │ ├── create_table_with_keyword_partition_by.sql │ │ │ ├── create_table_with_null_engine.sql │ │ │ ├── create_table_with_nullable.sql │ │ │ ├── create_table_with_on_clsuter.sql │ │ │ ├── create_table_with_projection.sql │ │ │ ├── create_table_with_projection_group_by_only.sql │ │ │ ├── create_table_with_qbit.sql │ │ │ ├── create_table_with_sample_by.sql │ │ │ ├── create_table_with_ttl_policy.sql │ │ │ ├── create_table_with_tuple_fields.sql │ │ │ ├── create_table_with_uuid.sql │ │ │ ├── create_user.sql │ │ │ ├── create_view_basic.sql │ │ │ ├── create_view_on_cluster_with_uuid.sql │ │ │ ├── create_view_with_comment.sql │ │ │ ├── create_with_time_zone.sql │ │ │ ├── desc_table_with_table_keyword.sql │ │ │ ├── desc_table_without_table_keyword.sql │ │ │ ├── describe_table_with_table_keyword.sql │ │ │ ├── describe_table_without_table_keyword.sql │ │ │ ├── drop_database.sql │ │ │ ├── drop_role.sql │ │ │ ├── drop_table_basic.sql │ │ │ ├── drop_table_with_no_delay.sql │ │ │ ├── drop_table_with_on_clsuter.sql │ │ │ ├── grant_privilege.sql │ │ │ ├── optimize.sql │ │ │ ├── rename.sql │ │ │ ├── show_create_table.sql │ │ │ ├── show_databases.sql │ │ │ ├── show_databases_comprehensive.sql │ │ │ ├── show_databases_format.sql │ │ │ ├── show_databases_format_string.sql │ │ │ ├── show_databases_ilike.sql │ │ │ ├── show_databases_like.sql │ │ │ ├── show_databases_limit.sql │ │ │ ├── show_databases_not_ilike.sql │ │ │ ├── show_databases_not_like.sql │ │ │ ├── show_databases_outfile.sql │ │ │ ├── show_tables.sql │ │ │ ├── systems.sql │ │ │ ├── truncate_table_basic.sql │ │ │ └── truncate_temporary_table_on_clsuter.sql │ │ ├── grant_privilege.sql │ │ ├── optimize.sql │ │ ├── output/ │ │ │ ├── alter_role.sql.golden.json │ │ │ ├── alter_table_add_column.sql.golden.json │ │ │ ├── alter_table_add_index.sql.golden.json │ │ │ ├── alter_table_add_projection.sql.golden.json │ │ │ ├── alter_table_add_projection_group_by_only.sql.golden.json │ │ │ ├── alter_table_attach_partition.sql.golden.json │ │ │ ├── alter_table_clear_column.sql.golden.json │ │ │ ├── alter_table_clear_index.sql.golden.json │ │ │ ├── alter_table_clear_projection.sql.golden.json │ │ │ ├── alter_table_delete.sql.golden.json │ │ │ ├── alter_table_delete_with_cluster.sql.golden.json │ │ │ ├── alter_table_detach_partition.sql.golden.json │ │ │ ├── alter_table_drop_column.sql.golden.json │ │ │ ├── alter_table_drop_detach_partition.sql.golden.json │ │ │ ├── alter_table_drop_index.sql.golden.json │ │ │ ├── alter_table_drop_partition.sql.golden.json │ │ │ ├── alter_table_drop_projection.sql.golden.json │ │ │ ├── alter_table_freeze_no_specify_partition.sql.golden.json │ │ │ ├── alter_table_freeze_partition.sql.golden.json │ │ │ ├── alter_table_materialize_index.sql.golden.json │ │ │ ├── alter_table_materialize_projection.sql.golden.json │ │ │ ├── alter_table_modify_column.sql.golden.json │ │ │ ├── alter_table_modify_column_remove.sql.golden.json │ │ │ ├── alter_table_modify_setting.sql.golden.json │ │ │ ├── alter_table_remove_ttl.sql.golden.json │ │ │ ├── alter_table_rename_column.sql.golden.json │ │ │ ├── alter_table_replace_partition.sql.golden.json │ │ │ ├── alter_table_reset_multiple_settings.sql.golden.json │ │ │ ├── alter_table_reset_setting.sql.golden.json │ │ │ ├── alter_table_update.sql.golden.json │ │ │ ├── alter_table_update_in_partition.sql.golden.json │ │ │ ├── alter_table_update_with_cluster.sql.golden.json │ │ │ ├── attach_table_basic.sql.golden.json │ │ │ ├── bug_001.sql.golden.json │ │ │ ├── check.sql.golden.json │ │ │ ├── create_database.sql.golden.json │ │ │ ├── create_database_replicated.sql.golden.json │ │ │ ├── create_dictionary_basic.sql.golden.json │ │ │ ├── create_dictionary_comprehensive.sql.golden.json │ │ │ ├── create_dictionary_with_comment.sql.golden.json │ │ │ ├── create_distributed_table.sql.golden.json │ │ │ ├── create_function_simple.sql.golden.json │ │ │ ├── create_live_view_basic.sql.golden.json │ │ │ ├── create_materialized_view_basic.sql.golden.json │ │ │ ├── create_materialized_view_with_comment_before_as.sql.golden.json │ │ │ ├── create_materialized_view_with_definer.sql.golden.json │ │ │ ├── create_materialized_view_with_empty_table_schema.sql.golden.json │ │ │ ├── create_materialized_view_with_gcs.sql.golden.json │ │ │ ├── create_materialized_view_with_refresh.sql.golden.json │ │ │ ├── create_mv_with_not_op.sql.golden.json │ │ │ ├── create_mv_with_order_by.sql.golden.json │ │ │ ├── create_named_collection_basic.sql.golden.json │ │ │ ├── create_named_collection_simple.sql.golden.json │ │ │ ├── create_named_collection_with_cluster.sql.golden.json │ │ │ ├── create_named_collection_with_overridable.sql.golden.json │ │ │ ├── create_or_replace.sql.golden.json │ │ │ ├── create_role.sql.golden.json │ │ │ ├── create_table_as_remote_function.sql.golden.json │ │ │ ├── create_table_basic.sql.golden.json │ │ │ ├── create_table_codec_no_args.sql.golden.json │ │ │ ├── create_table_json_typehints.sql.golden.json │ │ │ ├── create_table_with_codec_delta.sql.golden.json │ │ │ ├── create_table_with_enum_fields.sql.golden.json │ │ │ ├── create_table_with_index.sql.golden.json │ │ │ ├── create_table_with_keyword_partition_by.sql.golden.json │ │ │ ├── create_table_with_null_engine.sql.golden.json │ │ │ ├── create_table_with_nullable.sql.golden.json │ │ │ ├── create_table_with_on_clsuter.sql.golden.json │ │ │ ├── create_table_with_projection.sql.golden.json │ │ │ ├── create_table_with_projection_group_by_only.sql.golden.json │ │ │ ├── create_table_with_qbit.sql.golden.json │ │ │ ├── create_table_with_sample_by.sql.golden.json │ │ │ ├── create_table_with_ttl_policy.sql.golden.json │ │ │ ├── create_table_with_tuple_fields.sql.golden.json │ │ │ ├── create_table_with_uuid.sql.golden.json │ │ │ ├── create_user.sql.golden.json │ │ │ ├── create_view_basic.sql.golden.json │ │ │ ├── create_view_on_cluster_with_uuid.sql.golden.json │ │ │ ├── create_view_with_comment.sql.golden.json │ │ │ ├── create_with_time_zone.sql.golden.json │ │ │ ├── desc_table_with_table_keyword.sql.golden.json │ │ │ ├── desc_table_without_table_keyword.sql.golden.json │ │ │ ├── describe_table_with_table_keyword.sql.golden.json │ │ │ ├── describe_table_without_table_keyword.sql.golden.json │ │ │ ├── drop_database.sql.golden.json │ │ │ ├── drop_role.sql.golden.json │ │ │ ├── drop_table_basic.sql.golden.json │ │ │ ├── drop_table_with_no_delay.sql.golden.json │ │ │ ├── drop_table_with_on_clsuter.sql.golden.json │ │ │ ├── grant_privilege.sql.golden.json │ │ │ ├── optimize.sql.golden.json │ │ │ ├── rename.sql.golden.json │ │ │ ├── show_create_table.sql.golden.json │ │ │ ├── show_databases.sql.golden.json │ │ │ ├── show_databases_comprehensive.sql.golden.json │ │ │ ├── show_databases_format.sql.golden.json │ │ │ ├── show_databases_format_string.sql.golden.json │ │ │ ├── show_databases_ilike.sql.golden.json │ │ │ ├── show_databases_like.sql.golden.json │ │ │ ├── show_databases_limit.sql.golden.json │ │ │ ├── show_databases_not_ilike.sql.golden.json │ │ │ ├── show_databases_not_like.sql.golden.json │ │ │ ├── show_databases_outfile.sql.golden.json │ │ │ ├── show_tables.sql.golden.json │ │ │ ├── systems.sql.golden.json │ │ │ ├── truncate_table_basic.sql.golden.json │ │ │ └── truncate_temporary_table_on_clsuter.sql.golden.json │ │ ├── rename.sql │ │ ├── show_create_table.sql │ │ ├── show_databases.sql │ │ ├── show_databases_comprehensive.sql │ │ ├── show_databases_format.sql │ │ ├── show_databases_format_string.sql │ │ ├── show_databases_ilike.sql │ │ ├── show_databases_like.sql │ │ ├── show_databases_limit.sql │ │ ├── show_databases_not_ilike.sql │ │ ├── show_databases_not_like.sql │ │ ├── show_databases_outfile.sql │ │ ├── show_tables.sql │ │ ├── systems.sql │ │ ├── truncate_table_basic.sql │ │ └── truncate_temporary_table_on_clsuter.sql │ ├── dml/ │ │ ├── alter_table_modify_query.sql │ │ ├── alter_table_modify_ttl_multiple.sql │ │ ├── alter_table_with_comment.sql │ │ ├── alter_table_with_modify_remove_ttl.sql │ │ ├── alter_table_with_modify_ttl.sql │ │ ├── create_column_with_ttl.sql │ │ ├── delete_from.sql │ │ ├── format/ │ │ │ ├── alter_table_modify_query.sql │ │ │ ├── alter_table_modify_ttl_multiple.sql │ │ │ ├── alter_table_with_comment.sql │ │ │ ├── alter_table_with_modify_remove_ttl.sql │ │ │ ├── alter_table_with_modify_ttl.sql │ │ │ ├── beautify/ │ │ │ │ ├── alter_table_modify_query.sql │ │ │ │ ├── alter_table_modify_ttl_multiple.sql │ │ │ │ ├── alter_table_with_comment.sql │ │ │ │ ├── alter_table_with_modify_remove_ttl.sql │ │ │ │ ├── alter_table_with_modify_ttl.sql │ │ │ │ ├── create_column_with_ttl.sql │ │ │ │ ├── delete_from.sql │ │ │ │ ├── insert_select_without_from.sql │ │ │ │ ├── insert_values.sql │ │ │ │ ├── insert_with_format.sql │ │ │ │ ├── insert_with_keyword_placeholder.sql │ │ │ │ ├── insert_with_placeholder.sql │ │ │ │ └── insert_with_select.sql │ │ │ ├── create_column_with_ttl.sql │ │ │ ├── delete_from.sql │ │ │ ├── insert_select_without_from.sql │ │ │ ├── insert_values.sql │ │ │ ├── insert_with_format.sql │ │ │ ├── insert_with_keyword_placeholder.sql │ │ │ ├── insert_with_placeholder.sql │ │ │ └── insert_with_select.sql │ │ ├── insert_select_without_from.sql │ │ ├── insert_values.sql │ │ ├── insert_with_format.sql │ │ ├── insert_with_keyword_placeholder.sql │ │ ├── insert_with_placeholder.sql │ │ ├── insert_with_select.sql │ │ └── output/ │ │ ├── alter_table_modify_query.sql.golden.json │ │ ├── alter_table_modify_ttl_multiple.sql.golden.json │ │ ├── alter_table_with_comment.sql.golden.json │ │ ├── alter_table_with_modify_remove_ttl.sql.golden.json │ │ ├── alter_table_with_modify_ttl.sql.golden.json │ │ ├── create_column_with_ttl.sql.golden.json │ │ ├── delete_from.sql.golden.json │ │ ├── insert_select_without_from.sql.golden.json │ │ ├── insert_values.sql.golden.json │ │ ├── insert_with_format.sql.golden.json │ │ ├── insert_with_keyword_placeholder.sql.golden.json │ │ ├── insert_with_placeholder.sql.golden.json │ │ └── insert_with_select.sql.golden.json │ └── query/ │ ├── access_tuple_with_dot.sql │ ├── compatible/ │ │ └── 1_stateful/ │ │ ├── 00001_count_hits.sql │ │ ├── 00002_count_visits.sql │ │ ├── 00004_top_counters.sql │ │ ├── 00005_filtering.sql │ │ ├── 00006_agregates.sql │ │ ├── 00007_uniq.sql │ │ ├── 00008_uniq.sql │ │ ├── 00009_uniq_distributed.sql │ │ ├── 00010_quantiles_segfault.sql │ │ ├── 00011_sorting.sql │ │ ├── 00012_sorting_distributed.sql │ │ ├── 00013_sorting_of_nested.sql │ │ ├── 00014_filtering_arrays.sql │ │ ├── 00015_totals_and_no_aggregate_functions.sql │ │ ├── 00016_any_if_distributed_cond_always_false.sql │ │ ├── 00017_aggregation_uninitialized_memory.sql │ │ ├── 00020_distinct_order_by_distributed.sql │ │ ├── 00021_1_select_with_in.sql │ │ ├── 00021_2_select_with_in.sql │ │ ├── 00021_3_select_with_in.sql │ │ ├── 00022_merge_prewhere.sql │ │ ├── 00023_totals_limit.sql │ │ ├── 00024_random_counters.sql │ │ ├── 00030_array_enumerate_uniq.sql │ │ ├── 00031_array_enumerate_uniq.sql │ │ ├── 00032_aggregate_key64.sql │ │ ├── 00033_aggregate_key_string.sql │ │ ├── 00034_aggregate_key_fixed_string.sql │ │ ├── 00035_aggregate_keys128.sql │ │ ├── 00036_aggregate_hashed.sql │ │ ├── 00037_uniq_state_merge1.sql │ │ ├── 00038_uniq_state_merge2.sql │ │ ├── 00039_primary_key.sql │ │ ├── 00040_aggregating_materialized_view.sql │ │ ├── 00041_aggregating_materialized_view.sql │ │ ├── 00042_any_left_join.sql │ │ ├── 00043_any_left_join.sql │ │ ├── 00044_any_left_join_string.sql │ │ ├── 00045_uniq_upto.sql │ │ ├── 00046_uniq_upto_distributed.sql │ │ ├── 00047_bar.sql │ │ ├── 00048_min_max.sql │ │ ├── 00049_max_string_if.sql │ │ ├── 00050_min_max.sql │ │ ├── 00051_min_max_array.sql │ │ ├── 00052_group_by_in.sql │ │ ├── 00053_replicate_segfault.sql │ │ ├── 00054_merge_tree_partitions.sql │ │ ├── 00055_index_and_not.sql │ │ ├── 00056_view.sql │ │ ├── 00059_merge_sorting_empty_array_joined.sql │ │ ├── 00060_move_to_prewhere_and_sets.sql │ │ ├── 00061_storage_buffer.sql │ │ ├── 00062_loyalty.sql │ │ ├── 00063_loyalty_joins.sql │ │ ├── 00065_loyalty_with_storage_join.sql │ │ ├── 00066_sorting_distributed_many_replicas.sql │ │ ├── 00067_union_all.sql │ │ ├── 00068_subquery_in_prewhere.sql │ │ ├── 00069_duplicate_aggregation_keys.sql │ │ ├── 00071_merge_tree_optimize_aio.sql │ │ ├── 00072_compare_date_and_string_index.sql │ │ ├── 00073_uniq_array.sql │ │ ├── 00074_full_join.sql │ │ ├── 00075_left_array_join.sql │ │ ├── 00076_system_columns_bytes.sql │ │ ├── 00077_log_tinylog_stripelog.sql │ │ ├── 00078_group_by_arrays.sql │ │ ├── 00079_array_join_not_used_joined_column.sql │ │ ├── 00080_array_join_and_union.sql │ │ ├── 00081_group_by_without_key_and_totals.sql │ │ ├── 00082_quantiles.sql │ │ ├── 00083_array_filter.sql │ │ ├── 00084_external_aggregation.sql │ │ ├── 00085_monotonic_evaluation_segfault.sql │ │ ├── 00086_array_reduce.sql │ │ ├── 00087_where_0.sql │ │ ├── 00088_global_in_one_shard_and_rows_before_limit.sql │ │ ├── 00089_position_functions_with_non_constant_arg.sql │ │ ├── 00091_prewhere_two_conditions.sql │ │ ├── 00093_prewhere_array_join.sql │ │ ├── 00094_order_by_array_join_limit.sql │ │ ├── 00095_hyperscan_profiler.sql │ │ ├── 00097_constexpr_in_index.sql │ │ ├── 00139_like.sql │ │ ├── 00140_rename.sql │ │ ├── 00141_transform.sql │ │ ├── 00142_system_columns.sql │ │ ├── 00143_transform_non_const_default.sql │ │ ├── 00144_functions_of_aggregation_states.sql │ │ ├── 00145_aggregate_functions_statistics.sql │ │ ├── 00146_aggregate_function_uniq.sql │ │ ├── 00147_global_in_aggregate_function.sql │ │ ├── 00148_monotonic_functions_and_index.sql │ │ ├── 00149_quantiles_timing_distributed.sql │ │ ├── 00150_quantiles_timing_precision.sql │ │ ├── 00151_order_by_read_in_order.sql │ │ ├── 00152_insert_different_granularity.sql │ │ ├── 00153_aggregate_arena_race.sql │ │ ├── 00154_avro.sql │ │ ├── 00156_max_execution_speed_sample_merge.sql │ │ ├── 00157_cache_dictionary.sql │ │ ├── 00158_cache_dictionary_has.sql │ │ ├── 00160_decode_xml_component.sql │ │ ├── 00162_mmap_compression_none.sql │ │ ├── 00164_quantileBfloat16.sql │ │ ├── 00165_jit_aggregate_functions.sql │ │ ├── 00166_explain_estimate.sql │ │ ├── 00167_read_bytes_from_fs.sql │ │ ├── 00169_contingency.sql │ │ ├── 00170_s3_cache.sql │ │ ├── 00171_grouping_aggregated_transform_bug.sql │ │ ├── 00172_early_constant_folding.sql │ │ ├── 00173_group_by_use_nulls.sql │ │ ├── 00174_distinct_in_order.sql │ │ ├── 00175_counting_resources_in_subqueries.sql │ │ ├── 00176_distinct_limit_by_limit_bug_43377.sql │ │ └── 00177_select_from_gcs.sql │ ├── create_window_view.sql │ ├── format/ │ │ ├── access_tuple_with_dot.sql │ │ ├── beautify/ │ │ │ ├── access_tuple_with_dot.sql │ │ │ ├── create_window_view.sql │ │ │ ├── query_with_expr_compare.sql │ │ │ ├── select_case_multiple_when.sql │ │ │ ├── select_case_when_exists.sql │ │ │ ├── select_cast.sql │ │ │ ├── select_column_alias_string.sql │ │ │ ├── select_concat_expr.sql │ │ │ ├── select_expr.sql │ │ │ ├── select_extract_with_regex.sql │ │ │ ├── select_item_with_modifiers.sql │ │ │ ├── select_json_type.sql │ │ │ ├── select_keyword_alias_no_as.sql │ │ │ ├── select_order_by_timestamp.sql │ │ │ ├── select_order_by_with_fill_basic.sql │ │ │ ├── select_order_by_with_fill_from_to.sql │ │ │ ├── select_order_by_with_fill_interpolate.sql │ │ │ ├── select_order_by_with_fill_interpolate_no_columns.sql │ │ │ ├── select_order_by_with_fill_staleness.sql │ │ │ ├── select_order_by_with_fill_step.sql │ │ │ ├── select_simple.sql │ │ │ ├── select_simple_field_alias.sql │ │ │ ├── select_simple_with_bracket.sql │ │ │ ├── select_simple_with_cte_with_column_aliases.sql │ │ │ ├── select_simple_with_group_by_with_cube_totals.sql │ │ │ ├── select_simple_with_is_not_null.sql │ │ │ ├── select_simple_with_is_null.sql │ │ │ ├── select_simple_with_limit.sql │ │ │ ├── select_simple_with_top_clause.sql │ │ │ ├── select_simple_with_with_clause.sql │ │ │ ├── select_table_alias_without_keyword.sql │ │ │ ├── select_table_function_with_query.sql │ │ │ ├── select_when_condition.sql │ │ │ ├── select_window_comprehensive.sql │ │ │ ├── select_window_cte.sql │ │ │ ├── select_window_keyword_name_in_parens.sql │ │ │ ├── select_window_named_in_parens.sql │ │ │ ├── select_window_named_reference_extensions.sql │ │ │ ├── select_window_params.sql │ │ │ ├── select_with_distinct.sql │ │ │ ├── select_with_distinct_keyword.sql │ │ │ ├── select_with_distinct_on_dotted_columns.sql │ │ │ ├── select_with_distinct_on_keyword.sql │ │ │ ├── select_with_group_by.sql │ │ │ ├── select_with_join_only.sql │ │ │ ├── select_with_keyword_in_group_by.sql │ │ │ ├── select_with_keyword_placeholder.sql │ │ │ ├── select_with_left_join.sql │ │ │ ├── select_with_literal_table_name.sql │ │ │ ├── select_with_multi_array_and_inner_join.sql │ │ │ ├── select_with_multi_array_join.sql │ │ │ ├── select_with_multi_except.sql │ │ │ ├── select_with_multi_join.sql │ │ │ ├── select_with_multi_line_comment.sql │ │ │ ├── select_with_multi_union.sql │ │ │ ├── select_with_multi_union_distinct.sql │ │ │ ├── select_with_number_field.sql │ │ │ ├── select_with_placeholder.sql │ │ │ ├── select_with_query_parameter.sql │ │ │ ├── select_with_settings_additional_table_filters.sql │ │ │ ├── select_with_single_quote_table.sql │ │ │ ├── select_with_string_expr.sql │ │ │ ├── select_with_union_distinct.sql │ │ │ ├── select_with_variable.sql │ │ │ ├── select_with_window_function.sql │ │ │ ├── select_without_from_where.sql │ │ │ └── set_simple.sql │ │ ├── create_window_view.sql │ │ ├── query_with_expr_compare.sql │ │ ├── select_case_multiple_when.sql │ │ ├── select_case_when_exists.sql │ │ ├── select_cast.sql │ │ ├── select_column_alias_string.sql │ │ ├── select_concat_expr.sql │ │ ├── select_expr.sql │ │ ├── select_extract_with_regex.sql │ │ ├── select_item_with_modifiers.sql │ │ ├── select_json_type.sql │ │ ├── select_keyword_alias_no_as.sql │ │ ├── select_order_by_timestamp.sql │ │ ├── select_order_by_with_fill_basic.sql │ │ ├── select_order_by_with_fill_from_to.sql │ │ ├── select_order_by_with_fill_interpolate.sql │ │ ├── select_order_by_with_fill_interpolate_no_columns.sql │ │ ├── select_order_by_with_fill_staleness.sql │ │ ├── select_order_by_with_fill_step.sql │ │ ├── select_simple.sql │ │ ├── select_simple_field_alias.sql │ │ ├── select_simple_with_bracket.sql │ │ ├── select_simple_with_cte_with_column_aliases.sql │ │ ├── select_simple_with_group_by_with_cube_totals.sql │ │ ├── select_simple_with_is_not_null.sql │ │ ├── select_simple_with_is_null.sql │ │ ├── select_simple_with_limit.sql │ │ ├── select_simple_with_top_clause.sql │ │ ├── select_simple_with_with_clause.sql │ │ ├── select_table_alias_without_keyword.sql │ │ ├── select_table_function_with_query.sql │ │ ├── select_when_condition.sql │ │ ├── select_window_comprehensive.sql │ │ ├── select_window_cte.sql │ │ ├── select_window_keyword_name_in_parens.sql │ │ ├── select_window_named_in_parens.sql │ │ ├── select_window_named_reference_extensions.sql │ │ ├── select_window_params.sql │ │ ├── select_with_distinct.sql │ │ ├── select_with_distinct_keyword.sql │ │ ├── select_with_distinct_on_dotted_columns.sql │ │ ├── select_with_distinct_on_keyword.sql │ │ ├── select_with_group_by.sql │ │ ├── select_with_join_only.sql │ │ ├── select_with_keyword_in_group_by.sql │ │ ├── select_with_keyword_placeholder.sql │ │ ├── select_with_left_join.sql │ │ ├── select_with_literal_table_name.sql │ │ ├── select_with_multi_array_and_inner_join.sql │ │ ├── select_with_multi_array_join.sql │ │ ├── select_with_multi_except.sql │ │ ├── select_with_multi_join.sql │ │ ├── select_with_multi_line_comment.sql │ │ ├── select_with_multi_union.sql │ │ ├── select_with_multi_union_distinct.sql │ │ ├── select_with_number_field.sql │ │ ├── select_with_placeholder.sql │ │ ├── select_with_query_parameter.sql │ │ ├── select_with_settings_additional_table_filters.sql │ │ ├── select_with_single_quote_table.sql │ │ ├── select_with_string_expr.sql │ │ ├── select_with_union_distinct.sql │ │ ├── select_with_variable.sql │ │ ├── select_with_window_function.sql │ │ ├── select_without_from_where.sql │ │ └── set_simple.sql │ ├── output/ │ │ ├── access_tuple_with_dot.sql.golden.json │ │ ├── create_window_view.sql.golden.json │ │ ├── query_with_expr_compare.sql.golden.json │ │ ├── select_case_multiple_when.sql.golden.json │ │ ├── select_case_when_exists.sql.golden.json │ │ ├── select_cast.sql.golden.json │ │ ├── select_column_alias_string.sql.golden.json │ │ ├── select_concat_expr.sql.golden.json │ │ ├── select_expr.sql.golden.json │ │ ├── select_extract_with_regex.sql.golden.json │ │ ├── select_item_with_modifiers.sql.golden.json │ │ ├── select_json_type.sql.golden.json │ │ ├── select_keyword_alias_no_as.sql.golden.json │ │ ├── select_order_by_timestamp.sql.golden.json │ │ ├── select_order_by_with_fill_basic.sql.golden.json │ │ ├── select_order_by_with_fill_from_to.sql.golden.json │ │ ├── select_order_by_with_fill_interpolate.sql.golden.json │ │ ├── select_order_by_with_fill_interpolate_no_columns.sql.golden.json │ │ ├── select_order_by_with_fill_staleness.sql.golden.json │ │ ├── select_order_by_with_fill_step.sql.golden.json │ │ ├── select_simple.sql.golden.json │ │ ├── select_simple_field_alias.sql.golden.json │ │ ├── select_simple_with_bracket.sql.golden.json │ │ ├── select_simple_with_cte_with_column_aliases.sql.golden.json │ │ ├── select_simple_with_group_by_with_cube_totals.sql.golden.json │ │ ├── select_simple_with_is_not_null.sql.golden.json │ │ ├── select_simple_with_is_null.sql.golden.json │ │ ├── select_simple_with_limit.sql.golden.json │ │ ├── select_simple_with_top_clause.sql.golden.json │ │ ├── select_simple_with_with_clause.sql.golden.json │ │ ├── select_table_alias_without_keyword.sql.golden.json │ │ ├── select_table_function_with_query.sql.golden.json │ │ ├── select_when_condition.sql.golden.json │ │ ├── select_window_comprehensive.sql.golden.json │ │ ├── select_window_cte.sql.golden.json │ │ ├── select_window_keyword_name_in_parens.sql.golden.json │ │ ├── select_window_named_in_parens.sql.golden.json │ │ ├── select_window_named_reference_extensions.sql.golden.json │ │ ├── select_window_params.sql.golden.json │ │ ├── select_with_distinct.sql.golden.json │ │ ├── select_with_distinct_keyword.sql.golden.json │ │ ├── select_with_distinct_on_dotted_columns.sql.golden.json │ │ ├── select_with_distinct_on_keyword.sql.golden.json │ │ ├── select_with_group_by.sql.golden.json │ │ ├── select_with_join_only.sql.golden.json │ │ ├── select_with_keyword_in_group_by.sql.golden.json │ │ ├── select_with_keyword_placeholder.sql.golden.json │ │ ├── select_with_left_join.sql.golden.json │ │ ├── select_with_literal_table_name.sql.golden.json │ │ ├── select_with_multi_array_and_inner_join.sql.golden.json │ │ ├── select_with_multi_array_join.sql.golden.json │ │ ├── select_with_multi_except.sql.golden.json │ │ ├── select_with_multi_join.sql.golden.json │ │ ├── select_with_multi_line_comment.sql.golden.json │ │ ├── select_with_multi_union.sql.golden.json │ │ ├── select_with_multi_union_distinct.sql.golden.json │ │ ├── select_with_number_field.sql.golden.json │ │ ├── select_with_placeholder.sql.golden.json │ │ ├── select_with_query_parameter.sql.golden.json │ │ ├── select_with_settings_additional_table_filters.sql.golden.json │ │ ├── select_with_single_quote_table.sql.golden.json │ │ ├── select_with_string_expr.sql.golden.json │ │ ├── select_with_union_distinct.sql.golden.json │ │ ├── select_with_variable.sql.golden.json │ │ ├── select_with_window_function.sql.golden.json │ │ ├── select_without_from_where.sql.golden.json │ │ └── set_simple.sql.golden.json │ ├── query_with_expr_compare.sql │ ├── select_case_multiple_when.sql │ ├── select_case_when_exists.sql │ ├── select_cast.sql │ ├── select_column_alias_string.sql │ ├── select_concat_expr.sql │ ├── select_expr.sql │ ├── select_extract_with_regex.sql │ ├── select_item_with_modifiers.sql │ ├── select_json_type.sql │ ├── select_keyword_alias_no_as.sql │ ├── select_order_by_timestamp.sql │ ├── select_order_by_with_fill_basic.sql │ ├── select_order_by_with_fill_from_to.sql │ ├── select_order_by_with_fill_interpolate.sql │ ├── select_order_by_with_fill_interpolate_no_columns.sql │ ├── select_order_by_with_fill_staleness.sql │ ├── select_order_by_with_fill_step.sql │ ├── select_simple.sql │ ├── select_simple_field_alias.sql │ ├── select_simple_with_bracket.sql │ ├── select_simple_with_cte_with_column_aliases.sql │ ├── select_simple_with_group_by_with_cube_totals.sql │ ├── select_simple_with_is_not_null.sql │ ├── select_simple_with_is_null.sql │ ├── select_simple_with_limit.sql │ ├── select_simple_with_top_clause.sql │ ├── select_simple_with_with_clause.sql │ ├── select_table_alias_without_keyword.sql │ ├── select_table_function_with_query.sql │ ├── select_when_condition.sql │ ├── select_window_comprehensive.sql │ ├── select_window_cte.sql │ ├── select_window_keyword_name_in_parens.sql │ ├── select_window_named_in_parens.sql │ ├── select_window_named_reference_extensions.sql │ ├── select_window_params.sql │ ├── select_with_distinct.sql │ ├── select_with_distinct_keyword.sql │ ├── select_with_distinct_on_dotted_columns.sql │ ├── select_with_distinct_on_keyword.sql │ ├── select_with_group_by.sql │ ├── select_with_join_only.sql │ ├── select_with_keyword_in_group_by.sql │ ├── select_with_keyword_placeholder.sql │ ├── select_with_left_join.sql │ ├── select_with_literal_table_name.sql │ ├── select_with_multi_array_and_inner_join.sql │ ├── select_with_multi_array_join.sql │ ├── select_with_multi_except.sql │ ├── select_with_multi_join.sql │ ├── select_with_multi_line_comment.sql │ ├── select_with_multi_union.sql │ ├── select_with_multi_union_distinct.sql │ ├── select_with_number_field.sql │ ├── select_with_placeholder.sql │ ├── select_with_query_parameter.sql │ ├── select_with_settings_additional_table_filters.sql │ ├── select_with_single_quote_table.sql │ ├── select_with_string_expr.sql │ ├── select_with_union_distinct.sql │ ├── select_with_variable.sql │ ├── select_with_window_function.sql │ ├── select_without_from_where.sql │ └── set_simple.sql ├── type.go ├── visitor_test.go ├── walk.go └── walk_test.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/ci.yaml ================================================ name: CI Actions permissions: contents: read on: push: branches: - master pull_request: branches: - master jobs: workflow: name: Lint/Build/Test strategy: matrix: go-version: [1.21.x] os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} steps: - name: Install Go uses: actions/setup-go@v2 with: go-version: ${{matrix.go-version}} - name: Checkout Code Base uses: actions/checkout@v3 with: fetch-depth: '0' - name: Restore Go Module Cache uses: actions/cache@v4 with: path: ~/go/internal/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - name: Make Lint run: | export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.3 go mod tidy make lint - name: Test run: make test - name: Install goveralls run: go install github.com/mattn/goveralls@latest - name: Send coverage env: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: goveralls -coverprofile=coverage.out -service=github ================================================ FILE: .gitignore ================================================ # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Dependency directories (remove the comment below to include it) # vendor/ .vscode .idea .DS_Store # Binary main clickhouse-sql-parser ================================================ FILE: .golangci.yml ================================================ # This file contains all available configuration options # with their default values. # options for analysis running run: # default concurrency is a available CPU number concurrency: 4 # timeout for analysis, e.g. 30s, 5m, default is 1m timeout: 5m # exit code when at least one issue was found, default is 1 issues-exit-code: 1 # include test files or not, default is true tests: true # list of build tags, all linters use it. Default is empty list. build-tags: # which dirs to skip: issues from them won't be reported; # can use regexp here: generated.*, regexp is applied on full path; # default value is empty list, but default dirs are skipped independently # from this option's value (see skip-dirs-use-default). skip-dirs: # default is true. Enables skipping of directories: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ skip-dirs-use-default: true # which files to skip: they will be analyzed, but issues from them # won't be reported. Default value is empty list, but there is # no need to include all autogenerated files, we confidently recognize # autogenerated files. If it's not please let us know. skip-files: # output configuration options output: # colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions # default is "colored-line-number" format: colored-line-number # print lines of code with issue, default is true print-issued-lines: true # print linter name in the end of issue text, default is true print-linter-name: true # make issues output unique by line, default is true uniq-by-line: true # add a prefix to the output file references; default is no prefix path-prefix: "" # sorts results by: filepath, line and column sort-results: false # all available settings of specific linters linters-settings: dogsled: # checks assignments with too many blank identifiers; default is 2 max-blank-identifiers: 2 dupl: # tokens count to trigger issue, 150 by default threshold: 100 errcheck: # default is false: such cases aren't reported by default. check-type-assertions: false # default is false: such cases aren't reported by default. check-blank: false # list of functions to exclude from checking, where each entry is a single function to exclude. # see https://github.com/kisielk/errcheck#excluding-functions for details exclude-functions: errchkjson: # with check-error-free-encoding set to true, errchkjson does warn about errors # from json encoding functions that are safe to be ignored, # because they are not possible to happen (default false) # # if check-error-free-encoding is set to true and errcheck linter is enabled, # it is recommended to add the following exceptions to prevent from false positives: # # linters-settings: # errcheck: # exclude-functions: # - encoding/json.Marshal # - encoding/json.MarshalIndent # - (*encoding/json.Encoder).Encode check-error-free-encoding: false # if report-no-exported is true, encoding a struct without exported fields is reported as issue (default false) report-no-exported: false errorlint: # Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats errorf: true # Check for plain type assertions and type switches asserts: true # Check for plain error comparisons comparison: true funlen: lines: 100 statements: 60 gocognit: # minimal code complexity to report, 30 by default (but we recommend 10-20) min-complexity: 20 goconst: # minimal length of string constant, 3 by default min-len: 3 # minimum occurrences of constant string count to trigger issue, 3 by default min-occurrences: 3 # ignore test files, false by default ignore-tests: false # look for existing constants matching the values, true by default match-constant: true # search also for duplicated numbers, false by default numbers: false # minimum value, only works with goconst.numbers, 3 by default min: 3 # maximum value, only works with goconst.numbers, 3 by default max: 3 # ignore when constant is not used as function argument, true by default ignore-calls: true gocritic: # Which checks should be enabled; can't be combined with 'disabled-checks'; # See https://go-critic.github.io/overview#checks-overview # By default list of stable checks is used. enabled-checks: # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". enabled-tags: - performance # Settings passed to gocritic. # The settings key is the name of a supported gocritic checker. # The list of supported checkers can be find in https://go-critic.github.io/overview. settings: captLocal: # must be valid enabled check name # whether to restrict checker to params only (default true) paramsOnly: true elseif: # whether to skip balanced if-else pairs (default true) skipBalanced: true hugeParam: # size in bytes that makes the warning trigger (default 80) sizeThreshold: 80 rangeExprCopy: # size in bytes that makes the warning trigger (default 512) sizeThreshold: 512 # whether to check test functions (default true) skipTestFuncs: true rangeValCopy: # size in bytes that makes the warning trigger (default 128) sizeThreshold: 128 # whether to check test functions (default true) skipTestFuncs: true underef: # whether to skip (*x).method() calls where x is a pointer receiver (default true) skipRecvDeref: true gocyclo: # minimal code complexity to report, 30 by default (but we recommend 10-20) min-complexity: 10 godot: scope: declarations # list of regexps for excluding particular comment lines from check exclude: # example: exclude comments which contain numbers # - '[0-9]+' # check that each sentence starts with a capital letter capital: false godox: # report any comments starting with keywords, this is useful for TODO or FIXME comments that # might be left in the code accidentally and should be resolved before merging keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting gofmt: simplify: true goimports: # put imports beginning with prefix after 3rd-party packages; # it's a comma-separated list of prefixes local-prefixes: golint: # minimal confidence for issues, default is 0.8 min-confidence: 0.8 gomnd: settings: mnd: # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. checks: argument,case,condition,operation,return,assign # ignored-numbers: 1000 # ignored-files: magic_.*.go # ignored-functions: math.* gomoddirectives: replace-local: false replace-allow-list: retract-allow-no-explanation: false exclude-forbidden: false gomodguard: allowed: modules: # List of allowed modules # - gopkg.in/yaml.v2 domains: # List of allowed module domains # - golang.org blocked: modules: # List of blocked modules # - github.com/uudashr/go-module: # Blocked module # recommendations: # Recommended modules that should be used instead (Optional) # - golang.org/x/mod versions: # List of blocked module version constraints # - github.com/mitchellh/go-homedir: # Blocked module with version constraint # version: "< 1.1.0" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons # reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional) local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive gosec: # To select a subset of rules to run. # Available rules: https://github.com/securego/gosec#available-rules includes: - G401 - G306 - G101 # To specify a set of rules to explicitly exclude. # Available rules: https://github.com/securego/gosec#available-rules excludes: - G204 # Exclude generated files exclude-generated: true # Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high. severity: "low" # Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high. confidence: "low" # To specify the configuration of rules. # The configuration of rules is not fully documented by gosec: # https://github.com/securego/gosec#configuration # https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102 config: G306: "0600" G101: pattern: "(?i)example" ignore_entropy: false entropy_threshold: "80.0" per_char_threshold: "3.0" truncate: "32" gosimple: # Select the Go version to target. The default is '1.13'. go: "1.15" # https://staticcheck.io/docs/options#checks checks: [ "all" ] govet: # report about shadowed variables check-shadowing: false # settings per analyzer settings: printf: funcs: - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf # enable or disable analyzers by name enable: # - atomicalign enable-all: true disable: - shadow - fieldalignment disable-all: false depguard: list-type: blacklist include-go-root: false packages: # - github.com/sirupsen/logrus packages-with-error-message: # specify an error message to output when a blacklisted package is used # - github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" ifshort: # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax. # Has higher priority than max-decl-chars. max-decl-lines: 1 # Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax. max-decl-chars: 30 lll: # max line length, lines longer will be reported. Default is 120. # '\t' is counted as 1 character by default, and can be changed with the tab-width option line-length: 160 # tab width in spaces. Default to 1. tab-width: 4 makezero: # Allow only slices initialized with a length of zero. Default is false. always: false maligned: # print struct with more effective memory layout or not, false by default suggest-new: true misspell: # Correct spellings using locale preferences for US or UK. # Default is to use a neutral variety of English. # Setting locale to US will correct the British spelling of 'colour' to 'color'. locale: US ignore-words: - automizely nakedret: # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 max-func-lines: 30 nestif: # minimal complexity of if statements to report, 5 by default min-complexity: 5 nlreturn: # size of the block (including return statement that is still "OK") # so no return split required. block-size: 1 nolintlint: # Disable to ensure that all nolint directives actually have an effect. Default is false. allow-unused: false # Disable to ensure that nolint directives don't have a leading space. Default is true. allow-leading-space: true # Exclude following linters from requiring an explanation. Default is []. allow-no-explanation: [ ] # Enable to require an explanation of nonzero length after each nolint directive. Default is false. require-explanation: false # Enable to require nolint directives to mention the specific linter being suppressed. Default is false. require-specific: false prealloc: # XXX: we don't recommend using this linter before doing performance profiling. # For most programs usage of prealloc will be a premature optimization. # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them. # True by default. simple: true range-loops: true # Report preallocation suggestions on range loops, true by default for-loops: false # Report preallocation suggestions on for loops, false by default promlinter: # Promlinter cannot infer all metrics name in static analysis. # Enable strict mode will also include the errors caused by failing to parse the args. strict: false # Please refer to https://github.com/yeya24/promlinter#usage for detailed usage. disabled-linters: # - "Help" # - "MetricUnits" # - "Counter" # - "HistogramSummaryReserved" # - "MetricTypeInName" # - "ReservedChars" # - "CamelCase" # - "lintUnitAbbreviations" predeclared: # comma-separated list of predeclared identifiers to not report on ignore: "" # include method names and field names (i.e., qualified names) in checks q: false rowserrcheck: packages: - github.com/jmoiron/sqlx revive: # see https://github.com/mgechev/revive#available-rules for details. ignore-generated-header: true severity: warning rules: - name: indent-error-flow severity: warning staticcheck: # Select the Go version to target. The default is '1.13'. go: "1.15" # https://staticcheck.io/docs/options#checks checks: [ "all" ] stylecheck: # Select the Go version to target. The default is '1.13'. go: "1.15" # https://staticcheck.io/docs/options#checks checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ] # https://staticcheck.io/docs/options#dot_import_whitelist dot-import-whitelist: # https://staticcheck.io/docs/options#initialisms initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ] # https://staticcheck.io/docs/options#http_status_code_whitelist http-status-code-whitelist: [] tagliatelle: # check the struck tag name case case: # use the struct field name to check the name of the struct tag use-field-name: true rules: # any struct tag type can be used. json: snake testpackage: # regexp pattern to skip files skip-regexp: (export|internal)_test\.go unparam: # Inspect exported functions, default is false. Set to true if no external program/library imports your code. # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: # if it's called for subdir of a project it can't find external interfaces. All text editor integrations # with golangci-lint call it on a directory with the changed file. check-exported: false unused: # Select the Go version to target. The default is '1.13'. go: "1.15" whitespace: multi-if: false # Enforces newlines (or comments) after every multi-line if statement multi-func: false # Enforces newlines (or comments) after every multi-line function signature wsl: allow-assign-and-anything: false allow-assign-and-call: true allow-cuddle-declarations: false allow-multiline-assign: true allow-separated-leading-comment: false allow-trailing-comment: false force-case-trailing-whitespace: 0 force-err-cuddling: false force-short-decl-cuddling: false strict-append: true linters: enable: - dogsled - forcetypeassert - funlen - goconst - govet - gofmt - goimports - lll - megacheck - misspell - revive disable: - maligned - prealloc - scopelint - nilnil disable-all: false presets: - bugs - unused - sql fast: false issues: # List of regexps of issue texts to exclude, empty list by default. # But independently from this option we use default exclude patterns, exclude: - G404 - SA1029 # Excluding configuration per-path, per-linter, per-text and per-source exclude-rules: # Exclude some linters from running on tests files. - path: _test\.go linters: - cyclop - dupl - errcheck - funlen - gocognit - goconst - gocritic - gocyclo - gosec - lll - thelper - wrapcheck # Exclude known linters from partially hard-vendored code, # which is impossible to exclude via "nolint" comments. - path: internal/hmac/ text: "weak cryptographic primitive" linters: - gosec # Exclude some staticcheck messages - linters: - staticcheck text: "SA9003:" # Exclude lll issues for long lines with go:generate - linters: - lll source: "^//go:generate " # Default value for this option is true. exclude-use-default: true # The default value is false. If set to true exclude and exclude-rules # regular expressions become case sensitive. exclude-case-sensitive: false # The list of ids of default excludes to include or disable. By default it's empty. include: # - EXC0002 # disable excluding of issues about comments from golint # Maximum issues count per one linter. Set to 0 to disable. Default is 50. max-issues-per-linter: 0 # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. max-same-issues: 0 # Show only new issues: if there are unstaged changes or untracked files, # only those changes are analyzed, else only changes in HEAD~ are analyzed. # It's a super-useful option for integration of golangci-lint into existing # large codebase. It's not practical to fix all existing issues at the moment # of integration: much better don't allow issues in new code. # Default is false. new: true new-from-rev: "" # Show only new issues created in git patch with set file path. new-from-patch: # Fix found issues (if it's supported by the linter) fix: true severity: # Default value is empty string. # Set the default severity for issues. If severity rules are defined and the issues # do not match or no severity is provided to the rule this will be the default # severity applied. Severities should match the supported severity names of the # selected out format. # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message default-severity: error # The default value is false. # If set to true severity-rules regular expressions become case sensitive. case-sensitive: false # Default value is empty list. # When a list of severity rules are provided, severity information will be added to lint # issues. Severity rules have the same filtering capability as exclude rules except you # are allowed to specify one matcher per severity rule. # Only affects out formats that support setting severity information. rules: - linters: - dupl severity: info ================================================ FILE: AGENTS.md ================================================ # AI Agents Guidline This document outlines guidance for AI coding agent including project structure, coding style, testing, and contribution practices for the ClickHouse SQL Parser project. ## Development Commands ```shell # Build the CLI binary make # Run tests make test # Update golden fixtures after intentional output changes make update_test ``` After editing code, use `goimports` and `gofmt` to maintain code style, and run `make lint` to check for any issues before committing or requesting a review. ## Project Structure & Module Organization - `main.go` is the CLI entry point (`clickhouse-sql-parser`) for AST output and SQL formatting. - `parser/` contains core parser code: lexer (`lexer.go`), AST definitions (`ast.go`), traversal helpers (`walk.go`), and grammar-specific parser files (`parser_query.go`, `parser_table.go`, `parser_alter.go`, etc.). - Tests live next to source as `*_test.go` files, with fixtures under `parser/testdata/`. - Fixture groups are organized by SQL type (`basic/`, `query/`, `dml/`, `ddl/`), with generated expectations in `output/` (AST JSON) and `format/` (formatted SQL). ## Coding Style & Naming Conventions - Use Go 1.21 conventions (`go.mod`) and keep code `gofmt`/`goimports` clean (enforced by lint). - Naming is the most important style aspect, try you best to choose a clear and descriptive name for variables, functions, types, and files. For example, use `parseSelect` for a function that parses a SELECT statement, and `SelectStatement` for the corresponding AST node type. - Place parsing logic in the matching module by statement family (for example, query parsing in `parser/parser_query.go`). - Follow existing parser naming patterns such as `parseXxx` helpers and explicit AST type names. - Keep AST `FormatSQL()` output deterministic; formatting changes must be reflected in golden files. - You must go through the repository before adding new code to ensure consistency with existing patterns and styles. If you are unsure about where to place new code or how to format it, please refer to the existing codebase or ask for guidance. - Reusing existing code and patterns is encouraged to maintain consistency and reduce redundancy. If you find a similar function or pattern in the codebase, consider adapting it for your needs instead of creating something new from scratch. ## Testing Guidelines - Use Go’s `testing` package with `testify/require` assertions and `goldie` snapshot comparisons. - Add new SQL cases as `.sql` files under the appropriate `parser/testdata//` directory. - If expected outputs change, run `make update_test` and commit updated files in both `output/` and/or `format/`. - Prefer descriptive test names (`TestParser_*`, `TestWalk_*`) and subtests for per-fixture coverage. ## Commit & Pull Request Guidelines - Match existing commit style: concise, imperative subjects like `Add support for ...` or `Fix parsing failure ...`, optionally with issue refs (for example `(#235)`). - Keep PRs focused; describe grammar/AST impact, include representative SQL examples, and note regenerated fixtures. - Before requesting review, run `make lint` and `make test` locally to mirror CI expectations. ## Important Notes - You must confirm it's correctly added to `visitor.go`, `walk.go` and `format.go` when adding a new expression or statement type. This ensures that the new AST node is properly traversed and formatted. - Newly added test cases must be concise and cover the core functionality being tested first. ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2023 AfterShip Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ PROGRAM=clickhouse-sql-parser PKG_FILES=`go list ./... | sed -e 's=github.com/AfterShip/clickhouse-sql-parser/=./='` CCCOLOR="\033[37;1m" MAKECOLOR="\033[32;1m" ENDCOLOR="\033[0m" all: $(PROGRAM) .PHONY: all $(PROGRAM): go build -o $(PROGRAM) main.go test: @go test -v ./... -covermode=atomic -coverprofile=coverage.out -race -compatible update_test: @go test -v ./... -update -race -compatible lint: @printf $(CCCOLOR)"GolangCI Lint...\n"$(ENDCOLOR) @golangci-lint run --timeout 20m0s ================================================ FILE: README.md ================================================ # ClickHouse SQL Parser ![GitHub CI](https://github.com/AfterShip/clickhouse-sql-parser/actions/workflows/ci.yaml/badge.svg) [![Go Report Card](https://goreportcard.com/badge/github.com/AfterShip/clickhouse-sql-parser)](https://goreportcard.com/report/github.com/AfterShip/clickhouse-sql-parser) [![LICENSE](https://img.shields.io/github/license/AfterShip/clickhouse-sql-parser.svg)](https://github.com/AfterShip/clickhouse-sql-parser/blob/master/LICENSE) [![GoDoc](https://img.shields.io/badge/Godoc-reference-blue.svg)](https://godoc.org/github.com/AfterShip/clickhouse-sql-parser) [![Coverage Status](https://coveralls.io/repos/github/AfterShip/clickhouse-sql-parser/badge.svg?branch=master)](https://coveralls.io/github/AfterShip/clickhouse-sql-parser?branch=master) Featured|HelloGitHub The goal of this project is to build a ClickHouse SQL parser in Go with the following key features: - Parse ClickHouse SQL into AST - Beautify ClickHouse SQL format This project is inspired by [memefish](https://github.com/cloudspannerecosystem/memefish) which is a SQL parser for Spanner in Go. ## How to use You can use it as your Go library or CLI tool, see the following examples: - Use clickhouse-sql-parser as a Go library ```Go package main import ( clickhouse "github.com/AfterShip/clickhouse-sql-parser/parser" ) query := "SELECT * FROM clickhouse" parser := clickhouse.NewParser(query) // Parse query into AST statements, err := parser.ParseStmts() if err != nil { return nil, err } ``` - Install clickhouse-sql-parser as a CLI tool On Linux: ```bash $ go install github.com/AfterShip/clickhouse-sql-parser@latest ``` On macOS: ```bash $ brew install clickhouse-sql-parser ``` Parse ClickHouse SQL into AST or format ClickHouse SQL: ```bash ## Parse query into AST $ clickhouse-sql-parser "SELECT * FROM clickhouse WHERE a=100" ## Format query (compact, single-line output) $ clickhouse-sql-parser -format "SELECT * FROM clickhouse WHERE a=100" ## Beautify query (formatted with proper indentation and line breaks) $ clickhouse-sql-parser -beautify "SELECT * FROM clickhouse WHERE a=100" ## Parse query from file $ clickhouse-sql-parser -f ./test.sql ``` ### Beautify SQL Example The `-beautify` flag formats SQL with proper indentation and line breaks, making complex queries more readable: ```SQL # Input (compact, hard to read) $ clickhouse-sql-parser -beautify "SELECT user_id, COUNT(*) AS total, AVG(amount) AS avg_amount FROM orders WHERE status='completed' AND created_at>'2024-01-01' GROUP BY user_id HAVING COUNT(*)>5 ORDER BY total DESC LIMIT 10" # Output (beautified, easy to read) SELECT user_id, COUNT(*) AS total, AVG(amount) AS avg_amount FROM orders WHERE status = 'completed' AND created_at > '2024-01-01' GROUP BY user_id HAVING COUNT(*) > 5 ORDER BY total DESC LIMIT 10 ``` - Parsed tree(AST) back into a SQL statement ```Go parser := clickhouse.NewParser("SELECT * FROM clickhouse") // Parse query into AST statements, err := parser.ParseStmts() if err != nil { return nil, err } // Format AST back into a SQL string for _, stmt := range statements { fmt.Println(clickhouse.Format(stmt)) } ``` ## AST Traversal ### Walk Pattern (Recommended) The Walk pattern provides a simple and efficient way to traverse AST nodes. Use the `Walk` function to visit all nodes in the AST: ```Go import ( clickhouse "github.com/AfterShip/clickhouse-sql-parser/parser" ) parser := clickhouse.NewParser("SELECT * FROM table WHERE id = 1") statements, err := parser.ParseStmts() if err != nil { return err } // Walk through all nodes in the AST clickhouse.Walk(statements[0], func(node clickhouse.Expr) bool { fmt.Printf("Node type: %T\n", node) return true // return false to stop traversal for this subtree }) ``` #### Walk Pattern Functions - **`Walk(node Expr, fn WalkFunc)`** - Traverses all nodes in depth-first order - **`WalkWithBreak(node Expr, fn WalkFunc)`** - Allows early termination of traversal - **`Find(root Expr, predicate func(Expr) bool)`** - Finds the first node matching a condition - **`FindAll(root Expr, predicate func(Expr) bool)`** - Finds all nodes matching a condition - **`Transform(root Expr, transformer func(Expr) Expr)`** - Applies transformations to nodes #### Examples Find all table identifiers: ```Go tables := clickhouse.FindAll(stmt, func(node clickhouse.Expr) bool { _, ok := node.(*clickhouse.TableIdentifier) return ok }) ``` Find the first WHERE clause: ```Go whereClause, found := clickhouse.Find(stmt, func(node clickhouse.Expr) bool { _, ok := node.(*clickhouse.WhereClause) return ok }) ``` ## Update test assets For the files inside `output` and `format` dir are generated by the test cases, if you want to update them, you can run the following command: ```bash $ make update_test ``` ## Benchmarks ```sh go test -bench=. -benchmem ./parser ``` Results ``` $ go test -bench=. -benchmem ./parser goos: linux goarch: amd64 pkg: github.com/AfterShip/clickhouse-sql-parser/parser cpu: Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz BenchmarkParseSQLFiles/access_tuple_with_dot.sql-28 23294 58467 ns/op 13448 B/op 293 allocs/op BenchmarkParseSQLFiles/query_with_expr_compare.sql-28 43560 25704 ns/op 6240 B/op 132 allocs/op BenchmarkParseSQLFiles/select_cast.sql-28 75055 16518 ns/op 4648 B/op 92 allocs/op BenchmarkParseSQLFiles/select_column_alias_string.sql-28 499798 2785 ns/op 704 B/op 13 allocs/op BenchmarkParseSQLFiles/select_expr.sql-28 488187 2448 ns/op 696 B/op 12 allocs/op BenchmarkParseSQLFiles/select_item_with_modifiers.sql-28 54124 23305 ns/op 6232 B/op 136 allocs/op BenchmarkParseSQLFiles/select_order_by_timestamp.sql-28 232302 5809 ns/op 1368 B/op 28 allocs/op BenchmarkParseSQLFiles/select_simple.sql-28 30602 50022 ns/op 9920 B/op 216 allocs/op BenchmarkParseSQLFiles/select_simple_field_alias.sql-28 178126 6316 ns/op 1712 B/op 39 allocs/op BenchmarkParseSQLFiles/select_simple_with_bracket.sql-28 71902 16172 ns/op 3824 B/op 85 allocs/op BenchmarkParseSQLFiles/select_simple_with_cte_with_column_aliases.sql-28 67050 19916 ns/op 4648 B/op 101 allocs/op BenchmarkParseSQLFiles/select_simple_with_group_by_with_cube_totals.sql-28 107047 10348 ns/op 2768 B/op 58 allocs/op BenchmarkParseSQLFiles/select_simple_with_is_not_null.sql-28 55285 21957 ns/op 5224 B/op 111 allocs/op BenchmarkParseSQLFiles/select_simple_with_is_null.sql-28 66648 22412 ns/op 4728 B/op 102 allocs/op BenchmarkParseSQLFiles/select_simple_with_top_clause.sql-28 269910 4166 ns/op 1088 B/op 22 allocs/op BenchmarkParseSQLFiles/select_simple_with_with_clause.sql-28 58494 18417 ns/op 5144 B/op 109 allocs/op BenchmarkParseSQLFiles/select_table_alias_without_keyword.sql-28 121261 10011 ns/op 2896 B/op 65 allocs/op BenchmarkParseSQLFiles/select_table_function_with_query.sql-28 98017 14929 ns/op 4168 B/op 81 allocs/op BenchmarkParseSQLFiles/select_when_condition.sql-28 220394 5457 ns/op 1304 B/op 28 allocs/op BenchmarkParseSQLFiles/select_with_distinct.sql-28 172948 6531 ns/op 1560 B/op 33 allocs/op BenchmarkParseSQLFiles/select_with_join_only.sql-28 286346 5594 ns/op 1520 B/op 32 allocs/op BenchmarkParseSQLFiles/select_with_left_join.sql-28 88200 13627 ns/op 3880 B/op 75 allocs/op BenchmarkParseSQLFiles/select_with_literal_table_name.sql-28 241094 5099 ns/op 1304 B/op 27 allocs/op BenchmarkParseSQLFiles/select_with_multi_join.sql-28 44700 31964 ns/op 8240 B/op 188 allocs/op BenchmarkParseSQLFiles/select_with_multi_line_comment.sql-28 363499 4460 ns/op 824 B/op 18 allocs/op BenchmarkParseSQLFiles/select_with_multi_union.sql-28 146233 7827 ns/op 2176 B/op 36 allocs/op BenchmarkParseSQLFiles/select_with_number_field.sql-28 129945 8746 ns/op 2352 B/op 51 allocs/op BenchmarkParseSQLFiles/select_with_query_parameter.sql-28 33850 36346 ns/op 9936 B/op 209 allocs/op BenchmarkParseSQLFiles/select_with_string_expr.sql-28 142882 7530 ns/op 1880 B/op 34 allocs/op BenchmarkParseSQLFiles/select_with_union_distinct.sql-28 147031 9601 ns/op 2352 B/op 47 allocs/op BenchmarkParseSQLFiles/select_with_variable.sql-28 179158 6669 ns/op 1880 B/op 36 allocs/op BenchmarkParseSQLFiles/select_with_window_function.sql-28 54925 31320 ns/op 6720 B/op 136 allocs/op BenchmarkParseSQLFiles/select_with_placeholder.sql-28 196771 5145 ns/op 1272 B/op 26 allocs/op BenchmarkParseSQLFiles/set_simple.sql-28 172419 7062 ns/op 2480 B/op 49 allocs/op BenchmarkParseComplexQueries/testdata/query/select_with_multi_join.sql-28 39056 36897 ns/op 8240 B/op 188 allocs/op BenchmarkParseComplexQueries/testdata/query/select_with_window_function.sql-28 47629 29916 ns/op 6720 B/op 136 allocs/op BenchmarkParseComplexQueries/testdata/query/select_simple_with_with_clause.sql-28 69210 19731 ns/op 5144 B/op 109 allocs/op BenchmarkParseComplexQueries/testdata/query/select_with_left_join.sql-28 74576 15338 ns/op 3880 B/op 75 allocs/op BenchmarkParseComplexQueries/testdata/benchdata/posthog_huge_0.sql-28 235 6231253 ns/op 1236189 B/op 26696 allocs/op BenchmarkParseComplexQueries/testdata/benchdata/posthog_huge_1.sql-28 279 4438280 ns/op 1043374 B/op 22717 allocs/op PASS ok github.com/AfterShip/clickhouse-sql-parser/parser 66.547s ``` ## Contact us Feel free to open an issue or discussion if you have any issues or questions. ================================================ FILE: go.mod ================================================ module github.com/AfterShip/clickhouse-sql-parser go 1.21.0 require ( github.com/sebdah/goldie/v2 v2.5.3 github.com/stretchr/testify v1.8.4 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) ================================================ FILE: go.sum ================================================ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= ================================================ FILE: main.go ================================================ package main import ( "encoding/json" "flag" "fmt" "os" "strings" clickhouse "github.com/AfterShip/clickhouse-sql-parser/parser" ) const VERSION = "0.4.17" const help = ` Usage: clickhouse-sql-parser [YOUR SQL STRING] -f [YOUR SQL FILE] -format -beautify ` var options struct { help bool file string format bool beautify bool version bool } func init() { flag.BoolVar(&options.format, "format", false, "Print formatted ClickHouse SQL") flag.BoolVar(&options.beautify, "beautify", false, "Beautify print the ClickHouse SQL") flag.StringVar(&options.file, "f", "", "Parse SQL from file") flag.BoolVar(&options.help, "h", false, "Print help message") flag.BoolVar(&options.version, "v", false, "Print version") } func main() { flag.Parse() if options.version { fmt.Println("v" + VERSION) os.Exit(0) } if len(os.Args) < 2 || options.help { fmt.Print(help) os.Exit(0) } var err error var inputBytes []byte if options.file != "" { inputBytes, err = os.ReadFile(options.file) if err != nil { fmt.Fprintf(os.Stderr, "read file error: %s\n", err.Error()) os.Exit(1) } } else { if strings.HasPrefix(os.Args[len(os.Args)-1], "-") { fmt.Print(help) os.Exit(0) } inputBytes = []byte(os.Args[len(os.Args)-1]) } parser := clickhouse.NewParser(string(inputBytes)) stmts, err := parser.ParseStmts() if err != nil { fmt.Fprintf(os.Stderr, "parse statements error: %s\n", err.Error()) os.Exit(1) } if !options.format && !options.beautify { // print AST bytes, _ := json.MarshalIndent(stmts, "", " ") // nolint fmt.Println(string(bytes)) } else { // format SQL for _, stmt := range stmts { if options.beautify { formatter := clickhouse.NewFormatter() formatter.WithBeautify() formatter.WriteExpr(stmt) fmt.Println(formatter.String()) } else { fmt.Println(clickhouse.Format(stmt)) } } } } ================================================ FILE: parser/ast.go ================================================ package parser type OrderDirection string const ( OrderDirectionNone OrderDirection = "" OrderDirectionAsc OrderDirection = "ASC" OrderDirectionDesc OrderDirection = "DESC" ) type Expr interface { Pos() Pos End() Pos FormatSQL(*Formatter) Accept(visitor ASTVisitor) error } type DDL interface { Expr Type() string } type SelectItem struct { Expr Expr // Please refer: https://clickhouse.com/docs/en/sql-reference/statements/select#select-modifiers Modifiers []*FunctionExpr Alias *Ident } func (s *SelectItem) Pos() Pos { return s.Expr.Pos() } func (s *SelectItem) End() Pos { if s.Alias != nil { return s.Alias.End() } if len(s.Modifiers) > 0 { return s.Modifiers[len(s.Modifiers)-1].End() } return s.Expr.End() } func (s *SelectItem) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Expr.Accept(visitor); err != nil { return err } for _, modifier := range s.Modifiers { if err := modifier.Accept(visitor); err != nil { return err } } if s.Alias != nil { if err := s.Alias.Accept(visitor); err != nil { return err } } return visitor.VisitSelectItem(s) } type OperationExpr struct { OperationPos Pos Kind TokenKind } func (o *OperationExpr) Pos() Pos { return o.OperationPos } func (o *OperationExpr) End() Pos { return o.OperationPos + Pos(len(o.Kind)) } func (o *OperationExpr) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) return visitor.VisitOperationExpr(o) } type TernaryOperation struct { Condition Expr TrueExpr Expr FalseExpr Expr } func (t *TernaryOperation) Pos() Pos { return t.Condition.Pos() } func (t *TernaryOperation) End() Pos { return t.FalseExpr.End() } func (t *TernaryOperation) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.TrueExpr.Accept(visitor); err != nil { return err } if err := t.FalseExpr.Accept(visitor); err != nil { return err } if err := t.Condition.Accept(visitor); err != nil { return err } return visitor.VisitTernaryExpr(t) } type BinaryOperation struct { LeftExpr Expr Operation TokenKind RightExpr Expr HasGlobal bool HasNot bool } func (p *BinaryOperation) Pos() Pos { return p.LeftExpr.Pos() } func (p *BinaryOperation) End() Pos { return p.RightExpr.End() } func (p *BinaryOperation) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) if err := p.LeftExpr.Accept(visitor); err != nil { return err } if err := p.RightExpr.Accept(visitor); err != nil { return err } return visitor.VisitBinaryExpr(p) } type IndexOperation struct { Object Expr Operation TokenKind Index Expr } func (i *IndexOperation) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) if err := i.Object.Accept(visitor); err != nil { return err } if err := i.Index.Accept(visitor); err != nil { return err } return visitor.VisitIndexOperation(i) } func (i *IndexOperation) Pos() Pos { return i.Object.Pos() } func (i *IndexOperation) End() Pos { return i.Index.End() } type JoinTableExpr struct { Table *TableExpr StatementEnd Pos SampleRatio *SampleClause HasFinal bool } func (j *JoinTableExpr) Accept(visitor ASTVisitor) error { visitor.Enter(j) defer visitor.Leave(j) if err := j.Table.Accept(visitor); err != nil { return err } if j.SampleRatio != nil { return j.SampleRatio.Accept(visitor) } return visitor.VisitJoinTableExpr(j) } func (j *JoinTableExpr) Pos() Pos { return j.Table.Pos() } func (j *JoinTableExpr) End() Pos { return j.StatementEnd } type AlterTableClause interface { Expr AlterType() string } type AlterTable struct { AlterPos Pos StatementEnd Pos TableIdentifier *TableIdentifier OnCluster *ClusterClause AlterExprs []AlterTableClause } func (a *AlterTable) Pos() Pos { return a.AlterPos } func (a *AlterTable) End() Pos { return a.StatementEnd } func (a *AlterTable) Type() string { return "ALTER TABLE" } func (a *AlterTable) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.TableIdentifier.Accept(visitor); err != nil { return err } if a.OnCluster != nil { if err := a.OnCluster.Accept(visitor); err != nil { return err } } for _, expr := range a.AlterExprs { if err := expr.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTable(a) } type AlterTableAttachPartition struct { AttachPos Pos Partition *PartitionClause From *TableIdentifier } func (a *AlterTableAttachPartition) Pos() Pos { return a.AttachPos } func (a *AlterTableAttachPartition) End() Pos { if a.From != nil { return a.From.End() } return a.Partition.End() } func (a *AlterTableAttachPartition) AlterType() string { return "ATTACH_PARTITION" } func (a *AlterTableAttachPartition) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Partition.Accept(visitor); err != nil { return err } if a.From != nil { if err := a.From.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableAttachPartition(a) } type AlterTableDetachPartition struct { DetachPos Pos Partition *PartitionClause Settings *SettingsClause } func (a *AlterTableDetachPartition) Pos() Pos { return a.DetachPos } func (a *AlterTableDetachPartition) End() Pos { return a.Partition.End() } func (a *AlterTableDetachPartition) AlterType() string { return "DETACH_PARTITION" } func (a *AlterTableDetachPartition) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Partition.Accept(visitor); err != nil { return err } if a.Settings != nil { if err := a.Settings.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableDetachPartition(a) } type AlterTableDropPartition struct { DropPos Pos HasDetached bool Partition *PartitionClause Settings *SettingsClause } func (a *AlterTableDropPartition) Pos() Pos { return a.DropPos } func (a *AlterTableDropPartition) End() Pos { if a.Settings != nil { a.Settings.End() } return a.Partition.End() } func (a *AlterTableDropPartition) AlterType() string { return "DROP_PARTITION" } func (a *AlterTableDropPartition) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Partition.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableDropPartition(a) } type AlterTableMaterializeProjection struct { MaterializedPos Pos StatementEnd Pos IfExists bool ProjectionName *NestedIdentifier Partition *PartitionClause } func (a *AlterTableMaterializeProjection) Pos() Pos { return a.MaterializedPos } func (a *AlterTableMaterializeProjection) End() Pos { return a.StatementEnd } func (a *AlterTableMaterializeProjection) AlterType() string { return "MATERIALIZE_PROJECTION" } func (a *AlterTableMaterializeProjection) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.ProjectionName.Accept(visitor); err != nil { return err } if a.Partition != nil { if err := a.Partition.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableMaterializeProjection(a) } type AlterTableMaterializeIndex struct { MaterializedPos Pos StatementEnd Pos IfExists bool IndexName *NestedIdentifier Partition *PartitionClause } func (a *AlterTableMaterializeIndex) Pos() Pos { return a.MaterializedPos } func (a *AlterTableMaterializeIndex) End() Pos { return a.StatementEnd } func (a *AlterTableMaterializeIndex) AlterType() string { return "MATERIALIZE_INDEX" } func (a *AlterTableMaterializeIndex) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.IndexName.Accept(visitor); err != nil { return err } if a.Partition != nil { if err := a.Partition.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableMaterializeIndex(a) } type AlterTableFreezePartition struct { FreezePos Pos StatementEnd Pos Partition *PartitionClause } func (a *AlterTableFreezePartition) Pos() Pos { return a.FreezePos } func (a *AlterTableFreezePartition) End() Pos { return a.StatementEnd } func (a *AlterTableFreezePartition) AlterType() string { return "FREEZE_PARTITION" } func (a *AlterTableFreezePartition) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if a.Partition != nil { if err := a.Partition.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableFreezePartition(a) } type AlterTableAddColumn struct { AddPos Pos StatementEnd Pos Column *ColumnDef IfNotExists bool After *NestedIdentifier Settings *SettingsClause } func (a *AlterTableAddColumn) Pos() Pos { return a.AddPos } func (a *AlterTableAddColumn) End() Pos { if a.Settings != nil { return a.Settings.End() } return a.StatementEnd } func (a *AlterTableAddColumn) AlterType() string { return "ADD_COLUMN" } func (a *AlterTableAddColumn) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Column.Accept(visitor); err != nil { return err } if a.After != nil { if err := a.After.Accept(visitor); err != nil { return err } } if a.Settings != nil { if err := a.Settings.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableAddColumn(a) } type AlterTableAddIndex struct { AddPos Pos StatementEnd Pos Index *TableIndex IfNotExists bool After *NestedIdentifier } func (a *AlterTableAddIndex) Pos() Pos { return a.AddPos } func (a *AlterTableAddIndex) End() Pos { return a.StatementEnd } func (a *AlterTableAddIndex) AlterType() string { return "ADD_INDEX" } func (a *AlterTableAddIndex) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Index.Accept(visitor); err != nil { return err } if a.After != nil { if err := a.After.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableAddIndex(a) } type ProjectionOrderByClause struct { OrderByPos Pos Columns *ColumnExprList } func (p *ProjectionOrderByClause) Pos() Pos { return p.OrderByPos } func (p *ProjectionOrderByClause) End() Pos { return p.Columns.End() } func (p *ProjectionOrderByClause) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) return visitor.VisitProjectionOrderBy(p) } type ProjectionSelectStmt struct { LeftParenPos Pos RightParenPos Pos With *WithClause SelectColumns *ColumnExprList GroupBy *GroupByClause OrderBy *ProjectionOrderByClause } func (p *ProjectionSelectStmt) Pos() Pos { return p.LeftParenPos } func (p *ProjectionSelectStmt) End() Pos { return p.RightParenPos } func (p *ProjectionSelectStmt) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) if p.With != nil { if err := p.With.Accept(visitor); err != nil { return err } } if err := p.SelectColumns.Accept(visitor); err != nil { return err } if p.GroupBy != nil { if err := p.GroupBy.Accept(visitor); err != nil { return err } } if p.OrderBy != nil { if err := p.OrderBy.Accept(visitor); err != nil { return err } } return visitor.VisitProjectionSelect(p) } type TableProjection struct { IncludeProjectionKeyword bool ProjectionPos Pos Identifier *NestedIdentifier Select *ProjectionSelectStmt } func (t *TableProjection) Pos() Pos { return t.ProjectionPos } func (t *TableProjection) End() Pos { return t.Select.End() } func (t *TableProjection) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Identifier.Accept(visitor); err != nil { return err } if err := t.Select.Accept(visitor); err != nil { return err } return visitor.VisitTableProjection(t) } type AlterTableAddProjection struct { AddPos Pos StatementEnd Pos IfNotExists bool TableProjection *TableProjection After *NestedIdentifier } func (a *AlterTableAddProjection) Pos() Pos { return a.AddPos } func (a *AlterTableAddProjection) End() Pos { return a.StatementEnd } func (a *AlterTableAddProjection) AlterType() string { return "ADD_PROJECTION" } func (a *AlterTableAddProjection) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.TableProjection.Accept(visitor); err != nil { return err } if a.After != nil { if err := a.After.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableAddProjection(a) } type AlterTableDropColumn struct { DropPos Pos ColumnName *NestedIdentifier IfExists bool } func (a *AlterTableDropColumn) Pos() Pos { return a.DropPos } func (a *AlterTableDropColumn) End() Pos { return a.ColumnName.End() } func (a *AlterTableDropColumn) AlterType() string { return "DROP_COLUMN" } func (a *AlterTableDropColumn) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.ColumnName.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableDropColumn(a) } type AlterTableDropIndex struct { DropPos Pos IndexName *NestedIdentifier IfExists bool } func (a *AlterTableDropIndex) Pos() Pos { return a.DropPos } func (a *AlterTableDropIndex) End() Pos { return a.IndexName.End() } func (a *AlterTableDropIndex) AlterType() string { return "DROP_INDEX" } func (a *AlterTableDropIndex) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.IndexName.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableDropIndex(a) } type AlterTableDropProjection struct { DropPos Pos ProjectionName *NestedIdentifier IfExists bool } func (a *AlterTableDropProjection) Pos() Pos { return a.DropPos } func (a *AlterTableDropProjection) End() Pos { return a.ProjectionName.End() } func (a *AlterTableDropProjection) AlterType() string { return "DROP_PROJECTION" } func (a *AlterTableDropProjection) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.ProjectionName.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableDropProjection(a) } type AlterTableRemoveTTL struct { RemovePos Pos StatementEnd Pos } func (a *AlterTableRemoveTTL) Pos() Pos { return a.RemovePos } func (a *AlterTableRemoveTTL) End() Pos { return a.StatementEnd } func (a *AlterTableRemoveTTL) AlterType() string { return "REMOVE_TTL" } func (a *AlterTableRemoveTTL) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) return visitor.VisitAlterTableRemoveTTL(a) } type AlterTableClearColumn struct { ClearPos Pos StatementEnd Pos IfExists bool ColumnName *NestedIdentifier PartitionExpr *PartitionClause } func (a *AlterTableClearColumn) Pos() Pos { return a.ClearPos } func (a *AlterTableClearColumn) End() Pos { return a.StatementEnd } func (a *AlterTableClearColumn) AlterType() string { return "CLEAR_COLUMN" } func (a *AlterTableClearColumn) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.ColumnName.Accept(visitor); err != nil { return err } if a.PartitionExpr != nil { if err := a.PartitionExpr.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableClearColumn(a) } type AlterTableClearIndex struct { ClearPos Pos StatementEnd Pos IfExists bool IndexName *NestedIdentifier PartitionExpr *PartitionClause } func (a *AlterTableClearIndex) Pos() Pos { return a.ClearPos } func (a *AlterTableClearIndex) End() Pos { return a.StatementEnd } func (a *AlterTableClearIndex) AlterType() string { return "CLEAR_INDEX" } func (a *AlterTableClearIndex) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.IndexName.Accept(visitor); err != nil { return err } if a.PartitionExpr != nil { if err := a.PartitionExpr.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableClearIndex(a) } type AlterTableClearProjection struct { ClearPos Pos StatementEnd Pos IfExists bool ProjectionName *NestedIdentifier PartitionExpr *PartitionClause } func (a *AlterTableClearProjection) Pos() Pos { return a.ClearPos } func (a *AlterTableClearProjection) End() Pos { return a.StatementEnd } func (a *AlterTableClearProjection) AlterType() string { return "CLEAR_PROJECTION" } func (a *AlterTableClearProjection) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.ProjectionName.Accept(visitor); err != nil { return err } if a.PartitionExpr != nil { if err := a.PartitionExpr.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableClearProjection(a) } type AlterTableRenameColumn struct { RenamePos Pos IfExists bool OldColumnName *NestedIdentifier NewColumnName *NestedIdentifier } func (a *AlterTableRenameColumn) Pos() Pos { return a.RenamePos } func (a *AlterTableRenameColumn) End() Pos { return a.NewColumnName.End() } func (a *AlterTableRenameColumn) AlterType() string { return "RENAME_COLUMN" } func (a *AlterTableRenameColumn) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.OldColumnName.Accept(visitor); err != nil { return err } if err := a.NewColumnName.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableRenameColumn(a) } type AlterTableModifyQuery struct { ModifyPos Pos StatementEnd Pos SelectExpr *SelectQuery } func (a *AlterTableModifyQuery) Pos() Pos { return a.ModifyPos } func (a *AlterTableModifyQuery) End() Pos { return a.StatementEnd } func (a *AlterTableModifyQuery) AlterType() string { return "MODIFY_QUERY" } func (a *AlterTableModifyQuery) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.SelectExpr.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableModifyQuery(a) } type AlterTableModifyTTL struct { ModifyPos Pos StatementEnd Pos TTL *TTLClause } func (a *AlterTableModifyTTL) Pos() Pos { return a.ModifyPos } func (a *AlterTableModifyTTL) End() Pos { return a.StatementEnd } func (a *AlterTableModifyTTL) AlterType() string { return "MODIFY_TTL" } func (a *AlterTableModifyTTL) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.TTL.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableModifyTTL(a) } type AlterTableModifyColumn struct { ModifyPos Pos StatementEnd Pos IfExists bool Column *ColumnDef RemovePropertyType *RemovePropertyType } func (a *AlterTableModifyColumn) Pos() Pos { return a.ModifyPos } func (a *AlterTableModifyColumn) End() Pos { return a.StatementEnd } func (a *AlterTableModifyColumn) AlterType() string { return "MODIFY_COLUMN" } func (a *AlterTableModifyColumn) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Column.Accept(visitor); err != nil { return err } if a.RemovePropertyType != nil { if err := a.RemovePropertyType.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableModifyColumn(a) } type AlterTableModifySetting struct { ModifyPos Pos StatementEnd Pos Settings []*SettingExpr } func (a *AlterTableModifySetting) Pos() Pos { return a.ModifyPos } func (a *AlterTableModifySetting) End() Pos { return a.StatementEnd } func (a *AlterTableModifySetting) AlterType() string { return "MODIFY_SETTING" } func (a *AlterTableModifySetting) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) for _, setting := range a.Settings { if err := setting.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableModifySetting(a) } type AlterTableResetSetting struct { ResetPos Pos StatementEnd Pos Settings []*Ident } func (a *AlterTableResetSetting) Pos() Pos { return a.ResetPos } func (a *AlterTableResetSetting) End() Pos { return a.StatementEnd } func (a *AlterTableResetSetting) AlterType() string { return "RESET_SETTING" } func (a *AlterTableResetSetting) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) for _, setting := range a.Settings { if err := setting.Accept(visitor); err != nil { return err } } return visitor.VisitAlterTableResetSetting(a) } type AlterTableReplacePartition struct { ReplacePos Pos Partition *PartitionClause Table *TableIdentifier } func (a *AlterTableReplacePartition) Pos() Pos { return a.ReplacePos } func (a *AlterTableReplacePartition) End() Pos { return a.Table.End() } func (a *AlterTableReplacePartition) AlterType() string { return "REPLACE_PARTITION" } func (a *AlterTableReplacePartition) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Partition.Accept(visitor); err != nil { return err } if err := a.Table.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableReplacePartition(a) } type AlterTableDelete struct { DeletePos Pos StatementEnd Pos WhereClause Expr } func (a *AlterTableDelete) Pos() Pos { return a.DeletePos } func (a *AlterTableDelete) End() Pos { return a.StatementEnd } func (a *AlterTableDelete) AlterType() string { return "DELETE" } func (a *AlterTableDelete) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.WhereClause.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableDelete(a) } type AlterTableUpdate struct { UpdatePos Pos StatementEnd Pos Assignments []*UpdateAssignment InPartition *PartitionClause WhereClause Expr } func (a *AlterTableUpdate) Pos() Pos { return a.UpdatePos } func (a *AlterTableUpdate) End() Pos { return a.StatementEnd } func (a *AlterTableUpdate) AlterType() string { return "UPDATE" } func (a *AlterTableUpdate) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) for _, assignment := range a.Assignments { if err := assignment.Accept(visitor); err != nil { return err } } if a.InPartition != nil { if err := a.InPartition.Accept(visitor); err != nil { return err } } if err := a.WhereClause.Accept(visitor); err != nil { return err } return visitor.VisitAlterTableUpdate(a) } type UpdateAssignment struct { AssignmentPos Pos Column *NestedIdentifier Expr Expr } func (u *UpdateAssignment) Pos() Pos { return u.AssignmentPos } func (u *UpdateAssignment) End() Pos { return u.Expr.End() } func (u *UpdateAssignment) Accept(visitor ASTVisitor) error { visitor.Enter(u) defer visitor.Leave(u) if err := u.Column.Accept(visitor); err != nil { return err } if err := u.Expr.Accept(visitor); err != nil { return err } return visitor.VisitUpdateAssignment(u) } type RemovePropertyType struct { RemovePos Pos PropertyType Expr } func (a *RemovePropertyType) Pos() Pos { return a.RemovePos } func (a *RemovePropertyType) End() Pos { return a.PropertyType.End() } func (a *RemovePropertyType) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.PropertyType.Accept(visitor); err != nil { return err } return visitor.VisitRemovePropertyType(a) } type TableIndex struct { IndexPos Pos Name *NestedIdentifier ColumnExpr *ColumnExpr ColumnType Expr Granularity *NumberLiteral } func (a *TableIndex) Pos() Pos { return a.IndexPos } func (a *TableIndex) End() Pos { return a.Granularity.End() } func (a *TableIndex) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Name.Accept(visitor); err != nil { return err } if err := a.ColumnExpr.Accept(visitor); err != nil { return err } if err := a.ColumnType.Accept(visitor); err != nil { return err } if err := a.Granularity.Accept(visitor); err != nil { return err } return visitor.VisitTableIndex(a) } type Ident struct { Name string QuoteType int NamePos Pos NameEnd Pos } func (i *Ident) Pos() Pos { return i.NamePos } func (i *Ident) End() Pos { return i.NameEnd } func (i *Ident) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) return visitor.VisitIdent(i) } type UUID struct { Value *StringLiteral } func (u *UUID) Pos() Pos { return u.Value.LiteralPos } func (u *UUID) End() Pos { return u.Value.LiteralEnd } func (u *UUID) Accept(visitor ASTVisitor) error { visitor.Enter(u) defer visitor.Leave(u) return visitor.VisitUUID(u) } type CreateDatabase struct { CreatePos Pos // position of CREATE keyword StatementEnd Pos Name Expr IfNotExists bool // true if 'IF NOT EXISTS' is specified OnCluster *ClusterClause Engine *EngineExpr Comment *StringLiteral } func (c *CreateDatabase) Pos() Pos { return c.CreatePos } func (c *CreateDatabase) End() Pos { return c.StatementEnd } func (c *CreateDatabase) Type() string { return "DATABASE" } func (c *CreateDatabase) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if c.Engine != nil { if err := c.Engine.Accept(visitor); err != nil { return err } } return visitor.VisitCreateDatabase(c) } type CreateTable struct { CreatePos Pos // position of CREATE|ATTACH keyword StatementEnd Pos OrReplace bool Name *TableIdentifier IfNotExists bool UUID *UUID OnCluster *ClusterClause TableSchema *TableSchemaClause Engine *EngineExpr SubQuery *SubQuery TableFunction *TableFunctionExpr HasTemporary bool Comment *StringLiteral } func (c *CreateTable) Pos() Pos { return c.CreatePos } func (c *CreateTable) End() Pos { return c.StatementEnd } func (c *CreateTable) Type() string { return "CREATE TABLE" } func (c *CreateTable) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.UUID != nil { if err := c.UUID.Accept(visitor); err != nil { return err } } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if c.TableSchema != nil { if err := c.TableSchema.Accept(visitor); err != nil { return err } } if c.Engine != nil { if err := c.Engine.Accept(visitor); err != nil { return err } } if c.SubQuery != nil { if err := c.SubQuery.Accept(visitor); err != nil { return err } } if c.TableFunction != nil { if err := c.TableFunction.Accept(visitor); err != nil { return err } } return visitor.VisitCreateTable(c) } type CreateMaterializedView struct { CreatePos Pos // position of CREATE|ATTACH keyword StatementEnd Pos Name *TableIdentifier IfNotExists bool OnCluster *ClusterClause Refresh *RefreshExpr RandomizeFor *IntervalExpr DependsOn []*TableIdentifier Settings *SettingsClause HasAppend bool Engine *EngineExpr HasEmpty bool Destination *DestinationClause SubQuery *SubQuery Populate bool Comment *StringLiteral Definer *Ident SQLSecurity string } func (c *CreateMaterializedView) Pos() Pos { return c.CreatePos } func (c *CreateMaterializedView) End() Pos { return c.StatementEnd } func (c *CreateMaterializedView) Type() string { return "MATERIALIZED_VIEW" } func (c *CreateMaterializedView) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if c.Refresh != nil { if err := c.Refresh.Accept(visitor); err != nil { return err } } if c.RandomizeFor != nil { if err := c.RandomizeFor.Accept(visitor); err != nil { return err } } if c.DependsOn != nil { for _, dep := range c.DependsOn { if err := dep.Accept(visitor); err != nil { return err } } } if c.Settings != nil { if err := c.Settings.Accept(visitor); err != nil { return err } } if c.Engine != nil { if err := c.Engine.Accept(visitor); err != nil { return err } } if c.Destination != nil { if err := c.Destination.Accept(visitor); err != nil { return err } if c.Destination.TableSchema != nil { if err := c.Destination.TableSchema.Accept(visitor); err != nil { return err } } } if c.SubQuery != nil { if err := c.SubQuery.Accept(visitor); err != nil { return err } } if c.Definer != nil { if err := c.Definer.Accept(visitor); err != nil { return err } } if c.Comment != nil { if err := c.Comment.Accept(visitor); err != nil { return err } } return visitor.VisitCreateMaterializedView(c) } type CreateView struct { CreatePos Pos // position of CREATE|ATTACH keyword StatementEnd Pos OrReplace bool Name *TableIdentifier IfNotExists bool UUID *UUID OnCluster *ClusterClause TableSchema *TableSchemaClause Comment *StringLiteral SubQuery *SubQuery } func (c *CreateView) Pos() Pos { return c.CreatePos } func (c *CreateView) End() Pos { return c.StatementEnd } func (c *CreateView) Type() string { return "VIEW" } func (c *CreateView) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.UUID != nil { if err := c.UUID.Accept(visitor); err != nil { return err } } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if c.TableSchema != nil { if err := c.TableSchema.Accept(visitor); err != nil { return err } } if c.Comment != nil { if err := c.Comment.Accept(visitor); err != nil { return err } } if c.SubQuery != nil { if err := c.SubQuery.Accept(visitor); err != nil { return err } } return visitor.VisitCreateView(c) } type CreateFunction struct { CreatePos Pos OrReplace bool IfNotExists bool FunctionName *Ident OnCluster *ClusterClause Params *ParamExprList Expr Expr } func (c *CreateFunction) Type() string { return "FUNCTION" } func (c *CreateFunction) Pos() Pos { return c.CreatePos } func (c *CreateFunction) End() Pos { return c.Expr.End() } func (c *CreateFunction) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.FunctionName.Accept(visitor); err != nil { return err } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if err := c.Params.Accept(visitor); err != nil { return err } if err := c.Expr.Accept(visitor); err != nil { return err } return visitor.VisitCreateFunction(c) } type RoleName struct { Name Expr Scope *StringLiteral OnCluster *ClusterClause } func (r *RoleName) Pos() Pos { return r.Name.Pos() } func (r *RoleName) End() Pos { if r.Scope != nil { return r.Scope.End() } if r.OnCluster != nil { return r.OnCluster.End() } return r.Name.End() } func (r *RoleName) Accept(visitor ASTVisitor) error { visitor.Enter(r) defer visitor.Leave(r) if err := r.Name.Accept(visitor); err != nil { return err } if r.Scope != nil { if err := r.Scope.Accept(visitor); err != nil { return err } } if r.OnCluster != nil { if err := r.OnCluster.Accept(visitor); err != nil { return err } } return visitor.VisitRoleName(r) } type SettingPair struct { Name *Ident Operation TokenKind Value Expr } func (s *SettingPair) Pos() Pos { return s.Name.NamePos } func (s *SettingPair) End() Pos { return s.Value.End() } func (s *SettingPair) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Name.Accept(visitor); err != nil { return err } if s.Value != nil { if err := s.Value.Accept(visitor); err != nil { return err } } return visitor.VisitSettingPair(s) } type RoleSetting struct { SettingPairs []*SettingPair Modifier *Ident } func (r *RoleSetting) Pos() Pos { if len(r.SettingPairs) > 0 { return r.SettingPairs[0].Pos() } return r.Modifier.NamePos } func (r *RoleSetting) End() Pos { if r.Modifier != nil { return r.Modifier.NameEnd } return r.SettingPairs[len(r.SettingPairs)-1].End() } func (r *RoleSetting) Accept(visitor ASTVisitor) error { visitor.Enter(r) defer visitor.Leave(r) for _, settingPair := range r.SettingPairs { if err := settingPair.Accept(visitor); err != nil { return err } } if r.Modifier != nil { if err := r.Modifier.Accept(visitor); err != nil { return err } } return visitor.VisitRoleSetting(r) } type CreateRole struct { CreatePos Pos StatementEnd Pos IfNotExists bool OrReplace bool RoleNames []*RoleName AccessStorageType *Ident Settings []*RoleSetting } func (c *CreateRole) Pos() Pos { return c.CreatePos } func (c *CreateRole) End() Pos { return c.StatementEnd } func (c *CreateRole) Type() string { return "ROLE" } func (c *CreateRole) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) for _, roleName := range c.RoleNames { if err := roleName.Accept(visitor); err != nil { return err } } if c.AccessStorageType != nil { if err := c.AccessStorageType.Accept(visitor); err != nil { return err } } for _, setting := range c.Settings { if err := setting.Accept(visitor); err != nil { return err } } return visitor.VisitCreateRole(c) } type AuthenticationClause struct { AuthPos Pos AuthEnd Pos NotIdentified bool AuthType string // "no_password", "plaintext_password", "sha256_password", etc. AuthValue *StringLiteral LdapServer *StringLiteral KerberosRealm *StringLiteral IsKerberos bool } func (a *AuthenticationClause) Pos() Pos { return a.AuthPos } func (a *AuthenticationClause) End() Pos { return a.AuthEnd } func (a *AuthenticationClause) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if a.AuthValue != nil { if err := a.AuthValue.Accept(visitor); err != nil { return err } } if a.LdapServer != nil { if err := a.LdapServer.Accept(visitor); err != nil { return err } } if a.KerberosRealm != nil { if err := a.KerberosRealm.Accept(visitor); err != nil { return err } } return visitor.VisitAuthenticationClause(a) } type HostClause struct { HostPos Pos HostEnd Pos HostType string // "LOCAL", "NAME", "REGEXP", "IP", "LIKE", "ANY", "NONE" HostValue *StringLiteral } func (h *HostClause) Pos() Pos { return h.HostPos } func (h *HostClause) End() Pos { return h.HostEnd } func (h *HostClause) Accept(visitor ASTVisitor) error { visitor.Enter(h) defer visitor.Leave(h) if h.HostValue != nil { if err := h.HostValue.Accept(visitor); err != nil { return err } } return visitor.VisitHostClause(h) } type DefaultRoleClause struct { DefaultPos Pos DefaultEnd Pos Roles []*RoleName None bool } func (d *DefaultRoleClause) Pos() Pos { return d.DefaultPos } func (d *DefaultRoleClause) End() Pos { return d.DefaultEnd } func (d *DefaultRoleClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) for _, role := range d.Roles { if err := role.Accept(visitor); err != nil { return err } } return visitor.VisitDefaultRoleClause(d) } type GranteesClause struct { GranteesPos Pos GranteesEnd Pos Grantees []*RoleName ExceptUsers []*RoleName Any bool None bool } func (g *GranteesClause) Pos() Pos { return g.GranteesPos } func (g *GranteesClause) End() Pos { return g.GranteesEnd } func (g *GranteesClause) Accept(visitor ASTVisitor) error { visitor.Enter(g) defer visitor.Leave(g) for _, grantee := range g.Grantees { if err := grantee.Accept(visitor); err != nil { return err } } for _, except := range g.ExceptUsers { if err := except.Accept(visitor); err != nil { return err } } return visitor.VisitGranteesClause(g) } type CreateUser struct { CreatePos Pos StatementEnd Pos IfNotExists bool OrReplace bool UserNames []*RoleName Authentication *AuthenticationClause ValidUntil *StringLiteral Hosts []*HostClause DefaultRole *DefaultRoleClause DefaultDatabase *Ident DefaultDbNone bool Grantees *GranteesClause Settings []*RoleSetting } func (c *CreateUser) Pos() Pos { return c.CreatePos } func (c *CreateUser) End() Pos { return c.StatementEnd } func (c *CreateUser) Type() string { return "USER" } func (c *CreateUser) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) for _, userName := range c.UserNames { if err := userName.Accept(visitor); err != nil { return err } } if c.Authentication != nil { if err := c.Authentication.Accept(visitor); err != nil { return err } } if c.ValidUntil != nil { if err := c.ValidUntil.Accept(visitor); err != nil { return err } } for _, host := range c.Hosts { if err := host.Accept(visitor); err != nil { return err } } if c.DefaultRole != nil { if err := c.DefaultRole.Accept(visitor); err != nil { return err } } if c.DefaultDatabase != nil { if err := c.DefaultDatabase.Accept(visitor); err != nil { return err } } if c.Grantees != nil { if err := c.Grantees.Accept(visitor); err != nil { return err } } for _, setting := range c.Settings { if err := setting.Accept(visitor); err != nil { return err } } return visitor.VisitCreateUser(c) } type AlterRole struct { AlterPos Pos StatementEnd Pos IfExists bool RoleRenamePairs []*RoleRenamePair Settings []*RoleSetting } func (a *AlterRole) Pos() Pos { return a.AlterPos } func (a *AlterRole) End() Pos { return a.StatementEnd } func (a *AlterRole) Type() string { return "ROLE" } func (a *AlterRole) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) for _, roleRenamePair := range a.RoleRenamePairs { if err := roleRenamePair.Accept(visitor); err != nil { return err } } for _, setting := range a.Settings { if err := setting.Accept(visitor); err != nil { return err } } return visitor.VisitAlterRole(a) } type RoleRenamePair struct { RoleName *RoleName NewName Expr StatementEnd Pos } func (r *RoleRenamePair) Pos() Pos { return r.RoleName.Pos() } func (r *RoleRenamePair) End() Pos { return r.StatementEnd } func (r *RoleRenamePair) Accept(visitor ASTVisitor) error { visitor.Enter(r) defer visitor.Leave(r) if err := r.RoleName.Accept(visitor); err != nil { return err } if r.NewName != nil { if err := r.NewName.Accept(visitor); err != nil { return err } } return visitor.VisitRoleRenamePair(r) } type DestinationClause struct { ToPos Pos TableIdentifier *TableIdentifier TableSchema *TableSchemaClause } func (d *DestinationClause) Pos() Pos { return d.ToPos } func (d *DestinationClause) End() Pos { return d.TableIdentifier.End() } func (d *DestinationClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.TableIdentifier.Accept(visitor); err != nil { return err } return visitor.VisitDestinationExpr(d) } type ConstraintClause struct { ConstraintPos Pos Constraint *Ident Expr Expr } func (c *ConstraintClause) Pos() Pos { return c.ConstraintPos } func (c *ConstraintClause) End() Pos { return c.Expr.End() } func (c *ConstraintClause) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Constraint.Accept(visitor); err != nil { return err } if err := c.Expr.Accept(visitor); err != nil { return err } return visitor.VisitConstraintExpr(c) } type NullLiteral struct { NullPos Pos } func (n *NullLiteral) Pos() Pos { return n.NullPos } func (n *NullLiteral) End() Pos { return n.NullPos + 4 } func (n *NullLiteral) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) return visitor.VisitNullLiteral(n) } type NotNullLiteral struct { NotPos Pos NullLiteral *NullLiteral } func (n *NotNullLiteral) Pos() Pos { return n.NotPos } func (n *NotNullLiteral) End() Pos { return n.NullLiteral.End() } func (n *NotNullLiteral) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.NullLiteral.Accept(visitor); err != nil { return err } return visitor.VisitNotNullLiteral(n) } type NestedIdentifier struct { Ident *Ident DotIdent *Ident } func (n *NestedIdentifier) Pos() Pos { return n.Ident.Pos() } func (n *NestedIdentifier) End() Pos { if n.DotIdent != nil { return n.DotIdent.End() } return n.Ident.End() } func (n *NestedIdentifier) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Ident.Accept(visitor); err != nil { return err } if n.DotIdent != nil { if err := n.DotIdent.Accept(visitor); err != nil { return err } } return visitor.VisitNestedIdentifier(n) } type Path struct { Fields []*Ident } func (p *Path) Pos() Pos { if len(p.Fields) > 0 { return p.Fields[0].Pos() } return 0 } func (p *Path) End() Pos { if len(p.Fields) > 0 { return p.Fields[len(p.Fields)-1].End() } return 0 } func (p *Path) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) for _, ident := range p.Fields { if err := ident.Accept(visitor); err != nil { return err } } return visitor.VisitPath(p) } type TableIdentifier struct { Database *Ident Table *Ident } func (t *TableIdentifier) Pos() Pos { if t.Database != nil { return t.Database.Pos() } return t.Table.Pos() } func (t *TableIdentifier) End() Pos { return t.Table.End() } func (t *TableIdentifier) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if t.Database != nil { if err := t.Database.Accept(visitor); err != nil { return err } } if err := t.Table.Accept(visitor); err != nil { return err } return visitor.VisitTableIdentifier(t) } type TableSchemaClause struct { SchemaPos Pos SchemaEnd Pos Columns []Expr AliasTable *TableIdentifier TableFunction *TableFunctionExpr } func (t *TableSchemaClause) Pos() Pos { return t.SchemaPos } func (t *TableSchemaClause) End() Pos { return t.SchemaEnd } func (t *TableSchemaClause) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) for _, column := range t.Columns { if err := column.Accept(visitor); err != nil { return err } } if t.AliasTable != nil { if err := t.AliasTable.Accept(visitor); err != nil { return err } } if t.TableFunction != nil { if err := t.TableFunction.Accept(visitor); err != nil { return err } } return visitor.VisitTableSchemaExpr(t) } type TableArgListExpr struct { LeftParenPos Pos RightParenPos Pos Args []Expr } func (t *TableArgListExpr) Pos() Pos { return t.LeftParenPos } func (t *TableArgListExpr) End() Pos { return t.RightParenPos } func (t *TableArgListExpr) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) for _, arg := range t.Args { if err := arg.Accept(visitor); err != nil { return err } } return visitor.VisitTableArgListExpr(t) } type TableFunctionExpr struct { Name Expr Args *TableArgListExpr } func (t *TableFunctionExpr) Pos() Pos { return t.Name.Pos() } func (t *TableFunctionExpr) End() Pos { return t.Args.End() } func (t *TableFunctionExpr) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Name.Accept(visitor); err != nil { return err } if err := t.Args.Accept(visitor); err != nil { return err } return visitor.VisitTableFunctionExpr(t) } type ClusterClause struct { OnPos Pos Expr Expr } func (o *ClusterClause) Pos() Pos { return o.OnPos } func (o *ClusterClause) End() Pos { return o.Expr.End() } func (o *ClusterClause) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) if err := o.Expr.Accept(visitor); err != nil { return err } return visitor.VisitOnClusterExpr(o) } type PartitionClause struct { PartitionPos Pos Expr Expr ID *StringLiteral All bool } func (p *PartitionClause) Pos() Pos { return p.PartitionPos } func (p *PartitionClause) End() Pos { if p.ID != nil { return p.ID.LiteralEnd } return p.Expr.End() } func (p *PartitionClause) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) if p.Expr != nil { if err := p.Expr.Accept(visitor); err != nil { return err } } if p.ID != nil { if err := p.ID.Accept(visitor); err != nil { return err } } return visitor.VisitPartitionExpr(p) } type PartitionByClause struct { PartitionPos Pos Expr Expr } func (p *PartitionByClause) Pos() Pos { return p.PartitionPos } func (p *PartitionByClause) End() Pos { return p.Expr.End() } func (p *PartitionByClause) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) if err := p.Expr.Accept(visitor); err != nil { return err } return visitor.VisitPartitionByExpr(p) } type PrimaryKeyClause struct { PrimaryPos Pos Expr Expr } func (p *PrimaryKeyClause) Pos() Pos { return p.PrimaryPos } func (p *PrimaryKeyClause) End() Pos { return p.Expr.End() } func (p *PrimaryKeyClause) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) if err := p.Expr.Accept(visitor); err != nil { return err } return visitor.VisitPrimaryKeyExpr(p) } type SampleByClause struct { SamplePos Pos Expr Expr } func (s *SampleByClause) Pos() Pos { return s.SamplePos } func (s *SampleByClause) End() Pos { return s.Expr.End() } func (s *SampleByClause) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Expr.Accept(visitor); err != nil { return err } return visitor.VisitSampleByExpr(s) } type TTLPolicyRuleAction struct { ActionPos Pos ActionEnd Pos Action string Codec *CompressionCodec } func (t *TTLPolicyRuleAction) Pos() Pos { return t.ActionPos } func (t *TTLPolicyRuleAction) End() Pos { if t.Codec != nil { return t.Codec.End() } return t.ActionEnd } func (t *TTLPolicyRuleAction) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if t.Codec != nil { if err := t.Codec.Accept(visitor); err != nil { return err } } return visitor.VisitTTLPolicyItemAction(t) } type RefreshExpr struct { RefreshPos Pos Frequency string // EVERY|AFTER Interval *IntervalExpr Offset *IntervalExpr } func (r *RefreshExpr) Pos() Pos { return r.RefreshPos } func (r *RefreshExpr) End() Pos { if r.Offset != nil { return r.Offset.End() } return r.Interval.End() } func (r *RefreshExpr) Accept(visitor ASTVisitor) error { visitor.Enter(r) defer visitor.Leave(r) if r.Interval != nil { if err := r.Interval.Accept(visitor); err != nil { return err } } if r.Offset != nil { if err := r.Offset.Accept(visitor); err != nil { return err } } return visitor.VisitRefreshExpr(r) } type TTLPolicyRule struct { RulePos Pos ToVolume *StringLiteral ToDisk *StringLiteral Action *TTLPolicyRuleAction } func (t *TTLPolicyRule) Pos() Pos { return t.RulePos } func (t *TTLPolicyRule) End() Pos { if t.Action != nil { return t.Action.End() } if t.ToDisk != nil { return t.ToDisk.LiteralEnd } return t.ToVolume.LiteralEnd } func (t *TTLPolicyRule) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if t.ToVolume != nil { if err := t.ToVolume.Accept(visitor); err != nil { return err } } if t.ToDisk != nil { if err := t.ToDisk.Accept(visitor); err != nil { return err } } return visitor.VisitTTLPolicyRule(t) } type TTLPolicy struct { Item *TTLPolicyRule Where *WhereClause GroupBy *GroupByClause } func (t *TTLPolicy) Pos() Pos { if t.Item != nil { return t.Item.Pos() } if t.Where != nil { return t.Where.Pos() } return t.GroupBy.Pos() } func (t *TTLPolicy) End() Pos { if t.GroupBy != nil { return t.GroupBy.End() } if t.Where != nil { return t.Where.End() } return t.Item.End() } func (t *TTLPolicy) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if t.Item != nil { if err := t.Item.Accept(visitor); err != nil { return err } } if t.Where != nil { if err := t.Where.Accept(visitor); err != nil { return err } } if t.GroupBy != nil { if err := t.GroupBy.Accept(visitor); err != nil { return err } } return visitor.VisitTTLPolicy(t) } type TTLExpr struct { TTLPos Pos Expr Expr Policy *TTLPolicy } func (t *TTLExpr) Pos() Pos { return t.TTLPos } func (t *TTLExpr) End() Pos { return t.Expr.End() } func (t *TTLExpr) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Expr.Accept(visitor); err != nil { return err } if t.Policy != nil { if err := t.Policy.Accept(visitor); err != nil { return err } } return visitor.VisitTTLExpr(t) } type TTLClause struct { TTLPos Pos ListEnd Pos Items []*TTLExpr } func (t *TTLClause) Pos() Pos { return t.TTLPos } func (t *TTLClause) End() Pos { return t.ListEnd } func (t *TTLClause) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) for _, item := range t.Items { if err := item.Accept(visitor); err != nil { return err } } return visitor.VisitTTLExprList(t) } type Fill struct { FillPos Pos From Expr // optional To Expr // optional Step Expr // optional Staleness Expr // optional } func (f *Fill) Pos() Pos { return f.FillPos } func (f *Fill) End() Pos { if f.Staleness != nil { return f.Staleness.End() } if f.Step != nil { return f.Step.End() } if f.To != nil { return f.To.End() } if f.From != nil { return f.From.End() } return f.FillPos + Pos(len("FILL")) } func (f *Fill) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if f.From != nil { if err := f.From.Accept(visitor); err != nil { return err } } if f.To != nil { if err := f.To.Accept(visitor); err != nil { return err } } if f.Step != nil { if err := f.Step.Accept(visitor); err != nil { return err } } if f.Staleness != nil { if err := f.Staleness.Accept(visitor); err != nil { return err } } return visitor.VisitFill(f) } type OrderExpr struct { OrderPos Pos Expr Expr Alias *Ident Direction OrderDirection Fill *Fill // optional WITH FILL clause } func (o *OrderExpr) Pos() Pos { return o.OrderPos } func (o *OrderExpr) End() Pos { if o.Fill != nil { return o.Fill.End() } if o.Alias != nil { return o.Alias.End() } return o.Expr.End() } func (o *OrderExpr) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) if err := o.Expr.Accept(visitor); err != nil { return err } if o.Alias != nil { if err := o.Alias.Accept(visitor); err != nil { return err } } if o.Fill != nil { if err := o.Fill.Accept(visitor); err != nil { return err } } return visitor.VisitOrderByExpr(o) } type InterpolateItem struct { Column *Ident Expr Expr // optional AS expression } func (i *InterpolateItem) Pos() Pos { return i.Column.Pos() } func (i *InterpolateItem) End() Pos { if i.Expr != nil { return i.Expr.End() } return i.Column.End() } func (i *InterpolateItem) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) if err := i.Column.Accept(visitor); err != nil { return err } if i.Expr != nil { if err := i.Expr.Accept(visitor); err != nil { return err } } return visitor.VisitInterpolateItem(i) } type InterpolateClause struct { InterpolatePos Pos ListEnd Pos Items []*InterpolateItem // can be nil for INTERPOLATE without columns } func (i *InterpolateClause) Pos() Pos { return i.InterpolatePos } func (i *InterpolateClause) End() Pos { return i.ListEnd } func (i *InterpolateClause) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) for _, item := range i.Items { if err := item.Accept(visitor); err != nil { return err } } return visitor.VisitInterpolateClause(i) } type OrderByClause struct { OrderPos Pos ListEnd Pos Items []Expr Interpolate *InterpolateClause // optional INTERPOLATE clause } func (o *OrderByClause) Pos() Pos { return o.OrderPos } func (o *OrderByClause) End() Pos { if o.Interpolate != nil { return o.Interpolate.End() } return o.ListEnd } func (o *OrderByClause) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) for _, item := range o.Items { if err := item.Accept(visitor); err != nil { return err } } if o.Interpolate != nil { if err := o.Interpolate.Accept(visitor); err != nil { return err } } return visitor.VisitOrderByListExpr(o) } type SettingExpr struct { SettingsPos Pos Name *Ident Expr Expr } func (s *SettingExpr) Pos() Pos { return s.SettingsPos } func (s *SettingExpr) End() Pos { return s.Expr.End() } func (s *SettingExpr) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Name.Accept(visitor); err != nil { return err } if err := s.Expr.Accept(visitor); err != nil { return err } return visitor.VisitSettingsExpr(s) } type SettingsClause struct { SettingsPos Pos ListEnd Pos Items []*SettingExpr } func (s *SettingsClause) Pos() Pos { return s.SettingsPos } func (s *SettingsClause) End() Pos { return s.ListEnd } func (s *SettingsClause) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) for _, item := range s.Items { if err := item.Accept(visitor); err != nil { return err } } return visitor.VisitSettingsExprList(s) } type ParamExprList struct { LeftParenPos Pos RightParenPos Pos Items *ColumnExprList ColumnArgList *ColumnArgList } func (f *ParamExprList) Pos() Pos { return f.LeftParenPos } func (f *ParamExprList) End() Pos { return f.RightParenPos } func (f *ParamExprList) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Items.Accept(visitor); err != nil { return err } if f.ColumnArgList != nil { if err := f.ColumnArgList.Accept(visitor); err != nil { return err } } return visitor.VisitParamExprList(f) } type KeyValue struct { Key StringLiteral Value Expr } type MapLiteral struct { LBracePos Pos RBracePos Pos KeyValues []KeyValue } func (m *MapLiteral) Pos() Pos { return m.LBracePos } func (m *MapLiteral) End() Pos { return m.RBracePos } func (m *MapLiteral) Accept(visitor ASTVisitor) error { visitor.Enter(m) defer visitor.Leave(m) for _, kv := range m.KeyValues { if err := kv.Key.Accept(visitor); err != nil { return err } if err := kv.Value.Accept(visitor); err != nil { return err } } return visitor.VisitMapLiteral(m) } type NamedParameterExpr struct { NamePos Pos Name *Ident Value Expr } func (n *NamedParameterExpr) Pos() Pos { return n.NamePos } func (n *NamedParameterExpr) End() Pos { return n.Value.End() } func (n *NamedParameterExpr) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Name.Accept(visitor); err != nil { return err } if err := n.Value.Accept(visitor); err != nil { return err } return visitor.VisitNamedParameterExpr(n) } type QueryParam struct { LBracePos Pos RBracePos Pos Name *Ident Type ColumnType } func (q *QueryParam) Pos() Pos { return q.LBracePos } func (q *QueryParam) End() Pos { return q.RBracePos } func (q *QueryParam) Accept(visitor ASTVisitor) error { visitor.Enter(q) defer visitor.Leave(q) if err := q.Name.Accept(visitor); err != nil { return err } if err := q.Type.Accept(visitor); err != nil { return err } return visitor.VisitQueryParam(q) } type ArrayParamList struct { LeftBracketPos Pos RightBracketPos Pos Items *ColumnExprList } func (a *ArrayParamList) Pos() Pos { return a.LeftBracketPos } func (a *ArrayParamList) End() Pos { return a.RightBracketPos } func (a *ArrayParamList) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Items.Accept(visitor); err != nil { return err } return visitor.VisitArrayParamList(a) } type ObjectParams struct { Object Expr Params *ArrayParamList } func (o *ObjectParams) Pos() Pos { return o.Object.Pos() } func (o *ObjectParams) End() Pos { return o.Params.End() } func (o *ObjectParams) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) if err := o.Object.Accept(visitor); err != nil { return err } if err := o.Params.Accept(visitor); err != nil { return err } return visitor.VisitObjectParams(o) } type FunctionExpr struct { Name *Ident Params *ParamExprList } func (f *FunctionExpr) Pos() Pos { return f.Name.NamePos } func (f *FunctionExpr) End() Pos { return f.Params.RightParenPos } func (f *FunctionExpr) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Name.Accept(visitor); err != nil { return err } if err := f.Params.Accept(visitor); err != nil { return err } return visitor.VisitFunctionExpr(f) } type WindowFunctionExpr struct { Function *FunctionExpr OverPos Pos OverExpr Expr } func (w *WindowFunctionExpr) Pos() Pos { return w.Function.Pos() } func (w *WindowFunctionExpr) End() Pos { return w.OverExpr.End() } func (w *WindowFunctionExpr) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) if err := w.Function.Accept(visitor); err != nil { return err } if err := w.OverExpr.Accept(visitor); err != nil { return err } return visitor.VisitWindowFunctionExpr(w) } type TypedPlaceholder struct { LeftBracePos Pos RightBracePos Pos Name *Ident Type ColumnType } func (t *TypedPlaceholder) Pos() Pos { return t.LeftBracePos } func (t *TypedPlaceholder) End() Pos { return t.RightBracePos } func (t *TypedPlaceholder) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Name.Accept(visitor); err != nil { return err } if err := t.Type.Accept(visitor); err != nil { return err } return visitor.VisitTypedPlaceholder(t) } type ColumnExpr struct { Expr Expr Alias *Ident } func (c *ColumnExpr) Pos() Pos { return c.Expr.Pos() } func (c *ColumnExpr) End() Pos { if c.Alias != nil { return c.Alias.NameEnd } return c.Expr.End() } func (c *ColumnExpr) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Expr.Accept(visitor); err != nil { return err } if c.Alias != nil { if err := c.Alias.Accept(visitor); err != nil { return err } } return visitor.VisitColumnExpr(c) } type ColumnDef struct { NamePos Pos ColumnEnd Pos Name *NestedIdentifier Type ColumnType NotNull *NotNullLiteral Nullable *NullLiteral DefaultExpr Expr MaterializedExpr Expr AliasExpr Expr Codec *CompressionCodec TTL *TTLClause Comment *StringLiteral CompressionCodec *Ident } func (c *ColumnDef) Pos() Pos { return c.Name.Pos() } func (c *ColumnDef) End() Pos { return c.ColumnEnd } func (c *ColumnDef) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.Type != nil { if err := c.Type.Accept(visitor); err != nil { return err } } if c.NotNull != nil { if err := c.NotNull.Accept(visitor); err != nil { return err } } if c.Nullable != nil { if err := c.Nullable.Accept(visitor); err != nil { return err } } if c.DefaultExpr != nil { if err := c.DefaultExpr.Accept(visitor); err != nil { return err } } if c.MaterializedExpr != nil { if err := c.MaterializedExpr.Accept(visitor); err != nil { return err } } if c.AliasExpr != nil { if err := c.AliasExpr.Accept(visitor); err != nil { return err } } if c.Codec != nil { if err := c.Codec.Accept(visitor); err != nil { return err } } if c.TTL != nil { if err := c.TTL.Accept(visitor); err != nil { return err } } if c.Comment != nil { if err := c.Comment.Accept(visitor); err != nil { return err } } return visitor.VisitColumnDef(c) } type ColumnType interface { Expr Type() string } type ScalarType struct { Name *Ident } func (s *ScalarType) Pos() Pos { return s.Name.NamePos } func (s *ScalarType) End() Pos { return s.Name.NameEnd } func (s *ScalarType) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Name.Accept(visitor); err != nil { return err } return visitor.VisitScalarType(s) } func (s *ScalarType) Type() string { return s.Name.Name } type JSONPath struct { Idents []*Ident } type JSONTypeHint struct { Path *JSONPath Type ColumnType } type JSONOption struct { SkipPath *JSONPath SkipRegex *StringLiteral MaxDynamicPaths *NumberLiteral MaxDynamicTypes *NumberLiteral // Type hint for specific JSON subcolumn path, e.g., "message String" or "a.b UInt64" Column *JSONTypeHint } type JSONOptions struct { LParen Pos RParen Pos Items []*JSONOption } func (j *JSONOptions) Pos() Pos { return j.LParen } func (j *JSONOptions) End() Pos { return j.RParen } type JSONType struct { Name *Ident Options *JSONOptions } func (j *JSONType) Pos() Pos { return j.Name.NamePos } func (j *JSONType) End() Pos { if j.Options != nil { return j.Options.RParen } return j.Name.NameEnd } func (j *JSONType) Type() string { return j.Name.Name } func (j *JSONType) Accept(visitor ASTVisitor) error { visitor.Enter(j) defer visitor.Leave(j) if err := j.Name.Accept(visitor); err != nil { return err } return visitor.VisitJSONType(j) } type PropertyType struct { Name *Ident } func (c *PropertyType) Pos() Pos { return c.Name.NamePos } func (c *PropertyType) End() Pos { return c.Name.NameEnd } func (c *PropertyType) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } return visitor.VisitPropertyType(c) } func (c *PropertyType) Type() string { return c.Name.Name } type TypeWithParams struct { LeftParenPos Pos RightParenPos Pos Name *Ident Params []Literal } func (s *TypeWithParams) Pos() Pos { return s.Name.NamePos } func (s *TypeWithParams) End() Pos { return s.RightParenPos } func (s *TypeWithParams) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Name.Accept(visitor); err != nil { return err } for _, param := range s.Params { if err := param.Accept(visitor); err != nil { return err } } return visitor.VisitTypeWithParams(s) } func (s *TypeWithParams) Type() string { return s.Name.Name } type ComplexType struct { LeftParenPos Pos RightParenPos Pos Name *Ident Params []ColumnType } func (c *ComplexType) Pos() Pos { return c.Name.NamePos } func (c *ComplexType) End() Pos { return c.RightParenPos } func (c *ComplexType) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } for _, param := range c.Params { if err := param.Accept(visitor); err != nil { return err } } return visitor.VisitComplexType(c) } func (c *ComplexType) Type() string { return c.Name.Name } type NestedType struct { LeftParenPos Pos RightParenPos Pos Name *Ident Columns []Expr } func (n *NestedType) Pos() Pos { return n.Name.NamePos } func (n *NestedType) End() Pos { return n.RightParenPos } func (n *NestedType) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Name.Accept(visitor); err != nil { return err } for _, column := range n.Columns { if err := column.Accept(visitor); err != nil { return err } } return visitor.VisitNestedType(n) } func (n *NestedType) Type() string { return n.Name.Name } type CompressionCodec struct { CodecPos Pos RightParenPos Pos Type *Ident TypeLevel *NumberLiteral Name *Ident Level *NumberLiteral // compression level } func (c *CompressionCodec) Pos() Pos { return c.CodecPos } func (c *CompressionCodec) End() Pos { return c.RightParenPos } func (c *CompressionCodec) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if c.Type != nil { if err := c.Type.Accept(visitor); err != nil { return err } } if c.TypeLevel != nil { if err := c.TypeLevel.Accept(visitor); err != nil { return err } } if c.Name != nil { if err := c.Name.Accept(visitor); err != nil { return err } } if c.Level != nil { if err := c.Level.Accept(visitor); err != nil { return err } } return visitor.VisitCompressionCodec(c) } type Literal interface { Expr } type NumberLiteral struct { NumPos Pos NumEnd Pos Literal string Base int } func (n *NumberLiteral) Pos() Pos { return n.NumPos } func (n *NumberLiteral) End() Pos { return n.NumEnd } func (n *NumberLiteral) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) return visitor.VisitNumberLiteral(n) } type StringLiteral struct { LiteralPos Pos LiteralEnd Pos Literal string } func (s *StringLiteral) Pos() Pos { return s.LiteralPos } func (s *StringLiteral) End() Pos { return s.LiteralEnd } func (s *StringLiteral) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) return visitor.VisitStringLiteral(s) } type BoolLiteral struct { LiteralPos Pos LiteralEnd Pos Literal string } func (b *BoolLiteral) Pos() Pos { return b.LiteralPos } func (b *BoolLiteral) End() Pos { return b.LiteralEnd } func (b *BoolLiteral) Accept(visitor ASTVisitor) error { visitor.Enter(b) defer visitor.Leave(b) return visitor.VisitBoolLiteral(b) } type PlaceHolder struct { PlaceholderPos Pos PlaceHolderEnd Pos Type string } func (p *PlaceHolder) Pos() Pos { return p.PlaceholderPos } func (p *PlaceHolder) End() Pos { return p.PlaceHolderEnd } func (p *PlaceHolder) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) return visitor.VisitPlaceHolderExpr(p) } type RatioExpr struct { Numerator *NumberLiteral // numberLiteral (SLASH numberLiteral)? Denominator *NumberLiteral } func (r *RatioExpr) Pos() Pos { return r.Numerator.NumPos } func (r *RatioExpr) End() Pos { if r.Denominator != nil { return r.Denominator.NumEnd } return r.Numerator.NumEnd } func (r *RatioExpr) Accept(visitor ASTVisitor) error { visitor.Enter(r) defer visitor.Leave(r) if err := r.Numerator.Accept(visitor); err != nil { return err } if r.Denominator != nil { if err := r.Denominator.Accept(visitor); err != nil { return err } } return visitor.VisitRatioExpr(r) } type EnumValue struct { Name *StringLiteral Value *NumberLiteral } func (e *EnumValue) Pos() Pos { return e.Name.Pos() } func (e *EnumValue) End() Pos { return e.Value.End() } func (e *EnumValue) Accept(visitor ASTVisitor) error { visitor.Enter(e) defer visitor.Leave(e) if err := e.Name.Accept(visitor); err != nil { return err } if err := e.Value.Accept(visitor); err != nil { return err } return visitor.VisitEnumValue(e) } type EnumType struct { Name *Ident ListPos Pos ListEnd Pos Values []EnumValue } func (e *EnumType) Pos() Pos { return e.ListPos } func (e *EnumType) End() Pos { return e.ListEnd } func (e *EnumType) Accept(visitor ASTVisitor) error { visitor.Enter(e) defer visitor.Leave(e) if err := e.Name.Accept(visitor); err != nil { return err } for i := range e.Values { if err := e.Values[i].Accept(visitor); err != nil { return err } } return visitor.VisitEnumType(e) } func (e *EnumType) Type() string { return e.Name.Name } type IntervalExpr struct { // INTERVAL keyword position which might be omitted(IntervalPos = 0) IntervalPos Pos Expr Expr Unit *Ident } func (i *IntervalExpr) Pos() Pos { if i.IntervalPos != 0 { return i.IntervalPos } return i.Expr.Pos() } func (i *IntervalExpr) End() Pos { return i.Unit.End() } func (i *IntervalExpr) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) if err := i.Expr.Accept(visitor); err != nil { return err } if err := i.Unit.Accept(visitor); err != nil { return err } return visitor.VisitIntervalExpr(i) } // TODO(@git-hulk): split into EngineClause and EngineExpr type EngineExpr struct { EnginePos Pos EngineEnd Pos Name string Params *ParamExprList PrimaryKey *PrimaryKeyClause PartitionBy *PartitionByClause SampleBy *SampleByClause TTL *TTLClause Settings *SettingsClause OrderBy *OrderByClause } func (e *EngineExpr) Pos() Pos { return e.EnginePos } func (e *EngineExpr) End() Pos { return e.EngineEnd } func (e *EngineExpr) Accept(visitor ASTVisitor) error { visitor.Enter(e) defer visitor.Leave(e) if e.Params != nil { if err := e.Params.Accept(visitor); err != nil { return err } } if e.PrimaryKey != nil { if err := e.PrimaryKey.Accept(visitor); err != nil { return err } } if e.PartitionBy != nil { if err := e.PartitionBy.Accept(visitor); err != nil { return err } } if e.SampleBy != nil { if err := e.SampleBy.Accept(visitor); err != nil { return err } } if e.TTL != nil { if err := e.TTL.Accept(visitor); err != nil { return err } } if e.Settings != nil { if err := e.Settings.Accept(visitor); err != nil { return err } } if e.OrderBy != nil { if err := e.OrderBy.Accept(visitor); err != nil { return err } } return visitor.VisitEngineExpr(e) } type ColumnTypeExpr struct { Name *Ident } func (c *ColumnTypeExpr) Pos() Pos { return c.Name.NamePos } func (c *ColumnTypeExpr) End() Pos { return c.Name.NameEnd } func (c *ColumnTypeExpr) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } return visitor.VisitColumnTypeExpr(c) } type ColumnArgList struct { Distinct bool LeftParenPos Pos RightParenPos Pos Items []Expr } func (c *ColumnArgList) Pos() Pos { return c.LeftParenPos } func (c *ColumnArgList) End() Pos { return c.RightParenPos } func (c *ColumnArgList) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) for _, item := range c.Items { if err := item.Accept(visitor); err != nil { return err } } return visitor.VisitColumnArgList(c) } type ColumnExprList struct { ListPos Pos ListEnd Pos HasDistinct bool Items []Expr } func (c *ColumnExprList) Pos() Pos { return c.ListPos } func (c *ColumnExprList) End() Pos { return c.ListEnd } func (c *ColumnExprList) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) for _, item := range c.Items { if err := item.Accept(visitor); err != nil { return err } } return visitor.VisitColumnExprList(c) } type WhenClause struct { WhenPos Pos ThenPos Pos When Expr Then Expr ElsePos Pos Else Expr } func (w *WhenClause) Pos() Pos { return w.WhenPos } func (w *WhenClause) End() Pos { if w.Else != nil { return w.Else.End() } return w.Then.End() } func (w *WhenClause) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) if err := w.When.Accept(visitor); err != nil { return err } if err := w.Then.Accept(visitor); err != nil { return err } if w.Else != nil { if err := w.Else.Accept(visitor); err != nil { return err } } return visitor.VisitWhenExpr(w) } type CaseExpr struct { CasePos Pos EndPos Pos Expr Expr // optional Whens []*WhenClause ElsePos Pos Else Expr } func (c *CaseExpr) Pos() Pos { return c.CasePos } func (c *CaseExpr) End() Pos { return c.EndPos } func (c *CaseExpr) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if c.Expr != nil { if err := c.Expr.Accept(visitor); err != nil { return err } } for _, when := range c.Whens { if err := when.Accept(visitor); err != nil { return err } } if c.Else != nil { if err := c.Else.Accept(visitor); err != nil { return err } } return visitor.VisitCaseExpr(c) } type CastExpr struct { CastPos Pos Expr Expr Separator string AsPos Pos AsType Expr } func (c *CastExpr) Pos() Pos { return c.CastPos } func (c *CastExpr) End() Pos { return c.AsType.End() } func (c *CastExpr) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Expr.Accept(visitor); err != nil { return err } if err := c.AsType.Accept(visitor); err != nil { return err } return visitor.VisitCastExpr(c) } type WithClause struct { WithPos Pos EndPos Pos CTEs []*CTEStmt } func (w *WithClause) Pos() Pos { return w.WithPos } func (w *WithClause) End() Pos { return w.EndPos } func (w *WithClause) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) for _, cte := range w.CTEs { if err := cte.Accept(visitor); err != nil { return err } } return visitor.VisitWithExpr(w) } type TopClause struct { TopPos Pos TopEnd Pos Number *NumberLiteral WithTies bool } func (t *TopClause) Pos() Pos { return t.TopPos } func (t *TopClause) End() Pos { return t.TopEnd } func (t *TopClause) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Number.Accept(visitor); err != nil { return err } return visitor.VisitTopExpr(t) } type CreateLiveView struct { CreatePos Pos StatementEnd Pos Name *TableIdentifier IfNotExists bool UUID *UUID OnCluster *ClusterClause Destination *DestinationClause TableSchema *TableSchemaClause WithTimeout *WithTimeoutClause SubQuery *SubQuery } func (c *CreateLiveView) Type() string { return "LIVE_VIEW" } func (c *CreateLiveView) Pos() Pos { return c.CreatePos } func (c *CreateLiveView) End() Pos { return c.StatementEnd } func (c *CreateLiveView) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.UUID != nil { if err := c.UUID.Accept(visitor); err != nil { return err } } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if c.Destination != nil { if err := c.Destination.Accept(visitor); err != nil { return err } } if c.TableSchema != nil { if err := c.TableSchema.Accept(visitor); err != nil { return err } } if c.WithTimeout != nil { if err := c.WithTimeout.Accept(visitor); err != nil { return err } } if c.SubQuery != nil { if err := c.SubQuery.Accept(visitor); err != nil { return err } } return visitor.VisitCreateLiveView(c) } type CreateDictionary struct { CreatePos Pos StatementEnd Pos OrReplace bool Name *TableIdentifier IfNotExists bool UUID *UUID OnCluster *ClusterClause Schema *DictionarySchemaClause Engine *DictionaryEngineClause Comment *StringLiteral } func (c *CreateDictionary) Type() string { return "DICTIONARY" } func (c *CreateDictionary) Pos() Pos { return c.CreatePos } func (c *CreateDictionary) End() Pos { return c.StatementEnd } func (c *CreateDictionary) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.UUID != nil { if err := c.UUID.Accept(visitor); err != nil { return err } } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } if c.Schema != nil { if err := c.Schema.Accept(visitor); err != nil { return err } } if c.Engine != nil { if err := c.Engine.Accept(visitor); err != nil { return err } } if c.Comment != nil { if err := c.Comment.Accept(visitor); err != nil { return err } } return visitor.VisitCreateDictionary(c) } type CreateNamedCollection struct { CreatePos Pos StatementEnd Pos Name *Ident IfNotExists bool OnCluster *ClusterClause Params []*NamedCollectionParam } func (c *CreateNamedCollection) Pos() Pos { return c.CreatePos } func (c *CreateNamedCollection) End() Pos { return c.StatementEnd } func (c *CreateNamedCollection) Type() string { return "NAMED COLLECTION" } func (c *CreateNamedCollection) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Name.Accept(visitor); err != nil { return err } if c.OnCluster != nil { if err := c.OnCluster.Accept(visitor); err != nil { return err } } for _, param := range c.Params { if err := param.Accept(visitor); err != nil { return err } } return visitor.VisitCreateNamedCollection(c) } type NamedCollectionParam struct { ParamPos Pos Name *Ident Value Expr Overridable bool NotOverridable bool } func (n *NamedCollectionParam) Pos() Pos { return n.ParamPos } func (n *NamedCollectionParam) End() Pos { return n.Value.End() } func (n *NamedCollectionParam) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Name.Accept(visitor); err != nil { return err } if err := n.Value.Accept(visitor); err != nil { return err } return visitor.VisitNamedCollectionParam(n) } type DictionarySchemaClause struct { SchemaPos Pos Attributes []*DictionaryAttribute RParenPos Pos } func (d *DictionarySchemaClause) Pos() Pos { return d.SchemaPos } func (d *DictionarySchemaClause) End() Pos { return d.RParenPos + 1 } func (d *DictionarySchemaClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) for _, attr := range d.Attributes { if err := attr.Accept(visitor); err != nil { return err } } return visitor.VisitDictionarySchemaClause(d) } type DictionaryAttribute struct { NamePos Pos Name *Ident Type ColumnType Default Literal Expression Expr Hierarchical bool Injective bool IsObjectId bool } func (d *DictionaryAttribute) Pos() Pos { return d.NamePos } func (d *DictionaryAttribute) End() Pos { if d.IsObjectId { return d.NamePos + Pos(len("IS_OBJECT_ID")) } if d.Injective { return d.NamePos + Pos(len("INJECTIVE")) } if d.Hierarchical { return d.NamePos + Pos(len("HIERARCHICAL")) } if d.Expression != nil { return d.Expression.End() } if d.Default != nil { return d.Default.End() } return d.Type.End() } func (d *DictionaryAttribute) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Name.Accept(visitor); err != nil { return err } if err := d.Type.Accept(visitor); err != nil { return err } if d.Default != nil { if err := d.Default.Accept(visitor); err != nil { return err } } if d.Expression != nil { if err := d.Expression.Accept(visitor); err != nil { return err } } return visitor.VisitDictionaryAttribute(d) } type DictionaryEngineClause struct { EnginePos Pos PrimaryKey *DictionaryPrimaryKeyClause Source *DictionarySourceClause Lifetime *DictionaryLifetimeClause Layout *DictionaryLayoutClause Range *DictionaryRangeClause Settings *SettingsClause } func (d *DictionaryEngineClause) Pos() Pos { return d.EnginePos } func (d *DictionaryEngineClause) End() Pos { if d.Settings != nil { return d.Settings.End() } if d.Range != nil { return d.Range.End() } if d.Layout != nil { return d.Layout.End() } if d.Lifetime != nil { return d.Lifetime.End() } if d.Source != nil { return d.Source.End() } if d.PrimaryKey != nil { return d.PrimaryKey.End() } return d.EnginePos } func (d *DictionaryEngineClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if d.PrimaryKey != nil { if err := d.PrimaryKey.Accept(visitor); err != nil { return err } } if d.Source != nil { if err := d.Source.Accept(visitor); err != nil { return err } } if d.Lifetime != nil { if err := d.Lifetime.Accept(visitor); err != nil { return err } } if d.Layout != nil { if err := d.Layout.Accept(visitor); err != nil { return err } } if d.Range != nil { if err := d.Range.Accept(visitor); err != nil { return err } } if d.Settings != nil { if err := d.Settings.Accept(visitor); err != nil { return err } } return visitor.VisitDictionaryEngineClause(d) } type DictionaryPrimaryKeyClause struct { PrimaryKeyPos Pos Keys *ColumnExprList RParenPos Pos } func (d *DictionaryPrimaryKeyClause) Pos() Pos { return d.PrimaryKeyPos } func (d *DictionaryPrimaryKeyClause) End() Pos { return d.RParenPos + 1 } func (d *DictionaryPrimaryKeyClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Keys.Accept(visitor); err != nil { return err } return visitor.VisitDictionaryPrimaryKeyClause(d) } type DictionarySourceClause struct { SourcePos Pos Source *Ident Args []*DictionaryArgExpr RParenPos Pos } func (d *DictionarySourceClause) Pos() Pos { return d.SourcePos } func (d *DictionarySourceClause) End() Pos { return d.RParenPos + 1 } func (d *DictionarySourceClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Source.Accept(visitor); err != nil { return err } for _, arg := range d.Args { if err := arg.Accept(visitor); err != nil { return err } } return visitor.VisitDictionarySourceClause(d) } type DictionaryArgExpr struct { ArgPos Pos Name *Ident Value Expr // can be Ident with optional parentheses or literal } func (d *DictionaryArgExpr) Pos() Pos { return d.ArgPos } func (d *DictionaryArgExpr) End() Pos { return d.Value.End() } func (d *DictionaryArgExpr) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Name.Accept(visitor); err != nil { return err } if err := d.Value.Accept(visitor); err != nil { return err } return visitor.VisitDictionaryArgExpr(d) } type DictionaryLifetimeClause struct { LifetimePos Pos Min *NumberLiteral Max *NumberLiteral Value *NumberLiteral // for simple LIFETIME(value) form RParenPos Pos } func (d *DictionaryLifetimeClause) Pos() Pos { return d.LifetimePos } func (d *DictionaryLifetimeClause) End() Pos { return d.RParenPos + 1 } func (d *DictionaryLifetimeClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if d.Value != nil { if err := d.Value.Accept(visitor); err != nil { return err } } if d.Min != nil { if err := d.Min.Accept(visitor); err != nil { return err } } if d.Max != nil { if err := d.Max.Accept(visitor); err != nil { return err } } return visitor.VisitDictionaryLifetimeClause(d) } type DictionaryLayoutClause struct { LayoutPos Pos Layout *Ident Args []*DictionaryArgExpr RParenPos Pos } func (d *DictionaryLayoutClause) Pos() Pos { return d.LayoutPos } func (d *DictionaryLayoutClause) End() Pos { return d.RParenPos + 1 } func (d *DictionaryLayoutClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Layout.Accept(visitor); err != nil { return err } for _, arg := range d.Args { if err := arg.Accept(visitor); err != nil { return err } } return visitor.VisitDictionaryLayoutClause(d) } type DictionaryRangeClause struct { RangePos Pos Min *Ident Max *Ident RParenPos Pos } func (d *DictionaryRangeClause) Pos() Pos { return d.RangePos } func (d *DictionaryRangeClause) End() Pos { return d.RParenPos + 1 } func (d *DictionaryRangeClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Min.Accept(visitor); err != nil { return err } if err := d.Max.Accept(visitor); err != nil { return err } return visitor.VisitDictionaryRangeClause(d) } type WithTimeoutClause struct { WithTimeoutPos Pos Expr Expr Number *NumberLiteral } func (w *WithTimeoutClause) Pos() Pos { return w.WithTimeoutPos } func (w *WithTimeoutClause) End() Pos { return w.Number.End() } func (w *WithTimeoutClause) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) if err := w.Number.Accept(visitor); err != nil { return err } return visitor.VisitWithTimeoutExpr(w) } type TableExpr struct { TablePos Pos TableEnd Pos Alias *AliasExpr Expr Expr HasFinal bool } func (t *TableExpr) Pos() Pos { return t.TablePos } func (t *TableExpr) End() Pos { return t.TableEnd } func (t *TableExpr) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Expr.Accept(visitor); err != nil { return err } if t.Alias != nil { if err := t.Alias.Accept(visitor); err != nil { return err } } return visitor.VisitTableExpr(t) } type OnClause struct { OnPos Pos On *ColumnExprList } func (o *OnClause) Pos() Pos { return o.OnPos } func (o *OnClause) End() Pos { return o.On.End() } func (o *OnClause) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) if err := o.On.Accept(visitor); err != nil { return err } return visitor.VisitOnExpr(o) } type UsingClause struct { UsingPos Pos Using *ColumnExprList } func (u *UsingClause) Pos() Pos { return u.UsingPos } func (u *UsingClause) End() Pos { return u.Using.End() } func (u *UsingClause) Accept(visitor ASTVisitor) error { visitor.Enter(u) defer visitor.Leave(u) if err := u.Using.Accept(visitor); err != nil { return err } return visitor.VisitUsingExpr(u) } type JoinExpr struct { JoinPos Pos Left Expr Right Expr Modifiers []string Constraints Expr } func (j *JoinExpr) Pos() Pos { return j.JoinPos } func (j *JoinExpr) End() Pos { // Return the rightmost position if j.Right != nil { return j.Right.End() } if j.Constraints != nil { return j.Constraints.End() } return j.Left.End() } func (j *JoinExpr) Accept(visitor ASTVisitor) error { visitor.Enter(j) defer visitor.Leave(j) if err := j.Left.Accept(visitor); err != nil { return err } if j.Right != nil { if err := j.Right.Accept(visitor); err != nil { return err } } if j.Constraints != nil { if err := j.Constraints.Accept(visitor); err != nil { return err } } return visitor.VisitJoinExpr(j) } type JoinConstraintClause struct { ConstraintPos Pos On *ColumnExprList Using *ColumnExprList } func (j *JoinConstraintClause) Pos() Pos { return j.ConstraintPos } func (j *JoinConstraintClause) End() Pos { if j.On != nil { return j.On.End() } return j.Using.End() } func (j *JoinConstraintClause) Accept(visitor ASTVisitor) error { visitor.Enter(j) defer visitor.Leave(j) if j.On != nil { if err := j.On.Accept(visitor); err != nil { return err } } if j.Using != nil { if err := j.Using.Accept(visitor); err != nil { return err } } return visitor.VisitJoinConstraintExpr(j) } type FromClause struct { FromPos Pos Expr Expr } func (f *FromClause) Pos() Pos { return f.FromPos } func (f *FromClause) End() Pos { return f.Expr.End() } func (f *FromClause) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Expr.Accept(visitor); err != nil { return err } return visitor.VisitFromExpr(f) } type IsNullExpr struct { IsPos Pos Expr Expr } func (n *IsNullExpr) Pos() Pos { return n.IsPos } func (n *IsNullExpr) End() Pos { return n.Expr.End() } func (n *IsNullExpr) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Expr.Accept(visitor); err != nil { return err } return visitor.VisitIsNullExpr(n) } type IsNotNullExpr struct { IsPos Pos Expr Expr } func (n *IsNotNullExpr) Pos() Pos { return n.Expr.Pos() } func (n *IsNotNullExpr) End() Pos { return n.Expr.End() } func (n *IsNotNullExpr) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Expr.Accept(visitor); err != nil { return err } return visitor.VisitIsNotNullExpr(n) } type AliasExpr struct { Expr Expr AliasPos Pos Alias Expr } func (a *AliasExpr) Pos() Pos { return a.AliasPos } func (a *AliasExpr) End() Pos { return a.Alias.End() } func (a *AliasExpr) Accept(visitor ASTVisitor) error { visitor.Enter(a) defer visitor.Leave(a) if err := a.Expr.Accept(visitor); err != nil { return err } if err := a.Alias.Accept(visitor); err != nil { return err } return visitor.VisitAliasExpr(a) } type WhereClause struct { WherePos Pos Expr Expr } func (w *WhereClause) Pos() Pos { return w.WherePos } func (w *WhereClause) End() Pos { return w.Expr.End() } func (w *WhereClause) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) if err := w.Expr.Accept(visitor); err != nil { return err } return visitor.VisitWhereExpr(w) } type PrewhereClause struct { PrewherePos Pos Expr Expr } func (w *PrewhereClause) Pos() Pos { return w.PrewherePos } func (w *PrewhereClause) End() Pos { return w.Expr.End() } func (w *PrewhereClause) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) if err := w.Expr.Accept(visitor); err != nil { return err } return visitor.VisitPrewhereExpr(w) } type GroupByClause struct { GroupByPos Pos GroupByEnd Pos AggregateType string Expr Expr WithCube bool WithRollup bool WithTotals bool } func (g *GroupByClause) Pos() Pos { return g.GroupByPos } func (g *GroupByClause) End() Pos { return g.GroupByEnd } func (g *GroupByClause) Accept(visitor ASTVisitor) error { visitor.Enter(g) defer visitor.Leave(g) if g.Expr != nil { if err := g.Expr.Accept(visitor); err != nil { return err } } return visitor.VisitGroupByExpr(g) } type HavingClause struct { HavingPos Pos Expr Expr } func (h *HavingClause) Pos() Pos { return h.HavingPos } func (h *HavingClause) End() Pos { return h.Expr.End() } func (h *HavingClause) Accept(visitor ASTVisitor) error { visitor.Enter(h) defer visitor.Leave(h) if err := h.Expr.Accept(visitor); err != nil { return err } return visitor.VisitHavingExpr(h) } type LimitClause struct { LimitPos Pos Limit Expr Offset Expr } func (l *LimitClause) Pos() Pos { return l.LimitPos } func (l *LimitClause) End() Pos { if l.Offset != nil { return l.Offset.End() } return l.Limit.End() } func (l *LimitClause) Accept(visitor ASTVisitor) error { visitor.Enter(l) defer visitor.Leave(l) if l.Limit != nil { if err := l.Limit.Accept(visitor); err != nil { return err } } if l.Offset != nil { if err := l.Offset.Accept(visitor); err != nil { return err } } return visitor.VisitLimitExpr(l) } type LimitByClause struct { Limit *LimitClause ByExpr *ColumnExprList } func (l *LimitByClause) Pos() Pos { return l.Limit.Pos() } func (l *LimitByClause) End() Pos { if l.ByExpr != nil { return l.ByExpr.End() } if l.Limit != nil { return l.Limit.End() } return l.Limit.End() } func (l *LimitByClause) Accept(visitor ASTVisitor) error { visitor.Enter(l) defer visitor.Leave(l) if l.Limit != nil { if err := l.Limit.Accept(visitor); err != nil { return err } } if l.ByExpr != nil { if err := l.ByExpr.Accept(visitor); err != nil { return err } } return visitor.VisitLimitByExpr(l) } type WindowExpr struct { LeftParenPos Pos RightParenPos Pos WindowName *Ident PartitionBy *PartitionByClause OrderBy *OrderByClause Frame *WindowFrameClause } func (w *WindowExpr) Pos() Pos { return w.LeftParenPos } func (w *WindowExpr) End() Pos { return w.RightParenPos } func (w *WindowExpr) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) if w.WindowName != nil { if err := w.WindowName.Accept(visitor); err != nil { return err } } if w.PartitionBy != nil { if err := w.PartitionBy.Accept(visitor); err != nil { return err } } if w.OrderBy != nil { if err := w.OrderBy.Accept(visitor); err != nil { return err } } if w.Frame != nil { if err := w.Frame.Accept(visitor); err != nil { return err } } return visitor.VisitWindowConditionExpr(w) } type WindowDefinition struct { Name *Ident AsPos Pos Expr *WindowExpr } func (w *WindowDefinition) Pos() Pos { if w == nil || w.Name == nil { return 0 } return w.Name.Pos() } func (w *WindowDefinition) End() Pos { if w == nil || w.Expr == nil { return 0 } return w.Expr.End() } type WindowClause struct { WindowPos Pos EndPos Pos Windows []*WindowDefinition } func (w *WindowClause) Pos() Pos { return w.WindowPos } func (w *WindowClause) End() Pos { if w.EndPos != 0 { return w.EndPos } if len(w.Windows) == 0 { return w.WindowPos } return w.Windows[len(w.Windows)-1].End() } func (w *WindowClause) Accept(visitor ASTVisitor) error { visitor.Enter(w) defer visitor.Leave(w) for _, window := range w.Windows { if window == nil { continue } if window.Name != nil { if err := window.Name.Accept(visitor); err != nil { return err } } if window.Expr != nil { if err := window.Expr.Accept(visitor); err != nil { return err } } } return visitor.VisitWindowExpr(w) } type WindowFrameClause struct { FramePos Pos Type string Extend Expr } func (f *WindowFrameClause) Pos() Pos { return f.FramePos } func (f *WindowFrameClause) End() Pos { return f.Extend.End() } func (f *WindowFrameClause) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Extend.Accept(visitor); err != nil { return err } return visitor.VisitWindowFrameExpr(f) } type WindowFrameExtendExpr struct { Expr Expr Direction string EndPos Pos } func (f *WindowFrameExtendExpr) Pos() Pos { return f.Expr.Pos() } func (f *WindowFrameExtendExpr) End() Pos { if f.EndPos != 0 { return f.EndPos } return f.Expr.End() } func (f *WindowFrameExtendExpr) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Expr.Accept(visitor); err != nil { return err } return visitor.VisitWindowFrameExtendExpr(f) } type BetweenClause struct { Expr Expr Between Expr AndPos Pos And Expr } func (f *BetweenClause) Pos() Pos { if f.Expr != nil { return f.Expr.Pos() } return f.Between.Pos() } func (f *BetweenClause) End() Pos { return f.And.End() } func (f *BetweenClause) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if f.Expr != nil { if err := f.Expr.Accept(visitor); err != nil { return err } } if err := f.Between.Accept(visitor); err != nil { return err } if err := f.And.Accept(visitor); err != nil { return err } return visitor.VisitBetweenClause(f) } type WindowFrameCurrentRow struct { CurrentPos Pos RowEnd Pos } func (f *WindowFrameCurrentRow) Pos() Pos { return f.CurrentPos } func (f *WindowFrameCurrentRow) End() Pos { return f.RowEnd } func (f *WindowFrameCurrentRow) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) return visitor.VisitWindowFrameCurrentRow(f) } type WindowFrameUnbounded struct { UnboundedPos Pos UnboundedEnd Pos Direction string } func (f *WindowFrameUnbounded) Pos() Pos { return f.UnboundedPos } func (f *WindowFrameUnbounded) End() Pos { return f.UnboundedEnd } func (f *WindowFrameUnbounded) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) return visitor.VisitWindowFrameUnbounded(f) } type WindowFrameNumber struct { Number *NumberLiteral EndPos Pos Direction string } func (f *WindowFrameNumber) Pos() Pos { return f.Number.Pos() } func (f *WindowFrameNumber) End() Pos { return f.EndPos } func (f *WindowFrameNumber) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Number.Accept(visitor); err != nil { return err } return visitor.VisitWindowFrameNumber(f) } type WindowFrameParam struct { Param *QueryParam EndPos Pos Direction string } func (f *WindowFrameParam) Pos() Pos { return f.Param.Pos() } func (f *WindowFrameParam) End() Pos { return f.EndPos } func (f *WindowFrameParam) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Param.Accept(visitor); err != nil { return err } return visitor.VisitWindowFrameParam(f) } type SelectQuery struct { SelectPos Pos StatementEnd Pos With *WithClause Top *TopClause HasDistinct bool DistinctOn *DistinctOn SelectItems []*SelectItem From *FromClause Window *WindowClause Prewhere *PrewhereClause Where *WhereClause GroupBy *GroupByClause WithTotal bool Having *HavingClause OrderBy *OrderByClause LimitBy *LimitByClause Limit *LimitClause Settings *SettingsClause Format *FormatClause UnionAll *SelectQuery UnionDistinct *SelectQuery Except *SelectQuery } func (s *SelectQuery) Pos() Pos { return s.SelectPos } func (s *SelectQuery) End() Pos { return s.StatementEnd } func (s *SelectQuery) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if s.With != nil { if err := s.With.Accept(visitor); err != nil { return err } } if s.Top != nil { if err := s.Top.Accept(visitor); err != nil { return err } } if s.SelectItems != nil { for _, item := range s.SelectItems { if err := item.Accept(visitor); err != nil { return err } } } if s.From != nil { if err := s.From.Accept(visitor); err != nil { return err } } if s.Window != nil { if err := s.Window.Accept(visitor); err != nil { return err } } if s.Prewhere != nil { if err := s.Prewhere.Accept(visitor); err != nil { return err } } if s.Where != nil { if err := s.Where.Accept(visitor); err != nil { return err } } if s.GroupBy != nil { if err := s.GroupBy.Accept(visitor); err != nil { return err } } if s.Having != nil { if err := s.Having.Accept(visitor); err != nil { return err } } if s.OrderBy != nil { if err := s.OrderBy.Accept(visitor); err != nil { return err } } if s.LimitBy != nil { if err := s.LimitBy.Accept(visitor); err != nil { return err } } if s.Limit != nil { if err := s.Limit.Accept(visitor); err != nil { return err } } if s.Settings != nil { if err := s.Settings.Accept(visitor); err != nil { return err } } if s.Format != nil { if err := s.Format.Accept(visitor); err != nil { return err } } if s.UnionAll != nil { if err := s.UnionAll.Accept(visitor); err != nil { return err } } if s.UnionDistinct != nil { if err := s.UnionDistinct.Accept(visitor); err != nil { return err } } if s.Except != nil { if err := s.Except.Accept(visitor); err != nil { return err } } return visitor.VisitSelectQuery(s) } type DistinctOn struct { Idents []*NestedIdentifier DistinctOnPos Pos DistinctOnEnd Pos } func (s *DistinctOn) Pos() Pos { return s.DistinctOnPos } func (s *DistinctOn) End() Pos { return s.DistinctOnEnd } func (s *DistinctOn) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) for _, ident := range s.Idents { if err := ident.Accept(visitor); err != nil { return err } } return visitor.VisitDistinctOn(s) } type SubQuery struct { HasParen bool Select *SelectQuery } func (s *SubQuery) Pos() Pos { return s.Select.Pos() } func (s *SubQuery) End() Pos { return s.Select.End() } func (s *SubQuery) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if s.Select != nil { if err := s.Select.Accept(visitor); err != nil { return err } } return visitor.VisitSubQueryExpr(s) } type NotExpr struct { NotPos Pos Expr Expr } func (n *NotExpr) Pos() Pos { return n.NotPos } func (n *NotExpr) End() Pos { return n.Expr.End() } func (n *NotExpr) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Expr.Accept(visitor); err != nil { return err } return visitor.VisitNotExpr(n) } type NegateExpr struct { NegatePos Pos Expr Expr } func (n *NegateExpr) Pos() Pos { return n.NegatePos } func (n *NegateExpr) End() Pos { return n.Expr.End() } func (n *NegateExpr) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Expr.Accept(visitor); err != nil { return err } return visitor.VisitNegateExpr(n) } type GlobalInOperation struct { GlobalPos Pos Expr Expr } func (g *GlobalInOperation) Pos() Pos { return g.GlobalPos } func (g *GlobalInOperation) End() Pos { return g.Expr.End() } func (g *GlobalInOperation) Accept(visitor ASTVisitor) error { visitor.Enter(g) defer visitor.Leave(g) if err := g.Expr.Accept(visitor); err != nil { return err } return visitor.VisitGlobalInExpr(g) } type IntervalFrom struct { Interval *Ident FromPos Pos FromExpr Expr } func (i *IntervalFrom) Pos() Pos { return i.Interval.NamePos } func (i *IntervalFrom) End() Pos { return i.FromExpr.End() } func (i *IntervalFrom) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) if err := i.FromExpr.Accept(visitor); err != nil { return err } return visitor.VisitIntervalFrom(i) } type ExtractExpr struct { ExtractPos Pos ExtractEnd Pos Parameters []Expr } func (e *ExtractExpr) Pos() Pos { return e.ExtractPos } func (e *ExtractExpr) End() Pos { return e.ExtractEnd } func (e *ExtractExpr) Accept(visitor ASTVisitor) error { visitor.Enter(e) defer visitor.Leave(e) for _, param := range e.Parameters { if err := param.Accept(visitor); err != nil { return err } } return visitor.VisitExtractExpr(e) } type DropDatabase struct { DropPos Pos StatementEnd Pos Name *Ident IfExists bool OnCluster *ClusterClause } func (d *DropDatabase) Pos() Pos { return d.DropPos } func (d *DropDatabase) End() Pos { return d.StatementEnd } func (d *DropDatabase) Type() string { return "DATABASE" } func (d *DropDatabase) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Name.Accept(visitor); err != nil { return err } if d.OnCluster != nil { if err := d.OnCluster.Accept(visitor); err != nil { return err } } return visitor.VisitDropDatabase(d) } type DropStmt struct { DropPos Pos StatementEnd Pos DropTarget string Name *TableIdentifier IfExists bool OnCluster *ClusterClause IsTemporary bool Modifier string } func (d *DropStmt) Pos() Pos { return d.DropPos } func (d *DropStmt) End() Pos { return d.StatementEnd } func (d *DropStmt) Type() string { return "DROP " + d.DropTarget } func (d *DropStmt) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Name.Accept(visitor); err != nil { return err } if d.OnCluster != nil { if err := d.OnCluster.Accept(visitor); err != nil { return err } } return visitor.VisitDropStmt(d) } type DropUserOrRole struct { DropPos Pos Target string StatementEnd Pos Names []*RoleName IfExists bool Modifier string From *Ident } func (d *DropUserOrRole) Pos() Pos { return d.DropPos } func (d *DropUserOrRole) End() Pos { return d.StatementEnd } func (d *DropUserOrRole) Type() string { return d.Target } func (d *DropUserOrRole) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) for _, name := range d.Names { if err := name.Accept(visitor); err != nil { return err } } if d.From != nil { if err := d.From.Accept(visitor); err != nil { return err } } return visitor.VisitDropUserOrRole(d) } type UseStmt struct { UsePos Pos StatementEnd Pos Database *Ident } func (u *UseStmt) Pos() Pos { return u.UsePos } func (u *UseStmt) End() Pos { return u.Database.End() } func (u *UseStmt) Accept(visitor ASTVisitor) error { visitor.Enter(u) defer visitor.Leave(u) if err := u.Database.Accept(visitor); err != nil { return err } return visitor.VisitUseExpr(u) } type CTEStmt struct { CTEPos Pos Expr Expr Alias Expr } func (c *CTEStmt) Pos() Pos { return c.CTEPos } func (c *CTEStmt) End() Pos { return c.Expr.End() } func (c *CTEStmt) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Expr.Accept(visitor); err != nil { return err } if err := c.Alias.Accept(visitor); err != nil { return err } return visitor.VisitCTEExpr(c) } type SetStmt struct { SetPos Pos Settings *SettingsClause } func (s *SetStmt) Pos() Pos { return s.SetPos } func (s *SetStmt) End() Pos { return s.Settings.End() } func (s *SetStmt) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Settings.Accept(visitor); err != nil { return err } return visitor.VisitSetExpr(s) } type FormatClause struct { FormatPos Pos Format *Ident } func (f *FormatClause) Pos() Pos { return f.FormatPos } func (f *FormatClause) End() Pos { return f.Format.End() } func (f *FormatClause) Accept(visitor ASTVisitor) error { visitor.Enter(f) defer visitor.Leave(f) if err := f.Format.Accept(visitor); err != nil { return err } return visitor.VisitFormatExpr(f) } type OptimizeStmt struct { OptimizePos Pos StatementEnd Pos Table *TableIdentifier OnCluster *ClusterClause Partition *PartitionClause HasFinal bool Deduplicate *DeduplicateClause } func (o *OptimizeStmt) Pos() Pos { return o.OptimizePos } func (o *OptimizeStmt) End() Pos { return o.StatementEnd } func (o *OptimizeStmt) Accept(visitor ASTVisitor) error { visitor.Enter(o) defer visitor.Leave(o) if err := o.Table.Accept(visitor); err != nil { return err } if o.OnCluster != nil { if err := o.OnCluster.Accept(visitor); err != nil { return err } } if o.Partition != nil { if err := o.Partition.Accept(visitor); err != nil { return err } } if o.Deduplicate != nil { if err := o.Deduplicate.Accept(visitor); err != nil { return err } } return visitor.VisitOptimizeExpr(o) } type DeduplicateClause struct { DeduplicatePos Pos By *ColumnExprList Except *ColumnExprList } func (d *DeduplicateClause) Pos() Pos { return d.DeduplicatePos } func (d *DeduplicateClause) End() Pos { if d.By != nil { return d.By.End() } else if d.Except != nil { return d.Except.End() } return d.DeduplicatePos + Pos(len(KeywordDeduplicate)) } func (d *DeduplicateClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if d.By != nil { if err := d.By.Accept(visitor); err != nil { return err } } if d.Except != nil { if err := d.Except.Accept(visitor); err != nil { return err } } return visitor.VisitDeduplicateExpr(d) } type SystemStmt struct { SystemPos Pos Expr Expr } func (s *SystemStmt) Pos() Pos { return s.SystemPos } func (s *SystemStmt) End() Pos { return s.Expr.End() } func (s *SystemStmt) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Expr.Accept(visitor); err != nil { return err } return visitor.VisitSystemExpr(s) } type SystemFlushExpr struct { FlushPos Pos StatementEnd Pos Logs bool Distributed *TableIdentifier } func (s *SystemFlushExpr) Pos() Pos { return s.FlushPos } func (s *SystemFlushExpr) End() Pos { return s.StatementEnd } func (s *SystemFlushExpr) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if s.Distributed != nil { if err := s.Distributed.Accept(visitor); err != nil { return err } } return visitor.VisitSystemFlushExpr(s) } type SystemReloadExpr struct { ReloadPos Pos StatementEnd Pos Dictionary *TableIdentifier Type string } func (s *SystemReloadExpr) Pos() Pos { return s.ReloadPos } func (s *SystemReloadExpr) End() Pos { return s.StatementEnd } func (s *SystemReloadExpr) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if s.Dictionary != nil { if err := s.Dictionary.Accept(visitor); err != nil { return err } } return visitor.VisitSystemReloadExpr(s) } type SystemSyncExpr struct { SyncPos Pos Cluster *TableIdentifier } func (s *SystemSyncExpr) Pos() Pos { return s.SyncPos } func (s *SystemSyncExpr) End() Pos { return s.Cluster.End() } func (s *SystemSyncExpr) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Cluster.Accept(visitor); err != nil { return err } return visitor.VisitSystemSyncExpr(s) } type SystemCtrlExpr struct { CtrlPos Pos StatementEnd Pos Command string // START, STOP Type string // REPLICATED, DISTRIBUTED Cluster *TableIdentifier } func (s *SystemCtrlExpr) Pos() Pos { return s.CtrlPos } func (s *SystemCtrlExpr) End() Pos { return s.StatementEnd } func (s *SystemCtrlExpr) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if s.Cluster != nil { if err := s.Cluster.Accept(visitor); err != nil { return err } } return visitor.VisitSystemCtrlExpr(s) } type SystemDropExpr struct { DropPos Pos StatementEnd Pos Type string } func (s *SystemDropExpr) Pos() Pos { return s.DropPos } func (s *SystemDropExpr) End() Pos { return s.StatementEnd } func (s *SystemDropExpr) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) return visitor.VisitSystemDropExpr(s) } type TruncateTable struct { TruncatePos Pos StatementEnd Pos IsTemporary bool IfExists bool Name *TableIdentifier OnCluster *ClusterClause } func (t *TruncateTable) Pos() Pos { return t.TruncatePos } func (t *TruncateTable) End() Pos { return t.StatementEnd } func (t *TruncateTable) Type() string { return "TRUNCATE TABLE" } func (t *TruncateTable) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Name.Accept(visitor); err != nil { return err } if t.OnCluster != nil { if err := t.OnCluster.Accept(visitor); err != nil { return err } } return visitor.VisitTruncateTable(t) } type SampleClause struct { SamplePos Pos Ratio *RatioExpr Offset *RatioExpr } func (s *SampleClause) Pos() Pos { return s.SamplePos } func (s *SampleClause) End() Pos { if s.Offset != nil { return s.Offset.End() } return s.Ratio.End() } func (s *SampleClause) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if err := s.Ratio.Accept(visitor); err != nil { return err } if s.Offset != nil { if err := s.Offset.Accept(visitor); err != nil { return err } } return visitor.VisitSampleRatioExpr(s) } type DeleteClause struct { DeletePos Pos Table *TableIdentifier OnCluster *ClusterClause WhereExpr Expr } func (d *DeleteClause) Pos() Pos { return d.DeletePos } func (d *DeleteClause) End() Pos { return d.WhereExpr.End() } func (d *DeleteClause) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Table.Accept(visitor); err != nil { return err } if d.OnCluster != nil { if err := d.OnCluster.Accept(visitor); err != nil { return err } } if d.WhereExpr != nil { if err := d.WhereExpr.Accept(visitor); err != nil { return err } } return visitor.VisitDeleteFromExpr(d) } type ColumnNamesExpr struct { LeftParenPos Pos RightParenPos Pos ColumnNames []NestedIdentifier } func (c *ColumnNamesExpr) Pos() Pos { return c.LeftParenPos } func (c *ColumnNamesExpr) End() Pos { return c.RightParenPos } func (c *ColumnNamesExpr) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) for i := range c.ColumnNames { if err := c.ColumnNames[i].Accept(visitor); err != nil { return err } } return visitor.VisitColumnNamesExpr(c) } type AssignmentValues struct { LeftParenPos Pos RightParenPos Pos Values []Expr } func (v *AssignmentValues) Pos() Pos { return v.LeftParenPos } func (v *AssignmentValues) End() Pos { return v.RightParenPos } func (v *AssignmentValues) Accept(visitor ASTVisitor) error { visitor.Enter(v) defer visitor.Leave(v) for _, value := range v.Values { if err := value.Accept(visitor); err != nil { return err } } return visitor.VisitValuesExpr(v) } type InsertStmt struct { InsertPos Pos Format *FormatClause HasTableKeyword bool Table Expr ColumnNames *ColumnNamesExpr Values []*AssignmentValues SelectExpr *SelectQuery } func (i *InsertStmt) Pos() Pos { return i.InsertPos } func (i *InsertStmt) End() Pos { if i.SelectExpr != nil { return i.SelectExpr.End() } return i.Values[len(i.Values)-1].End() } func (i *InsertStmt) Accept(visitor ASTVisitor) error { visitor.Enter(i) defer visitor.Leave(i) if i.Format != nil { if err := i.Format.Accept(visitor); err != nil { return err } } if err := i.Table.Accept(visitor); err != nil { return err } if i.ColumnNames != nil { if err := i.ColumnNames.Accept(visitor); err != nil { return err } } for _, value := range i.Values { if err := value.Accept(visitor); err != nil { return err } } if i.SelectExpr != nil { if err := i.SelectExpr.Accept(visitor); err != nil { return err } } return visitor.VisitInsertExpr(i) } type CheckStmt struct { CheckPos Pos Table *TableIdentifier Partition *PartitionClause } func (c *CheckStmt) Pos() Pos { return c.CheckPos } func (c *CheckStmt) End() Pos { return c.Partition.End() } func (c *CheckStmt) Accept(visitor ASTVisitor) error { visitor.Enter(c) defer visitor.Leave(c) if err := c.Table.Accept(visitor); err != nil { return err } if c.Partition != nil { if err := c.Partition.Accept(visitor); err != nil { return err } } return visitor.VisitCheckExpr(c) } type UnaryExpr struct { UnaryPos Pos Kind TokenKind Expr Expr } func (n *UnaryExpr) Pos() Pos { return n.UnaryPos } func (n *UnaryExpr) End() Pos { return n.Expr.End() } func (n *UnaryExpr) Accept(visitor ASTVisitor) error { visitor.Enter(n) defer visitor.Leave(n) if err := n.Expr.Accept(visitor); err != nil { return err } return visitor.VisitUnaryExpr(n) } type RenameStmt struct { RenamePos Pos StatementEnd Pos RenameTarget string TargetPairList []*TargetPair OnCluster *ClusterClause } func (r *RenameStmt) Pos() Pos { return r.RenamePos } func (r *RenameStmt) End() Pos { return r.StatementEnd } func (r *RenameStmt) Type() string { return "RENAME " + r.RenameTarget } func (r *RenameStmt) Accept(visitor ASTVisitor) error { visitor.Enter(r) defer visitor.Leave(r) for _, pair := range r.TargetPairList { if err := pair.Old.Accept(visitor); err != nil { return err } if err := pair.New.Accept(visitor); err != nil { return err } } if r.OnCluster != nil { if err := r.OnCluster.Accept(visitor); err != nil { return err } } return visitor.VisitRenameStmt(r) } type TargetPair struct { Old *TableIdentifier New *TableIdentifier } func (t *TargetPair) Pos() Pos { return t.Old.Pos() } func (t *TargetPair) End() Pos { return t.New.End() } func (t *TargetPair) Accept(visitor ASTVisitor) error { visitor.Enter(t) defer visitor.Leave(t) if err := t.Old.Accept(visitor); err != nil { return err } if err := t.New.Accept(visitor); err != nil { return err } return visitor.VisitTargetPairExpr(t) } type ExplainStmt struct { ExplainPos Pos Type string Statement Expr } func (e *ExplainStmt) Pos() Pos { return e.ExplainPos } func (e *ExplainStmt) End() Pos { return e.Statement.End() } func (e *ExplainStmt) Accept(visitor ASTVisitor) error { visitor.Enter(e) defer visitor.Leave(e) if err := e.Statement.Accept(visitor); err != nil { return err } return visitor.VisitExplainExpr(e) } type PrivilegeClause struct { PrivilegePos Pos PrivilegeEnd Pos Keywords []string Params *ParamExprList } func (p *PrivilegeClause) Pos() Pos { return p.PrivilegePos } func (p *PrivilegeClause) End() Pos { return p.PrivilegeEnd } func (p *PrivilegeClause) Accept(visitor ASTVisitor) error { visitor.Enter(p) defer visitor.Leave(p) if p.Params != nil { if err := p.Params.Accept(visitor); err != nil { return err } } return visitor.VisitPrivilegeExpr(p) } type GrantPrivilegeStmt struct { GrantPos Pos StatementEnd Pos OnCluster *ClusterClause Privileges []*PrivilegeClause On *TableIdentifier To []*Ident WithOptions []string } func (g *GrantPrivilegeStmt) Pos() Pos { return g.GrantPos } func (g *GrantPrivilegeStmt) End() Pos { return g.StatementEnd } func (g *GrantPrivilegeStmt) Type() string { return "GRANT PRIVILEGE" } func (g *GrantPrivilegeStmt) Accept(visitor ASTVisitor) error { visitor.Enter(g) defer visitor.Leave(g) if g.OnCluster != nil { if err := g.OnCluster.Accept(visitor); err != nil { return err } } for _, privilege := range g.Privileges { if err := privilege.Accept(visitor); err != nil { return err } } if err := g.On.Accept(visitor); err != nil { return err } for _, role := range g.To { if err := role.Accept(visitor); err != nil { return err } } return visitor.VisitGrantPrivilegeExpr(g) } type ShowStmt struct { ShowPos Pos StatementEnd Pos ShowType string // e.g., "CREATE TABLE", "DATABASES", "TABLES" Target *TableIdentifier // for SHOW CREATE TABLE table_name // Optional clauses for SHOW DATABASES NotLike bool // true if NOT LIKE/ILIKE LikeType string // "LIKE" or "ILIKE", empty if not used LikePattern Expr // pattern expression for LIKE/ILIKE Limit Expr // limit expression OutFile *StringLiteral // filename for INTO OUTFILE Format *StringLiteral // format specification } func (s *ShowStmt) Pos() Pos { return s.ShowPos } func (s *ShowStmt) End() Pos { // Find the rightmost element to determine the end position if s.Format != nil { return s.Format.End() } if s.OutFile != nil { return s.OutFile.End() } if s.Limit != nil { return s.Limit.End() } if s.LikePattern != nil { return s.LikePattern.End() } if s.Target != nil { return s.Target.End() } return s.StatementEnd } func (s *ShowStmt) Accept(visitor ASTVisitor) error { visitor.Enter(s) defer visitor.Leave(s) if s.Target != nil { if err := s.Target.Accept(visitor); err != nil { return err } } if s.LikePattern != nil { if err := s.LikePattern.Accept(visitor); err != nil { return err } } if s.Limit != nil { if err := s.Limit.Accept(visitor); err != nil { return err } } if s.OutFile != nil { if err := s.OutFile.Accept(visitor); err != nil { return err } } if s.Format != nil { if err := s.Format.Accept(visitor); err != nil { return err } } return visitor.VisitShowExpr(s) } type DescribeStmt struct { DescribePos Pos StatementEnd Pos DescribeType string // e.g., "TABLE", empty if not used Target *TableIdentifier } func (d *DescribeStmt) Pos() Pos { return d.DescribePos } func (d *DescribeStmt) End() Pos { return d.Target.End() } func (d *DescribeStmt) Accept(visitor ASTVisitor) error { visitor.Enter(d) defer visitor.Leave(d) if err := d.Target.Accept(visitor); err != nil { return err } return visitor.VisitDescribeExpr(d) } ================================================ FILE: parser/ast_visitor.go ================================================ package parser type ASTVisitor interface { VisitOperationExpr(expr *OperationExpr) error VisitTernaryExpr(expr *TernaryOperation) error VisitBinaryExpr(expr *BinaryOperation) error VisitIndexOperation(expr *IndexOperation) error VisitAlterTable(expr *AlterTable) error VisitAlterTableAttachPartition(expr *AlterTableAttachPartition) error VisitAlterTableDetachPartition(expr *AlterTableDetachPartition) error VisitAlterTableDropPartition(expr *AlterTableDropPartition) error VisitAlterTableFreezePartition(expr *AlterTableFreezePartition) error VisitAlterTableAddColumn(expr *AlterTableAddColumn) error VisitAlterTableAddIndex(expr *AlterTableAddIndex) error VisitAlterTableAddProjection(expr *AlterTableAddProjection) error VisitTableProjection(expr *TableProjection) error VisitProjectionOrderBy(expr *ProjectionOrderByClause) error VisitProjectionSelect(expr *ProjectionSelectStmt) error VisitAlterTableDropColumn(expr *AlterTableDropColumn) error VisitAlterTableDropIndex(expr *AlterTableDropIndex) error VisitAlterTableDropProjection(expr *AlterTableDropProjection) error VisitAlterTableRemoveTTL(expr *AlterTableRemoveTTL) error VisitAlterTableClearColumn(expr *AlterTableClearColumn) error VisitAlterTableClearIndex(expr *AlterTableClearIndex) error VisitAlterTableClearProjection(expr *AlterTableClearProjection) error VisitAlterTableMaterializeIndex(expr *AlterTableMaterializeIndex) error VisitAlterTableMaterializeProjection(expr *AlterTableMaterializeProjection) error VisitAlterTableRenameColumn(expr *AlterTableRenameColumn) error VisitAlterTableModifyTTL(expr *AlterTableModifyTTL) error VisitAlterTableModifyQuery(expr *AlterTableModifyQuery) error VisitAlterTableModifyColumn(expr *AlterTableModifyColumn) error VisitAlterTableModifySetting(expr *AlterTableModifySetting) error VisitAlterTableResetSetting(expr *AlterTableResetSetting) error VisitAlterTableReplacePartition(expr *AlterTableReplacePartition) error VisitAlterTableDelete(expr *AlterTableDelete) error VisitAlterTableUpdate(expr *AlterTableUpdate) error VisitUpdateAssignment(expr *UpdateAssignment) error VisitRemovePropertyType(expr *RemovePropertyType) error VisitTableIndex(expr *TableIndex) error VisitIdent(expr *Ident) error VisitUUID(expr *UUID) error VisitCreateDatabase(expr *CreateDatabase) error VisitCreateTable(expr *CreateTable) error VisitCreateMaterializedView(expr *CreateMaterializedView) error VisitCreateView(expr *CreateView) error VisitCreateFunction(expr *CreateFunction) error VisitRoleName(expr *RoleName) error VisitSettingPair(expr *SettingPair) error VisitRoleSetting(expr *RoleSetting) error VisitCreateRole(expr *CreateRole) error VisitCreateUser(expr *CreateUser) error VisitAuthenticationClause(expr *AuthenticationClause) error VisitHostClause(expr *HostClause) error VisitDefaultRoleClause(expr *DefaultRoleClause) error VisitGranteesClause(expr *GranteesClause) error VisitAlterRole(expr *AlterRole) error VisitRoleRenamePair(expr *RoleRenamePair) error VisitDestinationExpr(expr *DestinationClause) error VisitConstraintExpr(expr *ConstraintClause) error VisitNullLiteral(expr *NullLiteral) error VisitNotNullLiteral(expr *NotNullLiteral) error VisitPath(expr *Path) error VisitNestedIdentifier(expr *NestedIdentifier) error VisitTableIdentifier(expr *TableIdentifier) error VisitTableSchemaExpr(expr *TableSchemaClause) error VisitTableArgListExpr(expr *TableArgListExpr) error VisitTableFunctionExpr(expr *TableFunctionExpr) error VisitOnClusterExpr(expr *ClusterClause) error VisitPartitionExpr(expr *PartitionClause) error VisitPartitionByExpr(expr *PartitionByClause) error VisitPrimaryKeyExpr(expr *PrimaryKeyClause) error VisitSampleByExpr(expr *SampleByClause) error VisitTTLExpr(expr *TTLExpr) error VisitTTLExprList(expr *TTLClause) error VisitTTLPolicy(expr *TTLPolicy) error VisitTTLPolicyRule(expr *TTLPolicyRule) error VisitTTLPolicyItemAction(expr *TTLPolicyRuleAction) error VisitRefreshExpr(expr *RefreshExpr) error VisitOrderByExpr(expr *OrderExpr) error VisitOrderByListExpr(expr *OrderByClause) error VisitFill(expr *Fill) error VisitInterpolateItem(expr *InterpolateItem) error VisitInterpolateClause(expr *InterpolateClause) error VisitSettingsExpr(expr *SettingExpr) error VisitSettingsExprList(expr *SettingsClause) error VisitParamExprList(expr *ParamExprList) error VisitMapLiteral(expr *MapLiteral) error VisitNamedParameterExpr(expr *NamedParameterExpr) error VisitArrayParamList(expr *ArrayParamList) error VisitQueryParam(expr *QueryParam) error VisitObjectParams(expr *ObjectParams) error VisitFunctionExpr(expr *FunctionExpr) error VisitWindowFunctionExpr(expr *WindowFunctionExpr) error VisitColumnDef(expr *ColumnDef) error VisitColumnExpr(expr *ColumnExpr) error VisitTypedPlaceholder(expr *TypedPlaceholder) error VisitScalarType(expr *ScalarType) error VisitJSONType(expr *JSONType) error VisitPropertyType(expr *PropertyType) error VisitTypeWithParams(expr *TypeWithParams) error VisitComplexType(expr *ComplexType) error VisitNestedType(expr *NestedType) error VisitCompressionCodec(expr *CompressionCodec) error VisitNumberLiteral(expr *NumberLiteral) error VisitStringLiteral(expr *StringLiteral) error VisitRatioExpr(expr *RatioExpr) error VisitEnumValue(expr *EnumValue) error VisitEnumType(expr *EnumType) error VisitIntervalExpr(expr *IntervalExpr) error VisitEngineExpr(expr *EngineExpr) error VisitColumnTypeExpr(expr *ColumnTypeExpr) error VisitColumnArgList(expr *ColumnArgList) error VisitColumnExprList(expr *ColumnExprList) error VisitWhenExpr(expr *WhenClause) error VisitCaseExpr(expr *CaseExpr) error VisitCastExpr(expr *CastExpr) error VisitWithExpr(expr *WithClause) error VisitTopExpr(expr *TopClause) error VisitCreateLiveView(expr *CreateLiveView) error VisitCreateDictionary(expr *CreateDictionary) error VisitCreateNamedCollection(expr *CreateNamedCollection) error VisitNamedCollectionParam(expr *NamedCollectionParam) error VisitDictionarySchemaClause(expr *DictionarySchemaClause) error VisitDictionaryAttribute(expr *DictionaryAttribute) error VisitDictionaryEngineClause(expr *DictionaryEngineClause) error VisitDictionaryPrimaryKeyClause(expr *DictionaryPrimaryKeyClause) error VisitDictionarySourceClause(expr *DictionarySourceClause) error VisitDictionaryArgExpr(expr *DictionaryArgExpr) error VisitDictionaryLifetimeClause(expr *DictionaryLifetimeClause) error VisitDictionaryLayoutClause(expr *DictionaryLayoutClause) error VisitDictionaryRangeClause(expr *DictionaryRangeClause) error VisitWithTimeoutExpr(expr *WithTimeoutClause) error VisitTableExpr(expr *TableExpr) error VisitOnExpr(expr *OnClause) error VisitUsingExpr(expr *UsingClause) error VisitJoinExpr(expr *JoinExpr) error VisitJoinConstraintExpr(expr *JoinConstraintClause) error VisitJoinTableExpr(expr *JoinTableExpr) error VisitFromExpr(expr *FromClause) error VisitIsNullExpr(expr *IsNullExpr) error VisitIsNotNullExpr(expr *IsNotNullExpr) error VisitAliasExpr(expr *AliasExpr) error VisitWhereExpr(expr *WhereClause) error VisitPrewhereExpr(expr *PrewhereClause) error VisitGroupByExpr(expr *GroupByClause) error VisitHavingExpr(expr *HavingClause) error VisitLimitExpr(expr *LimitClause) error VisitLimitByExpr(expr *LimitByClause) error VisitWindowConditionExpr(expr *WindowExpr) error VisitWindowExpr(expr *WindowClause) error VisitWindowFrameExpr(expr *WindowFrameClause) error VisitWindowFrameExtendExpr(expr *WindowFrameExtendExpr) error VisitBetweenClause(expr *BetweenClause) error VisitWindowFrameCurrentRow(expr *WindowFrameCurrentRow) error VisitWindowFrameUnbounded(expr *WindowFrameUnbounded) error VisitWindowFrameNumber(expr *WindowFrameNumber) error VisitWindowFrameParam(expr *WindowFrameParam) error VisitSelectQuery(expr *SelectQuery) error VisitSubQueryExpr(expr *SubQuery) error VisitNotExpr(expr *NotExpr) error VisitNegateExpr(expr *NegateExpr) error VisitGlobalInExpr(expr *GlobalInOperation) error VisitExtractExpr(expr *ExtractExpr) error VisitIntervalFrom(expr *IntervalFrom) error VisitDropDatabase(expr *DropDatabase) error VisitDropStmt(expr *DropStmt) error VisitDropUserOrRole(expr *DropUserOrRole) error VisitUseExpr(expr *UseStmt) error VisitCTEExpr(expr *CTEStmt) error VisitSetExpr(expr *SetStmt) error VisitFormatExpr(expr *FormatClause) error VisitOptimizeExpr(expr *OptimizeStmt) error VisitDeduplicateExpr(expr *DeduplicateClause) error VisitSystemExpr(expr *SystemStmt) error VisitSystemFlushExpr(expr *SystemFlushExpr) error VisitSystemReloadExpr(expr *SystemReloadExpr) error VisitSystemSyncExpr(expr *SystemSyncExpr) error VisitSystemCtrlExpr(expr *SystemCtrlExpr) error VisitSystemDropExpr(expr *SystemDropExpr) error VisitTruncateTable(expr *TruncateTable) error VisitSampleRatioExpr(expr *SampleClause) error VisitPlaceHolderExpr(expr *PlaceHolder) error VisitDeleteFromExpr(expr *DeleteClause) error VisitColumnNamesExpr(expr *ColumnNamesExpr) error VisitValuesExpr(expr *AssignmentValues) error VisitInsertExpr(expr *InsertStmt) error VisitCheckExpr(expr *CheckStmt) error VisitUnaryExpr(expr *UnaryExpr) error VisitRenameStmt(expr *RenameStmt) error VisitExplainExpr(expr *ExplainStmt) error VisitPrivilegeExpr(expr *PrivilegeClause) error VisitGrantPrivilegeExpr(expr *GrantPrivilegeStmt) error VisitShowExpr(expr *ShowStmt) error VisitDescribeExpr(expr *DescribeStmt) error VisitSelectItem(expr *SelectItem) error VisitTargetPairExpr(expr *TargetPair) error VisitDistinctOn(expr *DistinctOn) error VisitBoolLiteral(expr *BoolLiteral) error Enter(expr Expr) Leave(expr Expr) } type VisitFunc func(expr Expr) error type DefaultASTVisitor struct { Visit VisitFunc } func (v *DefaultASTVisitor) VisitOperationExpr(expr *OperationExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTernaryExpr(expr *TernaryOperation) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitBinaryExpr(expr *BinaryOperation) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitIndexOperation(expr *IndexOperation) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitJoinTableExpr(expr *JoinTableExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTable(expr *AlterTable) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableAttachPartition(expr *AlterTableAttachPartition) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableDetachPartition(expr *AlterTableDetachPartition) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableDropPartition(expr *AlterTableDropPartition) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableFreezePartition(expr *AlterTableFreezePartition) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableAddColumn(expr *AlterTableAddColumn) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableAddIndex(expr *AlterTableAddIndex) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableAddProjection(expr *AlterTableAddProjection) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitProjectionOrderBy(expr *ProjectionOrderByClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitProjectionSelect(expr *ProjectionSelectStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableProjection(expr *TableProjection) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableDropColumn(expr *AlterTableDropColumn) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableDropIndex(expr *AlterTableDropIndex) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableDropProjection(expr *AlterTableDropProjection) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableRemoveTTL(expr *AlterTableRemoveTTL) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableClearColumn(expr *AlterTableClearColumn) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableClearIndex(expr *AlterTableClearIndex) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableClearProjection(expr *AlterTableClearProjection) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableMaterializeProjection(expr *AlterTableMaterializeProjection) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableMaterializeIndex(expr *AlterTableMaterializeIndex) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableRenameColumn(expr *AlterTableRenameColumn) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableModifyQuery(expr *AlterTableModifyQuery) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableModifyTTL(expr *AlterTableModifyTTL) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableModifyColumn(expr *AlterTableModifyColumn) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableModifySetting(expr *AlterTableModifySetting) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableResetSetting(expr *AlterTableResetSetting) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableReplacePartition(expr *AlterTableReplacePartition) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableDelete(expr *AlterTableDelete) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterTableUpdate(expr *AlterTableUpdate) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitUpdateAssignment(expr *UpdateAssignment) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRemovePropertyType(expr *RemovePropertyType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableIndex(expr *TableIndex) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitIdent(expr *Ident) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitUUID(expr *UUID) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateDatabase(expr *CreateDatabase) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateTable(expr *CreateTable) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateMaterializedView(expr *CreateMaterializedView) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateView(expr *CreateView) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateFunction(expr *CreateFunction) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRoleName(expr *RoleName) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSettingPair(expr *SettingPair) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRoleSetting(expr *RoleSetting) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateRole(expr *CreateRole) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateUser(expr *CreateUser) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAuthenticationClause(expr *AuthenticationClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitHostClause(expr *HostClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDefaultRoleClause(expr *DefaultRoleClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitGranteesClause(expr *GranteesClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAlterRole(expr *AlterRole) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRoleRenamePair(expr *RoleRenamePair) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDestinationExpr(expr *DestinationClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitConstraintExpr(expr *ConstraintClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNullLiteral(expr *NullLiteral) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNotNullLiteral(expr *NotNullLiteral) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNestedIdentifier(expr *NestedIdentifier) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPath(expr *Path) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableIdentifier(expr *TableIdentifier) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableSchemaExpr(expr *TableSchemaClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableArgListExpr(expr *TableArgListExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableFunctionExpr(expr *TableFunctionExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitOnClusterExpr(expr *ClusterClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPartitionExpr(expr *PartitionClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPartitionByExpr(expr *PartitionByClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPrimaryKeyExpr(expr *PrimaryKeyClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSampleByExpr(expr *SampleByClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTTLExpr(expr *TTLExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTTLExprList(expr *TTLClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTTLPolicy(expr *TTLPolicy) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTTLPolicyRule(expr *TTLPolicyRule) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTTLPolicyItemAction(expr *TTLPolicyRuleAction) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRefreshExpr(expr *RefreshExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitOrderByExpr(expr *OrderExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitOrderByListExpr(expr *OrderByClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitFill(expr *Fill) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitInterpolateItem(expr *InterpolateItem) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitInterpolateClause(expr *InterpolateClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSettingsExpr(expr *SettingExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSettingsExprList(expr *SettingsClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitParamExprList(expr *ParamExprList) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitArrayParamList(expr *ArrayParamList) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitQueryParam(expr *QueryParam) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitMapLiteral(expr *MapLiteral) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNamedParameterExpr(expr *NamedParameterExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitObjectParams(expr *ObjectParams) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitFunctionExpr(expr *FunctionExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFunctionExpr(expr *WindowFunctionExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitColumnDef(expr *ColumnDef) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitColumnExpr(expr *ColumnExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTypedPlaceholder(expr *TypedPlaceholder) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitScalarType(expr *ScalarType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitJSONType(expr *JSONType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPropertyType(expr *PropertyType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTypeWithParams(expr *TypeWithParams) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitComplexType(expr *ComplexType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNestedType(expr *NestedType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCompressionCodec(expr *CompressionCodec) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNumberLiteral(expr *NumberLiteral) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitStringLiteral(expr *StringLiteral) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRatioExpr(expr *RatioExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitEnumValue(expr *EnumValue) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitEnumType(expr *EnumType) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitIntervalExpr(expr *IntervalExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitEngineExpr(expr *EngineExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitColumnTypeExpr(expr *ColumnTypeExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitColumnArgList(expr *ColumnArgList) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitColumnExprList(expr *ColumnExprList) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWhenExpr(expr *WhenClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCaseExpr(expr *CaseExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCastExpr(expr *CastExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWithExpr(expr *WithClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTopExpr(expr *TopClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateLiveView(expr *CreateLiveView) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateDictionary(expr *CreateDictionary) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCreateNamedCollection(expr *CreateNamedCollection) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNamedCollectionParam(expr *NamedCollectionParam) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionarySchemaClause(expr *DictionarySchemaClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryAttribute(expr *DictionaryAttribute) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryEngineClause(expr *DictionaryEngineClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryPrimaryKeyClause(expr *DictionaryPrimaryKeyClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionarySourceClause(expr *DictionarySourceClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryArgExpr(expr *DictionaryArgExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryLifetimeClause(expr *DictionaryLifetimeClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryLayoutClause(expr *DictionaryLayoutClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDictionaryRangeClause(expr *DictionaryRangeClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWithTimeoutExpr(expr *WithTimeoutClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTableExpr(expr *TableExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitOnExpr(expr *OnClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitUsingExpr(expr *UsingClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitJoinExpr(expr *JoinExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitJoinConstraintExpr(expr *JoinConstraintClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitFromExpr(expr *FromClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitIsNullExpr(expr *IsNullExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitIsNotNullExpr(expr *IsNotNullExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitAliasExpr(expr *AliasExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWhereExpr(expr *WhereClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPrewhereExpr(expr *PrewhereClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitGroupByExpr(expr *GroupByClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitHavingExpr(expr *HavingClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitLimitExpr(expr *LimitClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitLimitByExpr(expr *LimitByClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowConditionExpr(expr *WindowExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowExpr(expr *WindowClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFrameExpr(expr *WindowFrameClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFrameExtendExpr(expr *WindowFrameExtendExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitBetweenClause(expr *BetweenClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFrameCurrentRow(expr *WindowFrameCurrentRow) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFrameUnbounded(expr *WindowFrameUnbounded) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFrameNumber(expr *WindowFrameNumber) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitWindowFrameParam(expr *WindowFrameParam) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSelectQuery(expr *SelectQuery) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSubQueryExpr(expr *SubQuery) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNotExpr(expr *NotExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitNegateExpr(expr *NegateExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitGlobalInExpr(expr *GlobalInOperation) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitExtractExpr(expr *ExtractExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitIntervalFrom(expr *IntervalFrom) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDropDatabase(expr *DropDatabase) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDropStmt(expr *DropStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDropUserOrRole(expr *DropUserOrRole) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitUseExpr(expr *UseStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCTEExpr(expr *CTEStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSetExpr(expr *SetStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitFormatExpr(expr *FormatClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitOptimizeExpr(expr *OptimizeStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDeduplicateExpr(expr *DeduplicateClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSystemExpr(expr *SystemStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSystemFlushExpr(expr *SystemFlushExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSystemReloadExpr(expr *SystemReloadExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSystemSyncExpr(expr *SystemSyncExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSystemCtrlExpr(expr *SystemCtrlExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSystemDropExpr(expr *SystemDropExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTruncateTable(expr *TruncateTable) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSampleRatioExpr(expr *SampleClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPlaceHolderExpr(expr *PlaceHolder) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDeleteFromExpr(expr *DeleteClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitColumnNamesExpr(expr *ColumnNamesExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitValuesExpr(expr *AssignmentValues) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitInsertExpr(expr *InsertStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitCheckExpr(expr *CheckStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitUnaryExpr(expr *UnaryExpr) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitRenameStmt(expr *RenameStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitExplainExpr(expr *ExplainStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitPrivilegeExpr(expr *PrivilegeClause) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitGrantPrivilegeExpr(expr *GrantPrivilegeStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitShowExpr(expr *ShowStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDescribeExpr(expr *DescribeStmt) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitSelectItem(expr *SelectItem) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitTargetPairExpr(expr *TargetPair) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitDistinctOn(expr *DistinctOn) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) VisitBoolLiteral(expr *BoolLiteral) error { if v.Visit != nil { return v.Visit(expr) } return nil } func (v *DefaultASTVisitor) Enter(expr Expr) {} func (v *DefaultASTVisitor) Leave(expr Expr) {} ================================================ FILE: parser/benchmark_test.go ================================================ package parser import ( "os" "path/filepath" "testing" ) // BenchmarkParseSQLFiles benchmarks parsing all SQL files in the testdata/query directory func BenchmarkParseSQLFiles(b *testing.B) { testFiles, err := filepath.Glob("testdata/query/*.sql") if err != nil { b.Fatalf("Failed to glob test files: %v", err) } for _, file := range testFiles { content, err := os.ReadFile(file) if err != nil { b.Fatalf("Failed to read file %s: %v", file, err) } b.Run(filepath.Base(file), func(b *testing.B) { for i := 0; i < b.N; i++ { parser := NewParser(string(content)) _, err := parser.ParseStmts() if err != nil { b.Fatalf("Failed to parse SQL from %s: %v", file, err) } } }) } } // BenchmarkParseComplexQueries benchmarks parsing specifically complex SQL queries func BenchmarkParseComplexQueries(b *testing.B) { complexQueries := []string{ "testdata/query/select_with_multi_join.sql", "testdata/query/select_with_window_function.sql", "testdata/query/select_simple_with_with_clause.sql", "testdata/query/select_with_left_join.sql", "testdata/benchdata/posthog_huge_0.sql", "testdata/benchdata/posthog_huge_1.sql", } for _, queryFile := range complexQueries { content, err := os.ReadFile(queryFile) if err != nil { b.Fatalf("Failed to read file %s: %v", queryFile, err) } b.Run(queryFile, func(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { parser := NewParser(string(content)) _, err := parser.ParseStmts() if err != nil { b.Fatalf("Failed to parse SQL from %s: %v", queryFile, err) } } }) } } ================================================ FILE: parser/format.go ================================================ package parser import "strings" const ( whitespace byte = ' ' newline byte = '\n' ) type FormatMode int const ( FormatModeCompact FormatMode = iota + 1 FormatModeBeautify ) // Formatter renders SQL. type Formatter struct { builder strings.Builder mode FormatMode indentLevel int lineStart bool indent string } func NewFormatter() *Formatter { return &Formatter{ mode: FormatModeCompact, lineStart: true, indent: " ", } } func (f *Formatter) WithBeautify() *Formatter { f.mode = FormatModeBeautify return f } // WithIndent sets the indentation string used when beautifying SQL. // The indent parameter should not be empty to maintain proper formatting. func (f *Formatter) WithIndent(indent string) *Formatter { f.indent = indent return f } func (f *Formatter) writeIndentIfNeeded() { if !f.lineStart { return } for i := 0; i < f.indentLevel; i++ { f.builder.WriteString(f.indent) } f.lineStart = false } func (f *Formatter) WriteString(s string) { for i := 0; i < len(s); i++ { f.WriteByte(s[i]) } } func (f *Formatter) WriteByte(b byte) { if f.mode == FormatModeBeautify { if b == newline { f.builder.WriteByte(newline) f.lineStart = true return } f.writeIndentIfNeeded() f.builder.WriteByte(b) } else { f.builder.WriteByte(b) } } func (f *Formatter) WriteExpr(expr Expr) { if expr == nil { return } expr.FormatSQL(f) } func (f *Formatter) NewLine() { if f.mode != FormatModeBeautify { return } f.WriteByte(newline) } func (f *Formatter) Break() { if f.mode == FormatModeBeautify { f.NewLine() return } f.WriteByte(whitespace) } func (f *Formatter) Indent() { f.indentLevel++ } func (f *Formatter) Dedent() { if f.indentLevel > 0 { f.indentLevel-- } } func (f *Formatter) String() string { return f.builder.String() } // Format renders an expression into compact SQL. func Format(expr Expr) string { formatter := NewFormatter() formatter.WriteExpr(expr) return formatter.String() } func (p *BinaryOperation) isLogicalOp() bool { switch p.Operation { case TokenKind(KeywordAnd), TokenKind(KeywordOr): return true default: return p.HasGlobal || p.HasNot } } func isLogicalBinaryOp(expr Expr) bool { if bin, ok := expr.(*BinaryOperation); ok { return bin.isLogicalOp() } return false } func (p *BinaryOperation) writeLogicalOperand(formatter *Formatter, expr Expr) { if isLogicalBinaryOp(expr) { formatter.WriteExpr(expr) } else { formatter.Indent() formatter.WriteExpr(expr) formatter.Dedent() } } func (p *BinaryOperation) FormatSQL(formatter *Formatter) { if p.isLogicalOp() && formatter.mode == FormatModeBeautify { p.writeLogicalOperand(formatter, p.LeftExpr) formatter.NewLine() if p.HasNot { formatter.WriteString("NOT ") } else if p.HasGlobal { formatter.WriteString("GLOBAL ") } formatter.WriteString(string(p.Operation)) formatter.NewLine() p.writeLogicalOperand(formatter, p.RightExpr) return } formatter.WriteExpr(p.LeftExpr) if p.Operation != TokenKindDash { formatter.WriteByte(whitespace) } if p.HasNot { formatter.WriteString("NOT ") } else if p.HasGlobal { formatter.WriteString("GLOBAL ") } formatter.WriteString(string(p.Operation)) if p.Operation != TokenKindDash { formatter.WriteByte(whitespace) } formatter.WriteExpr(p.RightExpr) } func (a *AliasExpr) FormatSQL(formatter *Formatter) { if _, isSelect := a.Expr.(*SelectQuery); isSelect { formatter.WriteByte('(') formatter.WriteExpr(a.Expr) formatter.WriteByte(')') } else { formatter.WriteExpr(a.Expr) } formatter.WriteString(" AS ") formatter.WriteExpr(a.Alias) } func (a *AlterRole) FormatSQL(formatter *Formatter) { formatter.WriteString("ALTER ROLE ") if a.IfExists { formatter.WriteString("IF EXISTS ") } for i, roleRenamePair := range a.RoleRenamePairs { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(roleRenamePair) } if len(a.Settings) > 0 { formatter.Break() formatter.WriteString("SETTINGS") formatter.Indent() for i, setting := range a.Settings { if i > 0 { formatter.WriteString(",") } formatter.Break() formatter.WriteExpr(setting) } formatter.Dedent() } } func (a *AlterTable) FormatSQL(formatter *Formatter) { formatter.WriteString("ALTER TABLE ") formatter.WriteExpr(a.TableIdentifier) if a.OnCluster != nil { formatter.Break() formatter.WriteExpr(a.OnCluster) } for i, expr := range a.AlterExprs { formatter.Break() formatter.WriteExpr(expr) if i != len(a.AlterExprs)-1 { formatter.WriteString(",") } } } func (a *AlterTableAddColumn) FormatSQL(formatter *Formatter) { formatter.WriteString("ADD COLUMN ") if a.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(a.Column) if a.After != nil { formatter.WriteString(" AFTER ") formatter.WriteExpr(a.After) } if a.Settings != nil { formatter.Break() formatter.WriteExpr(a.Settings) } } func (a *AlterTableAddIndex) FormatSQL(formatter *Formatter) { formatter.WriteString("ADD ") if a.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(a.Index) if a.After != nil { formatter.WriteString(" AFTER ") formatter.WriteExpr(a.After) } } func (a *AlterTableAddProjection) FormatSQL(formatter *Formatter) { formatter.WriteString("ADD PROJECTION ") if a.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(a.TableProjection) if a.After != nil { formatter.WriteString(" AFTER ") formatter.WriteExpr(a.After) } } func (a *AlterTableAttachPartition) FormatSQL(formatter *Formatter) { formatter.WriteString("ATTACH ") formatter.WriteExpr(a.Partition) if a.From != nil { formatter.WriteString(" FROM ") formatter.WriteExpr(a.From) } } func (a *AlterTableClearColumn) FormatSQL(formatter *Formatter) { formatter.WriteString("CLEAR COLUMN ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.ColumnName) if a.PartitionExpr != nil { formatter.Break() formatter.WriteString("IN ") formatter.WriteExpr(a.PartitionExpr) } } func (a *AlterTableClearIndex) FormatSQL(formatter *Formatter) { formatter.WriteString("CLEAR INDEX ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.IndexName) if a.PartitionExpr != nil { formatter.Break() formatter.WriteString("IN ") formatter.WriteExpr(a.PartitionExpr) } } func (a *AlterTableClearProjection) FormatSQL(formatter *Formatter) { formatter.WriteString("CLEAR PROJECTION ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.ProjectionName) if a.PartitionExpr != nil { formatter.Break() formatter.WriteString("IN ") formatter.WriteExpr(a.PartitionExpr) } } func (a *AlterTableDelete) FormatSQL(formatter *Formatter) { formatter.WriteString("DELETE") formatter.Break() formatter.WriteString("WHERE ") formatter.WriteExpr(a.WhereClause) } func (a *AlterTableDetachPartition) FormatSQL(formatter *Formatter) { formatter.WriteString("DETACH ") formatter.WriteExpr(a.Partition) if a.Settings != nil { formatter.Break() formatter.WriteExpr(a.Settings) } } func (a *AlterTableDropColumn) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP COLUMN ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.ColumnName) } func (a *AlterTableDropIndex) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP INDEX ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.IndexName) } func (a *AlterTableDropPartition) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP ") if a.HasDetached { formatter.WriteString("DETACHED ") } formatter.WriteExpr(a.Partition) if a.Settings != nil { formatter.Break() formatter.WriteExpr(a.Settings) } } func (a *AlterTableDropProjection) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP PROJECTION ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.ProjectionName) } func (a *AlterTableFreezePartition) FormatSQL(formatter *Formatter) { formatter.WriteString("FREEZE") if a.Partition != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(a.Partition) } } func (a *AlterTableMaterializeIndex) FormatSQL(formatter *Formatter) { formatter.WriteString("MATERIALIZE INDEX") if a.IfExists { formatter.WriteString(" IF EXISTS") } formatter.WriteByte(whitespace) formatter.WriteExpr(a.IndexName) if a.Partition != nil { formatter.Break() formatter.WriteString("IN ") formatter.WriteExpr(a.Partition) } } func (a *AlterTableMaterializeProjection) FormatSQL(formatter *Formatter) { formatter.WriteString("MATERIALIZE PROJECTION") if a.IfExists { formatter.WriteString(" IF EXISTS") } formatter.WriteByte(whitespace) formatter.WriteExpr(a.ProjectionName) if a.Partition != nil { formatter.Break() formatter.WriteString("IN ") formatter.WriteExpr(a.Partition) } } func (a *AlterTableModifyColumn) FormatSQL(formatter *Formatter) { formatter.WriteString("MODIFY COLUMN ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.Column) if a.RemovePropertyType != nil { formatter.WriteExpr(a.RemovePropertyType) } } func (a *AlterTableModifyQuery) FormatSQL(formatter *Formatter) { formatter.WriteString("MODIFY QUERY") formatter.Indent() formatter.Break() formatter.WriteExpr(a.SelectExpr) formatter.Dedent() } func (a *AlterTableModifySetting) FormatSQL(formatter *Formatter) { formatter.WriteString("MODIFY SETTING") formatter.Indent() for i, setting := range a.Settings { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(setting) } formatter.Dedent() } func (a *AlterTableModifyTTL) FormatSQL(formatter *Formatter) { formatter.WriteString("MODIFY ") formatter.WriteExpr(a.TTL) } func (a *AlterTableRemoveTTL) FormatSQL(formatter *Formatter) { formatter.WriteString("REMOVE TTL") } func (a *AlterTableRenameColumn) FormatSQL(formatter *Formatter) { formatter.WriteString("RENAME COLUMN ") if a.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(a.OldColumnName) formatter.WriteString(" TO ") formatter.WriteExpr(a.NewColumnName) } func (a *AlterTableReplacePartition) FormatSQL(formatter *Formatter) { formatter.WriteString("REPLACE ") formatter.WriteExpr(a.Partition) formatter.WriteString(" FROM ") formatter.WriteExpr(a.Table) } func (a *AlterTableResetSetting) FormatSQL(formatter *Formatter) { formatter.WriteString("RESET SETTING") formatter.Indent() for i, setting := range a.Settings { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(setting) } formatter.Dedent() } func (a *AlterTableUpdate) FormatSQL(formatter *Formatter) { formatter.WriteString("UPDATE") formatter.Indent() for i, assignment := range a.Assignments { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(assignment) } formatter.Dedent() if a.InPartition != nil { formatter.Break() formatter.WriteString("IN ") formatter.WriteExpr(a.InPartition) } formatter.Break() formatter.WriteString("WHERE ") formatter.WriteExpr(a.WhereClause) } func (a *ArrayParamList) FormatSQL(formatter *Formatter) { formatter.WriteString("[") for i, item := range a.Items.Items { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(item) } formatter.WriteString("]") } func (v *AssignmentValues) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') for i, value := range v.Values { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(value) } formatter.WriteByte(')') } func (a *AuthenticationClause) FormatSQL(formatter *Formatter) { if a.NotIdentified { formatter.WriteString("NOT IDENTIFIED") return } formatter.WriteString("IDENTIFIED") if a.AuthType != "" { formatter.WriteString(" WITH ") formatter.WriteString(a.AuthType) } if a.AuthValue != nil { formatter.WriteString(" BY ") formatter.WriteExpr(a.AuthValue) } if a.LdapServer != nil { formatter.Break() formatter.WriteString("WITH ldap SERVER ") formatter.WriteExpr(a.LdapServer) } if a.IsKerberos { formatter.Break() formatter.WriteString("WITH kerberos") if a.KerberosRealm != nil && a.KerberosRealm.Literal != "" { formatter.WriteString(" REALM ") formatter.WriteExpr(a.KerberosRealm) } } } func (f *BetweenClause) FormatSQL(formatter *Formatter) { if f.Expr != nil { formatter.WriteExpr(f.Expr) formatter.WriteString(" BETWEEN ") } else { formatter.WriteString("BETWEEN ") } formatter.WriteExpr(f.Between) formatter.WriteString(" AND ") formatter.WriteExpr(f.And) } func (b *BoolLiteral) FormatSQL(formatter *Formatter) { formatter.WriteString(b.Literal) } func (c *CTEStmt) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Expr) formatter.WriteString(" AS ") if _, isSelect := c.Alias.(*SelectQuery); isSelect { formatter.WriteByte('(') formatter.WriteExpr(c.Alias) formatter.WriteByte(')') } else { formatter.WriteExpr(c.Alias) } } func (c *CaseExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("CASE") if c.Expr != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.Expr) } formatter.Indent() for _, when := range c.Whens { formatter.Break() formatter.WriteExpr(when) } if c.Else != nil { formatter.Break() formatter.WriteString("ELSE ") formatter.WriteExpr(c.Else) } formatter.Dedent() formatter.Break() formatter.WriteString("END") } func (c *CastExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("CAST(") formatter.WriteExpr(c.Expr) if c.Separator == "," { formatter.WriteString(", ") } else { formatter.WriteString(" AS ") } formatter.WriteExpr(c.AsType) formatter.WriteByte(')') } func (c *CheckStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("CHECK TABLE ") formatter.WriteExpr(c.Table) if c.Partition != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.Partition) } } func (o *ClusterClause) FormatSQL(formatter *Formatter) { formatter.WriteString("ON CLUSTER ") formatter.WriteExpr(o.Expr) } func (c *ColumnArgList) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') for i, item := range c.Items { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(item) } formatter.WriteByte(')') } func (c *ColumnDef) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Name) if c.Type != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.Type) } if c.NotNull != nil { formatter.WriteString(" NOT NULL") } else if c.Nullable != nil { formatter.WriteString(" NULL") } if c.DefaultExpr != nil { formatter.WriteString(" DEFAULT ") formatter.WriteExpr(c.DefaultExpr) } if c.MaterializedExpr != nil { formatter.WriteString(" MATERIALIZED ") formatter.WriteExpr(c.MaterializedExpr) } if c.AliasExpr != nil { formatter.WriteString(" ALIAS ") formatter.WriteExpr(c.AliasExpr) } if c.Codec != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.Codec) } if c.TTL != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.TTL) } if c.Comment != nil { formatter.WriteString(" COMMENT ") formatter.WriteExpr(c.Comment) } } func (c *ColumnExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Expr) if c.Alias != nil { formatter.WriteString(" AS ") formatter.WriteExpr(c.Alias) } } func (c *ColumnExprList) FormatSQL(formatter *Formatter) { if c.HasDistinct { formatter.WriteString("DISTINCT ") } for i, item := range c.Items { formatter.WriteExpr(item) if i != len(c.Items)-1 { formatter.WriteString(", ") } } } func (c *ColumnNamesExpr) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') for i, column := range c.ColumnNames { if i > 0 { formatter.WriteString(", ") } columnExpr := column formatter.WriteExpr(&columnExpr) } formatter.WriteByte(')') } func (c *ColumnTypeExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Name) } func (c *ComplexType) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Name) formatter.WriteByte('(') for i, param := range c.Params { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(param) } formatter.WriteByte(')') } func (c *CompressionCodec) FormatSQL(formatter *Formatter) { formatter.WriteString("CODEC(") if c.Type != nil { formatter.WriteExpr(c.Type) if c.TypeLevel != nil { formatter.WriteByte('(') formatter.WriteExpr(c.TypeLevel) formatter.WriteByte(')') } formatter.WriteByte(',') formatter.WriteByte(whitespace) } if c.Name != nil { formatter.WriteExpr(c.Name) if c.Level != nil { formatter.WriteByte('(') formatter.WriteExpr(c.Level) formatter.WriteByte(')') } } formatter.WriteByte(')') } func (c *ConstraintClause) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Constraint) formatter.WriteByte(whitespace) formatter.WriteExpr(c.Expr) } func (c *CreateDatabase) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE DATABASE ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.OnCluster) } if c.Engine != nil { formatter.Break() formatter.WriteExpr(c.Engine) } if c.Comment != nil { formatter.WriteString(" COMMENT ") formatter.WriteExpr(c.Comment) } } func (c *CreateDictionary) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE ") if c.OrReplace { formatter.WriteString("OR REPLACE ") } formatter.WriteString("DICTIONARY ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.UUID != nil { formatter.Break() formatter.WriteExpr(c.UUID) } if c.OnCluster != nil { formatter.Break() formatter.WriteExpr(c.OnCluster) } if c.Schema != nil { formatter.Break() formatter.WriteExpr(c.Schema) } if c.Engine != nil { formatter.Break() formatter.WriteExpr(c.Engine) } if c.Comment != nil { formatter.Break() formatter.WriteString("COMMENT ") formatter.WriteExpr(c.Comment) } } func (c *CreateFunction) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE") if c.OrReplace { formatter.WriteString(" OR REPLACE") } formatter.WriteString(" FUNCTION ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.FunctionName) if c.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.OnCluster) } formatter.WriteString(" AS ") formatter.WriteExpr(c.Params) formatter.WriteString(" -> ") formatter.WriteExpr(c.Expr) } func (c *CreateLiveView) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE LIVE VIEW ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.OnCluster != nil { formatter.Break() formatter.WriteExpr(c.OnCluster) } if c.WithTimeout != nil { formatter.Break() formatter.WriteExpr(c.WithTimeout) } if c.Destination != nil { formatter.Break() formatter.WriteExpr(c.Destination) } if c.TableSchema != nil { formatter.Break() formatter.WriteExpr(c.TableSchema) } if c.SubQuery != nil { formatter.Break() formatter.WriteString("AS ") formatter.WriteExpr(c.SubQuery) } } func (c *CreateMaterializedView) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE MATERIALIZED VIEW ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.OnCluster != nil { formatter.Break() formatter.WriteExpr(c.OnCluster) } if c.Refresh != nil { formatter.Break() formatter.WriteExpr(c.Refresh) } if c.RandomizeFor != nil { formatter.Break() formatter.WriteString("RANDOMIZE FOR ") formatter.WriteExpr(c.RandomizeFor) } if c.DependsOn != nil { formatter.Break() formatter.WriteString("DEPENDS ON ") for i, dep := range c.DependsOn { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(dep) } } if c.Settings != nil { formatter.Break() formatter.WriteExpr(c.Settings) } if c.HasAppend { formatter.Break() formatter.WriteString("APPEND") } if c.Engine != nil { formatter.Break() formatter.WriteExpr(c.Engine) } if c.Destination != nil { formatter.Break() formatter.WriteExpr(c.Destination) if c.Destination.TableSchema != nil { formatter.Break() formatter.WriteExpr(c.Destination.TableSchema) } } if c.HasEmpty { formatter.Break() formatter.WriteString("EMPTY") } if c.Definer != nil { formatter.Break() formatter.WriteString("DEFINER = ") formatter.WriteExpr(c.Definer) } if c.SQLSecurity != "" { formatter.Break() formatter.WriteString("SQL SECURITY ") formatter.WriteString(c.SQLSecurity) } if c.Populate { formatter.Break() formatter.WriteString("POPULATE") } if c.SubQuery != nil { formatter.Break() formatter.WriteString("AS") formatter.Indent() formatter.Break() formatter.WriteExpr(c.SubQuery) formatter.Dedent() } if c.Comment != nil { formatter.Break() formatter.WriteString("COMMENT ") formatter.WriteExpr(c.Comment) } } func (c *CreateNamedCollection) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE NAMED COLLECTION ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.OnCluster) } formatter.WriteString(" AS ") for i, param := range c.Params { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(param) } } func (c *CreateRole) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE ROLE ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } if c.OrReplace { formatter.WriteString("OR REPLACE ") } for i, roleName := range c.RoleNames { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(roleName) } if c.AccessStorageType != nil { formatter.WriteString(" IN ") formatter.WriteExpr(c.AccessStorageType) } if len(c.Settings) > 0 { formatter.Break() formatter.WriteString("SETTINGS") formatter.Indent() for i, setting := range c.Settings { if i > 0 { formatter.WriteString(",") } formatter.Break() formatter.WriteExpr(setting) } formatter.Dedent() } } func (c *CreateTable) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE") if c.OrReplace { formatter.WriteString(" OR REPLACE") } if c.HasTemporary { formatter.WriteString(" TEMPORARY") } formatter.WriteString(" TABLE ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.UUID != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.UUID) } if c.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.OnCluster) } if c.TableSchema != nil { formatter.Break() formatter.WriteExpr(c.TableSchema) } if c.Engine != nil { formatter.Break() formatter.WriteExpr(c.Engine) } if c.SubQuery != nil { formatter.Break() formatter.WriteString("AS ") formatter.WriteExpr(c.SubQuery) } if c.TableFunction != nil { formatter.Break() formatter.WriteString("AS ") formatter.WriteExpr(c.TableFunction) } if c.Comment != nil { formatter.Break() formatter.WriteString("COMMENT ") formatter.WriteExpr(c.Comment) } } func (c *CreateUser) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE USER ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } if c.OrReplace { formatter.WriteString("OR REPLACE ") } for i, userName := range c.UserNames { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(userName) } if c.Authentication != nil { formatter.Break() formatter.WriteExpr(c.Authentication) } if c.ValidUntil != nil { formatter.Break() formatter.WriteString("VALID UNTIL ") formatter.WriteExpr(c.ValidUntil) } if len(c.Hosts) > 0 { formatter.Break() for i, host := range c.Hosts { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(host) } } if c.DefaultRole != nil { formatter.Break() formatter.WriteExpr(c.DefaultRole) } if c.DefaultDatabase != nil { formatter.Break() formatter.WriteString("DEFAULT DATABASE ") formatter.WriteExpr(c.DefaultDatabase) } else if c.DefaultDbNone { formatter.Break() formatter.WriteString("DEFAULT DATABASE NONE") } if c.Grantees != nil { formatter.Break() formatter.WriteExpr(c.Grantees) } if len(c.Settings) > 0 { formatter.Break() formatter.WriteString("SETTINGS") formatter.Indent() for i, setting := range c.Settings { formatter.Break() formatter.WriteExpr(setting) if i < len(c.Settings)-1 { formatter.WriteString(",") } } formatter.Dedent() } } func (c *CreateView) FormatSQL(formatter *Formatter) { formatter.WriteString("CREATE") if c.OrReplace { formatter.WriteString(" OR REPLACE") } formatter.WriteString(" VIEW ") if c.IfNotExists { formatter.WriteString("IF NOT EXISTS ") } formatter.WriteExpr(c.Name) if c.UUID != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.UUID) } if c.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.OnCluster) } if c.TableSchema != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(c.TableSchema) } if c.Comment != nil { formatter.WriteString(" COMMENT ") formatter.WriteExpr(c.Comment) } if c.SubQuery != nil { formatter.WriteString(" AS ") formatter.WriteExpr(c.SubQuery) } } func (d *DeduplicateClause) FormatSQL(formatter *Formatter) { formatter.WriteString(" DEDUPLICATE") if d.By != nil { formatter.WriteString(" BY ") formatter.WriteExpr(d.By) } if d.Except != nil { formatter.WriteString(" EXCEPT ") formatter.WriteExpr(d.Except) } } func (d *DefaultRoleClause) FormatSQL(formatter *Formatter) { formatter.WriteString("DEFAULT ROLE ") if d.None { formatter.WriteString("NONE") } else { for i, role := range d.Roles { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(role) } } } func (d *DeleteClause) FormatSQL(formatter *Formatter) { formatter.WriteString("DELETE FROM ") formatter.WriteExpr(d.Table) if d.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(d.OnCluster) } if d.WhereExpr != nil { formatter.WriteString(" WHERE ") formatter.WriteExpr(d.WhereExpr) } } func (d *DescribeStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("DESCRIBE ") if d.DescribeType != "" { formatter.WriteString(d.DescribeType) formatter.WriteByte(whitespace) } formatter.WriteExpr(d.Target) } func (d *DestinationClause) FormatSQL(formatter *Formatter) { formatter.WriteString("TO ") formatter.WriteExpr(d.TableIdentifier) } func (d *DictionaryArgExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(d.Name) formatter.WriteByte(whitespace) formatter.WriteExpr(d.Value) } func (d *DictionaryAttribute) FormatSQL(formatter *Formatter) { formatter.WriteExpr(d.Name) formatter.WriteByte(whitespace) formatter.WriteExpr(d.Type) if d.Default != nil { formatter.WriteString(" DEFAULT ") formatter.WriteExpr(d.Default) } if d.Expression != nil { formatter.WriteString(" EXPRESSION ") formatter.WriteExpr(d.Expression) } if d.Hierarchical { formatter.WriteString(" HIERARCHICAL") } if d.Injective { formatter.WriteString(" INJECTIVE") } if d.IsObjectId { formatter.WriteString(" IS_OBJECT_ID") } } func (d *DictionaryEngineClause) FormatSQL(formatter *Formatter) { needsBreak := false breakAndWrite := func(expr Expr) { if needsBreak { formatter.Break() } formatter.WriteExpr(expr) needsBreak = true } if d.PrimaryKey != nil { breakAndWrite(d.PrimaryKey) } if d.Source != nil { breakAndWrite(d.Source) } if d.Lifetime != nil { breakAndWrite(d.Lifetime) } if d.Layout != nil { breakAndWrite(d.Layout) } if d.Range != nil { breakAndWrite(d.Range) } if d.Settings != nil { if needsBreak { formatter.Break() } formatter.WriteString("SETTINGS(") for i, item := range d.Settings.Items { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(item) } formatter.WriteString(")") } } func (d *DictionaryLayoutClause) FormatSQL(formatter *Formatter) { formatter.WriteString("LAYOUT(") formatter.WriteExpr(d.Layout) formatter.WriteString("(") for i, arg := range d.Args { if i > 0 { formatter.WriteByte(whitespace) } formatter.WriteExpr(arg) } formatter.WriteString("))") } func (d *DictionaryLifetimeClause) FormatSQL(formatter *Formatter) { formatter.WriteString("LIFETIME(") if d.Value != nil { formatter.WriteExpr(d.Value) } else if d.Min != nil && d.Max != nil { formatter.WriteString("MIN ") formatter.WriteExpr(d.Min) formatter.WriteString(" MAX ") formatter.WriteExpr(d.Max) } formatter.WriteString(")") } func (d *DictionaryPrimaryKeyClause) FormatSQL(formatter *Formatter) { formatter.WriteString("PRIMARY KEY ") formatter.WriteExpr(d.Keys) } func (d *DictionaryRangeClause) FormatSQL(formatter *Formatter) { formatter.WriteString("RANGE(") formatter.WriteString("MIN ") if d.Min != nil { formatter.WriteExpr(d.Min) } if d.Max != nil { formatter.WriteString(" MAX ") formatter.WriteExpr(d.Max) } formatter.WriteString(")") } func (d *DictionarySchemaClause) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') formatter.Indent() for i, attr := range d.Attributes { if i == 0 { formatter.NewLine() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(attr) } formatter.Dedent() formatter.NewLine() formatter.WriteByte(')') } func (d *DictionarySourceClause) FormatSQL(formatter *Formatter) { formatter.WriteString("SOURCE(") formatter.WriteExpr(d.Source) formatter.WriteString("(") for i, arg := range d.Args { if i > 0 { formatter.WriteByte(whitespace) } formatter.WriteExpr(arg) } formatter.WriteString("))") } func (s *DistinctOn) FormatSQL(formatter *Formatter) { formatter.WriteString("ON (") for i, ident := range s.Idents { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(ident) } formatter.WriteByte(')') } func (d *DropDatabase) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP DATABASE ") if d.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(d.Name) if d.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(d.OnCluster) } } func (d *DropStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP ") if d.IsTemporary { formatter.WriteString("TEMPORARY ") } formatter.WriteString(d.DropTarget + " ") if d.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(d.Name) if d.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(d.OnCluster) } if len(d.Modifier) != 0 { formatter.WriteString(" " + d.Modifier) } } func (d *DropUserOrRole) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP " + d.Target + " ") if d.IfExists { formatter.WriteString("IF EXISTS ") } for i, name := range d.Names { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(name) } if len(d.Modifier) != 0 { formatter.WriteString(" " + d.Modifier) } if d.From != nil { formatter.WriteString(" FROM ") formatter.WriteExpr(d.From) } } func (e *EngineExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("ENGINE = ") formatter.WriteString(e.Name) if e.Params != nil { formatter.WriteExpr(e.Params) } if e.OrderBy != nil { formatter.Break() formatter.WriteExpr(e.OrderBy) } if e.PartitionBy != nil { formatter.Break() formatter.WriteExpr(e.PartitionBy) } if e.PrimaryKey != nil { formatter.Break() formatter.WriteExpr(e.PrimaryKey) } if e.SampleBy != nil { formatter.Break() formatter.WriteExpr(e.SampleBy) } if e.TTL != nil { formatter.Break() formatter.WriteExpr(e.TTL) } if e.Settings != nil { formatter.Break() formatter.WriteExpr(e.Settings) } } func (e *EnumType) FormatSQL(formatter *Formatter) { formatter.WriteExpr(e.Name) formatter.WriteByte('(') for i, enum := range e.Values { if i > 0 { formatter.WriteString(", ") } enumExpr := enum formatter.WriteExpr(&enumExpr) } formatter.WriteByte(')') } func (e *EnumValue) FormatSQL(formatter *Formatter) { formatter.WriteExpr(e.Name) formatter.WriteByte('=') formatter.WriteExpr(e.Value) } func (e *ExplainStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("EXPLAIN ") formatter.WriteString(e.Type) formatter.WriteByte(whitespace) formatter.WriteExpr(e.Statement) } func (e *ExtractExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("EXTRACT(") for i, param := range e.Parameters { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(param) } formatter.WriteByte(')') } func (f *Fill) FormatSQL(formatter *Formatter) { formatter.WriteString("WITH FILL") if f.From != nil { formatter.WriteString(" FROM ") formatter.WriteExpr(f.From) } if f.To != nil { formatter.WriteString(" TO ") formatter.WriteExpr(f.To) } if f.Step != nil { formatter.WriteString(" STEP ") formatter.WriteExpr(f.Step) } if f.Staleness != nil { formatter.WriteString(" STALENESS ") formatter.WriteExpr(f.Staleness) } } func (f *FormatClause) FormatSQL(formatter *Formatter) { formatter.WriteString("FORMAT ") formatter.WriteExpr(f.Format) } func (f *FromClause) FormatSQL(formatter *Formatter) { formatter.WriteString("FROM") formatter.Indent() formatter.Break() formatter.WriteExpr(f.Expr) formatter.Dedent() } func (f *FunctionExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(f.Name) formatter.WriteExpr(f.Params) } func (g *GlobalInOperation) FormatSQL(formatter *Formatter) { formatter.WriteString("GLOBAL ") formatter.WriteExpr(g.Expr) } func (g *GrantPrivilegeStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("GRANT ") if g.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(g.OnCluster) } for i, privilege := range g.Privileges { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(privilege) } formatter.WriteString(" ON ") formatter.WriteExpr(g.On) formatter.WriteString(" TO ") for i, role := range g.To { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(role) } for _, option := range g.WithOptions { formatter.WriteString(" WITH " + option + " OPTION") } } func (g *GranteesClause) FormatSQL(formatter *Formatter) { formatter.WriteString("GRANTEES ") if g.Any { formatter.WriteString("ANY") } else if g.None { formatter.WriteString("NONE") } else { for i, grantee := range g.Grantees { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(grantee) } } if len(g.ExceptUsers) > 0 { formatter.Break() formatter.WriteString("EXCEPT ") for i, except := range g.ExceptUsers { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(except) } } } func (g *GroupByClause) FormatSQL(formatter *Formatter) { formatter.WriteString("GROUP BY") formatter.Indent() defer formatter.Dedent() if g.AggregateType != "" { formatter.Break() formatter.WriteString(g.AggregateType) } if g.Expr != nil { if g.AggregateType == "" { formatter.Break() } formatter.WriteExpr(g.Expr) } if g.WithCube { formatter.Break() formatter.WriteString("WITH CUBE") } if g.WithRollup { formatter.Break() formatter.WriteString("WITH ROLLUP") } if g.WithTotals { formatter.Break() formatter.WriteString("WITH TOTALS") } } func (h *HavingClause) FormatSQL(formatter *Formatter) { formatter.WriteString("HAVING ") formatter.WriteExpr(h.Expr) } func (h *HostClause) FormatSQL(formatter *Formatter) { formatter.WriteString("HOST ") formatter.WriteString(h.HostType) if h.HostValue != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(h.HostValue) } } func (i *Ident) FormatSQL(formatter *Formatter) { switch i.QuoteType { case BackTicks: formatter.WriteByte('`') formatter.WriteString(i.Name) formatter.WriteByte('`') case DoubleQuote: formatter.WriteByte('"') formatter.WriteString(i.Name) formatter.WriteByte('"') case SingleQuote: formatter.WriteByte('\'') formatter.WriteString(i.Name) formatter.WriteByte('\'') default: formatter.WriteString(i.Name) } } func (i *IndexOperation) FormatSQL(formatter *Formatter) { formatter.WriteExpr(i.Object) formatter.WriteString(string(i.Operation)) formatter.WriteExpr(i.Index) } func (i *InsertStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("INSERT INTO ") if i.HasTableKeyword { formatter.WriteString("TABLE ") } formatter.WriteExpr(i.Table) if i.ColumnNames != nil { formatter.Break() formatter.Indent() formatter.WriteExpr(i.ColumnNames) formatter.Dedent() } if i.Format != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(i.Format) } if i.SelectExpr != nil { formatter.Break() formatter.WriteExpr(i.SelectExpr) } else if len(i.Values) > 0 { formatter.Break() formatter.WriteString("VALUES") formatter.Indent() for j, value := range i.Values { formatter.Break() formatter.WriteExpr(value) if j != len(i.Values)-1 { formatter.WriteByte(',') } } formatter.Dedent() } } func (i *InterpolateClause) FormatSQL(formatter *Formatter) { formatter.WriteString("INTERPOLATE") if len(i.Items) > 0 { formatter.WriteString(" (") for idx, item := range i.Items { formatter.WriteExpr(item) if idx != len(i.Items)-1 { formatter.WriteString(", ") } } formatter.WriteByte(')') } } func (i *InterpolateItem) FormatSQL(formatter *Formatter) { formatter.WriteExpr(i.Column) if i.Expr != nil { formatter.WriteString(" AS ") formatter.WriteExpr(i.Expr) } } func (i *IntervalExpr) FormatSQL(formatter *Formatter) { if i.IntervalPos != 0 { formatter.WriteString("INTERVAL ") } formatter.WriteExpr(i.Expr) formatter.WriteByte(whitespace) formatter.WriteExpr(i.Unit) } func (i *IntervalFrom) FormatSQL(formatter *Formatter) { formatter.WriteExpr(i.Interval) formatter.WriteString(" FROM ") formatter.WriteExpr(i.FromExpr) } func (n *IsNotNullExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(n.Expr) formatter.WriteString(" IS NOT NULL") } func (n *IsNullExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(n.Expr) formatter.WriteString(" IS NULL") } func (j *JSONPath) FormatSQL(formatter *Formatter) { for i, ident := range j.Idents { if i > 0 { formatter.WriteByte('.') } formatter.WriteExpr(ident) } } func (j *JSONOption) FormatSQL(formatter *Formatter) { wroteAny := false if j.SkipPath != nil { formatter.WriteString("SKIP ") j.SkipPath.FormatSQL(formatter) wroteAny = true } if j.SkipRegex != nil { formatter.WriteString(" SKIP REGEXP ") formatter.WriteExpr(j.SkipRegex) wroteAny = true } if j.MaxDynamicPaths != nil { formatter.WriteString("max_dynamic_paths") formatter.WriteByte('=') formatter.WriteExpr(j.MaxDynamicPaths) wroteAny = true } if j.MaxDynamicTypes != nil { formatter.WriteString("max_dynamic_types") formatter.WriteByte('=') formatter.WriteExpr(j.MaxDynamicTypes) wroteAny = true } if j.Column != nil && j.Column.Path != nil && j.Column.Type != nil { // Add a leading space if there is already content. if wroteAny { formatter.WriteByte(whitespace) } j.Column.Path.FormatSQL(formatter) formatter.WriteByte(whitespace) formatter.WriteExpr(j.Column.Type) } } func (j *JSONOptions) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') // Ensure stable, readable ordering: // 1) numeric options (max_dynamic_*), 2) type-hint items, 3) skip options (SKIP, SKIP REGEXP) // Preserve original relative order within each group. numericOptionItems := make([]*JSONOption, 0, len(j.Items)) columnItems := make([]*JSONOption, 0, len(j.Items)) skipOptionItems := make([]*JSONOption, 0, len(j.Items)) for _, item := range j.Items { if item.MaxDynamicPaths != nil || item.MaxDynamicTypes != nil { numericOptionItems = append(numericOptionItems, item) continue } if item.Column != nil { columnItems = append(columnItems, item) continue } if item.SkipPath != nil || item.SkipRegex != nil { skipOptionItems = append(skipOptionItems, item) continue } // Fallback: treat as numeric option to avoid dropping unknown future fields. numericOptionItems = append(numericOptionItems, item) } wroteItem := false writeItems := func(items []*JSONOption) { for _, item := range items { if wroteItem { formatter.WriteString(", ") } item.FormatSQL(formatter) wroteItem = true } } writeItems(numericOptionItems) writeItems(columnItems) writeItems(skipOptionItems) formatter.WriteByte(')') } func (j *JSONType) FormatSQL(formatter *Formatter) { formatter.WriteExpr(j.Name) if j.Options != nil { j.Options.FormatSQL(formatter) } } func (j *JoinConstraintClause) FormatSQL(formatter *Formatter) { if j.On != nil { formatter.WriteString("ON ") formatter.WriteExpr(j.On) } else { formatter.WriteString("USING ") formatter.WriteExpr(j.Using) } } func (j *JoinExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(j.Left) if j.Right != nil { writeJoinSQL(formatter, j.Right) } } func writeJoinSQL(formatter *Formatter, expr Expr) { joinExpr, ok := expr.(*JoinExpr) if !ok { formatter.WriteByte(',') formatter.WriteExpr(expr) return } if len(joinExpr.Modifiers) == 0 { formatter.WriteByte(',') formatter.WriteExpr(joinExpr.Left) } else { formatter.Break() formatter.WriteString(strings.Join(joinExpr.Modifiers, " ")) formatter.Indent() formatter.Break() formatter.WriteExpr(joinExpr.Left) if joinExpr.Constraints != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(joinExpr.Constraints) } formatter.Dedent() } if joinExpr.Right != nil { writeJoinSQL(formatter, joinExpr.Right) } } func (j *JoinTableExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(j.Table) if j.SampleRatio != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(j.SampleRatio) } if j.HasFinal { formatter.WriteString(" FINAL") } } func (l *LimitByClause) FormatSQL(formatter *Formatter) { if l.Limit != nil { formatter.WriteExpr(l.Limit) } if l.ByExpr != nil { formatter.WriteString(" BY ") formatter.WriteExpr(l.ByExpr) } } func (l *LimitClause) FormatSQL(formatter *Formatter) { if l.Limit != nil { formatter.WriteString("LIMIT ") formatter.WriteExpr(l.Limit) if l.Offset != nil { formatter.WriteByte(whitespace) } } if l.Offset != nil { formatter.WriteString("OFFSET ") formatter.WriteExpr(l.Offset) } } func (m *MapLiteral) FormatSQL(formatter *Formatter) { formatter.WriteString("{") for i, value := range m.KeyValues { if i > 0 { formatter.WriteString(", ") } key := value.Key formatter.WriteExpr(&key) formatter.WriteString(": ") formatter.WriteExpr(value.Value) } formatter.WriteString("}") } func (n *NamedCollectionParam) FormatSQL(formatter *Formatter) { formatter.WriteExpr(n.Name) formatter.WriteString(" = ") formatter.WriteExpr(n.Value) if n.NotOverridable { formatter.WriteString(" NOT OVERRIDABLE") } else if n.Overridable { formatter.WriteString(" OVERRIDABLE") } } func (n *NamedParameterExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(n.Name) formatter.WriteByte('=') formatter.WriteExpr(n.Value) } func (n *NegateExpr) FormatSQL(formatter *Formatter) { formatter.WriteByte('-') formatter.WriteExpr(n.Expr) } func (n *NestedIdentifier) FormatSQL(formatter *Formatter) { if n.DotIdent != nil { formatter.WriteExpr(n.Ident) formatter.WriteByte('.') formatter.WriteExpr(n.DotIdent) } else { formatter.WriteExpr(n.Ident) } } func (n *NestedType) FormatSQL(formatter *Formatter) { // on the same level as the column type formatter.WriteExpr(n.Name) formatter.WriteByte('(') for i, column := range n.Columns { formatter.WriteExpr(column) if i != len(n.Columns)-1 { formatter.WriteString(", ") } } // right paren needs to be on the same level as the column formatter.WriteByte(')') } func (n *NotExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("NOT") formatter.WriteByte(whitespace) formatter.WriteExpr(n.Expr) } func (n *NotNullLiteral) FormatSQL(formatter *Formatter) { formatter.WriteString("NOT NULL") } func (n *NullLiteral) FormatSQL(formatter *Formatter) { formatter.WriteString("NULL") } func (n *NumberLiteral) FormatSQL(formatter *Formatter) { formatter.WriteString(n.Literal) } func (o *ObjectParams) FormatSQL(formatter *Formatter) { formatter.WriteExpr(o.Object) formatter.WriteExpr(o.Params) } func (o *OnClause) FormatSQL(formatter *Formatter) { formatter.WriteString("ON ") formatter.WriteExpr(o.On) } func (o *OperationExpr) FormatSQL(formatter *Formatter) { formatter.WriteString(strings.ToUpper(string(o.Kind))) } func (o *OptimizeStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("OPTIMIZE TABLE ") formatter.WriteExpr(o.Table) if o.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(o.OnCluster) } if o.Partition != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(o.Partition) } if o.HasFinal { formatter.WriteString(" FINAL") } if o.Deduplicate != nil { formatter.WriteExpr(o.Deduplicate) } } func (o *OrderByClause) FormatSQL(formatter *Formatter) { formatter.WriteString("ORDER BY") formatter.Indent() for i, item := range o.Items { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(item) } if o.Interpolate != nil { formatter.Break() formatter.WriteExpr(o.Interpolate) } formatter.Dedent() } func (o *OrderExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(o.Expr) if o.Alias != nil { formatter.WriteString(" AS ") formatter.WriteExpr(o.Alias) } if o.Direction != OrderDirectionNone { formatter.WriteByte(whitespace) formatter.WriteString(string(o.Direction)) } if o.Fill != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(o.Fill) } } func (f *ParamExprList) FormatSQL(formatter *Formatter) { formatter.WriteString("(") formatter.WriteExpr(f.Items) formatter.WriteString(")") if f.ColumnArgList != nil { formatter.WriteExpr(f.ColumnArgList) } } func (p *PartitionByClause) FormatSQL(formatter *Formatter) { formatter.WriteString("PARTITION BY ") formatter.WriteExpr(p.Expr) } func (p *PartitionClause) FormatSQL(formatter *Formatter) { formatter.WriteString("PARTITION ") if p.ID != nil { formatter.WriteExpr(p.ID) } else if p.All { formatter.WriteString("ALL") } else { formatter.WriteExpr(p.Expr) } } func (p *Path) FormatSQL(formatter *Formatter) { for i, ident := range p.Fields { if i > 0 { formatter.WriteByte('.') } formatter.WriteExpr(ident) } } func (p *PlaceHolder) FormatSQL(formatter *Formatter) { formatter.WriteString(p.Type) } func (w *PrewhereClause) FormatSQL(formatter *Formatter) { formatter.WriteString("PREWHERE ") formatter.WriteExpr(w.Expr) } func (p *PrimaryKeyClause) FormatSQL(formatter *Formatter) { formatter.WriteString("PRIMARY KEY ") formatter.WriteExpr(p.Expr) } func (p *PrivilegeClause) FormatSQL(formatter *Formatter) { for i, keyword := range p.Keywords { if i > 0 { formatter.WriteByte(whitespace) } formatter.WriteString(keyword) } if p.Params != nil { formatter.WriteExpr(p.Params) } } func (p *ProjectionOrderByClause) FormatSQL(formatter *Formatter) { formatter.WriteString("ORDER BY ") formatter.WriteExpr(p.Columns) } func (p *ProjectionSelectStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("(") if p.With != nil { formatter.WriteExpr(p.With) formatter.WriteByte(whitespace) } formatter.WriteString("SELECT ") formatter.WriteExpr(p.SelectColumns) if p.GroupBy != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(p.GroupBy) } if p.OrderBy != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(p.OrderBy) } formatter.WriteString(")") } func (c *PropertyType) FormatSQL(formatter *Formatter) { formatter.WriteExpr(c.Name) } func (q *QueryParam) FormatSQL(formatter *Formatter) { formatter.WriteString("{") formatter.WriteExpr(q.Name) formatter.WriteString(": ") formatter.WriteExpr(q.Type) formatter.WriteString("}") } func (r *RatioExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(r.Numerator) if r.Denominator != nil { formatter.WriteString("/") formatter.WriteExpr(r.Denominator) } } func (r *RefreshExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("REFRESH ") formatter.WriteString(r.Frequency) if r.Interval != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(r.Interval) } if r.Offset != nil { formatter.WriteString(" OFFSET ") formatter.WriteExpr(r.Offset) } } func (a *RemovePropertyType) FormatSQL(formatter *Formatter) { formatter.WriteString(" REMOVE ") formatter.WriteExpr(a.PropertyType) } func (r *RenameStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("RENAME " + r.RenameTarget + " ") for i, pair := range r.TargetPairList { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(pair.Old) formatter.WriteString(" TO ") formatter.WriteExpr(pair.New) } if r.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(r.OnCluster) } } func (r *RoleName) FormatSQL(formatter *Formatter) { formatter.WriteExpr(r.Name) if r.Scope != nil { formatter.WriteString("@") formatter.WriteExpr(r.Scope) } if r.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(r.OnCluster) } } func (r *RoleRenamePair) FormatSQL(formatter *Formatter) { formatter.WriteExpr(r.RoleName) if r.NewName != nil { formatter.WriteString(" RENAME TO ") formatter.WriteExpr(r.NewName) } } func (r *RoleSetting) FormatSQL(formatter *Formatter) { for i, settingPair := range r.SettingPairs { if i > 0 { formatter.Break() } formatter.WriteExpr(settingPair) } if r.Modifier != nil { if len(r.SettingPairs) > 0 { formatter.Break() } formatter.WriteExpr(r.Modifier) } } func (s *SampleByClause) FormatSQL(formatter *Formatter) { formatter.WriteString("SAMPLE BY ") formatter.WriteExpr(s.Expr) } func (s *SampleClause) FormatSQL(formatter *Formatter) { formatter.WriteString("SAMPLE ") formatter.WriteExpr(s.Ratio) if s.Offset != nil { formatter.WriteString(" OFFSET ") formatter.WriteExpr(s.Offset) } } func (s *ScalarType) FormatSQL(formatter *Formatter) { formatter.WriteExpr(s.Name) } func (s *SelectItem) FormatSQL(formatter *Formatter) { formatter.WriteExpr(s.Expr) for _, modifier := range s.Modifiers { formatter.WriteByte(whitespace) formatter.WriteExpr(modifier) } if s.Alias != nil { formatter.WriteString(" AS ") formatter.WriteExpr(s.Alias) } } func (s *SelectQuery) FormatSQL(formatter *Formatter) { if s.With != nil { formatter.WriteString("WITH") formatter.Indent() for i, cte := range s.With.CTEs { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(cte) } formatter.Dedent() formatter.Break() } formatter.WriteString("SELECT") if s.HasDistinct { formatter.WriteString(" DISTINCT") if s.DistinctOn != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(s.DistinctOn) } } if s.Top != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(s.Top) } formatter.Indent() for i, selectItem := range s.SelectItems { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(selectItem) } formatter.Dedent() if s.From != nil { formatter.Break() formatter.WriteExpr(s.From) } if s.Window != nil { formatter.Break() formatter.WriteExpr(s.Window) } if s.Prewhere != nil { formatter.Break() formatter.WriteExpr(s.Prewhere) } if s.Where != nil { formatter.Break() formatter.WriteExpr(s.Where) } if s.GroupBy != nil { formatter.Break() formatter.WriteExpr(s.GroupBy) } if s.Having != nil { formatter.Break() formatter.WriteExpr(s.Having) } if s.OrderBy != nil { formatter.Break() formatter.WriteExpr(s.OrderBy) } if s.LimitBy != nil { formatter.Break() formatter.WriteExpr(s.LimitBy) } if s.Limit != nil { formatter.Break() formatter.WriteExpr(s.Limit) } if s.Settings != nil { formatter.Break() formatter.WriteExpr(s.Settings) } if s.Format != nil { formatter.Break() formatter.WriteExpr(s.Format) } if s.UnionAll != nil { formatter.Break() formatter.WriteString("UNION ALL") formatter.Break() formatter.WriteExpr(s.UnionAll) } else if s.UnionDistinct != nil { formatter.Break() formatter.WriteString("UNION DISTINCT") formatter.Break() formatter.WriteExpr(s.UnionDistinct) } else if s.Except != nil { formatter.Break() formatter.WriteString("EXCEPT") formatter.Break() formatter.WriteExpr(s.Except) } } func (s *SetStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("SET ") for i, item := range s.Settings.Items { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(item) } } func (s *SettingExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(s.Name) formatter.WriteByte('=') formatter.WriteExpr(s.Expr) } func (s *SettingPair) FormatSQL(formatter *Formatter) { formatter.WriteExpr(s.Name) if s.Value != nil { if s.Operation == TokenKindSingleEQ { formatter.WriteString(string(s.Operation)) } else { formatter.WriteByte(whitespace) } formatter.WriteExpr(s.Value) } } func (s *SettingsClause) FormatSQL(formatter *Formatter) { formatter.WriteString("SETTINGS") formatter.Indent() for i, item := range s.Items { if i == 0 { formatter.Break() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(item) } formatter.Dedent() } func (s *ShowStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("SHOW ") formatter.WriteString(s.ShowType) if s.Target != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(s.Target) } // Add optional clauses for SHOW DATABASES if s.LikeType != "" && s.LikePattern != nil { if s.NotLike { formatter.WriteString(" NOT ") } else { formatter.WriteByte(whitespace) } formatter.WriteString(s.LikeType) formatter.WriteByte(whitespace) formatter.WriteExpr(s.LikePattern) } if s.Limit != nil { formatter.WriteString(" LIMIT ") formatter.WriteExpr(s.Limit) } if s.OutFile != nil { formatter.WriteString(" INTO OUTFILE ") formatter.WriteExpr(s.OutFile) } if s.Format != nil { formatter.WriteString(" FORMAT ") formatter.WriteExpr(s.Format) } } func (s *StringLiteral) FormatSQL(formatter *Formatter) { formatter.WriteByte('\'') formatter.WriteString(s.Literal) formatter.WriteByte('\'') } func (s *SubQuery) FormatSQL(formatter *Formatter) { if s.HasParen { formatter.WriteByte('(') } formatter.WriteExpr(s.Select) if s.HasParen { formatter.WriteByte(')') } } func (s *SystemCtrlExpr) FormatSQL(formatter *Formatter) { formatter.WriteString(s.Command) formatter.WriteByte(whitespace) formatter.WriteString(s.Type) if s.Cluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(s.Cluster) } } func (s *SystemDropExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("DROP ") formatter.WriteString(s.Type) } func (s *SystemFlushExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("FLUSH ") if s.Logs { formatter.WriteString("LOGS") } else { formatter.WriteExpr(s.Distributed) } } func (s *SystemReloadExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("RELOAD ") formatter.WriteString(s.Type) if s.Dictionary != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(s.Dictionary) } } func (s *SystemStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("SYSTEM") formatter.WriteByte(whitespace) formatter.WriteExpr(s.Expr) } func (s *SystemSyncExpr) FormatSQL(formatter *Formatter) { formatter.WriteString("SYNC ") formatter.WriteExpr(s.Cluster) } func (t *TTLClause) FormatSQL(formatter *Formatter) { formatter.WriteString("TTL ") for i, item := range t.Items { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(item) } } func (t *TTLExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(t.Expr) if t.Policy != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(t.Policy) } } func (t *TTLPolicy) FormatSQL(formatter *Formatter) { if t.Item != nil { formatter.WriteExpr(t.Item) } if t.Where != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(t.Where) } if t.GroupBy != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(t.GroupBy) } } func (t *TTLPolicyRule) FormatSQL(formatter *Formatter) { if t.ToVolume != nil { formatter.WriteString("TO VOLUME ") formatter.WriteExpr(t.ToVolume) } else if t.ToDisk != nil { formatter.WriteString("TO DISK ") formatter.WriteExpr(t.ToDisk) } else if t.Action != nil { formatter.WriteExpr(t.Action) } } func (t *TTLPolicyRuleAction) FormatSQL(formatter *Formatter) { formatter.WriteString(t.Action) if t.Codec != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(t.Codec) } } func (t *TableArgListExpr) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') for i, arg := range t.Args { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(arg) } formatter.WriteByte(')') } func (t *TableExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(t.Expr) if t.Alias != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(t.Alias) } if t.HasFinal { formatter.WriteString(" FINAL") } } func (t *TableFunctionExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(t.Name) formatter.WriteExpr(t.Args) } func (t *TableIdentifier) FormatSQL(formatter *Formatter) { if t.Database != nil { formatter.WriteExpr(t.Database) formatter.WriteByte('.') } formatter.WriteExpr(t.Table) } func (a *TableIndex) FormatSQL(formatter *Formatter) { formatter.WriteString("INDEX") formatter.WriteByte(whitespace) formatter.WriteExpr(a.Name) // Add space only if column expression doesn't start with '(' columnExprStr := Format(a.ColumnExpr) if len(columnExprStr) > 0 && columnExprStr[0] != '(' { formatter.WriteByte(whitespace) } formatter.WriteString(columnExprStr) formatter.WriteByte(whitespace) formatter.WriteString("TYPE") formatter.WriteByte(whitespace) formatter.WriteExpr(a.ColumnType) formatter.WriteByte(whitespace) formatter.WriteString("GRANULARITY") formatter.WriteByte(whitespace) formatter.WriteExpr(a.Granularity) } func (t *TableProjection) FormatSQL(formatter *Formatter) { if t.IncludeProjectionKeyword { formatter.WriteString("PROJECTION ") } formatter.WriteExpr(t.Identifier) formatter.WriteByte(whitespace) formatter.WriteExpr(t.Select) } func (t *TableSchemaClause) FormatSQL(formatter *Formatter) { if len(t.Columns) > 0 { formatter.WriteByte('(') formatter.Indent() for i, column := range t.Columns { if i == 0 { formatter.NewLine() } else { formatter.WriteByte(',') formatter.Break() } formatter.WriteExpr(column) } formatter.Dedent() formatter.NewLine() formatter.WriteByte(')') } if t.AliasTable != nil { formatter.WriteString(" AS ") formatter.WriteExpr(t.AliasTable) } if t.TableFunction != nil { formatter.WriteString(" AS ") formatter.WriteExpr(t.TableFunction) } } func (t *TargetPair) FormatSQL(formatter *Formatter) { formatter.WriteExpr(t.Old) formatter.WriteString(" TO ") formatter.WriteExpr(t.New) } func (t *TernaryOperation) FormatSQL(formatter *Formatter) { formatter.WriteExpr(t.Condition) formatter.WriteString(" ? ") formatter.WriteExpr(t.TrueExpr) formatter.WriteString(" : ") formatter.WriteExpr(t.FalseExpr) } func (t *TopClause) FormatSQL(formatter *Formatter) { formatter.WriteString("TOP ") formatter.WriteString(t.Number.Literal) if t.WithTies { formatter.WriteString(" WITH TIES") } } func (t *TruncateTable) FormatSQL(formatter *Formatter) { formatter.WriteString("TRUNCATE ") if t.IsTemporary { formatter.WriteString("TEMPORARY ") } formatter.WriteString("TABLE ") if t.IfExists { formatter.WriteString("IF EXISTS ") } formatter.WriteExpr(t.Name) if t.OnCluster != nil { formatter.WriteByte(whitespace) formatter.WriteExpr(t.OnCluster) } } func (s *TypeWithParams) FormatSQL(formatter *Formatter) { formatter.WriteExpr(s.Name) formatter.WriteByte('(') for i, size := range s.Params { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(size) } formatter.WriteByte(')') } func (t *TypedPlaceholder) FormatSQL(formatter *Formatter) { formatter.WriteString("{") formatter.WriteExpr(t.Name) formatter.WriteByte(':') formatter.WriteExpr(t.Type) formatter.WriteString("}") } func (u *UUID) FormatSQL(formatter *Formatter) { formatter.WriteString("UUID ") formatter.WriteExpr(u.Value) } func (n *UnaryExpr) FormatSQL(formatter *Formatter) { formatter.WriteString(string(n.Kind)) formatter.WriteByte(whitespace) formatter.WriteExpr(n.Expr) } func (u *UpdateAssignment) FormatSQL(formatter *Formatter) { formatter.WriteExpr(u.Column) formatter.WriteString(" = ") formatter.WriteExpr(u.Expr) } func (u *UseStmt) FormatSQL(formatter *Formatter) { formatter.WriteString("USE ") formatter.WriteExpr(u.Database) } func (u *UsingClause) FormatSQL(formatter *Formatter) { formatter.WriteString("USING ") formatter.WriteExpr(u.Using) } func (w *WhenClause) FormatSQL(formatter *Formatter) { formatter.WriteString("WHEN ") formatter.WriteExpr(w.When) formatter.WriteString(" THEN ") formatter.WriteExpr(w.Then) if w.Else != nil { formatter.WriteString(" ELSE ") formatter.WriteExpr(w.Else) } } func (w *WhereClause) FormatSQL(formatter *Formatter) { formatter.WriteString("WHERE") if isLogicalBinaryOp(w.Expr) { formatter.Break() formatter.WriteExpr(w.Expr) } else { formatter.Indent() formatter.Break() formatter.WriteExpr(w.Expr) formatter.Dedent() } } func (w *WindowDefinition) FormatSQL(formatter *Formatter) { formatter.WriteExpr(w.Name) formatter.WriteString(" AS ") formatter.WriteExpr(w.Expr) } func (w *WindowClause) FormatSQL(formatter *Formatter) { formatter.WriteString("WINDOW ") for i, window := range w.Windows { window.FormatSQL(formatter) if i != len(w.Windows)-1 { formatter.WriteString(", ") } } } func (w *WindowExpr) FormatSQL(formatter *Formatter) { formatter.WriteByte('(') hasPart := false if w.WindowName != nil { formatter.WriteExpr(w.WindowName) hasPart = true } if w.PartitionBy != nil { if hasPart { formatter.WriteByte(whitespace) } formatter.WriteExpr(w.PartitionBy) hasPart = true } if w.OrderBy != nil { if hasPart { formatter.WriteByte(whitespace) } formatter.WriteExpr(w.OrderBy) hasPart = true } if w.Frame != nil { if hasPart { formatter.WriteByte(whitespace) } formatter.WriteExpr(w.Frame) } formatter.WriteByte(')') } func (f *WindowFrameClause) FormatSQL(formatter *Formatter) { formatter.WriteString(f.Type) formatter.WriteByte(whitespace) formatter.WriteExpr(f.Extend) } func (f *WindowFrameCurrentRow) FormatSQL(formatter *Formatter) { formatter.WriteString("CURRENT ROW") } func (f *WindowFrameExtendExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(f.Expr) if f.Direction != "" { formatter.WriteByte(whitespace) formatter.WriteString(f.Direction) } } func (f *WindowFrameNumber) FormatSQL(formatter *Formatter) { formatter.WriteExpr(f.Number) formatter.WriteByte(whitespace) formatter.WriteString(f.Direction) } func (f *WindowFrameParam) FormatSQL(formatter *Formatter) { formatter.WriteExpr(f.Param) formatter.WriteByte(whitespace) formatter.WriteString(f.Direction) } func (f *WindowFrameUnbounded) FormatSQL(formatter *Formatter) { formatter.WriteString("UNBOUNDED ") formatter.WriteString(f.Direction) } func (w *WindowFunctionExpr) FormatSQL(formatter *Formatter) { formatter.WriteExpr(w.Function) formatter.WriteString(" OVER ") formatter.WriteExpr(w.OverExpr) } func (w *WithClause) FormatSQL(formatter *Formatter) { formatter.WriteString("WITH ") for i, cte := range w.CTEs { if i > 0 { formatter.WriteString(", ") } formatter.WriteExpr(cte) } } func (w *WithTimeoutClause) FormatSQL(formatter *Formatter) { formatter.WriteString("WITH TIMEOUT ") formatter.WriteExpr(w.Number) } ================================================ FILE: parser/format_test.go ================================================ package parser import ( "testing" "github.com/stretchr/testify/require" ) func TestFormatter_WithBeautify_Chaining(t *testing.T) { // Test that WithBeautify returns the formatter for chaining formatter := NewFormatter().WithBeautify() require.NotNil(t, formatter) require.Equal(t, FormatModeBeautify, formatter.mode) } func TestFormatter_WithIndent_Chaining(t *testing.T) { // Test that WithIndent returns the formatter for chaining formatter := NewFormatter().WithIndent(" ") require.NotNil(t, formatter) require.Equal(t, " ", formatter.indent) } func TestFormatter_ChainedMethods(t *testing.T) { // Test that methods can be chained together formatter := NewFormatter().WithBeautify().WithIndent("\t") require.NotNil(t, formatter) require.Equal(t, FormatModeBeautify, formatter.mode) require.Equal(t, "\t", formatter.indent) } func TestFormatter_WithIndent_CustomIndentation(t *testing.T) { // Test actual formatting with custom indent using parsed SQL sql := "SELECT col1, col2 FROM table1 WHERE col1 > 10" parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Len(t, stmts, 1) // Test with default 2-space indent formatter1 := NewFormatter().WithBeautify() formatter1.WriteExpr(stmts[0]) result1 := formatter1.String() // Test with 4-space indent formatter2 := NewFormatter().WithBeautify().WithIndent(" ") formatter2.WriteExpr(stmts[0]) result2 := formatter2.String() // Test with tab indent formatter3 := NewFormatter().WithBeautify().WithIndent("\t") formatter3.WriteExpr(stmts[0]) result3 := formatter3.String() // Verify all results are different (due to different indentation) require.NotEqual(t, result1, result2) require.NotEqual(t, result1, result3) require.NotEqual(t, result2, result3) // Verify they all contain the basic SQL keywords require.Contains(t, result1, "SELECT") require.Contains(t, result2, "SELECT") require.Contains(t, result3, "SELECT") require.Contains(t, result1, "FROM") require.Contains(t, result2, "FROM") require.Contains(t, result3, "FROM") } func TestFormatter_DefaultIndent(t *testing.T) { // Test that default indent is 2 spaces formatter := NewFormatter() require.Equal(t, " ", formatter.indent) } ================================================ FILE: parser/helper.go ================================================ package parser func IsDigit(c byte) bool { return '0' <= c && c <= '9' } func IsHexDigit(c byte) bool { return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' } func IsIdentStart(c byte) bool { return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' } func IsIdentPart(c byte) bool { return '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '$' } ================================================ FILE: parser/keyword.go ================================================ package parser const ( KeywordAdd = "ADD" KeywordAdmin = "ADMIN" KeywordAfter = "AFTER" KeywordAlias = "ALIAS" KeywordAll = "ALL" KeywordAlter = "ALTER" KeywordAnd = "AND" KeywordAnti = "ANTI" KeywordAny = "ANY" KeywordAppend = "APPEND" KeywordApply = "APPLY" KeywordArray = "ARRAY" KeywordAs = "AS" KeywordAsc = "ASC" KeywordAscending = "ASCENDING" KeywordAsof = "ASOF" KeywordAst = "AST" KeywordAsync = "ASYNC" KeywordAttach = "ATTACH" KeywordBetween = "BETWEEN" KeywordBoth = "BOTH" KeywordBy = "BY" KeywordCache = "CACHE" KeywordCase = "CASE" KeywordCast = "CAST" KeywordCheck = "CHECK" KeywordClear = "CLEAR" KeywordCluster = "CLUSTER" KeywordCodec = "CODEC" KeywordCollate = "COLLATE" KeywordCollection = "COLLECTION" KeywordColumn = "COLUMN" KeywordColumns = "COLUMNS" KeywordComment = "COMMENT" KeywordCompiled = "COMPILED" KeywordConfig = "CONFIG" KeywordConstraint = "CONSTRAINT" KeywordCreate = "CREATE" KeywordCross = "CROSS" KeywordCube = "CUBE" KeywordCurrent = "CURRENT" KeywordDatabase = "DATABASE" KeywordDatabases = "DATABASES" KeywordDate = "DATE" KeywordDay = "DAY" KeywordDeduplicate = "DEDUPLICATE" KeywordDefault = "DEFAULT" KeywordDelay = "DELAY" KeywordDelete = "DELETE" KeywordDepends = "DEPENDS" KeywordDesc = "DESC" KeywordDescending = "DESCENDING" KeywordDescribe = "DESCRIBE" KeywordDetach = "DETACH" KeywordDetached = "DETACHED" KeywordDictionaries = "DICTIONARIES" KeywordDictionary = "DICTIONARY" KeywordDisk = "DISK" KeywordDistinct = "DISTINCT" KeywordDistributed = "DISTRIBUTED" KeywordDrop = "DROP" KeywordDNS = "DNS" KeywordElse = "ELSE" KeywordEmbedded = "EMBEDDED" KeywordEmpty = "EMPTY" KeywordEnd = "END" KeywordEngine = "ENGINE" KeywordEstimate = "ESTIMATE" KeywordEvents = "EVENTS" KeywordEvery = "EVERY" KeywordExcept = "EXCEPT" KeywordExists = "EXISTS" KeywordExplain = "EXPLAIN" KeywordExpression = "EXPRESSION" KeywordExtract = "EXTRACT" KeywordFalse = "FALSE" KeywordFetches = "FETCHES" KeywordFileSystem = "FILESYSTEM" KeywordFill = "FILL" KeywordFinal = "FINAL" KeywordFirst = "FIRST" KeywordFlush = "FLUSH" KeywordFollowing = "FOLLOWING" KeywordFor = "FOR" KeywordFormat = "FORMAT" KeywordFreeze = "FREEZE" KeywordFrom = "FROM" KeywordFull = "FULL" KeywordFunction = "FUNCTION" KeywordFunctions = "FUNCTIONS" KeywordGlobal = "GLOBAL" KeywordGrant = "GRANT" KeywordGrantees = "GRANTEES" KeywordGranularity = "GRANULARITY" KeywordGroup = "GROUP" KeywordGrouping = "GROUPING" KeywordHaving = "HAVING" KeywordHierarchical = "HIERARCHICAL" KeywordHost = "HOST" KeywordHour = "HOUR" KeywordId = "ID" KeywordIdentified = "IDENTIFIED" KeywordIf = "IF" KeywordIlike = "ILIKE" KeywordIn = "IN" KeywordIndex = "INDEX" KeywordInf = "INF" KeywordInjective = "INJECTIVE" KeywordInner = "INNER" KeywordInsert = "INSERT" KeywordInterval = "INTERVAL" KeywordInterpolate = "INTERPOLATE" KeywordInto = "INTO" KeywordIp = "IP" KeywordIs = "IS" KeywordIs_object_id = "IS_OBJECT_ID" KeywordJoin = "JOIN" KeywordJSON = "JSON" KeywordKey = "KEY" KeywordKill = "KILL" KeywordKerberos = "KERBEROS" KeywordLast = "LAST" KeywordLayout = "LAYOUT" KeywordLdap = "LDAP" KeywordLeading = "LEADING" KeywordLeft = "LEFT" KeywordLifetime = "LIFETIME" KeywordLike = "LIKE" KeywordLimit = "LIMIT" KeywordLive = "LIVE" KeywordLocal = "LOCAL" KeywordLogs = "LOGS" KeywordMark = "MARK" KeywordMaterialize = "MATERIALIZE" KeywordMaterialized = "MATERIALIZED" KeywordMax = "MAX" KeywordMerges = "MERGES" KeywordMin = "MIN" KeywordMinute = "MINUTE" KeywordModify = "MODIFY" KeywordMonth = "MONTH" KeywordMove = "MOVE" KeywordMoves = "MOVES" KeywordMutation = "MUTATION" KeywordName = "NAME" KeywordNamed = "NAMED" KeywordNan_sql = "NAN_SQL" KeywordNo = "NO" KeywordNone = "NONE" KeywordNot = "NOT" KeywordNull = "NULL" KeywordNulls = "NULLS" KeywordOffset = "OFFSET" KeywordOn = "ON" KeywordOptimize = "OPTIMIZE" KeywordOption = "OPTION" KeywordOr = "OR" KeywordOrder = "ORDER" KeywordOverridable = "OVERRIDABLE" KeywordOuter = "OUTER" KeywordOutfile = "OUTFILE" KeywordOver = "OVER" KeywordPartition = "PARTITION" KeywordPipeline = "PIPELINE" KeywordPolicy = "POLICY" KeywordPopulate = "POPULATE" KeywordPreceding = "PRECEDING" KeywordPrewhere = "PREWHERE" KeywordPrimary = "PRIMARY" KeywordProjection = "PROJECTION" KeywordQuarter = "QUARTER" KeywordQuery = "QUERY" KeywordQueues = "QUEUES" KeywordQuota = "QUOTA" KeywordRandomize = "RANDOMIZE" KeywordRange = "RANGE" KeywordRealm = "REALM" KeywordRecompress = "RECOMPRESS" KeywordRefresh = "REFRESH" KeywordRegexp = "REGEXP" KeywordReload = "RELOAD" KeywordRemove = "REMOVE" KeywordRename = "RENAME" KeywordReplace = "REPLACE" KeywordReset = "RESET" KeywordReplica = "REPLICA" KeywordReplicated = "REPLICATED" KeywordReplication = "REPLICATION" KeywordRestart = "RESTART" KeywordRight = "RIGHT" KeywordRole = "ROLE" KeywordRollup = "ROLLUP" KeywordRow = "ROW" KeywordRows = "ROWS" KeywordSample = "SAMPLE" KeywordSecond = "SECOND" KeywordSelect = "SELECT" KeywordSemi = "SEMI" KeywordSends = "SENDS" KeywordServer = "SERVER" KeywordSet = "SET" KeywordSets = "SETS" KeywordSetting = "SETTING" KeywordSettings = "SETTINGS" KeywordShow = "SHOW" KeywordShutdown = "SHUTDOWN" KeywordSkip = "SKIP" KeywordSource = "SOURCE" KeywordStart = "START" KeywordStaleness = "STALENESS" KeywordStep = "STEP" KeywordStop = "STOP" KeywordSubstring = "SUBSTRING" KeywordSync = "SYNC" KeywordSyntax = "SYNTAX" KeywordSystem = "SYSTEM" KeywordTable = "TABLE" KeywordTables = "TABLES" KeywordTemporary = "TEMPORARY" KeywordTest = "TEST" KeywordThen = "THEN" KeywordTies = "TIES" KeywordTimeout = "TIMEOUT" KeywordTimestamp = "TIMESTAMP" KeywordTo = "TO" KeywordTop = "TOP" KeywordTotals = "TOTALS" KeywordTrailing = "TRAILING" KeywordTrim = "TRIM" KeywordTrue = "TRUE" KeywordTruncate = "TRUNCATE" KeywordTtl = "TTL" KeywordType = "TYPE" KeywordUnbounded = "UNBOUNDED" KeywordUncompressed = "UNCOMPRESSED" KeywordUnion = "UNION" KeywordUpdate = "UPDATE" KeywordUse = "USE" KeywordUser = "USER" KeywordUsing = "USING" KeywordUntil = "UNTIL" KeywordUuid = "UUID" KeywordValid = "VALID" KeywordValues = "VALUES" KeywordView = "VIEW" KeywordVolume = "VOLUME" KeywordWatch = "WATCH" KeywordWeek = "WEEK" KeywordWhen = "WHEN" KeywordWhere = "WHERE" KeywordWindow = "WINDOW" KeywordWith = "WITH" KeywordYear = "YEAR" KeywordDefiner = "DEFINER" KeywordSQL = "SQL" KeywordSecurity = "SECURITY" ) var keywords = NewSet( KeywordAdd, KeywordAdmin, KeywordAfter, KeywordAlias, KeywordAll, KeywordAlter, KeywordAnd, KeywordAnti, KeywordAny, KeywordAppend, KeywordApply, KeywordArray, KeywordAs, KeywordAsc, KeywordAscending, KeywordAsof, KeywordAst, KeywordAsync, KeywordAttach, KeywordBetween, KeywordBoth, KeywordBy, KeywordCache, KeywordCase, KeywordCast, KeywordCheck, KeywordClear, KeywordCluster, KeywordCodec, KeywordCollate, KeywordCollection, KeywordColumn, KeywordColumns, KeywordComment, KeywordCompiled, KeywordConfig, KeywordConstraint, KeywordCreate, KeywordCross, KeywordCube, KeywordCurrent, KeywordDatabase, KeywordDatabases, KeywordDate, KeywordDay, KeywordDeduplicate, KeywordDefault, KeywordDelay, KeywordDelete, KeywordDepends, KeywordDesc, KeywordDescending, KeywordDescribe, KeywordDetach, KeywordDetached, KeywordDictionaries, KeywordDictionary, KeywordDisk, KeywordDistinct, KeywordDistributed, KeywordDrop, KeywordDNS, KeywordElse, KeywordEnd, KeywordEngine, KeywordEstimate, KeywordEmbedded, KeywordEmpty, KeywordEvents, KeywordEvery, KeywordExcept, KeywordExists, KeywordExplain, KeywordExpression, KeywordExtract, KeywordFalse, KeywordFetches, KeywordFileSystem, KeywordFill, KeywordFinal, KeywordFirst, KeywordFlush, KeywordFollowing, KeywordFor, KeywordFormat, KeywordFreeze, KeywordFrom, KeywordFull, KeywordFunction, KeywordFunctions, KeywordGlobal, KeywordGrant, KeywordGrantees, KeywordGranularity, KeywordGroup, KeywordGrouping, KeywordHaving, KeywordHierarchical, KeywordHost, KeywordHour, KeywordId, KeywordIdentified, KeywordIf, KeywordIlike, KeywordIn, KeywordIndex, KeywordInf, KeywordInjective, KeywordInner, KeywordInsert, KeywordInterval, KeywordInterpolate, KeywordInto, KeywordIp, KeywordIs, KeywordIs_object_id, KeywordJoin, KeywordJSON, KeywordKey, KeywordKill, KeywordKerberos, KeywordLast, KeywordLayout, KeywordLdap, KeywordLeading, KeywordLeft, KeywordLifetime, KeywordLike, KeywordLimit, KeywordLive, KeywordLocal, KeywordLogs, KeywordMark, KeywordMaterialize, KeywordMaterialized, KeywordMax, KeywordMerges, KeywordMin, KeywordMinute, KeywordModify, KeywordMonth, KeywordMove, KeywordMoves, KeywordMutation, KeywordName, KeywordNamed, KeywordNan_sql, KeywordNo, KeywordNone, KeywordNot, KeywordNull, KeywordNulls, KeywordOffset, KeywordOn, KeywordOptimize, KeywordOption, KeywordOr, KeywordOrder, KeywordOuter, KeywordOverridable, KeywordOutfile, KeywordOver, KeywordPartition, KeywordPipeline, KeywordPolicy, KeywordPopulate, KeywordPreceding, KeywordPrewhere, KeywordPrimary, KeywordProjection, KeywordQuarter, KeywordQuery, KeywordQueues, KeywordQuota, KeywordRandomize, KeywordRange, KeywordRealm, KeywordRecompress, KeywordRefresh, KeywordRegexp, KeywordReload, KeywordRemove, KeywordRename, KeywordReplace, KeywordReset, KeywordReplica, KeywordReplicated, KeywordReplication, KeywordRestart, KeywordRight, KeywordRole, KeywordRollup, KeywordRow, KeywordRows, KeywordSample, KeywordSecond, KeywordSelect, KeywordSemi, KeywordSends, KeywordServer, KeywordSet, KeywordSets, KeywordSetting, KeywordSettings, KeywordShow, KeywordShutdown, KeywordSkip, KeywordSource, KeywordStart, KeywordStaleness, KeywordStep, KeywordStop, KeywordSubstring, KeywordSync, KeywordSyntax, KeywordSystem, KeywordTable, KeywordTables, KeywordTemporary, KeywordTest, KeywordThen, KeywordTies, KeywordTimeout, KeywordTimestamp, KeywordTo, KeywordTop, KeywordTotals, KeywordTrailing, KeywordTrim, KeywordTrue, KeywordTruncate, KeywordTtl, KeywordType, KeywordUnbounded, KeywordUncompressed, KeywordUnion, KeywordUpdate, KeywordUse, KeywordUser, KeywordUsing, KeywordUntil, KeywordUuid, KeywordValid, KeywordValues, KeywordView, KeywordVolume, KeywordWatch, KeywordWeek, KeywordWhen, KeywordWhere, KeywordWindow, KeywordWith, KeywordYear, KeywordDefiner, KeywordSQL, KeywordSecurity, ) ================================================ FILE: parser/lexer.go ================================================ package parser import ( "errors" "fmt" "strings" "unicode" "unicode/utf8" ) const ( TokenKindEOF TokenKind = "" TokenKindIdent TokenKind = "" TokenKindKeyword TokenKind = "" TokenKindInt TokenKind = "" TokenKindFloat TokenKind = "" TokenKindString TokenKind = "" TokenKindDot = "." TokenKindSingleEQ TokenKind = "=" TokenKindDoubleEQ TokenKind = "==" TokenKindNE TokenKind = "!=" TokenKindLT TokenKind = "<" TokenKindLE TokenKind = "<=" TokenKindGT TokenKind = ">" TokenKindGE TokenKind = ">=" TokenKindQuestionMark TokenKind = "?" TokenKindPlus TokenKind = "+" TokenKindMinus TokenKind = "-" TokenKindMul TokenKind = "*" TokenKindDiv TokenKind = "/" TokenKindMod TokenKind = "%" TokenKindConcat TokenKind = "||" TokenKindArrow TokenKind = "->" TokenKindDash TokenKind = "::" TokenKindLParen TokenKind = "(" TokenKindRParen TokenKind = ")" TokenKindLBrace TokenKind = "{" TokenKindRBrace TokenKind = "}" TokenKindLBracket TokenKind = "[" TokenKindRBracket TokenKind = "]" TokenKindComma TokenKind = "," TokenKindColon TokenKind = ":" TokenKindAtSign TokenKind = "@" ) const ( Unquoted = iota + 1 DoubleQuote BackTicks SingleQuote ) type Pos int type TokenKind string type Token struct { Pos Pos End Pos Kind TokenKind String string Base int // 10 or 16 on TokenKindInt QuoteType int } func (t *Token) ToString() string { if t.Kind == TokenKindKeyword { return strings.ToUpper(t.String) } return t.String } type lexerState struct { current int lastToken *Token } type Lexer struct { lexerState input string } func NewLexer(buf string) *Lexer { return &Lexer{input: buf} } func (l *Lexer) saveState() lexerState { return l.lexerState } func (l *Lexer) restoreState(state lexerState) { l.lexerState = state } func (l *Lexer) skipN(n int) { l.current += n } func (l *Lexer) slice(i, j int) string { return l.input[l.current+i : l.current+j] } func (l *Lexer) peekN(n int) byte { return l.input[l.current+n] } func (l *Lexer) peekOk(n int) bool { return l.current+n < len(l.input) } func (l *Lexer) isKeyword(ident string) bool { return keywords.Contains(ident) } func (l *Lexer) consumeNumber() error { i := 0 base := 10 if l.peekN(0) == '+' || l.peekN(0) == '-' { // skip sign i++ } if l.peekN(0) == '0' && l.peekOk(1) && l.peekN(1) == 'x' { i += 2 base = 16 } hasExp := false tokenKind := TokenKindInt hasNumberPart := false for l.peekOk(i) { hasNumberPart = true c := l.peekN(i) switch { case base == 10 && IsDigit(c): i++ continue case base == 16 && IsHexDigit(c): i++ continue case c == '.': // float tokenKind = TokenKindFloat i++ continue case base != 16 && (c == 'e' || c == 'E' || c == 'p' || c == 'P'): if hasExp { return errors.New("invalid number") } i++ if l.peekOk(i) && (l.peekN(i) == '+' || l.peekN(i) == '-') { i++ } if !l.peekOk(i) || !IsDigit(l.peekN(i)) { return errors.New("exponent part should contain at least one digit") } hasExp = true continue } break } if (l.peekOk(i) && IsIdentPart(l.peekN(i))) || !hasNumberPart { return errors.New("invalid number") } l.lastToken = &Token{ Kind: tokenKind, String: l.slice(0, i), Pos: Pos(l.current), End: Pos(l.current + i), Base: base, } l.skipN(i) return nil } func (l *Lexer) consumeIdent(_ Pos) error { token := &Token{} quoteType := Unquoted if l.peekOk(0) && (l.peekN(0) == '`' || l.peekN(0) == '"') { if l.peekOk(0) && l.peekN(0) == '`' { quoteType = BackTicks } else { quoteType = DoubleQuote } l.skipN(1) } i := 0 if quoteType == Unquoted { if l.peekOk(i) && l.peekN(i) == '$' { i++ } for l.peekOk(i) && IsIdentPart(l.peekN(i)) { i++ } } else { for l.peekOk(i) && (quoteType == BackTicks && l.peekN(i) != '`' || quoteType == DoubleQuote && l.peekN(i) != '"') { i++ } if !l.peekOk(i) || (quoteType == BackTicks && l.peekN(i) != '`') || (quoteType == DoubleQuote && l.peekN(i) != '"') { return fmt.Errorf("unclosed quoted identifier: %s", l.slice(0, i)) } } slice := l.slice(0, i) if quoteType == Unquoted && l.isKeyword(strings.ToUpper(slice)) { token.Kind = TokenKindKeyword } else { token.Kind = TokenKindIdent } token.Pos = Pos(l.current) token.End = Pos(l.current + i) token.String = slice token.QuoteType = quoteType l.lastToken = token l.skipN(i) if quoteType != Unquoted { l.skipN(1) } return nil } func (l *Lexer) consumeSingleLineComment() { l.skipN(2) i := 0 for l.peekOk(i) && l.peekN(i) != '\r' && l.peekN(i) != '\n' { i++ } l.skipN(i + 1) } func (l *Lexer) consumeMultiLineComment() { l.skipN(2) i := 0 for !l.isEOF() { if l.peekOk(i+1) && l.peekN(i) == '*' && l.peekN(i+1) == '/' { i += 2 break } i++ } l.skipN(i) } func (l *Lexer) consumeString() error { i := 1 endChar := byte('\'') for l.peekOk(i) { c := l.peekN(i) // backslash escape if c == '\\' { i++ if l.peekOk(i) { i++ } continue } // single quote if c == endChar { // double single quote '' if l.peekOk(i+1) && l.peekN(i+1) == endChar { i += 2 continue } break } i++ } if !l.peekOk(i) || l.peekN(i) != endChar { return errors.New("invalid string") } l.lastToken = &Token{ Kind: TokenKindString, String: l.slice(1, i), Pos: Pos(l.current + 1), End: Pos(l.current + i), } l.skipN(i + 1) return nil } func (l *Lexer) skipComments() { for !l.isEOF() { l.skipSpace() if !l.peekOk(0) { return } switch l.peekN(0) { case '-': if l.peekOk(1) && l.peekN(1) == '-' { l.consumeSingleLineComment() continue } return case '/': // multi-line comment if l.peekOk(1) && l.peekN(1) == '*' { l.consumeMultiLineComment() continue } return case '\r', '\n': // skip \r\n or \n\r l.skipN(1) default: return } } } func (l *Lexer) peekToken() (*Token, error) { savedState := l.saveState() if err := l.consumeToken(); err != nil { return nil, err } token := l.lastToken l.restoreState(savedState) return token, nil } func (l *Lexer) hasPrecedenceToken(last *Token) bool { return last != nil && (last.Kind == TokenKindIdent || last.Kind == TokenKindKeyword || last.Kind == TokenKindInt || last.Kind == TokenKindFloat || last.Kind == TokenKindString) } func (l *Lexer) consumeToken() error { // clear last token lastToken := l.lastToken l.lastToken = nil l.skipComments() l.skipSpace() if l.isEOF() { return nil } switch l.peekN(0) { case '>', '<', '!', '=', '|': if l.peekN(0) == '|' && l.peekOk(1) && l.peekN(1) == '|' || // || l.peekN(0) == '<' && l.peekOk(1) && l.peekN(1) == '>' || // <> l.peekN(0) == '=' && l.peekOk(1) && l.peekN(1) == '=' || // == l.peekN(0) != '|' && l.peekOk(1) && l.peekN(1) == '=' { // |= l.lastToken = &Token{ String: l.slice(0, 2), Kind: TokenKind(l.slice(0, 2)), Pos: Pos(l.current), End: Pos(l.current + 2), } l.skipN(2) return nil } case '+', '-': // hasPrecedenceToken is used to distinguish between unary and binary operators if !l.hasPrecedenceToken(lastToken) && l.peekOk(1) && IsDigit(l.peekN(1)) { return l.consumeNumber() } else if l.peekOk(1) && l.peekN(1) == '>' { l.lastToken = &Token{ String: l.slice(0, 2), Kind: TokenKindArrow, Pos: Pos(l.current), End: Pos(l.current + 2), } l.skipN(2) return nil } case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': return l.consumeNumber() case '`', '$', '"': return l.consumeIdent(Pos(l.current)) case '\'': return l.consumeString() case ':': if l.peekOk(1) && l.peekN(1) == ':' { l.lastToken = &Token{ String: l.slice(0, 2), Kind: TokenKindDash, Pos: Pos(l.current), End: Pos(l.current + 2), } l.skipN(2) return nil } case '.': l.lastToken = &Token{ String: l.slice(0, 1), Kind: TokenKindDot, Pos: Pos(l.current), End: Pos(l.current + 1), } l.skipN(1) return nil } if IsIdentStart(l.peekN(0)) { return l.consumeIdent(Pos(l.current)) } token := &Token{} token.Pos = Pos(l.current) token.End = Pos(l.current + 1) token.String = l.input[l.current : l.current+1] token.Kind = TokenKind(token.String) l.skipN(1) l.lastToken = token return nil } func (l *Lexer) isEOF() bool { return l.current >= len(l.input) } func (l *Lexer) skipSpace() { for !l.isEOF() { r, size := utf8.DecodeRuneInString(l.input[l.current:]) if !unicode.IsSpace(r) { break } l.current += size } } ================================================ FILE: parser/lexer_test.go ================================================ package parser import ( "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestConsumeComment(t *testing.T) { comments := []string{ "-- hello world", "-- hello world\n", "-- hello world\r\n", "-- hello world\r", "/* hello world */", "/* hello world */\n", "/* hello world */\r\n", "/* hello world */\r", "/* hello world */ /* hello world */", "/* hello world */ /* hello world */\n", "/* hello world */ /* hello world */\r\n", "/* hello world */ /* hello world */\r", } for _, c := range comments { lexer := NewLexer(c) err := lexer.consumeToken() require.NoError(t, err) } } func TestConsumeString(t *testing.T) { t.Run("Simple strings", func(t *testing.T) { strs := []string{ "'hello world'", "'123'", } for _, s := range strs { lexer := NewLexer(s) err := lexer.consumeToken() require.NoError(t, err) require.Equal(t, TokenKindString, lexer.lastToken.Kind) require.Equal(t, strings.Trim(s, "'"), lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Strings with backslash-escaped quotes", func(t *testing.T) { testCases := []struct { input string expected string }{ {`'hello\'world'`, `hello\'world`}, {`'test\''`, `test\'`}, {`'\'abc\''`, `\'abc\'`}, } for _, tc := range testCases { lexer := NewLexer(tc.input) err := lexer.consumeToken() require.NoError(t, err, "Failed to parse: %s", tc.input) require.Equal(t, TokenKindString, lexer.lastToken.Kind) require.Equal(t, tc.expected, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Strings with double single quotes", func(t *testing.T) { testCases := []struct { input string expected string }{ {`'hello''world'`, `hello''world`}, {`'test''123'`, `test''123`}, {`'abc''def''ghi'`, `abc''def''ghi`}, } for _, tc := range testCases { lexer := NewLexer(tc.input) err := lexer.consumeToken() require.NoError(t, err, "Failed to parse: %s", tc.input) require.Equal(t, TokenKindString, lexer.lastToken.Kind) require.Equal(t, tc.expected, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Strings with backslash-escaped backslashes", func(t *testing.T) { testCases := []struct { input string expected string }{ {`'a\\b'`, `a\\b`}, {`'test\\123'`, `test\\123`}, } for _, tc := range testCases { lexer := NewLexer(tc.input) err := lexer.consumeToken() require.NoError(t, err, "Failed to parse: %s", tc.input) require.Equal(t, TokenKindString, lexer.lastToken.Kind) require.Equal(t, tc.expected, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) } func TestConsumeNumber(t *testing.T) { t.Run("Integer number", func(t *testing.T) { integers := []string{ "123", "123e+10", "123e-10", "123e10", "123E10", "123E+10", "123E-10", } for _, i := range integers { lexer := NewLexer(i) err := lexer.consumeToken() require.NoError(t, err) require.Equal(t, TokenKindInt, lexer.lastToken.Kind) require.Equal(t, 10, lexer.lastToken.Base) require.Equal(t, i, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Hexadecimal number", func(t *testing.T) { numbers := []string{ "0x123", "0x1", } for _, n := range numbers { lexer := NewLexer(n) err := lexer.consumeToken() require.NoError(t, err) require.Equal(t, TokenKindInt, lexer.lastToken.Kind) require.Equal(t, 16, lexer.lastToken.Base) require.Equal(t, n, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Invalid number", func(t *testing.T) { invalidNumbers := []string{ "123e", "123e+", "123e-", "123e", "123E", "123E+", "123E-", "0x", "0xg", } for _, n := range invalidNumbers { lexer := NewLexer(n) err := lexer.consumeToken() require.Error(t, err) } }) t.Run("Float number", func(t *testing.T) { floats := []string{ "123.456", "123.456e+10", "123.456e-10", "123.456e10", "123.456E10", "123.456E+10", "123.456E-10", } for _, f := range floats { lexer := NewLexer(f) err := lexer.consumeToken() require.NoError(t, err) require.Equal(t, TokenKindFloat, lexer.lastToken.Kind) require.Equal(t, f, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Invalid float number", func(t *testing.T) { invalidFloats := []string{ "123.456b", "123.456e", "123.456e+", "123.456e-", "123.456e+10e", "123.456e-10e", "123.456e10e", "123.456E10e", "123.456E+10e", "123.456E-10e", "123.456e+10e+10", } for _, f := range invalidFloats { lexer := NewLexer(f) err := lexer.consumeToken() assert.Error(t, err) } }) t.Run("Name", func(t *testing.T) { idents := []string{ "`CASE`", "`TEST`", "`WHEN`", "hello", "hello_world", "hello123", "hello_123", "hello_123_world", "hello_123_world_456", "hello_123_world_456_789", "hello_123_world_456_789_abc", "hello_123_world_456_789_abc_def", "hello_123_world_456_789_abc_def_ghi", "hello_123_world_456_789_abc_def_ghi_jkl", "hello_123_world_456_789_abc_def_ghi_jkl_mno", "hello_123_world_456_789_abc_def_ghi_jkl_mno_pqr", } for _, i := range idents { lexer := NewLexer(i) err := lexer.consumeToken() require.NoError(t, err) require.Equal(t, TokenKindIdent, lexer.lastToken.Kind) require.Equal(t, strings.Trim(i, "`"), lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) t.Run("Keyword", func(t *testing.T) { for _, k := range keywords.Members() { lexer := NewLexer(k) err := lexer.consumeToken() require.NoError(t, err) require.Equal(t, TokenKindKeyword, lexer.lastToken.Kind) require.Equal(t, k, lexer.lastToken.String) require.True(t, lexer.isEOF()) } }) } ================================================ FILE: parser/parse_system.go ================================================ package parser import ( "fmt" "strings" ) func (p *Parser) parseSetStmt(pos Pos) (*SetStmt, error) { if err := p.expectKeyword(KeywordSet); err != nil { return nil, err } settings, err := p.parseSettingsClause(p.Pos()) if err != nil { return nil, err } return &SetStmt{ SetPos: pos, Settings: settings, }, nil } func (p *Parser) parseSettingsStmt(pos Pos) (*SetStmt, error) { if err := p.expectKeyword(KeywordSettings); err != nil { return nil, err } settings, err := p.parseSettingsClause(p.Pos()) if err != nil { return nil, err } return &SetStmt{ SetPos: pos, Settings: settings, }, nil } func (p *Parser) parseSystemFlushExpr(pos Pos) (*SystemFlushExpr, error) { if err := p.expectKeyword(KeywordFlush); err != nil { return nil, err } switch { case p.matchKeyword(KeywordLogs): lastToken := p.last() _ = p.lexer.consumeToken() return &SystemFlushExpr{ FlushPos: pos, StatementEnd: lastToken.End, Logs: true, }, nil case p.tryConsumeKeywords(KeywordDistributed): distributed, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &SystemFlushExpr{ FlushPos: pos, StatementEnd: distributed.End(), Distributed: distributed, }, nil default: return nil, fmt.Errorf("expected LOGS|DISTRIBUTED") } } func (p *Parser) parseSystemReloadExpr(pos Pos) (*SystemReloadExpr, error) { if err := p.expectKeyword(KeywordReload); err != nil { return nil, err } switch { case p.matchKeyword(KeywordDictionaries): lastToken := p.last() _ = p.lexer.consumeToken() return &SystemReloadExpr{ ReloadPos: pos, StatementEnd: lastToken.End, Type: KeywordDictionaries, }, nil case p.tryConsumeKeywords(KeywordDictionary): dictionary, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &SystemReloadExpr{ ReloadPos: pos, StatementEnd: dictionary.End(), Type: KeywordDictionary, Dictionary: dictionary, }, nil case p.tryConsumeKeywords(KeywordEmbedded): lastToken := p.last() if err := p.expectKeyword(KeywordDictionaries); err != nil { return nil, err } return &SystemReloadExpr{ ReloadPos: pos, StatementEnd: lastToken.End, Type: "EMBEDDED DICTIONARIES", }, nil default: return nil, fmt.Errorf("expected DICTIONARIES|CONFIG") } } func (p *Parser) parseSystemSyncExpr(pos Pos) (*SystemSyncExpr, error) { if err := p.expectKeyword(KeywordSync); err != nil { return nil, err } if err := p.expectKeyword(KeywordReplica); err != nil { return nil, err } cluster, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &SystemSyncExpr{ SyncPos: pos, Cluster: cluster, }, nil } func (p *Parser) parseSystemCtrlExpr(pos Pos) (*SystemCtrlExpr, error) { if !p.matchKeyword(KeywordStart) && !p.matchKeyword(KeywordStop) { return nil, fmt.Errorf("expected START|STOP") } command := strings.ToUpper(p.last().String) _ = p.lexer.consumeToken() var typ string switch { case p.tryConsumeKeywords(KeywordDistributed): switch { case p.matchKeyword(KeywordSends): typ = "DISTRIBUTED SENDS" case p.matchKeyword(KeywordFetches): typ = "FETCHES" case p.matchKeyword(KeywordMerges): typ = "MERGES" case p.matchKeyword(KeywordTtl): typ = "TTL MERGES" if err := p.expectKeyword(KeywordMerges); err != nil { return nil, err } default: return nil, fmt.Errorf("expected SENDS|FETCHES|MERGES|TTL") } cluster, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &SystemCtrlExpr{ CtrlPos: pos, StatementEnd: cluster.End(), Command: command, Type: typ, Cluster: cluster, }, nil case p.tryConsumeKeywords(KeywordReplicated): lastToken := p.last() if err := p.expectKeyword(KeywordSends); err != nil { return nil, err } typ = "REPLICATED SENDS" return &SystemCtrlExpr{ CtrlPos: pos, StatementEnd: lastToken.End, Command: command, Type: typ, }, nil default: return nil, fmt.Errorf("expected DISTRIBUTED|REPLICATED") } } func (p *Parser) parseSystemDropExpr(pos Pos) (*SystemDropExpr, error) { if err := p.expectKeyword(KeywordDrop); err != nil { return nil, err } switch { case p.matchKeyword(KeywordDNS), p.matchKeyword(KeywordMark), p.matchKeyword(KeywordUncompressed), p.matchKeyword(KeywordFileSystem), p.matchKeyword(KeywordQuery): prefixToken := p.last() _ = p.lexer.consumeToken() lastToken := p.last() if err := p.expectKeyword(KeywordCache); err != nil { return nil, err } return &SystemDropExpr{ DropPos: pos, StatementEnd: lastToken.End, Type: prefixToken.String + " CACHE", }, nil case p.matchKeyword(KeywordCompiled): _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordExpression); err != nil { return nil, err } lastToken := p.last() if err := p.expectKeyword(KeywordCache); err != nil { return nil, err } return &SystemDropExpr{ DropPos: pos, StatementEnd: lastToken.End, Type: "COMPILED EXPRESSION CACHE", }, nil default: return nil, fmt.Errorf("expected DNS|MARK|REPLICA|DATABASE|UNCOMPRESSION|COMPILED|QUERY") } } func (p *Parser) tryParseDeduplicateClause(pos Pos) (*DeduplicateClause, error) { if !p.matchKeyword(KeywordDeduplicate) { return nil, nil } return p.parseDeduplicateClause(pos) } func (p *Parser) parseDeduplicateClause(pos Pos) (*DeduplicateClause, error) { if err := p.expectKeyword(KeywordDeduplicate); err != nil { return nil, err } if !p.tryConsumeKeywords(KeywordBy) { return &DeduplicateClause{ DeduplicatePos: pos, }, nil } by, err := p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } var except *ColumnExprList if p.tryConsumeKeywords(KeywordExcept) { except, err = p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } } return &DeduplicateClause{ DeduplicatePos: pos, By: by, Except: except, }, nil } func (p *Parser) parseOptimizeStmt(pos Pos) (*OptimizeStmt, error) { if err := p.expectKeyword(KeywordOptimize); err != nil { return nil, err } if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } table, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } statementEnd := table.End() onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if onCluster != nil { statementEnd = onCluster.End() } partition, err := p.tryParsePartitionClause(p.Pos()) if err != nil { return nil, err } if partition != nil { statementEnd = partition.End() } hasFinal := false lastPos := p.Pos() if p.tryConsumeKeywords(KeywordFinal) { hasFinal = true statementEnd = lastPos } deduplicate, err := p.tryParseDeduplicateClause(p.Pos()) if err != nil { return nil, err } if deduplicate != nil { statementEnd = deduplicate.End() } return &OptimizeStmt{ OptimizePos: pos, StatementEnd: statementEnd, Table: table, OnCluster: onCluster, Partition: partition, HasFinal: hasFinal, Deduplicate: deduplicate, }, nil } func (p *Parser) parseSystemStmt(pos Pos) (*SystemStmt, error) { if err := p.expectKeyword(KeywordSystem); err != nil { return nil, err } var err error var expr Expr switch { case p.matchKeyword(KeywordFlush): expr, err = p.parseSystemFlushExpr(p.Pos()) case p.matchKeyword(KeywordReload): expr, err = p.parseSystemReloadExpr(p.Pos()) case p.matchKeyword(KeywordSync): expr, err = p.parseSystemSyncExpr(p.Pos()) case p.matchKeyword(KeywordStart), p.matchKeyword(KeywordStop): expr, err = p.parseSystemCtrlExpr(p.Pos()) case p.matchKeyword(KeywordDrop): expr, err = p.parseSystemDropExpr(p.Pos()) default: return nil, fmt.Errorf("expected FLUSH|RELOAD|SYNC|START|STOP") } if err != nil { return nil, err } return &SystemStmt{ SystemPos: pos, Expr: expr, }, nil } func (p *Parser) parseCheckStmt(pos Pos) (*CheckStmt, error) { if err := p.expectKeyword(KeywordCheck); err != nil { return nil, err } if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } table, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } partition, err := p.tryParsePartitionClause(p.Pos()) if err != nil { return nil, err } return &CheckStmt{ CheckPos: pos, Table: table, Partition: partition, }, nil } func (p *Parser) parseRoleName(_ Pos) (*RoleName, error) { switch { case p.matchTokenKind(TokenKindIdent): name, err := p.parseIdent() if err != nil { return nil, err } var scope *StringLiteral if p.tryConsumeTokenKind(TokenKindAtSign) != nil { scope, err = p.parseString(p.Pos()) if err != nil { return nil, err } } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } return &RoleName{ Name: name, Scope: scope, OnCluster: onCluster, }, nil case p.matchTokenKind(TokenKindString): name, err := p.parseString(p.Pos()) if err != nil { return nil, err } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } return &RoleName{ Name: name, OnCluster: onCluster, }, nil default: return nil, fmt.Errorf("expected or ") } } func (p *Parser) tryParseRoleSettings(pos Pos) ([]*RoleSetting, error) { if !p.tryConsumeKeywords(KeywordSettings) { return nil, nil } return p.parseRoleSettings(pos) } func (p *Parser) parseRoleSetting(_ Pos) (*RoleSetting, error) { pairs := make([]*SettingPair, 0) for p.matchTokenKind(TokenKindIdent) { name, err := p.parseIdent() if err != nil { return nil, err } switch name.Name { case "NONE", "READABLE", "WRITABLE", "CONST", "CHANGEABLE_IN_READONLY": return &RoleSetting{ Modifier: name, SettingPairs: pairs, }, nil } switch { case p.matchTokenKind(TokenKindSingleEQ), p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat), p.matchTokenKind(TokenKindString): var op TokenKind if token := p.tryConsumeTokenKind(TokenKindSingleEQ); token != nil { op = token.Kind } value, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } // docs: https://clickhouse.com/docs/en/sql-reference/statements/alter/role // the operator "=" was required if the variable name is NOT in // ["MIN", "MAX", "PROFILE"] and value is existed. if value != nil && name.Name != "MIN" && name.Name != "MAX" && name.Name != "PROFILE" && op != TokenKindSingleEQ { return nil, fmt.Errorf("expected operator = or no value, but got %s", op) } pairs = append(pairs, &SettingPair{ Name: name, Operation: op, Value: value, }) default: pairs = append(pairs, &SettingPair{ Name: name, }) } } return &RoleSetting{ SettingPairs: pairs, }, nil } func (p *Parser) parseRoleSettings(_ Pos) ([]*RoleSetting, error) { settings := make([]*RoleSetting, 0) for { setting, err := p.parseRoleSetting(p.Pos()) if err != nil { return nil, err } settings = append(settings, setting) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } return settings, nil } func (p *Parser) parseCreateRole(pos Pos) (*CreateRole, error) { if err := p.expectKeyword(KeywordRole); err != nil { return nil, err } ifNotExists := false orReplace := false switch { case p.matchKeyword(KeywordIf): _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordNot); err != nil { return nil, err } if err := p.expectKeyword(KeywordExists); err != nil { return nil, err } ifNotExists = true case p.matchKeyword(KeywordOr): _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordReplace); err != nil { return nil, err } orReplace = true } roleNames := make([]*RoleName, 0) roleName, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } roleNames = append(roleNames, roleName) for p.tryConsumeTokenKind(TokenKindComma) != nil { roleName, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } roleNames = append(roleNames, roleName) } statementEnd := roleNames[len(roleNames)-1].End() var accessStorageType *Ident if p.tryConsumeKeywords(KeywordIn) { accessStorageType, err = p.parseIdent() if err != nil { return nil, err } statementEnd = accessStorageType.NameEnd } settings, err := p.tryParseRoleSettings(p.Pos()) if err != nil { return nil, err } if settings != nil { statementEnd = settings[len(settings)-1].End() } return &CreateRole{ CreatePos: pos, StatementEnd: statementEnd, IfNotExists: ifNotExists, OrReplace: orReplace, RoleNames: roleNames, AccessStorageType: accessStorageType, Settings: settings, }, nil } func (p *Parser) parseAuthenticationClause(pos Pos) (*AuthenticationClause, error) { auth := &AuthenticationClause{AuthPos: pos} if p.tryConsumeKeywords(KeywordNot) { if err := p.expectKeyword(KeywordIdentified); err != nil { return nil, err } auth.NotIdentified = true auth.AuthEnd = p.last().End return auth, nil } if err := p.expectKeyword(KeywordIdentified); err != nil { return nil, err } auth.AuthEnd = p.last().End if p.tryConsumeKeywords(KeywordWith) { if p.matchKeyword(KeywordLdap) { _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordServer); err != nil { return nil, err } server, err := p.parseString(p.Pos()) if err != nil { return nil, err } auth.LdapServer = server auth.AuthEnd = server.End() } else if p.matchKeyword(KeywordKerberos) { _ = p.lexer.consumeToken() auth.IsKerberos = true auth.AuthEnd = p.last().End if p.tryConsumeKeywords(KeywordRealm) { realm, err := p.parseString(p.Pos()) if err != nil { return nil, err } auth.KerberosRealm = realm auth.AuthEnd = realm.End() } } else if p.matchTokenKind(TokenKindIdent) { // Auth types like no_password, plaintext_password, etc. authType := p.last().String _ = p.lexer.consumeToken() auth.AuthType = authType auth.AuthEnd = p.last().End if p.tryConsumeKeywords(KeywordBy) { value, err := p.parseString(p.Pos()) if err != nil { return nil, err } auth.AuthValue = value auth.AuthEnd = value.End() } } } return auth, nil } func (p *Parser) parseHostClause(pos Pos) (*HostClause, error) { if err := p.expectKeyword(KeywordHost); err != nil { return nil, err } host := &HostClause{HostPos: pos} switch { case p.matchOneOfKeywords(KeywordLocal, KeywordAny, KeywordNone): hostType := p.last().String _ = p.lexer.consumeToken() host.HostType = hostType host.HostEnd = p.last().End case p.matchOneOfKeywords(KeywordName, KeywordRegexp, KeywordIp, KeywordLike): hostType := p.last().String _ = p.lexer.consumeToken() host.HostType = hostType value, err := p.parseString(p.Pos()) if err != nil { return nil, err } host.HostValue = value host.HostEnd = value.End() default: return nil, fmt.Errorf("expected LOCAL|NAME|REGEXP|IP|LIKE|ANY|NONE") } return host, nil } func (p *Parser) parseDefaultRoleClause(pos Pos) (*DefaultRoleClause, error) { if err := p.expectKeyword(KeywordDefault); err != nil { return nil, err } if err := p.expectKeyword(KeywordRole); err != nil { return nil, err } defaultRole := &DefaultRoleClause{DefaultPos: pos} if p.tryConsumeKeywords(KeywordNone) { defaultRole.None = true defaultRole.DefaultEnd = p.last().End return defaultRole, nil } roles := make([]*RoleName, 0) role, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } roles = append(roles, role) for p.tryConsumeTokenKind(TokenKindComma) != nil { role, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } roles = append(roles, role) } defaultRole.Roles = roles defaultRole.DefaultEnd = roles[len(roles)-1].End() return defaultRole, nil } func (p *Parser) parseGranteesClause(pos Pos) (*GranteesClause, error) { if err := p.expectKeyword(KeywordGrantees); err != nil { return nil, err } grantees := &GranteesClause{GranteesPos: pos} if p.tryConsumeKeywords(KeywordAny) { grantees.Any = true grantees.GranteesEnd = p.last().End } else if p.tryConsumeKeywords(KeywordNone) { grantees.None = true grantees.GranteesEnd = p.last().End } else { // Parse list of grantees granteeList := make([]*RoleName, 0) grantee, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } granteeList = append(granteeList, grantee) for p.tryConsumeTokenKind(TokenKindComma) != nil { grantee, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } granteeList = append(granteeList, grantee) } grantees.Grantees = granteeList grantees.GranteesEnd = granteeList[len(granteeList)-1].End() } // Check for EXCEPT clause if p.tryConsumeKeywords(KeywordExcept) { exceptList := make([]*RoleName, 0) except, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } exceptList = append(exceptList, except) for p.tryConsumeTokenKind(TokenKindComma) != nil { except, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } exceptList = append(exceptList, except) } grantees.ExceptUsers = exceptList grantees.GranteesEnd = exceptList[len(exceptList)-1].End() } return grantees, nil } func (p *Parser) parseCreateUserModifiers(createUser *CreateUser) error { switch { case p.matchKeyword(KeywordIf): _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordNot); err != nil { return err } if err := p.expectKeyword(KeywordExists); err != nil { return err } createUser.IfNotExists = true case p.matchKeyword(KeywordOr): _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordReplace); err != nil { return err } createUser.OrReplace = true } return nil } func (p *Parser) parseUserNames() ([]*RoleName, error) { userNames := make([]*RoleName, 0) userName, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } userNames = append(userNames, userName) for p.tryConsumeTokenKind(TokenKindComma) != nil { userName, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } userNames = append(userNames, userName) } return userNames, nil } func (p *Parser) parseHostClauses() ([]*HostClause, error) { hosts := make([]*HostClause, 0) host, err := p.parseHostClause(p.Pos()) if err != nil { return nil, err } hosts = append(hosts, host) for p.tryConsumeTokenKind(TokenKindComma) != nil { host, err := p.parseHostClause(p.Pos()) if err != nil { return nil, err } hosts = append(hosts, host) } return hosts, nil } func (p *Parser) parseDefaultClause(createUser *CreateUser) (bool, error) { nextToken, err := p.lexer.peekToken() if err != nil { return false, err } if nextToken.String == KeywordRole { defaultRole, err := p.parseDefaultRoleClause(p.Pos()) if err != nil { return false, err } createUser.DefaultRole = defaultRole createUser.StatementEnd = defaultRole.End() return true, nil } else if nextToken.String == KeywordDatabase { _ = p.lexer.consumeToken() // consume DEFAULT _ = p.lexer.consumeToken() // consume DATABASE if p.tryConsumeKeywords(KeywordNone) { createUser.DefaultDbNone = true createUser.StatementEnd = p.last().End } else { db, err := p.parseIdent() if err != nil { return false, err } createUser.DefaultDatabase = db createUser.StatementEnd = db.End() } return true, nil } return false, nil } func (p *Parser) parseOptionalClauses(createUser *CreateUser) error { continueParsing := true for continueParsing { switch { case p.matchOneOfKeywords(KeywordNot, KeywordIdentified): auth, err := p.parseAuthenticationClause(p.Pos()) if err != nil { return err } createUser.Authentication = auth createUser.StatementEnd = auth.End() case p.matchKeyword(KeywordValid): _ = p.lexer.consumeToken() // consume VALID keyword if err := p.expectKeyword(KeywordUntil); err != nil { return err } validUntil, err := p.parseString(p.Pos()) if err != nil { return err } createUser.ValidUntil = validUntil createUser.StatementEnd = validUntil.End() case p.matchKeyword(KeywordHost): hosts, err := p.parseHostClauses() if err != nil { return err } createUser.Hosts = hosts createUser.StatementEnd = hosts[len(hosts)-1].End() case p.matchKeyword(KeywordDefault): parsed, err := p.parseDefaultClause(createUser) if err != nil { return err } if !parsed { continueParsing = false } case p.matchKeyword(KeywordGrantees): grantees, err := p.parseGranteesClause(p.Pos()) if err != nil { return err } createUser.Grantees = grantees createUser.StatementEnd = grantees.End() case p.matchKeyword(KeywordSettings): _ = p.lexer.consumeToken() // consume SETTINGS keyword settings, err := p.parseRoleSettings(p.Pos()) if err != nil { return err } createUser.Settings = settings if len(settings) > 0 { createUser.StatementEnd = settings[len(settings)-1].End() } default: continueParsing = false } } return nil } func (p *Parser) parseCreateUser(pos Pos) (*CreateUser, error) { if err := p.expectKeyword(KeywordUser); err != nil { return nil, err } createUser := &CreateUser{CreatePos: pos} // Handle IF NOT EXISTS or OR REPLACE if err := p.parseCreateUserModifiers(createUser); err != nil { return nil, err } // Parse user names userNames, err := p.parseUserNames() if err != nil { return nil, err } createUser.UserNames = userNames createUser.StatementEnd = userNames[len(userNames)-1].End() // Parse optional clauses if err := p.parseOptionalClauses(createUser); err != nil { return nil, err } return createUser, nil } func (p *Parser) parserDropUserOrRole(pos Pos) (*DropUserOrRole, error) { var target string switch { case p.matchOneOfKeywords(KeywordUser, KeywordRole): target = p.last().String _ = p.lexer.consumeToken() default: return nil, fmt.Errorf("expected USER|ROLE") } ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } names := make([]*RoleName, 0) name, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } names = append(names, name) for p.tryConsumeTokenKind(TokenKindComma) != nil { name, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } names = append(names, name) } statementEnd := names[len(names)-1].End() onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if onCluster != nil { statementEnd = onCluster.End() } var from *Ident if p.tryConsumeKeywords(KeywordFrom) { from, err = p.parseIdent() if err != nil { return nil, err } } modifier, err := p.tryParseModifier() if err != nil { return nil, err } return &DropUserOrRole{ DropPos: pos, StatementEnd: statementEnd, Target: target, IfExists: ifExists, Names: names, From: from, Modifier: modifier, }, nil } func (p *Parser) parsePrivilegeSelectOrInsert(pos Pos) (*PrivilegeClause, error) { keyword := p.last().String _ = p.lexer.consumeToken() var err error var params *ParamExprList if p.matchTokenKind(TokenKindLParen) { params, err = p.parseFunctionParams(p.Pos()) if err != nil { return nil, err } } return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{keyword}, Params: params, }, nil } func (p *Parser) parsePrivilegeAlter(pos Pos) (*PrivilegeClause, error) { keywords := []string{KeywordAlter} switch { case p.tryConsumeKeywords(KeywordIndex): keywords = append(keywords, KeywordIndex) case p.matchOneOfKeywords(KeywordUpdate, KeywordDelete, KeywordUser, KeywordRole, KeywordQuota): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) case p.matchOneOfKeywords(KeywordAdd, KeywordDrop, KeywordModify, KeywordClear, KeywordComment, KeywordRename, KeywordMaterialized): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) switch { case p.tryConsumeKeywords(KeywordColumn): keywords = append(keywords, KeywordColumn) case p.tryConsumeKeywords(KeywordIndex): keywords = append(keywords, KeywordIndex) keywords = append(keywords, KeywordConstraint) case p.tryConsumeKeywords(KeywordTtl): keywords = append(keywords, KeywordTtl) default: return nil, fmt.Errorf("expected COLUMN|INDEX") } case p.tryConsumeKeywords(KeywordOrder): if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } keywords = append(keywords, KeywordOrder, KeywordBy) case p.tryConsumeKeywords(KeywordSample): if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } keywords = append(keywords, KeywordSample, KeywordBy) case p.tryConsumeKeywords(KeywordSettings): keywords = append(keywords, KeywordSettings) case p.tryConsumeKeywords(KeywordView): keywords = append(keywords, KeywordView) switch { case p.tryConsumeKeywords(KeywordModify): keywords = append(keywords, KeywordModify) case p.tryConsumeKeywords(KeywordRefresh): keywords = append(keywords, KeywordRefresh) default: return nil, fmt.Errorf("expected MODIFY|REFRESH") } case p.matchOneOfKeywords(KeywordMove, KeywordFreeze): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) if err := p.expectKeyword(KeywordPartition); err != nil { return nil, err } keywords = append(keywords, KeywordPartition) default: return nil, fmt.Errorf("expected UPDATE|DELETE|ADD|DROP|MODIFY|CLEAR|COMMENT|RENAME|MATERIALIZED|ORDER|SAMPLE|SETTINGS|VIEW|MOVE|FREEZE") } return &PrivilegeClause{ PrivilegePos: pos, Keywords: keywords, }, nil } func (p *Parser) parsePrivilegeCreate(pos Pos) (*PrivilegeClause, error) { keywords := []string{KeywordCreate} switch { case p.matchOneOfKeywords(KeywordDatabase, KeywordDictionary, KeywordTable, KeywordFunction, KeywordView, KeywordUser, KeywordRole, KeywordQuota): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) case p.tryConsumeKeywords(KeywordTemporary): if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } keywords = append(keywords, KeywordTemporary, KeywordTable) case p.tryConsumeKeywords(KeywordRows): if err := p.expectKeyword(KeywordPolicy); err != nil { return nil, err } keywords = append(keywords, KeywordRows, KeywordPolicy) default: return nil, fmt.Errorf("expected DATABASE|DICTIONARY|TABLE|FUNCTION|VIEW|USER|ROLE|ROWS") } return &PrivilegeClause{ PrivilegePos: pos, Keywords: keywords, }, nil } func (p *Parser) parsePrivilegeDrop(pos Pos) (*PrivilegeClause, error) { keywords := []string{KeywordDrop} switch { case p.matchOneOfKeywords(KeywordDatabase, KeywordDictionary, KeywordUser, KeywordRole, KeywordQuota, KeywordTable, KeywordFunction, KeywordView): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) default: return nil, fmt.Errorf("expected DATABASE|DICTIONARY|TABLE|FUNCTION|VIEW") } return &PrivilegeClause{ PrivilegePos: pos, Keywords: keywords, }, nil } func (p *Parser) parsePrivilegeShow(pos Pos) (*PrivilegeClause, error) { keywords := []string{KeywordShow} switch { case p.matchOneOfKeywords(KeywordDatabases, KeywordDictionaries, KeywordTables, KeywordColumns): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) default: return nil, fmt.Errorf("expected DATABASES|DICTIONARIES|TABLES|COLUMNS") } return &PrivilegeClause{ PrivilegePos: pos, Keywords: keywords, }, nil } func (p *Parser) parsePrivilegeSystem(pos Pos) (*PrivilegeClause, error) { keywords := []string{KeywordShow} switch { case p.matchOneOfKeywords(KeywordShutdown, KeywordMerges, KeywordFetches, KeywordSends, KeywordMoves, KeywordCluster): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) case p.tryConsumeKeywords(KeywordDrop): keywords = append(keywords, KeywordDrop) switch { case p.tryConsumeKeywords(KeywordCache): keywords = append(keywords, KeywordCache) case p.matchOneOfKeywords(KeywordMark, KeywordDNS, KeywordUncompressed): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) if err := p.expectKeyword(KeywordCache); err != nil { return nil, err } keywords = append(keywords, KeywordCache) default: return nil, fmt.Errorf("expected CACHE|MARK|DNS|UNCOMPRESSED") } case p.tryConsumeKeywords(KeywordReload): keywords = append(keywords, KeywordReload) switch { case p.matchOneOfKeywords(KeywordDictionary, KeywordFunction, KeywordFunctions, KeywordConfig): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) default: return nil, fmt.Errorf("expected DICTIONARY|FUNCTION|FUNCTIONS|CONFIG") } case p.tryConsumeKeywords(KeywordFlush): keywords = append(keywords, KeywordFlush) switch { case p.matchOneOfKeywords(KeywordLogs, KeywordDistributed): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) default: return nil, fmt.Errorf("expected LOGS|DISTRIBUTED") } case p.tryConsumeKeywords(KeywordTtl): keywords = append(keywords, KeywordTtl) if err := p.expectKeyword(KeywordMerges); err != nil { return nil, err } keywords = append(keywords, KeywordMerges) case p.matchOneOfKeywords(KeywordSync, KeywordRestart): keyword := p.last().String _ = p.lexer.consumeToken() keywords = append(keywords, keyword) if err := p.expectKeyword(KeywordReplica); err != nil { return nil, err } keywords = append(keywords, KeywordReplica) case p.tryConsumeKeywords(KeywordReplication): keywords = append(keywords, KeywordReplication) if err := p.expectKeyword(KeywordQueues); err != nil { return nil, err } keywords = append(keywords, KeywordQueues) default: return nil, fmt.Errorf("expected QUEUES|SHUTDOWN|MERGES|FETCHES|SENDS|MOVES|CLUSTER|DROP|RELOAD|FLUSH|TTL|SYNC|RESTART|REPLICATION") } return &PrivilegeClause{ PrivilegePos: pos, Keywords: keywords, }, nil } func (p *Parser) parsePrivilegeClause(pos Pos) (*PrivilegeClause, error) { if p.matchTokenKind(TokenKindIdent) { if p.last().String == "dictGet" { _ = p.lexer.consumeToken() return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{"dictGet"}, }, nil } } switch { case p.matchOneOfKeywords(KeywordSelect, KeywordInsert): return p.parsePrivilegeSelectOrInsert(pos) case p.tryConsumeKeywords(KeywordAlter): return p.parsePrivilegeAlter(pos) case p.tryConsumeKeywords(KeywordCreate): return p.parsePrivilegeCreate(pos) case p.tryConsumeKeywords(KeywordDrop): return p.parsePrivilegeDrop(pos) case p.tryConsumeKeywords(KeywordShow): return p.parsePrivilegeShow(pos) case p.matchKeyword(KeywordAll), p.matchTokenKind(KeywordNone): _ = p.lexer.consumeToken() return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{KeywordAll}, }, nil case p.tryConsumeKeywords(KeywordKill): if err := p.expectKeyword(KeywordQuery); err != nil { return nil, err } return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{KeywordKill, KeywordQuery}, }, nil case p.tryConsumeKeywords(KeywordSystem): return p.parsePrivilegeSystem(pos) case p.tryConsumeKeywords(KeywordAdmin): if err := p.expectKeyword(KeywordOption); err != nil { return nil, err } return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{KeywordAdmin, KeywordOption}, }, nil case p.matchOneOfKeywords(KeywordOptimize, KeywordTruncate): keyword := p.last().String _ = p.lexer.consumeToken() return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{keyword}, }, nil case p.tryConsumeKeywords(KeywordRole): if err := p.expectKeyword(KeywordAdmin); err != nil { return nil, err } return &PrivilegeClause{ PrivilegePos: pos, Keywords: []string{KeywordRole, KeywordAdmin}, }, nil } return nil, fmt.Errorf("expected SELECT|INSERT|ALTER|CREATE|DROP|SHOW|KILL|SYSTEM|OPTIMIZE|TRUNCATE") } func (p *Parser) parsePrivilegeRoles(_ Pos) ([]*Ident, error) { roles := make([]*Ident, 0) role, err := p.parseIdent() if err != nil { return nil, err } roles = append(roles, role) for p.tryConsumeTokenKind(TokenKindComma) != nil { role, err := p.parseIdent() if err != nil { return nil, err } roles = append(roles, role) } return roles, nil } func (p *Parser) parseGrantOptions(_ Pos) ([]string, error) { options := make([]string, 0) for p.matchKeyword(KeywordWith) { option, err := p.parseGrantOption(p.Pos()) if err != nil { return nil, err } options = append(options, option) } return options, nil } func (p *Parser) parseGrantOption(_ Pos) (string, error) { if err := p.expectKeyword(KeywordWith); err != nil { return "", err } ident, err := p.parseIdent() if err != nil { return "", err } if err := p.expectKeyword(KeywordOption); err != nil { return "", err } return ident.Name, nil } func (p *Parser) parseGrantSource(_ Pos) (*TableIdentifier, error) { ident, err := p.parseIdentOrStar() if err != nil { return nil, err } if p.tryConsumeTokenKind(TokenKindDot) == nil { return &TableIdentifier{ Table: ident, }, nil } dotIdent, err := p.parseIdentOrStar() if err != nil { return nil, err } return &TableIdentifier{ Database: ident, Table: dotIdent, }, nil } func (p *Parser) parseGrantPrivilegeStmt(pos Pos) (*GrantPrivilegeStmt, error) { if err := p.expectKeyword(KeywordGrant); err != nil { return nil, err } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } var privileges []*PrivilegeClause privilege, err := p.parsePrivilegeClause(p.Pos()) if err != nil { return nil, err } privileges = append(privileges, privilege) for p.tryConsumeTokenKind(TokenKindComma) != nil { privilege, err := p.parsePrivilegeClause(p.Pos()) if err != nil { return nil, err } privileges = append(privileges, privilege) } statementEnd := privileges[len(privileges)-1].End() if err := p.expectKeyword(KeywordOn); err != nil { return nil, err } on, err := p.parseGrantSource(p.Pos()) if err != nil { return nil, err } if err := p.expectKeyword(KeywordTo); err != nil { return nil, err } toRoles, err := p.parsePrivilegeRoles(p.Pos()) if err != nil { return nil, err } if len(toRoles) != 0 { statementEnd = toRoles[len(toRoles)-1].NameEnd } options, err := p.parseGrantOptions(p.Pos()) if err != nil { return nil, err } if len(options) != 0 { statementEnd = p.End() } return &GrantPrivilegeStmt{ GrantPos: pos, StatementEnd: statementEnd, OnCluster: onCluster, Privileges: privileges, On: on, To: toRoles, WithOptions: options, }, nil } func (p *Parser) parseAlterRole(pos Pos) (*AlterRole, error) { if err := p.expectKeyword(KeywordRole); err != nil { return nil, err } ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } roleRenamePairs := make([]*RoleRenamePair, 0) roleRenamePair, err := p.parseRoleRenamePair(p.Pos()) if err != nil { return nil, err } roleRenamePairs = append(roleRenamePairs, roleRenamePair) for p.tryConsumeTokenKind(TokenKindComma) != nil { roleRenamePair, err := p.parseRoleRenamePair(p.Pos()) if err != nil { return nil, err } roleRenamePairs = append(roleRenamePairs, roleRenamePair) } statementEnd := roleRenamePairs[len(roleRenamePairs)-1].End() settings, err := p.tryParseRoleSettings(p.Pos()) if err != nil { return nil, err } if settings != nil { statementEnd = settings[len(settings)-1].End() } return &AlterRole{ AlterPos: pos, StatementEnd: statementEnd, IfExists: ifExists, RoleRenamePairs: roleRenamePairs, Settings: settings, }, nil } func (p *Parser) parseRoleRenamePair(_ Pos) (*RoleRenamePair, error) { roleName, err := p.parseRoleName(p.Pos()) if err != nil { return nil, err } roleRenamePair := &RoleRenamePair{ RoleName: roleName, StatementEnd: roleName.End(), } if p.tryConsumeKeywords(KeywordRename) { if err := p.expectKeyword(KeywordTo); err != nil { return nil, err } newName, err := p.parseIdent() if err != nil { return nil, err } roleRenamePair.NewName = newName roleRenamePair.StatementEnd = newName.NameEnd } return roleRenamePair, nil } ================================================ FILE: parser/parser_alter.go ================================================ package parser import ( "errors" "fmt" ) func (p *Parser) parseAlterTable(pos Pos) (*AlterTable, error) { alterTable := &AlterTable{ AlterPos: pos, AlterExprs: make([]AlterTableClause, 0), } if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } alterTable.TableIdentifier = tableIdentifier onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } alterTable.OnCluster = onCluster for !p.lexer.isEOF() { var alter AlterTableClause switch { case p.matchKeyword(KeywordAdd): alter, err = p.parseAlterTableAdd(p.Pos()) case p.matchKeyword(KeywordDrop): alter, err = p.parseAlterTableDrop(p.Pos()) case p.matchKeyword(KeywordAttach): alter, err = p.parseAlterTableAttachPartition(p.Pos()) case p.matchKeyword(KeywordDetach): _ = p.lexer.consumeToken() alter, err = p.parseAlterTableDetachPartition(p.Pos()) case p.matchKeyword(KeywordFreeze): alter, err = p.parseAlterTableFreezePartition(p.Pos()) case p.matchKeyword(KeywordRemove): alter, err = p.parseAlterTableRemoveTTL(p.Pos()) case p.matchKeyword(KeywordRename): alter, err = p.parseAlterTableRenameColumn(p.Pos()) case p.matchKeyword(KeywordClear): alter, err = p.parseAlterTableClear(p.Pos()) case p.matchKeyword(KeywordModify): alter, err = p.parseAlterTableModify(p.Pos()) case p.matchKeyword(KeywordReplace): alter, err = p.parseAlterTableReplacePartition(p.Pos()) case p.matchKeyword(KeywordMaterialize): alter, err = p.parseAlterTableMaterialize(p.Pos()) case p.matchKeyword(KeywordReset): alter, err = p.parseAlterTableReset(p.Pos()) case p.matchKeyword(KeywordDelete): alter, err = p.parseAlterTableDelete(p.Pos()) case p.matchKeyword(KeywordUpdate): alter, err = p.parseAlterTableUpdate(p.Pos()) default: return nil, errors.New("expected token: ADD|DROP|ATTACH|DETACH|FREEZE|REMOVE|CLEAR|MODIFY|REPLACE|MATERIALIZE|RESET|DELETE|UPDATE") } if err != nil { return nil, err } alterTable.AlterExprs = append(alterTable.AlterExprs, alter) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } if len(alterTable.AlterExprs) == 0 { return nil, errors.New("expected token: ADD|DROP") } alterTable.StatementEnd = alterTable.AlterExprs[len(alterTable.AlterExprs)-1].End() return alterTable, nil } func (p *Parser) parseAlterTableAdd(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordAdd); err != nil { return nil, err } switch { case p.matchKeyword(KeywordColumn): return p.parseAlterTableAddColumn(pos) case p.matchKeyword(KeywordIndex): return p.parseAlterTableAddIndex(pos) case p.matchKeyword(KeywordProjection): return p.parseAlterTableAddProjection(pos) default: return nil, errors.New("expected token: COLUMN|INDEX|PROJECTION") } } func (p *Parser) parseAlterTableAddColumn(pos Pos) (*AlterTableAddColumn, error) { if err := p.expectKeyword(KeywordColumn); err != nil { return nil, err } ifNotExists, err := p.tryParseIfNotExists() if err != nil { return nil, err } column, err := p.parseTableColumnExpr(p.Pos()) if err != nil { return nil, err } statementEnd := column.End() after, err := p.tryParseAfterClause() if err != nil { return nil, err } if after != nil { statementEnd = after.End() } settings, err := p.tryParseSettingsClause(p.Pos()) if err != nil { return nil, err } if settings != nil { statementEnd = settings.End() } return &AlterTableAddColumn{ AddPos: pos, StatementEnd: statementEnd, Column: column, IfNotExists: ifNotExists, After: after, Settings: settings, }, nil } func (p *Parser) parseAlterTableAddIndex(pos Pos) (*AlterTableAddIndex, error) { indexPos := p.Pos() if err := p.expectKeyword(KeywordIndex); err != nil { return nil, err } ifNotExists, err := p.tryParseIfNotExists() if err != nil { return nil, err } index, err := p.parseTableIndex(indexPos) if err != nil { return nil, err } statementEnd := index.End() after, err := p.tryParseAfterClause() if err != nil { return nil, err } if after != nil { statementEnd = after.End() } return &AlterTableAddIndex{ AddPos: pos, StatementEnd: statementEnd, IfNotExists: ifNotExists, Index: index, After: after, }, nil } func (p *Parser) tryParseProjectionOrderBy(pos Pos) (*ProjectionOrderByClause, error) { if !p.tryConsumeKeywords(KeywordOrder) { return nil, nil // nolint } if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } columns, err := p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } return &ProjectionOrderByClause{ OrderByPos: pos, Columns: columns, }, nil } func (p *Parser) parseProjectionSelect(pos Pos) (*ProjectionSelectStmt, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } with, err := p.tryParseWithClause(p.Pos()) if err != nil { return nil, err } if err := p.expectKeyword(KeywordSelect); err != nil { return nil, err } columns, err := p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } groupBy, err := p.tryParseGroupByClause(p.Pos()) if err != nil { return nil, err } orderBy, err := p.tryParseProjectionOrderBy(p.Pos()) if err != nil { return nil, err } lastToken := p.last() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &ProjectionSelectStmt{ LeftParenPos: pos, RightParenPos: lastToken.Pos, With: with, SelectColumns: columns, GroupBy: groupBy, OrderBy: orderBy, }, nil } func (p *Parser) parseTableProjection(pos Pos, includeProjectionKeyword bool) (*TableProjection, error) { if includeProjectionKeyword { if err := p.expectKeyword(KeywordProjection); err != nil { return nil, err } } identifier, err := p.ParseNestedIdentifier(pos) if err != nil { return nil, err } selectExpr, err := p.parseProjectionSelect(p.Pos()) if err != nil { return nil, err } return &TableProjection{ IncludeProjectionKeyword: includeProjectionKeyword, ProjectionPos: pos, Identifier: identifier, Select: selectExpr, }, nil } func (p *Parser) parseAlterTableAddProjection(pos Pos) (*AlterTableAddProjection, error) { if err := p.expectKeyword(KeywordProjection); err != nil { return nil, err } ifNotExists, err := p.tryParseIfNotExists() if err != nil { return nil, err } tableProjection, err := p.parseTableProjection(p.Pos(), false) if err != nil { return nil, err } statementEnd := tableProjection.End() after, err := p.tryParseAfterClause() if err != nil { return nil, err } if after != nil { statementEnd = after.End() } return &AlterTableAddProjection{ AddPos: pos, StatementEnd: statementEnd, IfNotExists: ifNotExists, TableProjection: tableProjection, After: after, }, nil } func (p *Parser) parseTableIndex(pos Pos) (*TableIndex, error) { name, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } columnExpr, err := p.parseColumnsExpr(p.Pos()) if err != nil { return nil, err } if err := p.expectKeyword(KeywordType); err != nil { return nil, err } columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } if err := p.expectKeyword(KeywordGranularity); err != nil { return nil, err } granularity, err := p.parseDecimal(p.Pos()) if err != nil { return nil, err } return &TableIndex{ IndexPos: pos, Name: name, ColumnExpr: columnExpr, ColumnType: columnType, Granularity: granularity, }, nil } func (p *Parser) parseAlterTableDrop(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordDrop); err != nil { return nil, err } switch { case p.matchKeyword(KeywordColumn), p.matchKeyword(KeywordIndex), p.matchKeyword(KeywordProjection): return p.parseAlterTableDropClause(pos) case p.matchKeyword(KeywordDetached), p.matchKeyword(KeywordPartition): return p.parseAlterTableDropPartition(pos) default: return nil, errors.New("expected keyword: COLUMN|INDEX|PROJECTION|DETACHED|PARTITION") } } // Syntax: ALTER TABLE DETACH partitionClause func (p *Parser) parseAlterTableDetachPartition(pos Pos) (AlterTableClause, error) { partitionPos := p.Pos() if err := p.expectKeyword(KeywordPartition); err != nil { return nil, err } partition := &PartitionClause{ PartitionPos: partitionPos, } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } partition.Expr = expr settings, err := p.tryParseSettingsClause(p.Pos()) if err != nil { return nil, err } return &AlterTableDetachPartition{ DetachPos: pos, Partition: partition, Settings: settings, }, nil } func (p *Parser) tryParsePartitionClause(pos Pos) (*PartitionClause, error) { if !p.matchKeyword(KeywordPartition) { return nil, nil // nolint } return p.parsePartitionClause(pos) } func (p *Parser) parsePartitionClause(pos Pos) (*PartitionClause, error) { if err := p.expectKeyword(KeywordPartition); err != nil { return nil, err } partition := &PartitionClause{ PartitionPos: pos, } if p.tryConsumeKeywords(KeywordId) { id, err := p.parseString(p.Pos()) if err != nil { return nil, err } partition.ID = id } else if p.tryConsumeKeywords(KeywordAll) { partition.All = true } else { expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } partition.Expr = expr } return partition, nil } // Syntax: ALTER TABLE ATTACH partitionClause (FROM tableIdentifier)? func (p *Parser) parseAlterTableAttachPartition(pos Pos) (AlterTableClause, error) { alterTable := &AlterTableAttachPartition{AttachPos: pos} if err := p.expectKeyword(KeywordAttach); err != nil { return nil, err } partition, err := p.parsePartitionClause(p.Pos()) if err != nil { return nil, err } alterTable.Partition = partition // FROM [db.]table? if p.tryConsumeKeywords(KeywordFrom) { tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } alterTable.From = tableIdentifier } return alterTable, nil } func (p *Parser) parseAlterTableDropClause(pos Pos) (AlterTableClause, error) { var kind string switch { case p.matchKeyword(KeywordColumn): kind = KeywordColumn case p.matchKeyword(KeywordIndex): kind = KeywordIndex case p.matchKeyword(KeywordProjection): kind = KeywordProjection default: return nil, fmt.Errorf("expected token: COLUMN|INDEX|PROJECTION, but got %s", p.lastTokenKind()) } _ = p.lexer.consumeToken() ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } name, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } if kind == KeywordProjection { return &AlterTableDropProjection{ DropPos: pos, ProjectionName: name, IfExists: ifExists, }, nil } else if kind == KeywordColumn { return &AlterTableDropColumn{ DropPos: pos, ColumnName: name, IfExists: ifExists, }, nil } else { return &AlterTableDropIndex{ DropPos: pos, IndexName: name, IfExists: ifExists, }, nil } } func (p *Parser) tryParseAfterClause() (*NestedIdentifier, error) { if !p.tryConsumeKeywords(KeywordAfter) { return nil, nil // nolint } return p.ParseNestedIdentifier(p.Pos()) } // Syntax: ALTER TABLE DROP partitionClause func (p *Parser) parseAlterTableDropPartition(pos Pos) (AlterTableClause, error) { var hasDetached bool if p.matchKeyword(KeywordDetached) { _ = p.lexer.consumeToken() hasDetached = true } partitionPos := p.Pos() if err := p.expectKeyword(KeywordPartition); err != nil { return nil, err } partition := &PartitionClause{ PartitionPos: partitionPos, } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } partition.Expr = expr settings, err := p.tryParseSettingsClause(p.Pos()) if err != nil { return nil, err } return &AlterTableDropPartition{ DropPos: pos, Partition: partition, HasDetached: hasDetached, Settings: settings, }, nil } func (p *Parser) parseAlterTableFreezePartition(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordFreeze); err != nil { return nil, err } alterTable := &AlterTableFreezePartition{ FreezePos: pos, StatementEnd: p.Pos(), } if p.matchKeyword(KeywordPartition) { partition, err := p.parsePartitionClause(p.Pos()) if err != nil { return nil, err } alterTable.Partition = partition alterTable.StatementEnd = partition.End() } return alterTable, nil } func (p *Parser) parseAlterTableRemoveTTL(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordRemove); err != nil { return nil, err } if err := p.expectKeyword(KeywordTtl); err != nil { return nil, err } return &AlterTableRemoveTTL{ RemovePos: pos, StatementEnd: p.Pos(), }, nil } func (p *Parser) parseAlterTableClear(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordClear); err != nil { return nil, err } return p.parseAlterTableClearClause(pos) } // Syntax: ALTER TABLE CLEAR COLUMN|INDEX|PROJECTION (IF EXISTS)? nestedIdentifier (IN partitionClause)? func (p *Parser) parseAlterTableClearClause(pos Pos) (AlterTableClause, error) { var kind string switch { case p.matchKeyword(KeywordColumn): kind = KeywordColumn case p.matchKeyword(KeywordIndex): kind = KeywordIndex case p.matchKeyword(KeywordProjection): kind = KeywordProjection default: return nil, fmt.Errorf("expected keyword: COLUMN|INDEX|PROJECTION, but got %q", p.lastTokenKind()) } _ = p.lexer.consumeToken() ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } name, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } statementEnd := name.End() var partition *PartitionClause if p.tryConsumeKeywords(KeywordIn) { partition, err = p.tryParsePartitionClause(p.Pos()) if err != nil { return nil, err } if partition != nil { statementEnd = partition.End() } } if kind == KeywordProjection { return &AlterTableClearProjection{ ClearPos: pos, StatementEnd: statementEnd, IfExists: ifExists, ProjectionName: name, PartitionExpr: partition, }, nil } else if kind == KeywordColumn { return &AlterTableClearColumn{ ClearPos: pos, StatementEnd: statementEnd, IfExists: ifExists, ColumnName: name, PartitionExpr: partition, }, nil } else { return &AlterTableClearIndex{ ClearPos: pos, StatementEnd: statementEnd, IfExists: ifExists, IndexName: name, PartitionExpr: partition, }, nil } } // Syntax: ALTER TABLE RENAME COLUMN (IF EXISTS)? nestedIdentifier TO nestedIdentifier func (p *Parser) parseAlterTableRenameColumn(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordRename); err != nil { return nil, err } if err := p.expectKeyword(KeywordColumn); err != nil { return nil, err } ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } oldColumnName, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } if err = p.expectKeyword(KeywordTo); err != nil { return nil, err } newColumnName, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } return &AlterTableRenameColumn{ RenamePos: pos, IfExists: ifExists, OldColumnName: oldColumnName, NewColumnName: newColumnName, }, nil } func (p *Parser) parseAlterTableModify(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordModify); err != nil { return nil, err } switch { case p.matchKeyword(KeywordColumn): return p.parseAlterTableModifyColumn(pos) case p.matchKeyword(KeywordTtl): ttlPos := p.Pos() _ = p.lexer.consumeToken() items, err := p.parseTTLClause(ttlPos, true) if err != nil { return nil, err } listEnd := ttlPos if len(items) > 0 { listEnd = items[len(items)-1].End() } ttlClause := &TTLClause{ TTLPos: ttlPos, ListEnd: listEnd, Items: items, } return &AlterTableModifyTTL{ ModifyPos: pos, StatementEnd: ttlClause.End(), TTL: ttlClause, }, nil case p.matchKeyword(KeywordQuery): _ = p.lexer.consumeToken() selectQuery, err := p.parseSelectQuery(pos) if err != nil { return nil, err } return &AlterTableModifyQuery{ ModifyPos: pos, StatementEnd: selectQuery.End(), SelectExpr: selectQuery, }, nil case p.matchKeyword(KeywordSetting): _ = p.lexer.consumeToken() // consume "SETTING" settings, err := p.parseSettingsList(p.Pos()) if err != nil { return nil, err } // settings must not be empty statementEnd := settings[len(settings)-1].End() return &AlterTableModifySetting{ ModifyPos: pos, StatementEnd: statementEnd, Settings: settings, }, nil default: return nil, fmt.Errorf("expected keyword: COLUMN|TTL|QUERY|SETTING, but got %q", p.last().String) } } // syntax: MODIFY COLUMN (IF EXISTS)? tableColumnDfnt func (p *Parser) parseAlterTableModifyColumn(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordColumn); err != nil { return nil, err } ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } // at least parse out column name column, err := p.parseTableColumnExpr(p.Pos()) if err != nil { return nil, err } alterTableModifyColumn := &AlterTableModifyColumn{ ModifyPos: pos, StatementEnd: column.End(), IfExists: ifExists, Column: column, } // syntax: MODIFY COLUMN (IF EXISTS)? nestedIdentifier REMOVE tableColumnPropertyType removePropertyType, err := p.tryParseRemovePropertyTypeExpr(p.Pos()) if err != nil { return nil, err } alterTableModifyColumn.RemovePropertyType = removePropertyType return alterTableModifyColumn, nil } func (p *Parser) tryParseRemovePropertyTypeExpr(pos Pos) (*RemovePropertyType, error) { if !p.matchKeyword(KeywordRemove) { return nil, nil } if err := p.expectKeyword(KeywordRemove); err != nil { return nil, err } columnPropertyType, err := p.parseColumnPropertyType(p.Pos()) if err != nil { return nil, err } return &RemovePropertyType{ RemovePos: pos, PropertyType: columnPropertyType, }, nil } func (p *Parser) parseAlterTableReplacePartition(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordReplace); err != nil { return nil, err } partition, err := p.parsePartitionClause(p.Pos()) if err != nil { return nil, err } if err = p.expectKeyword(KeywordFrom); err != nil { return nil, err } table, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &AlterTableReplacePartition{ ReplacePos: pos, Partition: partition, Table: table, }, nil } func (p *Parser) parseAlterTableMaterialize(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordMaterialize); err != nil { return nil, err } var kind string switch { case p.matchKeyword(KeywordIndex): kind = KeywordIndex case p.matchKeyword(KeywordProjection): kind = KeywordProjection default: return nil, fmt.Errorf("expected keyword: INDEX|PROJECTION, but got %q", p.lastTokenKind()) } _ = p.lexer.consumeToken() ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } name, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } statementEnd := name.End() var partition *PartitionClause if p.tryConsumeKeywords(KeywordIn) { partition, err = p.tryParsePartitionClause(p.Pos()) if err != nil { return nil, err } statementEnd = partition.End() } if kind == KeywordIndex { return &AlterTableMaterializeIndex{ MaterializedPos: pos, StatementEnd: statementEnd, IfExists: ifExists, IndexName: name, Partition: partition, }, nil } return &AlterTableMaterializeProjection{ MaterializedPos: pos, StatementEnd: statementEnd, IfExists: ifExists, ProjectionName: name, Partition: partition, }, nil } func (p *Parser) parseAlterTableReset(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordReset); err != nil { return nil, err } if err := p.expectKeyword(KeywordSetting); err != nil { return nil, err } // Parse comma-separated setting names inline var settings []*Ident setting, err := p.parseIdent() if err != nil { return nil, err } settings = append(settings, setting) for p.tryConsumeTokenKind(TokenKindComma) != nil { setting, err = p.parseIdent() if err != nil { return nil, err } settings = append(settings, setting) } statementEnd := settings[len(settings)-1].End() return &AlterTableResetSetting{ ResetPos: pos, StatementEnd: statementEnd, Settings: settings, }, nil } // Syntax: ALTER TABLE DELETE WHERE condition func (p *Parser) parseAlterTableDelete(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordDelete); err != nil { return nil, err } if err := p.expectKeyword(KeywordWhere); err != nil { return nil, err } whereExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &AlterTableDelete{ DeletePos: pos, StatementEnd: whereExpr.End(), WhereClause: whereExpr, }, nil } // Syntax: ALTER TABLE UPDATE column1 = expr1 [, column2 = expr2, ...] [IN PARTITION partition_id] WHERE condition func (p *Parser) parseAlterTableUpdate(pos Pos) (AlterTableClause, error) { if err := p.expectKeyword(KeywordUpdate); err != nil { return nil, err } // Parse at least one assignment assignments := make([]*UpdateAssignment, 0) assignment, err := p.parseUpdateAssignment(p.Pos()) if err != nil { return nil, err } assignments = append(assignments, assignment) // Parse additional comma-separated assignments for p.tryConsumeTokenKind(TokenKindComma) != nil { assignment, err = p.parseUpdateAssignment(p.Pos()) if err != nil { return nil, err } assignments = append(assignments, assignment) } var inPartition *PartitionClause if p.tryConsumeKeywords(KeywordIn) { inPartition, err = p.parsePartitionClause(p.Pos()) if err != nil { return nil, err } } if err := p.expectKeyword(KeywordWhere); err != nil { return nil, err } whereExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &AlterTableUpdate{ UpdatePos: pos, StatementEnd: whereExpr.End(), Assignments: assignments, InPartition: inPartition, WhereClause: whereExpr, }, nil } // Parse column = expression assignment func (p *Parser) parseUpdateAssignment(pos Pos) (*UpdateAssignment, error) { column, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } // Why don't we use parseExpr here? Because `ALTER TABLE UPDATE` syntax allows to // use `IN PARTITION` keywords after assignments. So we need to limit the precedence // to avoid parsing `IN PARTITION` as part of the expression. expr, err := p.parseSubExpr(p.Pos(), precedenceIn) if err != nil { return nil, err } return &UpdateAssignment{ AssignmentPos: pos, Column: column, Expr: expr, }, nil } ================================================ FILE: parser/parser_column.go ================================================ package parser import ( "fmt" "strings" ) const ( PrecedenceUnknown = iota PrecedenceOr PrecedenceAnd PrecedenceQuery PrecedenceNot PrecedenceGlobal PrecedenceIs PrecedenceCompare PrecedenceBetweenLike precedenceIn PrecedenceConcat PrecedenceAddSub PrecedenceMulDivMod PrecedenceBracket PrecedenceArrow PrecedenceDot PrecedenceDoubleColon ) func (p *Parser) tryParseColumnComment(pos Pos) (*StringLiteral, error) { if !p.tryConsumeKeywords(KeywordComment) { return nil, nil // nolint } return p.parseString(pos) } func (p *Parser) getNextPrecedence() int { switch { case p.matchKeyword(KeywordOr): return PrecedenceOr case p.matchKeyword(KeywordAnd): return PrecedenceAnd case p.matchKeyword(KeywordIs): return PrecedenceIs case p.matchKeyword(KeywordNot): return PrecedenceNot case p.matchTokenKind(TokenKindDot): return PrecedenceDot case p.matchTokenKind(TokenKindDash): return PrecedenceDoubleColon case p.matchTokenKind(TokenKindSingleEQ), p.matchTokenKind(TokenKindLT), p.matchTokenKind(TokenKindLE), p.matchTokenKind(TokenKindGE), p.matchTokenKind(TokenKindGT), p.matchTokenKind(TokenKindDoubleEQ), p.matchTokenKind(TokenKindNE), p.matchTokenKind("<>"): return PrecedenceCompare case p.matchTokenKind(TokenKindConcat): return PrecedenceConcat case p.matchTokenKind(TokenKindPlus), p.matchTokenKind(TokenKindMinus): return PrecedenceAddSub case p.matchTokenKind(TokenKindMul), p.matchTokenKind(TokenKindDiv), p.matchTokenKind(TokenKindMod): return PrecedenceMulDivMod case p.matchTokenKind(TokenKindArrow): return PrecedenceArrow case p.matchTokenKind(TokenKindLParen), p.matchTokenKind(TokenKindLBracket): return PrecedenceBracket case p.matchTokenKind(TokenKindDash): return PrecedenceDoubleColon case p.matchTokenKind(TokenKindDot): return PrecedenceDot case p.matchKeyword(KeywordBetween), p.matchKeyword(KeywordLike), p.matchKeyword(KeywordIlike): return PrecedenceBetweenLike case p.matchKeyword(KeywordIn): return precedenceIn case p.matchKeyword(KeywordGlobal): return PrecedenceGlobal case p.matchTokenKind(TokenKindQuestionMark): return PrecedenceQuery default: return PrecedenceUnknown } } func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) { switch { case p.matchTokenKind(TokenKindSingleEQ), p.matchTokenKind(TokenKindLT), p.matchTokenKind(TokenKindLE), p.matchTokenKind(TokenKindGE), p.matchTokenKind(TokenKindGT), p.matchTokenKind(TokenKindNE), p.matchTokenKind("<>"), p.matchTokenKind(TokenKindMinus), p.matchTokenKind(TokenKindPlus), p.matchTokenKind(TokenKindMul), p.matchTokenKind(TokenKindDiv), p.matchTokenKind(TokenKindMod), p.matchTokenKind(TokenKindConcat), p.matchKeyword(KeywordIn), p.matchKeyword(KeywordLike), p.matchKeyword(KeywordIlike), p.matchKeyword(KeywordAnd), p.matchKeyword(KeywordOr), p.matchTokenKind(TokenKindArrow), p.matchTokenKind(TokenKindDoubleEQ): op := p.last().ToString() _ = p.lexer.consumeToken() rightExpr, err := p.parseSubExpr(p.Pos(), precedence) if err != nil { return nil, err } return &BinaryOperation{ LeftExpr: expr, Operation: TokenKind(op), RightExpr: rightExpr, }, nil case p.matchTokenKind(TokenKindDash): _ = p.lexer.consumeToken() if p.matchTokenKind(TokenKindIdent) && p.last().String == "Tuple" { name, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } // it's a tuple type definition after "::" operator rightExpr, err := p.parseNestedType(name, p.Pos()) if err != nil { return nil, err } return &BinaryOperation{ LeftExpr: expr, Operation: TokenKindDash, RightExpr: rightExpr, }, nil } rightExpr, err := p.parseSubExpr(p.Pos(), precedence) if err != nil { return nil, err } return &BinaryOperation{ LeftExpr: expr, Operation: TokenKindDash, RightExpr: rightExpr, }, nil case p.matchKeyword(KeywordBetween): return p.parseBetweenClause(expr) case p.matchKeyword(KeywordGlobal): _ = p.lexer.consumeToken() if p.expectKeyword(KeywordIn) != nil { return nil, fmt.Errorf("expected IN after GLOBAL, got %s", p.lastTokenKind()) } rightExpr, err := p.parseSubExpr(p.Pos(), precedence) if err != nil { return nil, err } return &BinaryOperation{ LeftExpr: expr, Operation: "GLOBAL IN", RightExpr: rightExpr, }, nil case p.matchTokenKind(TokenKindDot): _ = p.lexer.consumeToken() // access column with dot notation var rightExpr Expr var err error if p.matchTokenKind(TokenKindIdent) { rightExpr, err = p.parseIdent() } else { rightExpr, err = p.parseDecimal(p.Pos()) } if err != nil { return nil, err } return &IndexOperation{ Object: expr, Operation: TokenKindDot, Index: rightExpr, }, nil case p.matchKeyword(KeywordNot): _ = p.lexer.consumeToken() switch { case p.matchKeyword(KeywordIn): case p.matchKeyword(KeywordLike): case p.matchKeyword(KeywordIlike): default: return nil, fmt.Errorf("expected IN, LIKE or ILIKE after NOT, got %s", p.lastTokenKind()) } if p.matchKeyword(KeywordBetween) { return p.parseBetweenClause(expr) } op := p.last().ToString() _ = p.lexer.consumeToken() rightExpr, err := p.parseSubExpr(p.Pos(), precedence) if err != nil { return nil, err } return &BinaryOperation{ LeftExpr: expr, Operation: TokenKind("NOT " + op), RightExpr: rightExpr, }, nil case p.matchTokenKind(TokenKindLBracket): params, err := p.parseArrayParams(p.Pos()) if err != nil { return nil, err } return &ObjectParams{ Object: expr, Params: params, }, nil case p.matchTokenKind(TokenKindQuestionMark): return p.parseTernaryExpr(expr) case p.matchKeyword(KeywordIs): _ = p.lexer.consumeToken() isNotNull := p.tryConsumeKeywords(KeywordNot) if err := p.expectKeyword(KeywordNull); err != nil { return nil, err } if isNotNull { return &IsNotNullExpr{ IsPos: p.Pos(), Expr: expr, }, nil } return &IsNullExpr{ IsPos: p.Pos(), Expr: expr, }, nil default: return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } } func (p *Parser) parseExpr(pos Pos) (Expr, error) { return p.parseSubExpr(pos, PrecedenceUnknown) } func (p *Parser) parseSubExpr(pos Pos, precedence int) (Expr, error) { expr, err := p.parseUnaryExpr(pos) if err != nil { return nil, err } for !p.lexer.isEOF() { nextPrecedence := p.getNextPrecedence() if nextPrecedence <= precedence { return expr, nil } // parse binary operation expr, err = p.parseInfix(expr, nextPrecedence) if err != nil { return nil, err } } return expr, nil } func (p *Parser) parseTernaryExpr(condition Expr) (*TernaryOperation, error) { if err := p.expectTokenKind(TokenKindQuestionMark); err != nil { return nil, err } trueExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindColon); err != nil { return nil, err } falseExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &TernaryOperation{ Condition: condition, TrueExpr: trueExpr, FalseExpr: falseExpr, }, nil } func (p *Parser) parseExtractFrom(ident *Ident) (*IntervalFrom, error) { fromPos := p.Pos() if err := p.expectKeyword(KeywordFrom); err != nil { return nil, err } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &IntervalFrom{ Interval: ident, FromPos: fromPos, FromExpr: expr, }, nil } func (p *Parser) parseColumnExtractExpr(pos Pos) (*ExtractExpr, error) { if err := p.expectKeyword(KeywordExtract); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } parameters := make([]Expr, 0) for !p.lexer.isEOF() { expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } var param Expr if ident, ok := expr.(*Ident); ok { if intervalUnits.Contains(strings.ToUpper(ident.Name)) && p.matchKeyword(KeywordFrom) { param, err = p.parseExtractFrom(ident) if err != nil { return nil, err } parameters = append(parameters, param) } else { parameters = append(parameters, expr) } } else { parameters = append(parameters, expr) } if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } if len(parameters) == 0 { return nil, fmt.Errorf("EXTRACT requires at least one parameter") } extractEnd := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &ExtractExpr{ ExtractPos: pos, ExtractEnd: extractEnd, Parameters: parameters, }, nil } func (p *Parser) parseUnaryExpr(pos Pos) (Expr, error) { op := p.last() switch { case p.matchTokenKind(TokenKindPlus), p.matchTokenKind(TokenKindMinus), p.matchKeyword(KeywordNot): _ = p.lexer.consumeToken() default: return p.parseColumnExpr(pos) } expr, err := p.parseColumnExpr(p.Pos()) if err != nil { return nil, err } return &UnaryExpr{ UnaryPos: pos, Kind: TokenKind(op.ToString()), Expr: expr, }, nil } func (p *Parser) peekTokenKind(kind TokenKind) bool { if p.lexer.isEOF() { return false } token, err := p.lexer.peekToken() if err != nil || token == nil { return false } return token.Kind == kind } func (p *Parser) peekKeyword(keyword string) bool { if p.lexer.isEOF() { return false } token, err := p.lexer.peekToken() if err != nil || token == nil { return false } return token.Kind == TokenKindKeyword && strings.EqualFold(token.String, keyword) } // isSelectItemTerminatorKeyword checks whether the current token is a keyword // that begins a clause following the SELECT item list. When true, we should not // treat the keyword itself as a bare alias. func (p *Parser) isSelectItemTerminatorKeyword() bool { switch { case p.matchKeyword(KeywordFrom): return true case p.matchKeyword(KeywordWhere): return true case p.matchKeyword(KeywordPrewhere): return true case p.matchKeyword(KeywordGroup): return true case p.matchKeyword(KeywordHaving): return true case p.matchKeyword(KeywordWindow): return true case p.matchKeyword(KeywordOrder): return true case p.matchKeyword(KeywordLimit): return true case p.matchKeyword(KeywordOffset): return true case p.matchKeyword(KeywordSettings): return true case p.matchKeyword(KeywordFormat): return true case p.matchKeyword(KeywordUnion): return true case p.matchKeyword(KeywordExcept): return true default: return false } } func (p *Parser) parseColumnExpr(pos Pos) (Expr, error) { //nolint:funlen // Should parse the keyword as an identifier if the keyword is followed by one of comma, `AS`. // For example: `SELECT 1 as interval GROUP BY interval` is a valid syntax in ClickHouse. if p.matchTokenKind(TokenKindKeyword) && (p.peekTokenKind(TokenKindComma) || p.peekKeyword(KeywordAs)) { return p.parseIdent() } switch { case p.matchKeyword(KeywordInterval): return p.parseInterval(true) case p.matchKeyword(KeywordDate), p.matchKeyword(KeywordTimestamp): nextToken, err := p.lexer.peekToken() if err != nil { return nil, err } if nextToken != nil && nextToken.Kind == TokenKindString { return p.parseString(p.Pos()) } return p.parseIdentOrFunction(pos) case p.matchKeyword(KeywordCast): return p.parseColumnCastExpr(pos) case p.matchKeyword(KeywordCase): return p.parseColumnCaseExpr(pos) case p.matchKeyword(KeywordSelect): return p.parseSelectQuery(pos) case p.matchKeyword(KeywordExtract): return p.parseColumnExtractExpr(pos) case p.matchTokenKind(TokenKindIdent): return p.parseIdentOrFunction(pos) case p.matchTokenKind(TokenKindString): // string literal return p.parseString(pos) case p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat): // number literal return p.parseNumber(pos) case p.matchTokenKind(TokenKindLParen): if peek, _ := p.lexer.peekToken(); peek != nil { if peek.Kind == TokenKindKeyword && strings.EqualFold(peek.String, KeywordSelect) { return p.parseSubQuery(pos) } } return p.parseFunctionParams(p.Pos()) case p.matchTokenKind("*"): return p.parseColumnStar(p.Pos()) case p.matchTokenKind(TokenKindLBracket): return p.parseArrayParams(p.Pos()) case p.matchTokenKind(TokenKindLBrace): // The map literal string also starts with '{', so we need to check the next token // to determine if it is a map literal or a query param. // Treat both identifiers and keywords as identifier-like for placeholders. // parseIdent accepts keywords-as-ident, so this is safe. if p.peekTokenKind(TokenKindIdent) || p.peekTokenKind(TokenKindKeyword) { return p.parseQueryParam(p.Pos()) } return p.parseMapLiteral(p.Pos()) case p.matchTokenKind(TokenKindDot): return p.parseNumber(p.Pos()) case p.matchTokenKind(TokenKindQuestionMark): // Placeholder `?` _ = p.lexer.consumeToken() return &PlaceHolder{ PlaceholderPos: pos, PlaceHolderEnd: pos, Type: string(TokenKindQuestionMark), }, nil default: return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } } func (p *Parser) parseColumnCastExpr(pos Pos) (Expr, error) { if err := p.expectKeyword(KeywordCast); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } columnExpr, err := p.parseColumnExpr(p.Pos()) if err != nil { return nil, err } var separator string asPos := p.Pos() switch { // CAST(x, T) and CAST(x AS T) are equivalent case p.matchKeyword(KeywordAs), p.matchTokenKind(","): separator = p.last().String _ = p.lexer.consumeToken() default: return nil, fmt.Errorf("expected AS or , but got %s", p.lastTokenKind()) } var asColumnType Expr // CAST(1 AS 'Float') or CAST(1 AS Float) are equivalent if p.matchTokenKind(TokenKindString) { asColumnType, err = p.parseString(p.Pos()) } else { asColumnType, err = p.parseColumnType(p.Pos()) } if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &CastExpr{ CastPos: pos, AsPos: asPos, Separator: separator, Expr: columnExpr, AsType: asColumnType, }, nil } func (p *Parser) parseColumnExprListWithLParen(pos Pos) (*ColumnExprList, error) { return p.parseColumnExprListWithTerm(TokenKindRParen, pos) } func (p *Parser) parseColumnExprListWithSquareBracket(pos Pos) (*ColumnExprList, error) { return p.parseColumnExprListWithTerm(TokenKindRBracket, pos) } func (p *Parser) parseColumnExprList(pos Pos) (*ColumnExprList, error) { return p.parseColumnExprListWithTerm("", pos) } func (p *Parser) parseColumnExprListWithTerm(term TokenKind, pos Pos) (*ColumnExprList, error) { columnExprList := &ColumnExprList{ ListPos: pos, ListEnd: pos, } columnExprList.HasDistinct = p.tryConsumeKeywords(KeywordDistinct) columnList := make([]Expr, 0) for !p.lexer.isEOF() || p.last() != nil { if term != "" && p.matchTokenKind(term) { break } columnExpr, err := p.parseColumnsExpr(p.Pos()) if err != nil { return nil, err } if columnExpr == nil { break } columnList = append(columnList, columnExpr) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } columnExprList.Items = columnList if len(columnList) > 0 { columnExprList.ListEnd = columnList[len(columnList)-1].End() } return columnExprList, nil } func (p *Parser) parseSelectItems() ([]*SelectItem, error) { selectItems := make([]*SelectItem, 0) for !p.lexer.isEOF() || p.last() != nil { selectItem, err := p.parseSelectItem() if err != nil { return nil, err } if selectItem == nil { break } selectItems = append(selectItems, selectItem) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } return selectItems, nil } func (p *Parser) parseInterval(requireKeyword bool) (*IntervalExpr, error) { var intervalPos Pos if requireKeyword { intervalPos = p.Pos() if err := p.expectKeyword(KeywordInterval); err != nil { return nil, err } } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } unit, err := p.parseIdent() if err != nil { return nil, err } if !intervalUnits.Contains(strings.ToUpper(unit.Name)) { return nil, fmt.Errorf("unknown interval type: <%q>", unit.Name) } return &IntervalExpr{ IntervalPos: intervalPos, Expr: expr, Unit: unit, }, nil } func (p *Parser) parseFunctionExpr(_ Pos) (*FunctionExpr, error) { // parse function name name, err := p.parseIdent() if err != nil { return nil, err } // parse function params params, err := p.parseFunctionParams(p.Pos()) if err != nil { return nil, err } return &FunctionExpr{ Name: name, Params: params, }, nil } func (p *Parser) parseColumnArgList(pos Pos) (*ColumnArgList, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } distinct := p.tryConsumeKeywords(KeywordDistinct) var items []Expr for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) { item, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } items = append(items, item) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &ColumnArgList{ LeftParenPos: pos, RightParenPos: rightParenPos, Distinct: distinct, Items: items, }, nil } func (p *Parser) parseFunctionParams(pos Pos) (*ParamExprList, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } params, err := p.parseColumnExprListWithLParen(p.Pos()) if err != nil { return nil, err } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } paramExprList := &ParamExprList{ LeftParenPos: pos, RightParenPos: rightParenPos, Items: params, } // For some aggregate functions might support parametric arguments: // e.g. QUANTILE(0.5)(x) or QUANTILE(0.5, 0.9)(x). // So we need to have a check if there is another argument list with detecting the left bracket. if p.matchTokenKind(TokenKindLParen) { columnArgList, err := p.parseColumnArgList(p.Pos()) if err != nil { return nil, err } paramExprList.ColumnArgList = columnArgList } return paramExprList, nil } func (p *Parser) parseMapLiteral(pos Pos) (*MapLiteral, error) { if err := p.expectTokenKind(TokenKindLBrace); err != nil { return nil, err } keyValues := make([]KeyValue, 0) for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRBrace) { key, err := p.parseString(p.Pos()) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindColon); err != nil { return nil, err } value, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } keyValues = append(keyValues, KeyValue{ Key: *key, Value: value, }) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rightBracePos := p.Pos() if err := p.expectTokenKind(TokenKindRBrace); err != nil { return nil, err } return &MapLiteral{ LBracePos: pos, RBracePos: rightBracePos, KeyValues: keyValues, }, nil } func (p *Parser) parseQueryParam(pos Pos) (*QueryParam, error) { if err := p.expectTokenKind(TokenKindLBrace); err != nil { return nil, err } ident, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindColon); err != nil { return nil, err } columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } rightBracePos := p.Pos() if err := p.expectTokenKind(TokenKindRBrace); err != nil { return nil, err } return &QueryParam{ LBracePos: pos, RBracePos: rightBracePos, Name: ident, Type: columnType, }, nil } func (p *Parser) parseArrayParams(pos Pos) (*ArrayParamList, error) { if err := p.expectTokenKind(TokenKindLBracket); err != nil { return nil, err } params, err := p.parseColumnExprListWithSquareBracket(p.Pos()) if err != nil { return nil, err } rightBracketPos := p.Pos() if err := p.expectTokenKind(TokenKindRBracket); err != nil { return nil, err } return &ArrayParamList{ LeftBracketPos: pos, RightBracketPos: rightBracketPos, Items: params, }, nil } func (p *Parser) parseColumnsExpr(pos Pos) (*ColumnExpr, error) { expr, err := p.parseExpr(pos) if err != nil { return nil, err } var alias *Ident if p.tryConsumeKeywords(KeywordAs) { alias, err = p.parseIdent() if err != nil { return nil, err } } return &ColumnExpr{ Expr: expr, Alias: alias, }, nil } func (p *Parser) parseSelectItem() (*SelectItem, error) { expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } modifiers := make([]*FunctionExpr, 0) for { if p.matchKeyword(KeywordExcept) || p.matchKeyword(KeywordApply) || p.matchKeyword(KeywordReplace) { modifier, err := p.parseFunctionExpr(p.Pos()) if err != nil { return nil, err } modifiers = append(modifiers, modifier) } else { break } } var alias *Ident switch { case p.tryConsumeKeywords(KeywordAs): alias, err = p.parseIdent() if err != nil { return nil, err } case p.lastTokenKind() == TokenKindKeyword && !p.isSelectItemTerminatorKeyword(): alias, err = p.parseIdent() if err != nil { return nil, err } default: alias = p.tryParseIdent() } return &SelectItem{ Expr: expr, Modifiers: modifiers, Alias: alias, }, nil } func (p *Parser) parseColumnCaseExpr(pos Pos) (*CaseExpr, error) { // CASE expr caseExpr := &CaseExpr{CasePos: pos} if err := p.expectKeyword(KeywordCase); err != nil { return nil, err } // case expr is optional if !p.matchKeyword(KeywordWhen) { expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } caseExpr.Expr = expr } // WHEN expr THEN expr whenClauses := make([]*WhenClause, 0) for p.matchKeyword(KeywordWhen) { whenPos := p.Pos() _ = p.lexer.consumeToken() whenCondition, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } thenPos := p.Pos() if err := p.expectKeyword(KeywordThen); err != nil { return nil, err } thenCondition, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } whenClauses = append(whenClauses, &WhenClause{ WhenPos: whenPos, ThenPos: thenPos, When: whenCondition, Then: thenCondition, }) } caseExpr.Whens = whenClauses // ELSE expr elsePos := p.Pos() if p.tryConsumeKeywords(KeywordElse) { elseExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } caseExpr.ElsePos = elsePos caseExpr.Else = elseExpr } if err := p.expectKeyword(KeywordEnd); err != nil { return nil, err } return caseExpr, nil } func (p *Parser) parseColumnType(_ Pos) (ColumnType, error) { ident, err := p.parseIdent() if err != nil { return nil, err } return p.parseColumnTypeArgs(ident) } func (p *Parser) parseColumnTypeArgs(ident *Ident) (ColumnType, error) { // nolint:funlen if lParen := p.tryConsumeTokenKind(TokenKindLParen); lParen != nil { switch { case p.matchTokenKind(TokenKindIdent): switch { case strings.EqualFold(ident.Name, "Nested"): return p.parseNestedType(ident, p.Pos()) case strings.EqualFold(ident.Name, "JSON"): return p.parseJSONType(ident, p.Pos()) case strings.EqualFold(ident.Name, "QBit"): return p.parseColumnTypeWithParams(ident, p.Pos()) case strings.EqualFold(ident.Name, "Tuple"): return p.parseNestedType(ident, p.Pos()) default: return p.parseComplexType(ident, p.Pos()) } case p.matchTokenKind(TokenKindString): if peekToken, err := p.lexer.peekToken(); err == nil && peekToken.Kind == TokenKindSingleEQ { // enum values return p.parseEnumType(ident, p.Pos()) } // like Datetime('Asia/Dubai') return p.parseColumnTypeWithParams(ident, p.Pos()) case p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat): // fixed size return p.parseColumnTypeWithParams(ident, p.Pos()) case p.matchTokenKind(TokenKindRParen): rightParenPos := p.Pos() _ = p.lexer.consumeToken() return &TypeWithParams{ Name: ident, LeftParenPos: lParen.Pos, RightParenPos: rightParenPos, }, nil default: return nil, fmt.Errorf("unexpected token kind: %v", p.lastTokenKind()) } } return &ScalarType{Name: ident}, nil } func (p *Parser) parseColumnPropertyType(_ Pos) (Expr, error) { ident, err := p.parseIdent() if err != nil { return nil, err } return &PropertyType{ Name: ident, }, nil } func (p *Parser) parseComplexType(name *Ident, pos Pos) (*ComplexType, error) { subTypes := make([]ColumnType, 0) for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) { subExpr, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } subTypes = append(subTypes, subExpr) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &ComplexType{ LeftParenPos: pos, RightParenPos: rightParenPos, Name: name, Params: subTypes, }, nil } func (p *Parser) parseEnumType(name *Ident, pos Pos) (*EnumType, error) { enumType := &EnumType{ Name: name, ListPos: pos, Values: make([]EnumValue, 0), } for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) { enumValue, err := p.parseEnumValueExpr(p.Pos()) if err != nil { return nil, err } if enumValue == nil { break } enumType.Values = append(enumType.Values, *enumValue) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } if len(enumType.Values) > 0 { enumType.ListEnd = enumType.Values[len(enumType.Values)-1].Value.NumEnd } if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return enumType, nil } func (p *Parser) parseColumnTypeWithParams(name *Ident, pos Pos) (*TypeWithParams, error) { params := make([]Literal, 0) param, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } params = append(params, param) for !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindComma) != nil { size, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } params = append(params, size) } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &TypeWithParams{ Name: name, LeftParenPos: pos, RightParenPos: rightParenPos, Params: params, }, nil } func (p *Parser) parseJSONPath() (*JSONPath, error) { idents := make([]*Ident, 0) ident, err := p.parseIdent() if err != nil { return nil, err } idents = append(idents, ident) for !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindDot) != nil { ident, err := p.parseIdent() if err != nil { return nil, err } idents = append(idents, ident) } return &JSONPath{ Idents: idents, }, nil } func (p *Parser) parseJSONMaxDynamicOptions(pos Pos) (*JSONOption, error) { ident, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } switch ident.Name { case "max_dynamic_types": number, err := p.parseNumber(pos) if err != nil { return nil, err } return &JSONOption{MaxDynamicTypes: number}, nil case "max_dynamic_paths": number, err := p.parseNumber(pos) if err != nil { return nil, err } return &JSONOption{MaxDynamicPaths: number}, nil default: return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } } func (p *Parser) parseJSONOption() (*JSONOption, error) { switch { case p.tryConsumeKeywords(KeywordSkip): if p.tryConsumeKeywords(KeywordRegexp) { regex, err := p.parseString(p.Pos()) if err != nil { return nil, err } return &JSONOption{ SkipRegex: regex, }, nil } jsonPath, err := p.parseJSONPath() if err != nil { return nil, err } return &JSONOption{ SkipPath: jsonPath, }, nil case p.matchTokenKind(TokenKindIdent): // Could be max_dynamic_* option OR a type hint like: a.b String // Lookahead to see if there's an '=' following the identifier path (max_dynamic_*) // or if it's a path followed by a ColumnType. // We'll parse a JSONPath first, then decide. // Save lexer state by consuming as path greedily using existing helpers. // Try: if single ident and next is '=' -> max_dynamic_*; else treat as path + type // Peek next token after current ident without consuming type; we need to // attempt to parse as max_dynamic_* first as it's existing behavior for a single ident. // To support dotted paths, we need to capture path, then if '=' exists, it's option; otherwise parse type. path, err := p.parseJSONPath() if err != nil { return nil, err } if p.tryConsumeTokenKind(TokenKindSingleEQ) != nil { // This is a max_dynamic_* option; only valid when path is a single ident of that name // Reconstruct handling similar to parseJSONMaxDynamicOptions but we already consumed ident and '=' // Determine which option based on the first ident name if len(path.Idents) != 1 { return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } name := path.Idents[0].Name switch name { case "max_dynamic_types": number, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } return &JSONOption{MaxDynamicTypes: number}, nil case "max_dynamic_paths": number, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } return &JSONOption{MaxDynamicPaths: number}, nil default: return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } } // Otherwise, expect a ColumnType as a type hint for the JSON subpath colType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } return &JSONOption{Column: &JSONTypeHint{Path: path, Type: colType}}, nil default: return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } } func (p *Parser) parseJSONType(name *Ident, pos Pos) (*JSONType, error) { if p.matchTokenKind(TokenKindLParen) { return &JSONType{Name: name}, nil } options := make([]*JSONOption, 0) for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) { option, err := p.parseJSONOption() if err != nil { return nil, err } options = append(options, option) if p.tryConsumeTokenKind(",") == nil { break } } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &JSONType{ Name: name, Options: &JSONOptions{ LParen: pos, RParen: rightParenPos, Items: options, }, }, nil } func (p *Parser) parseNestedType(name *Ident, pos Pos) (*NestedType, error) { columns, err := p.parseNestedTypeFields() if err != nil { return nil, err } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &NestedType{ LeftParenPos: pos, RightParenPos: rightParenPos, Name: name, Columns: columns, }, nil } func (p *Parser) parseNestedTypeFields() ([]Expr, error) { switch { case p.lexer.isEOF() || p.matchTokenKind(TokenKindRParen): // Cases like `Tuple()` return []Expr{}, nil case p.matchTokenKind(TokenKindIdent): ident, err := p.parseIdent() if err != nil { return nil, err } if p.matchTokenKind(TokenKindIdent) { // Cases like `Tuple(a Int, b String)` or `Nested(a Int, b String)` return p.parseNestedTypeFieldsWithNames(ident) } // Cases like `Tuple(Int, String)` return p.parseNestedTypeFieldsWithoutNames(ident) default: return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind()) } } func (p *Parser) parseNestedTypeFieldsWithNames(columnName *Ident) ([]Expr, error) { columns := make([]Expr, 0) columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } columns = append(columns, &ColumnDef{ NamePos: columnName.Pos(), Name: &NestedIdentifier{ Ident: columnName, }, Type: columnType, ColumnEnd: columnType.End(), }) if p.tryConsumeTokenKind(TokenKindComma) == nil { return columns, nil } for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) { column, err := p.parseNestedTypeFieldWithName() if err != nil { return nil, err } if column == nil { break } columns = append(columns, column) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } return columns, nil } func (p *Parser) parseNestedTypeFieldsWithoutNames(columnType *Ident) ([]Expr, error) { columns := make([]Expr, 0) column, err := p.parseColumnTypeArgs(columnType) if err != nil { return nil, err } columns = append(columns, column) if p.tryConsumeTokenKind(TokenKindComma) == nil { return columns, nil } for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) { column, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } if column == nil { break } columns = append(columns, column) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } return columns, nil } func (p *Parser) parseNestedTypeFieldWithName() (Expr, error) { name, err := p.parseIdent() if err != nil { return nil, err } columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } return &ColumnDef{ NamePos: name.Pos(), Name: &NestedIdentifier{ Ident: name, }, Type: columnType, ColumnEnd: columnType.End(), }, nil } func (p *Parser) tryParseCompressionCodecs(pos Pos) (*CompressionCodec, error) { if !p.tryConsumeKeywords(KeywordCodec) { return nil, nil // nolint } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } // parse codec name codecType, err := p.parseIdent() if err != nil { return nil, err } // parse DELTA if CODEC(Delta, ZSTD(1)) // or CODEC(Delta(9), ZSTD(1)) or CODEC(T64, ZSTD(1)) var name *Ident var typeLevel *NumberLiteral switch strings.ToUpper(codecType.Name) { case "DELTA", "DOUBLEDELTA", "T64", "GORILLA": // try parse delta level typeLevel, err = p.tryParseCompressionLevel(p.Pos()) if err != nil { return nil, err } if p.matchTokenKind(TokenKindComma) { if err := p.expectTokenKind(TokenKindComma); err != nil { return nil, err } name, err = p.parseIdent() if err != nil { return nil, err } } case "ZSTD", "LZ4HC", "LH4": // For compression codecs, try to parse level typeLevel, err = p.tryParseCompressionLevel(p.Pos()) if err != nil { return nil, err } } var level *NumberLiteral // TODO: check if the codec name is valid if name != nil { switch strings.ToUpper(name.Name) { case "ZSTD", "LZ4HC", "LH4": level, err = p.tryParseCompressionLevel(p.Pos()) if err != nil { return nil, err } } } rightParenPos := p.End() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } // If there's only one codec (no second name), store it in Name field instead of Type // This handles cases like CODEC(DoubleDelta) or CODEC(ZSTD(1)) if name == nil { return &CompressionCodec{ CodecPos: pos, RightParenPos: rightParenPos, Type: nil, TypeLevel: nil, Name: codecType, Level: typeLevel, }, nil } // Two codecs: Type is the preprocessing codec, Name is the compression codec // e.g., CODEC(DoubleDelta, ZSTD(1)) return &CompressionCodec{ CodecPos: pos, RightParenPos: rightParenPos, Type: codecType, TypeLevel: typeLevel, Name: name, Level: level, }, nil } func (p *Parser) parseEnumValueExpr(pos Pos) (*EnumValue, error) { name, err := p.parseString(pos) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } value, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } return &EnumValue{ Name: name, Value: value, }, nil } func (p *Parser) parseColumnStar(pos Pos) (*Ident, error) { if err := p.expectTokenKind("*"); err != nil { return nil, err } return &Ident{ NamePos: pos, NameEnd: pos, Name: "*", }, nil } func (p *Parser) tryParseCompressionLevel(pos Pos) (*NumberLiteral, error) { if p.tryConsumeTokenKind(TokenKindLParen) == nil { return nil, nil // nolint } num, err := p.parseNumber(pos) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return num, nil } ================================================ FILE: parser/parser_common.go ================================================ package parser import ( "errors" "fmt" "strings" ) type Parser struct { lexer *Lexer } func NewParser(buffer string) *Parser { return &Parser{ lexer: NewLexer(buffer), } } func (p *Parser) lastTokenKind() TokenKind { if p.last() == nil { return TokenKindEOF } return p.last().Kind } func (p *Parser) last() *Token { return p.lexer.lastToken } func (p *Parser) End() Pos { if p.last() == nil { return Pos(p.lexer.current + 1) } return p.last().End } func (p *Parser) Pos() Pos { last := p.last() if last == nil { return Pos(p.lexer.current) } return last.Pos } func (p *Parser) matchTokenKind(kind TokenKind) bool { return p.lastTokenKind() == kind || (kind == TokenKindIdent && p.lastTokenKind() == TokenKindKeyword) } // expectTokenKind consumes the last token if it is the given kind. func (p *Parser) expectTokenKind(kind TokenKind) error { if lastToken := p.tryConsumeTokenKind(kind); lastToken != nil { return nil } return fmt.Errorf("expected the last token kind is: %s, but got %s", kind, p.lastTokenKind()) } func (p *Parser) tryConsumeTokenKind(kind TokenKind) *Token { if p.matchTokenKind(kind) { lastToken := p.last() _ = p.lexer.consumeToken() return lastToken } return nil } func (p *Parser) matchKeyword(keyword string) bool { return p.matchTokenKind(TokenKindKeyword) && strings.EqualFold(p.last().String, keyword) } func (p *Parser) matchOneOfKeywords(keywords ...string) bool { for _, keyword := range keywords { if p.matchKeyword(keyword) { return true } } return false } func (p *Parser) expectKeyword(keyword string) error { if !p.matchKeyword(keyword) { return fmt.Errorf("expected keyword: %s, but got %s", keyword, p.lastTokenKind()) } _ = p.lexer.consumeToken() return nil } func (p *Parser) tryConsumeKeywords(keywords ...string) bool { savedState := p.lexer.saveState() for _, keyword := range keywords { if !p.matchKeyword(keyword) { p.lexer.restoreState(savedState) return false } _ = p.lexer.consumeToken() } return true } func (p *Parser) tryParseIdent() *Ident { if p.lastTokenKind() != TokenKindIdent { return nil } lastToken := p.last() _ = p.lexer.consumeToken() return &Ident{ NamePos: lastToken.Pos, NameEnd: lastToken.End, Name: lastToken.String, QuoteType: lastToken.QuoteType, } } func (p *Parser) parseIdent() (*Ident, error) { lastToken := p.last() if err := p.expectTokenKind(TokenKindIdent); err != nil { return nil, err } ident := &Ident{ NamePos: lastToken.Pos, NameEnd: lastToken.End, Name: lastToken.String, QuoteType: lastToken.QuoteType, } return ident, nil } func (p *Parser) parseIdentOrStar() (*Ident, error) { switch { case p.matchTokenKind(TokenKindIdent): return p.parseIdent() case p.matchTokenKind("*"): lastToken := p.last() _ = p.lexer.consumeToken() return &Ident{ NamePos: lastToken.Pos, NameEnd: lastToken.End, Name: lastToken.String, }, nil default: return nil, fmt.Errorf("expected or *, but got %q", p.lastTokenKind()) } } func (p *Parser) parseIdentOrString() (*Ident, error) { switch { case p.matchTokenKind(TokenKindIdent): return p.parseIdent() case p.matchTokenKind(TokenKindString): lastToken := p.last() _ = p.lexer.consumeToken() return &Ident{ NamePos: lastToken.Pos, NameEnd: lastToken.End, Name: lastToken.String, QuoteType: SingleQuote, // Treat string literals as single-quoted identifiers }, nil default: return nil, fmt.Errorf("expected or , but got %q", p.lastTokenKind()) } } func (p *Parser) tryParseDotIdent(_ Pos) (*Ident, error) { if p.tryConsumeTokenKind(TokenKindDot) == nil { return nil, nil // nolint } return p.parseIdent() } func (p *Parser) tryParseDotIdentOrString(_ Pos) (*Ident, error) { if p.tryConsumeTokenKind(TokenKindDot) == nil { return nil, nil // nolint } return p.parseIdentOrString() } func (p *Parser) parseUUID() (*UUID, error) { if err := p.expectKeyword(KeywordUuid); err != nil { return nil, err } uuidString, err := p.parseString(p.Pos()) if err != nil { return nil, err } return &UUID{ Value: uuidString, }, nil } func (p *Parser) tryParseUUID() (*UUID, error) { if !p.matchKeyword(KeywordUuid) { return nil, nil // nolint } return p.parseUUID() } func (p *Parser) tryParseComment() (*StringLiteral, error) { if !p.tryConsumeKeywords(KeywordComment) { return nil, nil } return p.parseString(p.Pos()) } func (p *Parser) tryParseIfExists() (bool, error) { if !p.tryConsumeKeywords(KeywordIf) { return false, nil } if err := p.expectKeyword(KeywordExists); err != nil { return false, err } return true, nil } func (p *Parser) tryParseIfNotExists() (bool, error) { if !p.tryConsumeKeywords(KeywordIf) { return false, nil } if err := p.expectKeyword(KeywordNot); err != nil { return false, err } if err := p.expectKeyword(KeywordExists); err != nil { return false, err } return true, nil } func (p *Parser) tryParseNull(pos Pos) *NullLiteral { if !p.tryConsumeKeywords(KeywordNull) { return nil } return &NullLiteral{NullPos: pos} } func (p *Parser) tryParseNotNull(pos Pos) (*NotNullLiteral, error) { if !p.tryConsumeKeywords(KeywordNot) { return nil, nil // nolint } notNull := &NotNullLiteral{NotPos: pos} nullPos := p.Pos() if err := p.expectKeyword(KeywordNull); err != nil { return notNull, err } notNull.NullLiteral = &NullLiteral{NullPos: nullPos} return notNull, nil } func (p *Parser) parseDecimal(pos Pos) (*NumberLiteral, error) { number, err := p.parseNumber(pos) if err != nil { return nil, err } if number.Base != 10 { return nil, fmt.Errorf("invalid decimal literal: %q", number.Literal) } return number, nil } func (p *Parser) parseNumber(pos Pos) (*NumberLiteral, error) { var err error lastToken := p.last() switch { case p.matchTokenKind(TokenKindInt): err = p.expectTokenKind(TokenKindInt) case p.matchTokenKind(TokenKindFloat): err = p.expectTokenKind(TokenKindFloat) case p.matchTokenKind(TokenKindDot): _ = p.lexer.consumeToken() lastToken = p.last() if err := p.expectTokenKind(TokenKindInt); err != nil { return nil, err } if lastToken.Base != 10 { return nil, fmt.Errorf("invalid decimal literal: %q", lastToken.String) } lastToken.String = "." + lastToken.String lastToken.Kind = TokenKindFloat default: return nil, fmt.Errorf("expected or , but got %q", p.lastTokenKind()) } if err != nil { return nil, err } number := &NumberLiteral{ NumPos: pos, NumEnd: lastToken.End, Literal: lastToken.String, Base: lastToken.Base, } return number, nil } func (p *Parser) parseString(pos Pos) (*StringLiteral, error) { lastToken := p.last() if err := p.expectTokenKind(TokenKindString); err != nil { return nil, err } str := &StringLiteral{ LiteralPos: pos, LiteralEnd: lastToken.End, Literal: lastToken.String, } return str, nil } func (p *Parser) parseLiteral(pos Pos) (Literal, error) { switch { case p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat): return p.parseNumber(pos) case p.matchTokenKind(TokenKindString): return p.parseString(pos) case p.matchTokenKind(TokenKindIdent): return p.parseIdent() case p.matchKeyword(KeywordNull): // accept the NULL keyword return &NullLiteral{NullPos: pos}, nil default: return nil, fmt.Errorf("expected , , or keyword , but got %q", p.lastTokenKind()) } } func (p *Parser) ParseNestedIdentifier(pos Pos) (*NestedIdentifier, error) { ident, err := p.parseIdent() if err != nil { return nil, err } dotIdent, err := p.tryParseDotIdent(p.Pos()) if err != nil { return nil, err } if dotIdent != nil { return &NestedIdentifier{ Ident: ident, DotIdent: dotIdent, }, nil } return &NestedIdentifier{ Ident: ident, }, nil } func (p *Parser) tryParseFormat(pos Pos) (*FormatClause, error) { if !p.matchKeyword(KeywordFormat) { return nil, nil // nolint } return p.parseFormat(pos) } func (p *Parser) parseFormat(pos Pos) (*FormatClause, error) { if err := p.expectKeyword(KeywordFormat); err != nil { return nil, err } formatIdent, err := p.parseIdent() if err != nil { return nil, err } return &FormatClause{ FormatPos: pos, Format: formatIdent, }, nil } func (p *Parser) wrapError(err error) error { if err == nil { return nil } lineNo := 0 column := 0 for i := 0; i < int(p.Pos()); i++ { if p.lexer.input[i] == '\n' { lineNo++ column = 0 } else { column++ } } lines := strings.Split(p.lexer.input, "\n") var buf strings.Builder buf.WriteString(fmt.Sprintf("line %d:%d %s\n", lineNo, column, err.Error())) for i, line := range lines { if i == lineNo { buf.WriteString(line) buf.WriteByte('\n') for j := 0; j < column; j++ { buf.WriteByte(' ') } if p.last() != nil { buf.WriteString(strings.Repeat("^", len(p.last().String))) } else { buf.WriteString("^") } buf.WriteByte('\n') } } return errors.New(buf.String()) } func (p *Parser) parseRatioExpr(pos Pos) (*RatioExpr, error) { numerator, err := p.parseNumber(pos) if err != nil { return nil, err } var denominator *NumberLiteral if p.tryConsumeTokenKind(TokenKindDiv) != nil { denominator, err = p.parseNumber(pos) if err != nil { return nil, err } } return &RatioExpr{ Numerator: numerator, Denominator: denominator, }, nil } ================================================ FILE: parser/parser_drop.go ================================================ package parser func (p *Parser) parseDropDatabase(pos Pos) (*DropDatabase, error) { if err := p.expectKeyword(KeywordDatabase); err != nil { return nil, err } isExists, err := p.tryParseIfExists() if err != nil { return nil, err } name, err := p.parseIdent() if err != nil { return nil, err } statementEnd := name.End() onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if onCluster != nil { statementEnd = onCluster.End() } return &DropDatabase{ DropPos: pos, Name: name, IfExists: isExists, OnCluster: onCluster, StatementEnd: statementEnd, }, nil } func (p *Parser) parseDropStmt(pos Pos) (*DropStmt, error) { var isTemporary bool dropTarget := KeywordTable switch { case p.tryConsumeKeywords(KeywordDictionary): dropTarget = KeywordDictionary case p.tryConsumeKeywords(KeywordView): dropTarget = KeywordView default: isTemporary = p.tryConsumeKeywords(KeywordTemporary) if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } } isExists, err := p.tryParseIfExists() if err != nil { return nil, err } name, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } modifier, err := p.tryParseModifier() if err != nil { return nil, err } return &DropStmt{ DropPos: pos, DropTarget: dropTarget, Name: name, IfExists: isExists, OnCluster: onCluster, IsTemporary: isTemporary, Modifier: modifier, StatementEnd: p.Pos(), }, nil } func (p *Parser) tryParseModifier() (string, error) { switch { case p.tryConsumeKeywords(KeywordSync): return "SYNC", nil case p.tryConsumeKeywords(KeywordNo): if err := p.expectKeyword(KeywordDelay); err != nil { return "", err } return "NO DELAY", nil } return "", nil } ================================================ FILE: parser/parser_query.go ================================================ package parser import ( "errors" "fmt" "slices" ) func (p *Parser) tryParseWithClause(pos Pos) (*WithClause, error) { if !p.matchKeyword(KeywordWith) { return nil, nil } return p.parseWithClause(pos) } func (p *Parser) parseWithClause(pos Pos) (*WithClause, error) { if err := p.expectKeyword(KeywordWith); err != nil { return nil, err } cteExpr, err := p.parseCTEStmt(p.Pos()) if err != nil { return nil, err } ctes := []*CTEStmt{cteExpr} for p.tryConsumeTokenKind(TokenKindComma) != nil { cteExpr, err := p.parseCTEStmt(p.Pos()) if err != nil { return nil, err } ctes = append(ctes, cteExpr) } return &WithClause{ WithPos: pos, CTEs: ctes, EndPos: ctes[len(ctes)-1].End(), }, nil } func (p *Parser) tryParseTopClause(pos Pos) (*TopClause, error) { if !p.matchKeyword(KeywordTop) { return nil, nil } return p.parseTopClause(pos) } func (p *Parser) parseTopClause(pos Pos) (*TopClause, error) { if err := p.expectKeyword(KeywordTop); err != nil { return nil, err } number, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } topEnd := number.End() withTies := false if p.tryConsumeKeywords(KeywordWith) { topEnd = p.End() if err := p.expectKeyword(KeywordTies); err != nil { return nil, err } withTies = true } return &TopClause{ TopPos: pos, TopEnd: topEnd, Number: number, WithTies: withTies, }, nil } func (p *Parser) tryParseDistinctOn(pos Pos) (*DistinctOn, error) { if !p.matchKeyword(KeywordOn) { return nil, nil } return p.parseDistinctOn(pos) } func (p *Parser) parseDistinctOn(pos Pos) (*DistinctOn, error) { if err := p.expectKeyword(KeywordOn); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } col, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } idents := []*NestedIdentifier{col} for p.matchTokenKind(TokenKindComma) { _ = p.lexer.consumeToken() col, err = p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } idents = append(idents, col) } if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &DistinctOn{ Idents: idents, DistinctOnPos: pos, DistinctOnEnd: p.Pos(), }, nil } func (p *Parser) tryParseFromClause(pos Pos) (*FromClause, error) { if !p.matchKeyword(KeywordFrom) { return nil, nil } return p.parseFromClause(pos) } func (p *Parser) parseFromClause(pos Pos) (*FromClause, error) { if err := p.expectKeyword(KeywordFrom); err != nil { return nil, err } expr, err := p.parseJoinExpr(p.Pos()) if err != nil { return nil, err } return &FromClause{ FromPos: pos, Expr: expr, }, nil } func (p *Parser) tryParseJoinConstraints(pos Pos) (Expr, error) { switch { case p.tryConsumeKeywords(KeywordOn): columnExprList, err := p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } return &OnClause{ OnPos: pos, On: columnExprList, }, nil case p.tryConsumeKeywords(KeywordUsing): hasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil columnExprList, err := p.parseColumnExprListWithLParen(p.Pos()) if err != nil { return nil, err } if hasParen { if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } } return &UsingClause{ UsingPos: pos, Using: columnExprList, }, nil } return nil, nil } func (p *Parser) parseJoinOp(_ Pos) []string { var modifiers []string switch { case p.tryConsumeKeywords(KeywordCross): // cross join modifiers = append(modifiers, KeywordCross) case p.matchKeyword(KeywordAny), p.matchKeyword(KeywordAll): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() if p.matchKeyword(KeywordFull) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } if p.matchKeyword(KeywordLeft) || p.matchKeyword(KeywordRight) || p.matchKeyword(KeywordInner) || p.matchKeyword(KeywordOuter) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } case p.matchKeyword(KeywordSemi), p.matchKeyword(KeywordAsof): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() if p.matchKeyword(KeywordLeft) || p.matchKeyword(KeywordRight) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } if p.matchKeyword(KeywordOuter) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } case p.matchKeyword(KeywordInner): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() if p.matchKeyword(KeywordAll) || p.matchKeyword(KeywordAny) || p.matchKeyword(KeywordAsof) || p.matchKeyword(KeywordArray) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } case p.matchKeyword(KeywordLeft): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() if p.matchKeyword(KeywordOuter) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } if p.matchKeyword(KeywordSemi) || p.matchKeyword(KeywordAnti) || p.matchKeyword(KeywordAny) || p.matchKeyword(KeywordAll) || p.matchKeyword(KeywordAsof) || p.matchKeyword(KeywordArray) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } case p.matchKeyword(KeywordRight): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() if p.matchKeyword(KeywordOuter) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } if p.matchKeyword(KeywordSemi) || p.matchKeyword(KeywordAnti) || p.matchKeyword(KeywordAny) || p.matchKeyword(KeywordAll) || p.matchKeyword(KeywordAsof) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } case p.matchKeyword(KeywordFull): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() if p.matchKeyword(KeywordOuter) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } if p.matchKeyword(KeywordAll) || p.matchKeyword(KeywordAny) { modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } case p.matchKeyword(KeywordArray): modifiers = append(modifiers, p.last().String) _ = p.lexer.consumeToken() } return modifiers } func (p *Parser) parseJoinTableExpr(_ Pos) (Expr, error) { switch { case p.matchTokenKind(TokenKindIdent), p.matchTokenKind(TokenKindString), p.matchTokenKind(TokenKindLParen): tableExpr, err := p.parseTableExpr(p.Pos()) if err != nil { return nil, err } statementEnd := tableExpr.End() hasFinal := p.matchKeyword(KeywordFinal) if hasFinal { statementEnd = p.End() _ = p.lexer.consumeToken() } sampleRatio, err := p.tryParseSampleClause(p.Pos()) if err != nil { return nil, err } if sampleRatio != nil { statementEnd = sampleRatio.End() } return &JoinTableExpr{ Table: tableExpr, SampleRatio: sampleRatio, HasFinal: hasFinal, StatementEnd: statementEnd, }, nil default: return nil, fmt.Errorf("expected table name or subquery, got %s", fmt.Sprintf("%v", p.lastTokenKind())) } } func (p *Parser) parseJoinRightExpr(pos Pos) (expr Expr, err error) { var rightExpr Expr var modifiers []string switch { case p.tryConsumeKeywords(KeywordGlobal): case p.tryConsumeKeywords(KeywordLocal): case p.tryConsumeTokenKind(TokenKindComma) != nil: return p.parseJoinExpr(p.Pos()) default: modifiers = p.parseJoinOp(p.Pos()) } if len(modifiers) != 0 && !p.matchKeyword(KeywordJoin) { return nil, fmt.Errorf("expected JOIN, got %s", p.lastTokenKind()) } if !p.tryConsumeKeywords(KeywordJoin) { return nil, nil } modifiers = append(modifiers, KeywordJoin) // Check if this is an ARRAY JOIN if slices.Contains(modifiers, KeywordArray) { // For ARRAY JOIN, parse column expression list instead of table expression expr, err = p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } // ARRAY JOIN doesn't have constraints (ON/USING) // try parse next join rightExpr, err = p.parseJoinRightExpr(p.Pos()) if err != nil { return nil, err } return &JoinExpr{ JoinPos: pos, Left: expr, Right: rightExpr, Modifiers: modifiers, Constraints: nil, }, nil } expr, err = p.parseJoinTableExpr(p.Pos()) if err != nil { return nil, err } constrains, err := p.tryParseJoinConstraints(p.Pos()) if err != nil { return nil, err } // try parse next join rightExpr, err = p.parseJoinRightExpr(p.Pos()) if err != nil { return nil, err } return &JoinExpr{ JoinPos: pos, Left: expr, Right: rightExpr, Modifiers: modifiers, Constraints: constrains, }, nil } func (p *Parser) parseJoinExpr(pos Pos) (expr Expr, err error) { if expr, err = p.parseJoinTableExpr(p.Pos()); err != nil { return nil, err } rightExpr, err := p.parseJoinRightExpr(p.Pos()) if err != nil { return nil, err } if rightExpr == nil { return expr, nil } return &JoinExpr{ JoinPos: pos, Left: expr, Right: rightExpr, }, nil } func (p *Parser) parseTableExpr(pos Pos) (*TableExpr, error) { var expr Expr var err error switch { case p.matchTokenKind(TokenKindString), p.matchTokenKind(TokenKindIdent): // table name tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } // it's a table name if tableIdentifier.Database != nil || !p.matchTokenKind(TokenKindLParen) { // database.table expr = tableIdentifier } else { // table function expr tableArgs, err := p.parseTableArgList(p.Pos()) if err != nil { return nil, err } expr = &TableFunctionExpr{ Name: tableIdentifier.Table, Args: tableArgs, } } case p.matchTokenKind(TokenKindLParen): expr, err = p.parseSubQuery(p.Pos()) default: return nil, errors.New("expect table name or subquery") } if err != nil { return nil, err } tableEnd := expr.End() if p.tryConsumeKeywords(KeywordAs) { alias, err := p.parseIdent() if err != nil { return nil, err } expr = &AliasExpr{ Expr: expr, AliasPos: alias.Pos(), Alias: alias, } tableEnd = expr.End() } else if p.matchTokenKind(TokenKindIdent) && p.lastTokenKind() != TokenKindKeyword { alias, err := p.parseIdent() if err != nil { return nil, err } expr = &AliasExpr{ Expr: expr, AliasPos: alias.Pos(), Alias: alias, } tableEnd = expr.End() } isFinalExist := false if p.tryConsumeKeywords(KeywordFinal) { switch expr.(type) { case *TableFunctionExpr: return nil, errors.New("table function doesn't support FINAL") case *SelectQuery: return nil, errors.New("subquery doesn't support FINAL") } isFinalExist = true tableEnd = expr.End() } return &TableExpr{ TablePos: pos, TableEnd: tableEnd, Expr: expr, HasFinal: isFinalExist, }, nil } func (p *Parser) tryParsePrewhereClause(pos Pos) (*PrewhereClause, error) { if !p.matchKeyword(KeywordPrewhere) { return nil, nil } return p.parsePrewhereClause(pos) } func (p *Parser) parsePrewhereClause(pos Pos) (*PrewhereClause, error) { if err := p.expectKeyword(KeywordPrewhere); err != nil { return nil, err } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &PrewhereClause{ PrewherePos: pos, Expr: expr, }, nil } func (p *Parser) tryParseWhereClause(pos Pos) (*WhereClause, error) { if !p.matchKeyword(KeywordWhere) { return nil, nil } return p.parseWhereClause(pos) } func (p *Parser) parseWhereClause(pos Pos) (*WhereClause, error) { if err := p.expectKeyword(KeywordWhere); err != nil { return nil, err } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &WhereClause{ WherePos: pos, Expr: expr, }, nil } func (p *Parser) tryParseGroupByClause(pos Pos) (*GroupByClause, error) { if !p.matchKeyword(KeywordGroup) { return nil, nil } return p.parseGroupByClause(pos) } // syntax: groupByClause? (WITH (CUBE | ROLLUP))? (WITH TOTALS)? func (p *Parser) parseGroupByClause(pos Pos) (*GroupByClause, error) { if err := p.expectKeyword(KeywordGroup); err != nil { return nil, err } if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } var expr Expr var err error aggregateType := "" switch { case p.matchKeyword(KeywordCube) || p.matchKeyword(KeywordRollup): aggregateType = p.last().String _ = p.lexer.consumeToken() expr, err = p.parseFunctionParams(p.Pos()) case p.tryConsumeKeywords(KeywordGrouping, KeywordSets): aggregateType = "GROUPING SETS" expr, err = p.parseFunctionParams(p.Pos()) case p.tryConsumeKeywords(KeywordAll): aggregateType = "ALL" default: expr, err = p.parseColumnExprListWithLParen(p.Pos()) } if err != nil { return nil, err } groupBy := &GroupByClause{ GroupByPos: pos, AggregateType: aggregateType, Expr: expr, } // parse WITH CUBE, ROLLUP, TOTALS for p.tryConsumeKeywords(KeywordWith) { switch { case p.tryConsumeKeywords(KeywordCube): groupBy.WithCube = true case p.tryConsumeKeywords(KeywordRollup): groupBy.WithRollup = true case p.tryConsumeKeywords(KeywordTotals): groupBy.WithTotals = true default: return nil, fmt.Errorf("expected CUBE, ROLLUP or TOTALS, got %s", p.lastTokenKind()) } } groupBy.GroupByEnd = p.Pos() return groupBy, nil } func (p *Parser) tryParseLimitAfterLimitByClause(pos Pos) (*LimitClause, error) { if !p.matchKeyword(KeywordLimit) { return nil, nil } return p.parseLimitClause(pos) } func (p *Parser) tryParseLimitClause(pos Pos) (*LimitClause, error) { if !p.matchKeyword(KeywordLimit) && !p.matchKeyword(KeywordOffset) { return nil, nil } return p.parseLimitClause(pos) } func (p *Parser) parseLimitClause(pos Pos) (*LimitClause, error) { var limit Expr var offset Expr var err error if p.tryConsumeKeywords(KeywordLimit) { limit, err = p.parseExpr(p.Pos()) if err != nil { return nil, err } if p.tryConsumeKeywords(KeywordOffset) { offset, err = p.parseExpr(p.Pos()) } else if p.tryConsumeTokenKind(TokenKindComma) != nil { offset = limit limit, err = p.parseExpr(p.Pos()) } } else if p.tryConsumeKeywords(KeywordOffset) { offset, err = p.parseExpr(p.Pos()) } if err != nil { return nil, err } return &LimitClause{ LimitPos: pos, Limit: limit, Offset: offset, }, nil } func (p *Parser) tryParseLimitByClause(pos Pos) (Expr, error) { if !p.matchKeyword(KeywordLimit) { return nil, nil } return p.parseLimitByClause(pos) } func (p *Parser) parseBetweenClause(expr Expr) (*BetweenClause, error) { if err := p.expectKeyword(KeywordBetween); err != nil { return nil, err } betweenExpr, err := p.parseSubExpr(p.Pos(), PrecedenceBetweenLike) if err != nil { return nil, err } andPos := p.Pos() if err := p.expectKeyword(KeywordAnd); err != nil { return nil, err } andExpr, err := p.parseSubExpr(p.Pos(), PrecedenceBetweenLike) if err != nil { return nil, err } return &BetweenClause{ Expr: expr, Between: betweenExpr, AndPos: andPos, And: andExpr, }, nil } func (p *Parser) parseLimitByClause(pos Pos) (Expr, error) { limit, err := p.parseLimitClause(pos) if err != nil { return nil, err } var by *ColumnExprList if !p.tryConsumeKeywords(KeywordBy) { return limit, nil } if by, err = p.parseColumnExprListWithLParen(p.Pos()); err != nil { return nil, err } return &LimitByClause{ Limit: limit, ByExpr: by, }, nil } func (p *Parser) tryParseWindowFrameClause(pos Pos) (*WindowFrameClause, error) { if !p.matchKeyword(KeywordRows) && !p.matchKeyword(KeywordRange) { return nil, nil } return p.parseWindowFrameClause(pos) } func (p *Parser) parseWindowFrameClause(pos Pos) (*WindowFrameClause, error) { var windowFrameType string if p.matchKeyword(KeywordRows) || p.matchKeyword(KeywordRange) { windowFrameType = p.last().String _ = p.lexer.consumeToken() } else { return nil, fmt.Errorf("expected ROWS or RANGE for window frame") } var expr Expr if p.tryConsumeKeywords(KeywordBetween) { left, err := p.parseFrameExtent() if err != nil { return nil, err } andPos := p.Pos() if err := p.expectKeyword(KeywordAnd); err != nil { return nil, err } right, err := p.parseFrameExtent() if err != nil { return nil, err } expr = &BetweenClause{ Between: left, AndPos: andPos, And: right, } } else { // single extent extent, err := p.parseFrameExtent() if err != nil { return nil, err } expr = extent } return &WindowFrameClause{ FramePos: pos, Type: windowFrameType, Extend: expr, }, nil } // parseFrameExtent parses a single frame extent func (p *Parser) parseFrameExtent() (Expr, error) { switch { case p.matchKeyword(KeywordCurrent): return p.parseFrameCurrentRow() case p.matchKeyword(KeywordUnbounded): return p.parseFrameUnbounded() case p.matchTokenKind(TokenKindInt): return p.parseFrameNumber() case p.matchTokenKind(TokenKindLBrace): return p.parseFrameParam() case p.matchKeyword(KeywordInterval): return p.parseFrameInterval() default: return nil, fmt.Errorf("expected UNBOUNDED, CURRENT ROW, integer, parameter, or interval") } } func (p *Parser) parseFrameCurrentRow() (Expr, error) { currentPos := p.Pos() _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordRow); err != nil { return nil, err } rowEnd := p.End() return &WindowFrameCurrentRow{ CurrentPos: currentPos, RowEnd: rowEnd, }, nil } func (p *Parser) parseFrameUnbounded() (Expr, error) { unboundedPos := p.Pos() _ = p.lexer.consumeToken() direction, err := p.parseFrameDirection() if err != nil { return nil, err } return &WindowFrameUnbounded{ UnboundedPos: unboundedPos, Direction: direction, }, nil } func (p *Parser) parseFrameNumber() (Expr, error) { number, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } direction, endPos, err := p.parseFrameDirectionWithEnd() if err != nil { return nil, err } return &WindowFrameNumber{ EndPos: endPos, Number: number, Direction: direction, }, nil } func (p *Parser) parseFrameParam() (Expr, error) { queryParam, err := p.parseQueryParam(p.Pos()) if err != nil { return nil, err } direction, endPos, err := p.parseFrameDirectionWithEnd() if err != nil { return nil, err } return &WindowFrameParam{ Param: queryParam, EndPos: endPos, Direction: direction, }, nil } func (p *Parser) parseFrameInterval() (Expr, error) { intervalExpr, err := p.parseInterval(true) if err != nil { return nil, err } direction, endPos, err := p.parseFrameDirectionWithEnd() if err != nil { return nil, err } return &WindowFrameExtendExpr{ Expr: intervalExpr, Direction: direction, EndPos: endPos, }, nil } func (p *Parser) parseFrameDirection() (string, error) { switch { case p.matchKeyword(KeywordPreceding), p.matchKeyword(KeywordFollowing): direction := p.last().String _ = p.lexer.consumeToken() return direction, nil default: return "", fmt.Errorf("expected PRECEDING or FOLLOWING, got %s", p.lastTokenKind()) } } func (p *Parser) parseFrameDirectionWithEnd() (string, Pos, error) { if !p.matchKeyword(KeywordPreceding) && !p.matchKeyword(KeywordFollowing) { return "", 0, fmt.Errorf("expected PRECEDING or FOLLOWING, got %s", p.lastTokenKind()) } endPos := p.End() direction := p.last().String _ = p.lexer.consumeToken() return direction, endPos, nil } func (p *Parser) tryParseWindowClause(pos Pos) (*WindowClause, error) { if !p.matchKeyword(KeywordWindow) { return nil, nil } return p.parseWindowClause(pos) } func (p *Parser) parseWindowCondition(pos Pos) (*WindowExpr, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } var windowName *Ident if p.canParseWindowNameInParens() { var err error windowName, err = p.parseIdent() if err != nil { return nil, err } } partitionBy, err := p.tryParsePartitionByClause(pos) if err != nil { return nil, err } orderBy, err := p.tryParseOrderByClause(p.Pos()) if err != nil { return nil, err } frame, err := p.tryParseWindowFrameClause(p.Pos()) if err != nil { return nil, err } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &WindowExpr{ LeftParenPos: pos, RightParenPos: rightParenPos, WindowName: windowName, PartitionBy: partitionBy, OrderBy: orderBy, Frame: frame, }, nil } func (p *Parser) canParseWindowNameInParens() bool { if !p.matchTokenKind(TokenKindIdent) { return false } if !p.matchTokenKind(TokenKindKeyword) { return true } savedState := p.lexer.saveState() defer p.lexer.restoreState(savedState) switch { case p.matchKeyword(KeywordPartition), p.matchKeyword(KeywordOrder): _ = p.lexer.consumeToken() return !p.matchKeyword(KeywordBy) case p.matchKeyword(KeywordRows), p.matchKeyword(KeywordRange): _ = p.lexer.consumeToken() return !p.matchKeyword(KeywordBetween) && !p.matchKeyword(KeywordCurrent) && !p.matchKeyword(KeywordUnbounded) && !p.matchTokenKind(TokenKindInt) && !p.matchTokenKind(TokenKindLBrace) && !p.matchKeyword(KeywordInterval) default: return true } } func (p *Parser) parseWindowClause(pos Pos) (*WindowClause, error) { if err := p.expectKeyword(KeywordWindow); err != nil { return nil, err } windows := make([]*WindowDefinition, 0, 1) for { windowName, err := p.parseIdent() if err != nil { return nil, err } asPos := p.Pos() if err := p.expectKeyword(KeywordAs); err != nil { return nil, err } condition, err := p.parseWindowCondition(p.Pos()) if err != nil { return nil, err } windows = append(windows, &WindowDefinition{ Name: windowName, AsPos: asPos, Expr: condition, }) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } var endPos Pos if len(windows) > 0 { endPos = windows[len(windows)-1].End() } return &WindowClause{ WindowPos: pos, EndPos: endPos, Windows: windows, }, nil } func (p *Parser) tryParseHavingClause(pos Pos) (*HavingClause, error) { if !p.matchKeyword(KeywordHaving) { return nil, nil } return p.parseHavingClause(pos) } func (p *Parser) parseHavingClause(pos Pos) (*HavingClause, error) { if err := p.expectKeyword(KeywordHaving); err != nil { return nil, err } expr, err := p.parseColumnsExpr(p.Pos()) if err != nil { return nil, err } return &HavingClause{ HavingPos: pos, Expr: expr, }, nil } func (p *Parser) parseSubQuery(_ Pos) (*SubQuery, error) { hasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil selectQuery, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } if hasParen { if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } } return &SubQuery{ HasParen: hasParen, Select: selectQuery, }, nil } func (p *Parser) parseSelectQuery(_ Pos) (*SelectQuery, error) { if !p.matchKeyword(KeywordSelect) && !p.matchKeyword(KeywordWith) && !p.matchTokenKind(TokenKindLParen) { return nil, fmt.Errorf("expected SELECT, WITH or (, got %s", p.lastTokenKind()) } hasParen := p.tryConsumeTokenKind(TokenKindLParen) != nil selectStmt, err := p.parseSelectStmt(p.Pos()) if err != nil { return nil, err } switch { case p.tryConsumeKeywords(KeywordUnion): switch { case p.tryConsumeKeywords(KeywordAll): unionAllExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } selectStmt.UnionAll = unionAllExpr case p.tryConsumeKeywords(KeywordDistinct): unionDistinctExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } selectStmt.UnionDistinct = unionDistinctExpr default: return nil, fmt.Errorf("expected ALL or DISTINCT, got %s", p.lastTokenKind()) } case p.tryConsumeKeywords(KeywordExcept): exceptExpr, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } selectStmt.Except = exceptExpr } if hasParen { if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } } return selectStmt, nil } func (p *Parser) parseSelectStmt(pos Pos) (*SelectQuery, error) { // nolint: funlen withClause, err := p.tryParseWithClause(pos) if err != nil { return nil, err } if err := p.expectKeyword(KeywordSelect); err != nil { return nil, err } // DISTINCT? hasDistinct := p.tryConsumeKeywords(KeywordDistinct) distinctOn, err := p.tryParseDistinctOn(p.Pos()) if err != nil { return nil, err } top, err := p.tryParseTopClause(p.Pos()) if err != nil { return nil, err } selectItems, err := p.parseSelectItems() if err != nil { return nil, err } statementEnd := pos if len(selectItems) > 0 { statementEnd = selectItems[len(selectItems)-1].End() } from, err := p.tryParseFromClause(p.Pos()) if err != nil { return nil, err } if from != nil { statementEnd = from.End() } prewhere, err := p.tryParsePrewhereClause(p.Pos()) if err != nil { return nil, err } if prewhere != nil { statementEnd = prewhere.End() } where, err := p.tryParseWhereClause(p.Pos()) if err != nil { return nil, err } if where != nil { statementEnd = where.End() } groupBy, err := p.tryParseGroupByClause(p.Pos()) if err != nil { return nil, err } if groupBy != nil { statementEnd = groupBy.End() } withTotal := false lastPos := p.Pos() if p.tryConsumeKeywords(KeywordWith) { if err := p.expectKeyword(KeywordTotals); err != nil { return nil, err } withTotal = true statementEnd = lastPos } having, err := p.tryParseHavingClause(p.Pos()) if err != nil { return nil, err } if having != nil { statementEnd = having.End() } window, err := p.tryParseWindowClause(p.Pos()) if err != nil { return nil, err } if window != nil { statementEnd = window.End() } orderBy, err := p.tryParseOrderByClause(p.Pos()) if err != nil { return nil, err } if orderBy != nil { statementEnd = orderBy.End() } var limitBy *LimitByClause var limit *LimitClause parsedLimitBy, err := p.tryParseLimitByClause(p.Pos()) if err != nil { return nil, err } if parsedLimitBy != nil { statementEnd = parsedLimitBy.End() switch e := parsedLimitBy.(type) { case *LimitByClause: limitBy = e limit, err = p.tryParseLimitAfterLimitByClause(p.Pos()) if err != nil { return nil, err } if limit != nil { statementEnd = limit.End() } case *LimitClause: limit = e } } else { limit, err = p.tryParseLimitClause(p.Pos()) if err != nil { return nil, err } if limit != nil { statementEnd = limit.End() } } settings, err := p.tryParseSettingsClause(p.Pos()) if err != nil { return nil, err } if settings != nil { statementEnd = settings.End() } format, err := p.tryParseFormat(p.Pos()) if err != nil { return nil, err } if format != nil { statementEnd = format.End() } return &SelectQuery{ With: withClause, SelectPos: pos, StatementEnd: statementEnd, Top: top, HasDistinct: hasDistinct, DistinctOn: distinctOn, SelectItems: selectItems, From: from, Window: window, Prewhere: prewhere, Where: where, GroupBy: groupBy, Having: having, OrderBy: orderBy, LimitBy: limitBy, Limit: limit, Settings: settings, Format: format, WithTotal: withTotal, }, nil } func (p *Parser) parseCTEStmt(pos Pos) (*CTEStmt, error) { expr, err := p.parseExpr(pos) if err != nil { return nil, err } if err := p.expectKeyword(KeywordAs); err != nil { return nil, err } if p.matchTokenKind(TokenKindLParen) { selectQuery, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } return &CTEStmt{ CTEPos: pos, Expr: expr, Alias: selectQuery, }, nil } name, err := p.parseIdent() if err != nil { return nil, err } return &CTEStmt{ CTEPos: pos, Expr: expr, Alias: name, }, nil } func (p *Parser) tryParseSampleClause(pos Pos) (*SampleClause, error) { if !p.matchKeyword(KeywordSample) { return nil, nil } return p.parseSampleClause(pos) } func (p *Parser) parseSampleClause(pos Pos) (*SampleClause, error) { if err := p.expectKeyword(KeywordSample); err != nil { return nil, err } ratio, err := p.parseRatioExpr(p.Pos()) if err != nil { return nil, err } var offset *RatioExpr if p.matchKeyword(KeywordOffset) { _ = p.lexer.consumeToken() offset, err = p.parseRatioExpr(p.Pos()) if err != nil { return nil, err } } return &SampleClause{ SamplePos: pos, Ratio: ratio, Offset: offset, }, nil } func (p *Parser) parseExplainStmt(pos Pos) (*ExplainStmt, error) { if err := p.expectKeyword(KeywordExplain); err != nil { return nil, err } var explainType string switch { case p.matchKeyword(KeywordSyntax), p.matchKeyword(KeywordPipeline), p.matchKeyword(KeywordEstimate), p.matchKeyword(KeywordAst): explainType = p.last().String _ = p.lexer.consumeToken() default: return nil, fmt.Errorf("expected SYNTAX, PIPELINE, ESTIMATE or AST, got %s", p.lastTokenKind()) } stmt, err := p.parseSelectQuery(p.Pos()) if err != nil { return nil, err } return &ExplainStmt{ ExplainPos: pos, Type: explainType, Statement: stmt, }, nil } ================================================ FILE: parser/parser_table.go ================================================ package parser import ( "errors" "fmt" ) func (p *Parser) parseDDL(pos Pos) (DDL, error) { switch { case p.matchKeyword(KeywordCreate), p.matchKeyword(KeywordAttach): _ = p.lexer.consumeToken() orReplace := p.tryConsumeKeywords(KeywordOr, KeywordReplace) if orReplace && !p.matchOneOfKeywords(KeywordTemporary, KeywordTable, KeywordView, KeywordFunction, KeywordDictionary) { return nil, fmt.Errorf("expected keyword: TEMPORARY|TABLE|VIEW|FUNCTION|DICTIONARY, but got %q", p.last().String) } switch { case p.matchKeyword(KeywordNamed): return p.parseCreateNamedCollection(pos) case p.matchKeyword(KeywordDatabase): return p.parseCreateDatabase(pos) case p.matchKeyword(KeywordDictionary): return p.parseCreateDictionary(pos, orReplace) case p.matchKeyword(KeywordTable), p.matchKeyword(KeywordTemporary): return p.parseCreateTable(pos, orReplace) case p.matchKeyword(KeywordFunction): return p.parseCreateFunction(pos, orReplace) case p.matchKeyword(KeywordMaterialized): return p.parseCreateMaterializedView(pos) case p.matchKeyword(KeywordLive): return p.parseCreateLiveView(pos) case p.matchKeyword(KeywordView): return p.parseCreateView(pos, orReplace) case p.matchKeyword(KeywordRole): return p.parseCreateRole(pos) case p.matchKeyword(KeywordUser): return p.parseCreateUser(pos) default: return nil, fmt.Errorf("expected keyword: NAMED|DATABASE|DICTIONARY|TABLE|VIEW|ROLE|USER|FUNCTION|MATERIALIZED, but got %q", p.lastTokenKind()) } case p.matchKeyword(KeywordAlter): _ = p.lexer.consumeToken() switch { case p.matchKeyword(KeywordRole): return p.parseAlterRole(pos) case p.matchKeyword(KeywordTable): return p.parseAlterTable(pos) default: return nil, fmt.Errorf("expected keyword: TABLE|ROLE, but got %q", p.last().String) } case p.matchKeyword(KeywordDrop), p.matchKeyword(KeywordDetach): _ = p.lexer.consumeToken() switch { case p.matchKeyword(KeywordDatabase): return p.parseDropDatabase(pos) case p.matchKeyword(KeywordTemporary), p.matchKeyword(KeywordView), p.matchKeyword(KeywordDictionary), p.matchKeyword(KeywordTable): return p.parseDropStmt(pos) case p.matchKeyword(KeywordUser), p.matchKeyword(KeywordRole): return p.parserDropUserOrRole(pos) default: return nil, fmt.Errorf("expected keyword: DATABASE|TABLE, but got %q", p.last().String) } case p.matchKeyword(KeywordTruncate): return p.parseTruncateTable(pos) case p.matchKeyword(KeywordRename): return p.parseRenameStmt(pos) } return nil, nil // nolint } func (p *Parser) parseCreateDatabase(pos Pos) (*CreateDatabase, error) { if err := p.expectKeyword(KeywordDatabase); err != nil { return nil, err } // try to parse IF NOT EXISTS clause ifNotExists, err := p.tryParseIfNotExists() if err != nil { return nil, err } // parse database name name, err := p.parseIdent() if err != nil { return nil, err } StatementEnd := name.End() onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if onCluster != nil { StatementEnd = onCluster.End() } engineExpr, err := p.tryParseEngineExpr(p.Pos()) if err != nil { return nil, err } if engineExpr != nil { StatementEnd = engineExpr.End() } commentExpr, err := p.tryParseComment() if err != nil { return nil, err } return &CreateDatabase{ CreatePos: pos, StatementEnd: StatementEnd, Name: name, IfNotExists: ifNotExists, OnCluster: onCluster, Engine: engineExpr, Comment: commentExpr, }, nil } func (p *Parser) parseCreateDictionary(pos Pos, orReplace bool) (*CreateDictionary, error) { if err := p.expectKeyword(KeywordDictionary); err != nil { return nil, err } createDict := &CreateDictionary{ CreatePos: pos, OrReplace: orReplace, } // parse IF NOT EXISTS clause if exists var err error createDict.IfNotExists, err = p.tryParseIfNotExists() if err != nil { return nil, err } // parse dictionary name name, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } createDict.Name = name // try parse UUID clause if exists uuid, err := p.tryParseUUID() if err != nil { return nil, err } createDict.UUID = uuid // parse ON CLUSTER clause if exists onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } createDict.OnCluster = onCluster // parse dictionary schema clause (required) schema, err := p.parseDictionarySchemaClause(p.Pos()) if err != nil { return nil, err } createDict.Schema = schema // parse dictionary engine clause (required) engine, err := p.parseDictionaryEngineClause(p.Pos()) if err != nil { return nil, err } createDict.Engine = engine createDict.StatementEnd = engine.End() // parse COMMENT clause if exists comment, err := p.tryParseComment() if err != nil { return nil, err } createDict.Comment = comment if comment != nil { createDict.StatementEnd = comment.End() } return createDict, nil } func (p *Parser) parseCreateNamedCollection(pos Pos) (*CreateNamedCollection, error) { if err := p.expectKeyword(KeywordNamed); err != nil { return nil, err } if err := p.expectKeyword(KeywordCollection); err != nil { return nil, err } createCollection := &CreateNamedCollection{ CreatePos: pos, } // parse IF NOT EXISTS clause if exists var err error createCollection.IfNotExists, err = p.tryParseIfNotExists() if err != nil { return nil, err } // parse collection name name, err := p.parseIdent() if err != nil { return nil, err } createCollection.Name = name // parse ON CLUSTER clause if exists onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } createCollection.OnCluster = onCluster // parse AS keyword if err := p.expectKeyword(KeywordAs); err != nil { return nil, err } // parse parameters params := make([]*NamedCollectionParam, 0) for !p.lexer.isEOF() { param, err := p.parseNamedCollectionParam(p.Pos()) if err != nil { return nil, err } params = append(params, param) // Check if there's another parameter if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } createCollection.Params = params if len(params) > 0 { createCollection.StatementEnd = params[len(params)-1].End() } else if onCluster != nil { createCollection.StatementEnd = onCluster.End() } else { createCollection.StatementEnd = name.End() } return createCollection, nil } func (p *Parser) parseNamedCollectionParam(pos Pos) (*NamedCollectionParam, error) { name, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } // Parse the value - can be string, number, or identifier var value Expr switch { case p.matchTokenKind(TokenKindString): literal, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } value = literal case p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat): literal, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } value = literal case p.matchTokenKind(TokenKindIdent): ident, err := p.parseIdent() if err != nil { return nil, err } value = ident default: return nil, fmt.Errorf("expected string, number or identifier in named collection parameter, got %s", p.lastTokenKind()) } param := &NamedCollectionParam{ ParamPos: pos, Name: name, Value: value, } // Parse optional [NOT] OVERRIDABLE clause if p.tryConsumeKeywords(KeywordNot) { param.NotOverridable = true if err := p.expectKeyword(KeywordOverridable); err != nil { return nil, err } } else if p.tryConsumeKeywords(KeywordOverridable) { param.Overridable = true } return param, nil } func (p *Parser) parseCreateTable(pos Pos, orReplace bool) (*CreateTable, error) { createTable := &CreateTable{CreatePos: pos, OrReplace: orReplace} createTable.HasTemporary = p.tryConsumeKeywords(KeywordTemporary) if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } // parse IF NOT EXISTS clause if exists var err error createTable.IfNotExists, err = p.tryParseIfNotExists() if err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } createTable.Name = tableIdentifier // try parse UUID clause if exists uuid, err := p.tryParseUUID() if err != nil { return nil, err } createTable.UUID = uuid // parse ON CLUSTER clause if exists onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } createTable.OnCluster = onCluster tableSchema, err := p.parseTableSchemaClause(p.Pos()) if err != nil { return nil, err } createTable.TableSchema = tableSchema engineExpr, err := p.tryParseEngineExpr(p.Pos()) if err != nil { return nil, err } if engineExpr != nil { createTable.Engine = engineExpr createTable.StatementEnd = engineExpr.End() } if p.tryConsumeKeywords(KeywordAs) { // After AS, we can have: SELECT/WITH (with or without parens), or table_function(...) // Check if it's a SELECT/WITH query (explicitly check keywords/paren before ident) if p.matchKeyword(KeywordSelect) || p.matchKeyword(KeywordWith) || p.matchTokenKind(TokenKindLParen) { // It's a SELECT or WITH query (with or without parentheses) subQuery, err := p.parseSubQuery(p.Pos()) if err != nil { return nil, err } createTable.SubQuery = subQuery createTable.StatementEnd = subQuery.End() } else if p.matchTokenKind(TokenKindIdent) { // It's a table function: remote(...), remoteSecure(...), etc. ident, err := p.parseIdent() if err != nil { return nil, err } if p.matchTokenKind(TokenKindLParen) { argsExpr, err := p.parseTableArgList(p.Pos()) if err != nil { return nil, err } tableFunc := &TableFunctionExpr{ Name: ident, Args: argsExpr, } createTable.TableFunction = tableFunc createTable.StatementEnd = tableFunc.End() } else { return nil, fmt.Errorf("expected ( after identifier in AS clause, got %q", p.lastTokenKind()) } } else { return nil, fmt.Errorf("expected SELECT, WITH or identifier after AS, got %q", p.lastTokenKind()) } } comment, err := p.tryParseComment() if err != nil { return nil, err } createTable.Comment = comment return createTable, nil } func (p *Parser) parseIdentOrFunction(_ Pos) (Expr, error) { ident, err := p.parseIdent() if err != nil { return nil, err } switch { case p.matchTokenKind(TokenKindLBracket): params, err := p.parseArrayParams(p.Pos()) if err != nil { return nil, err } return &ObjectParams{ Object: ident, Params: params, }, nil case p.matchTokenKind(TokenKindLParen): params, err := p.parseFunctionParams(p.Pos()) if err != nil { return nil, err } funcExpr := &FunctionExpr{ Name: ident, Params: params, } overPos := p.Pos() if p.tryConsumeKeywords(KeywordOver) { var overExpr Expr switch { case p.matchTokenKind(TokenKindIdent): overExpr, err = p.parseIdent() case p.matchTokenKind(TokenKindLParen): overExpr, err = p.parseWindowCondition(p.Pos()) if err != nil { return nil, err } default: return nil, fmt.Errorf("expected window name or (, but got %q", p.lastTokenKind()) } if err != nil { return nil, err } return &WindowFunctionExpr{ Function: funcExpr, OverPos: overPos, OverExpr: overExpr, }, nil } return funcExpr, nil case p.tryConsumeTokenKind(TokenKindDot) != nil: switch { case p.matchTokenKind(TokenKindIdent): fields := []*Ident{ident} for { child, err := p.parseIdent() if err != nil { return nil, err } fields = append(fields, child) if p.tryConsumeTokenKind(TokenKindDot) == nil { break } } return &Path{Fields: fields}, nil case p.matchTokenKind("*"): nextIdent, err := p.parseColumnStar(p.Pos()) if err != nil { return nil, err } return &NestedIdentifier{ Ident: ident, DotIdent: nextIdent, }, nil case p.matchTokenKind(TokenKindInt): i, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } return &IndexOperation{ Object: ident, Operation: TokenKindDot, Index: i, }, nil default: return nil, fmt.Errorf("expected IDENT, NUMBER or *, but got %q", p.lastTokenKind()) } } return ident, nil } func (p *Parser) parseTableIdentifier(_ Pos) (*TableIdentifier, error) { ident, err := p.parseIdentOrString() if err != nil { return nil, err } dotIdent, err := p.tryParseDotIdentOrString(p.Pos()) if err != nil { return nil, err } if dotIdent != nil { return &TableIdentifier{ Database: ident, Table: dotIdent, }, nil } return &TableIdentifier{ Table: ident, }, nil } func (p *Parser) parseTableSchemaClause(pos Pos) (*TableSchemaClause, error) { switch { case p.matchTokenKind(TokenKindLParen): // parse column definitions if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } columns, err := p.parseTableColumns() if err != nil { return nil, err } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &TableSchemaClause{ SchemaPos: pos, SchemaEnd: rightParenPos, Columns: columns, }, nil case p.matchKeyword(KeywordAs) && !p.peekKeyword(KeywordSelect) && !p.peekKeyword(KeywordWith) && !p.peekTokenKind(TokenKindLParen): // Handle AS only if followed by identifier (not SELECT/WITH/LPAREN) // This handles: AS ident, AS ident.ident, AS ident(...) // CREATE TABLE will handle: AS SELECT, AS WITH, AS (SELECT ...) p.tryConsumeKeywords(KeywordAs) ident, err := p.parseIdent() if err != nil { return nil, err } switch { case p.matchTokenKind(TokenKindDot): // it's a database.table dotIdent, err := p.tryParseDotIdent(p.Pos()) if err != nil { return nil, err } return &TableSchemaClause{ SchemaPos: pos, SchemaEnd: dotIdent.End(), AliasTable: &TableIdentifier{ Database: ident, Table: dotIdent, }, }, nil case p.matchTokenKind(TokenKindLParen): // it's a table function argsExpr, err := p.parseTableArgList(pos) if err != nil { return nil, err } return &TableSchemaClause{ SchemaPos: pos, SchemaEnd: p.End(), TableFunction: &TableFunctionExpr{ Name: ident, Args: argsExpr, }, }, nil default: return &TableSchemaClause{ SchemaPos: pos, SchemaEnd: p.End(), AliasTable: &TableIdentifier{ Table: ident, }, }, nil } } // no schema is ok for MATERIALIZED VIEW return nil, nil } func (p *Parser) parseTableColumns() ([]Expr, error) { columns := make([]Expr, 0) for !p.lexer.isEOF() { switch { case p.matchKeyword(KeywordIndex): indexPos := p.Pos() _ = p.lexer.consumeToken() index, err := p.parseTableIndex(indexPos) if err != nil { return nil, err } columns = append(columns, index) case p.matchKeyword(KeywordConstraint): constraintPos := p.Pos() _ = p.lexer.consumeToken() ident, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectKeyword(KeywordCheck); err != nil { return nil, err } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } columns = append(columns, &ConstraintClause{ ConstraintPos: constraintPos, Constraint: ident, Expr: expr, }) case p.matchKeyword(KeywordProjection): projection, err := p.parseTableProjection(p.Pos(), true) if err != nil { return nil, err } columns = append(columns, projection) default: column, err := p.tryParseTableColumnExpr(p.Pos()) if err != nil { return nil, err } if column == nil { break } columns = append(columns, column) } if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } // end of column definitions return columns, nil } func (p *Parser) tryParseTableColumnExpr(pos Pos) (*ColumnDef, error) { if !p.matchTokenKind(TokenKindIdent) { return nil, nil // nolint } return p.parseTableColumnExpr(pos) } func (p *Parser) parseTableColumnExpr(pos Pos) (*ColumnDef, error) { // Not a column definition, just return column := &ColumnDef{NamePos: pos} // parse column name name, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } column.Name = name columnEnd := name.End() if p.matchTokenKind(TokenKindIdent) && !p.matchKeyword(KeywordRemove) { columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } column.Type = columnType columnEnd = columnType.End() } nullable := p.tryParseNull(p.Pos()) if nullable != nil { columnEnd = nullable.End() } notNull, err := p.tryParseNotNull(p.Pos()) if err != nil { return nil, err } if notNull != nil { columnEnd = notNull.End() } switch { case p.tryConsumeKeywords(KeywordDefault): column.DefaultExpr, err = p.parseExpr(p.Pos()) columnEnd = column.DefaultExpr.End() case p.tryConsumeKeywords(KeywordMaterialized): column.MaterializedExpr, err = p.parseExpr(p.Pos()) columnEnd = column.MaterializedExpr.End() case p.tryConsumeKeywords(KeywordAlias): column.AliasExpr, err = p.parseExpr(p.Pos()) columnEnd = column.AliasExpr.End() } if err != nil { return nil, err } comment, err := p.tryParseColumnComment(p.Pos()) if err != nil { return nil, err } if comment != nil { columnEnd = comment.End() } codec, err := p.tryParseCompressionCodecs(p.Pos()) if err != nil { return nil, err } if codec != nil { columnEnd = codec.End() } ttl, err := p.tryParseTTLClause(p.Pos(), false) if err != nil { return nil, err } if ttl != nil { columnEnd = ttl.End() } column.TTL = ttl column.ColumnEnd = columnEnd column.Comment = comment column.Codec = codec column.Nullable = nullable column.NotNull = notNull return column, nil } func (p *Parser) parseTableArgExpr(pos Pos) (Expr, error) { switch { case p.matchTokenKind(TokenKindIdent): ident, err := p.parseIdent() if err != nil { return nil, err } switch { // nest identifier case p.matchTokenKind(TokenKindDot): dotIdent, err := p.tryParseDotIdent(p.Pos()) if err != nil { return nil, err } return &NestedIdentifier{ Ident: ident, DotIdent: dotIdent, }, nil case p.matchTokenKind(TokenKindLParen): argsExpr, err := p.parseTableArgList(pos) if err != nil { return nil, err } return &TableFunctionExpr{ Name: ident, Args: argsExpr, }, nil default: return ident, nil } case p.matchTokenKind(TokenKindLParen): return p.parseSubQuery(p.Pos()) case p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindString), p.matchKeyword(KeywordNull): return p.parseLiteral(p.Pos()) default: return nil, fmt.Errorf("unexpected token: %q, expected , ", p.last().String) } } func (p *Parser) parseTableArgList(pos Pos) (*TableArgListExpr, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } args := make([]Expr, 0) for !p.lexer.isEOF() { // Check if this is a named parameter (identifier followed by =) var arg Expr var err error // Try to detect named parameter pattern: last token is identifier, next token is = isNamedParam := false lastKind := p.lastTokenKind() if lastKind == TokenKindIdent || lastKind == TokenKindKeyword { // Last token is an identifier, peek at the next token nextToken, peekErr := p.lexer.peekToken() if peekErr == nil && nextToken != nil && nextToken.Kind == TokenKindSingleEQ { isNamedParam = true } } if isNamedParam { // Parse as named parameter - the identifier is already the last token // We need to get it, consume the =, and parse the value name := &Ident{ NamePos: p.last().Pos, NameEnd: p.last().End, Name: p.last().String, } // Consume the = token if err := p.lexer.consumeToken(); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } // Parse the value value, err := p.parseTableArgExpr(p.Pos()) if err != nil { return nil, err } arg = &NamedParameterExpr{ NamePos: name.NamePos, Name: name, Value: value, } } else { // Parse as regular table arg expression arg, err = p.parseTableArgExpr(p.Pos()) } if err != nil { return nil, err } args = append(args, arg) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &TableArgListExpr{ LeftParenPos: pos, RightParenPos: rightParenPos, Args: args, }, nil } func (p *Parser) tryParseClusterClause(pos Pos) (*ClusterClause, error) { if !p.tryConsumeKeywords(KeywordOn) { return nil, nil // nolint } if err := p.expectKeyword(KeywordCluster); err != nil { return nil, err } var expr Expr var err error switch { case p.matchTokenKind(TokenKindIdent): expr, err = p.parseIdent() case p.matchTokenKind(TokenKindString): expr, err = p.parseString(p.Pos()) default: return nil, fmt.Errorf("unexpected token: %q, expected or ", p.last().String) } if err != nil { return nil, err } return &ClusterClause{ OnPos: pos, Expr: expr, }, nil } func (p *Parser) tryParsePartitionByClause(pos Pos) (*PartitionByClause, error) { if !p.tryConsumeKeywords(KeywordPartition) { return nil, nil // nolint } if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } // parse partition key list columnExpr, err := p.parseColumnExprListWithLParen(p.Pos()) if err != nil { return nil, err } return &PartitionByClause{ PartitionPos: pos, Expr: columnExpr, }, nil } func (p *Parser) tryParsePrimaryKeyClause(pos Pos) (*PrimaryKeyClause, error) { if !p.tryConsumeKeywords(KeywordPrimary) { return nil, nil // nolint } if err := p.expectKeyword(KeywordKey); err != nil { return nil, err } // parse partition key list columnExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &PrimaryKeyClause{ PrimaryPos: pos, Expr: columnExpr, }, nil } func (p *Parser) tryParseOrderByClause(pos Pos) (*OrderByClause, error) { if !p.tryConsumeKeywords(KeywordOrder) { return nil, nil // nolint } if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } return p.parseOrderByClause(pos) } func (p *Parser) parseOrderByClause(pos Pos) (*OrderByClause, error) { orderByListExpr := &OrderByClause{OrderPos: pos, ListEnd: pos} items := make([]Expr, 0) for { expr, err := p.parseOrderExpr(pos) if err != nil { return nil, err } if expr == nil { break } items = append(items, expr) if p.lexer.isEOF() || p.tryConsumeTokenKind(TokenKindComma) == nil { break } } if len(items) > 0 { orderByListExpr.ListEnd = items[len(items)-1].End() } orderByListExpr.Items = items // Parse optional INTERPOLATE clause if p.matchKeyword(KeywordInterpolate) { interpolatePos := p.Pos() _ = p.lexer.consumeToken() interpolate, err := p.parseInterpolateClause(interpolatePos) if err != nil { return nil, err } orderByListExpr.Interpolate = interpolate orderByListExpr.ListEnd = interpolate.End() } return orderByListExpr, nil } func (p *Parser) parseOrderExpr(pos Pos) (*OrderExpr, error) { // parse column expr columnExpr, err := p.parseExpr(pos) if err != nil { return nil, err } var alias *Ident if p.matchKeyword(KeywordAs) { // It should be a subquery instead of an order by alias if the `AS` is followed by `SELECT` keyword. if nextToken, err := p.lexer.peekToken(); err == nil && nextToken.ToString() == KeywordSelect { return &OrderExpr{ OrderPos: pos, Expr: columnExpr, }, nil } // consume the `AS` keyword _ = p.lexer.consumeToken() alias, err = p.parseIdent() if err != nil { return nil, err } } else if p.matchKeyword(KeywordTtl) { return &OrderExpr{ OrderPos: pos, Expr: columnExpr, }, nil } direction := OrderDirectionNone switch { case p.matchKeyword(KeywordAsc), p.matchKeyword(KeywordAscending): direction = OrderDirectionAsc _ = p.lexer.consumeToken() case p.matchKeyword(KeywordDesc), p.matchKeyword(KeywordDescending): direction = OrderDirectionDesc _ = p.lexer.consumeToken() } // Parse optional WITH FILL clause var fill *Fill if p.tryConsumeKeywords(KeywordWith, KeywordFill) { fillPos := p.Pos() fill, err = p.parseFillClause(fillPos) if err != nil { return nil, err } } return &OrderExpr{ OrderPos: pos, Alias: alias, Expr: columnExpr, Direction: direction, Fill: fill, }, nil } func (p *Parser) parseFillClause(fillPos Pos) (*Fill, error) { fill := &Fill{FillPos: fillPos} // Parse optional FROM clause if p.tryConsumeKeywords(KeywordFrom) { fromExpr, err := p.parseExpr(fillPos) if err != nil { return nil, err } fill.From = fromExpr } // Parse optional TO clause if p.tryConsumeKeywords(KeywordTo) { toExpr, err := p.parseExpr(fillPos) if err != nil { return nil, err } fill.To = toExpr } // Parse optional STEP clause if p.tryConsumeKeywords(KeywordStep) { stepExpr, err := p.parseExpr(fillPos) if err != nil { return nil, err } fill.Step = stepExpr } // Parse optional STALENESS clause if p.tryConsumeKeywords(KeywordStaleness) { stalenessExpr, err := p.parseExpr(fillPos) if err != nil { return nil, err } fill.Staleness = stalenessExpr } return fill, nil } func (p *Parser) parseInterpolateClause(interpolatePos Pos) (*InterpolateClause, error) { interpolate := &InterpolateClause{ InterpolatePos: interpolatePos, ListEnd: interpolatePos + Pos(len("INTERPOLATE")), } if p.tryConsumeTokenKind(TokenKindLParen) == nil { // INTERPOLATE without columns is valid return interpolate, nil } items := make([]*InterpolateItem, 0) for { column, err := p.parseIdent() if err != nil { return nil, err } item := &InterpolateItem{Column: column} if p.tryConsumeKeywords(KeywordAs) { expr, err := p.parseExpr(interpolatePos) if err != nil { return nil, err } item.Expr = expr } items = append(items, item) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rparen := p.tryConsumeTokenKind(TokenKindRParen) if rparen == nil { return nil, fmt.Errorf("expected ')' after INTERPOLATE column list") } interpolate.Items = items interpolate.ListEnd = rparen.End return interpolate, nil } func (p *Parser) tryParseTTLClause(pos Pos, allowMultiValues bool) (*TTLClause, error) { if !p.tryConsumeKeywords(KeywordTtl) { return nil, nil // nolint } ttlExprList := &TTLClause{TTLPos: pos, ListEnd: pos} // accept the TTL keyword items, err := p.parseTTLClause(pos, allowMultiValues) if err != nil { return nil, err } if len(items) > 0 { ttlExprList.ListEnd = items[len(items)-1].End() } ttlExprList.Items = items return ttlExprList, nil } // parseTTLClause parses the TTL clause. // allowMultiValues is used to determine whether to allow multiple TTL values. func (p *Parser) parseTTLClause(pos Pos, allowMultiValues bool) ([]*TTLExpr, error) { items := make([]*TTLExpr, 0) expr, err := p.parseTTLExpr(pos) if err != nil { return nil, err } items = append(items, expr) for allowMultiValues && !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindComma) != nil { expr, err = p.parseTTLExpr(pos) if err != nil { return nil, err } items = append(items, expr) } return items, nil } func (p *Parser) tryParseTTLPolicy(pos Pos) (*TTLPolicy, error) { var rule *TTLPolicyRule switch { case p.tryConsumeKeywords(KeywordTo): if p.tryConsumeKeywords(KeywordDisk) { value, err := p.parseString(p.Pos()) if err != nil { return nil, err } rule = &TTLPolicyRule{RulePos: pos, ToDisk: value} } else if p.tryConsumeKeywords(KeywordVolume) { value, err := p.parseString(p.Pos()) if err != nil { return nil, err } rule = &TTLPolicyRule{RulePos: pos, ToVolume: value} } else { return nil, fmt.Errorf("unexpected token: %q, expected DISK or VOLUME", p.lastTokenKind()) } case p.matchKeyword(KeywordDelete), p.matchKeyword(KeywordRecompress): token := p.last() _ = p.lexer.consumeToken() action := &TTLPolicyRuleAction{ ActionPos: token.Pos, ActionEnd: token.End, Action: token.ToString(), } codec, err := p.tryParseCompressionCodecs(p.Pos()) if err != nil { return nil, err } action.Codec = codec rule = &TTLPolicyRule{RulePos: pos, Action: action} default: return nil, nil // nolint } policy := &TTLPolicy{Item: rule} where, err := p.tryParseWhereClause(p.Pos()) if err != nil { return nil, err } policy.Where = where groupBy, err := p.tryParseGroupByClause(p.Pos()) if err != nil { return nil, err } policy.GroupBy = groupBy return policy, nil } func (p *Parser) parseTTLExpr(pos Pos) (*TTLExpr, error) { columnExpr, err := p.parseExpr(pos) if err != nil { return nil, err } policy, err := p.tryParseTTLPolicy(p.Pos()) if err != nil { return nil, err } return &TTLExpr{ TTLPos: pos, Expr: columnExpr, Policy: policy, }, nil } func (p *Parser) tryParseSampleByClause(pos Pos) (*SampleByClause, error) { if !p.tryConsumeKeywords(KeywordSample) { return nil, nil // nolint } if err := p.expectKeyword(KeywordBy); err != nil { return nil, err } // parse sample by expr columnExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &SampleByClause{ SamplePos: pos, Expr: columnExpr, }, nil } func (p *Parser) tryParseSettingsClause(pos Pos) (*SettingsClause, error) { if !p.tryConsumeKeywords(KeywordSettings) { return nil, nil // nolint } return p.parseSettingsClause(pos) } func (p *Parser) parseSettingsClause(pos Pos) (*SettingsClause, error) { settings := &SettingsClause{SettingsPos: pos, ListEnd: pos} items, err := p.parseSettingsList(p.Pos()) if err != nil { return nil, err } if len(items) == 0 { return nil, fmt.Errorf("settings list is empty") } settings.ListEnd = items[len(items)-1].End() settings.Items = items return settings, nil } func (p *Parser) parseSettingsList(pos Pos) ([]*SettingExpr, error) { items := make([]*SettingExpr, 0) expr, err := p.parseSettingsExpr(pos) if err != nil { return nil, err } items = append(items, expr) for p.tryConsumeTokenKind(TokenKindComma) != nil { expr, err = p.parseSettingsExpr(p.Pos()) if err != nil { return nil, err } items = append(items, expr) } return items, nil } func (p *Parser) parseSettingsExpr(pos Pos) (*SettingExpr, error) { ident, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } var expr Expr switch { case p.matchTokenKind(TokenKindInt): number, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } expr = number case p.matchTokenKind(TokenKindString): str, err := p.parseString(p.Pos()) expr = str if err != nil { return nil, err } case p.matchTokenKind(TokenKindLBrace): m, err := p.parseMapLiteral(p.Pos()) if err != nil { return nil, err } expr = m case p.matchKeyword(KeywordTrue), p.matchKeyword(KeywordFalse): // Handle TRUE/FALSE keywords as boolean literals lastToken := p.last() _ = p.lexer.consumeToken() expr = &BoolLiteral{ LiteralPos: lastToken.Pos, LiteralEnd: lastToken.End, Literal: lastToken.String, } default: return nil, fmt.Errorf("unexpected token: %q, expected , or ", p.last().String) } return &SettingExpr{ SettingsPos: pos, Name: ident, Expr: expr, }, nil } func (p *Parser) parseDestinationClause(pos Pos) (*DestinationClause, error) { if err := p.expectKeyword(KeywordTo); err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &DestinationClause{ ToPos: pos, TableIdentifier: tableIdentifier, }, nil } func (p *Parser) tryParseEngineExpr(pos Pos) (*EngineExpr, error) { if !p.matchKeyword(KeywordEngine) { return nil, nil // nolint } return p.parseEngineExpr(pos) } func (p *Parser) parseEngineExpr(pos Pos) (*EngineExpr, error) { if err := p.expectKeyword(KeywordEngine); err != nil { return nil, err } _ = p.tryConsumeTokenKind(TokenKindSingleEQ) engineExpr := &EngineExpr{EnginePos: pos} var engineEnd Pos switch { case p.matchTokenKind(TokenKindIdent): ident, err := p.parseIdent() if err != nil { return nil, err } engineExpr.Name = ident.Name engineEnd = ident.End() if p.matchTokenKind(TokenKindLParen) { params, err := p.parseFunctionParams(p.Pos()) if err != nil { return nil, err } engineExpr.Params = params engineExpr.EngineEnd = params.End() } default: return nil, fmt.Errorf("unexpected token: %s", p.lastTokenKind()) } for !p.lexer.isEOF() { switch { case p.matchKeyword(KeywordOrder): orderBy, err := p.tryParseOrderByClause(p.Pos()) if err != nil { return nil, err } engineExpr.OrderBy = orderBy engineEnd = orderBy.End() case p.matchKeyword(KeywordPartition): partitionBy, err := p.tryParsePartitionByClause(p.Pos()) if err != nil { return nil, err } engineExpr.PartitionBy = partitionBy engineEnd = partitionBy.End() case p.matchKeyword(KeywordPrimary): primaryKey, err := p.tryParsePrimaryKeyClause(p.Pos()) if err != nil { return nil, err } engineExpr.PrimaryKey = primaryKey engineEnd = primaryKey.End() case p.matchKeyword(KeywordSample): sampleBy, err := p.tryParseSampleByClause(p.Pos()) if err != nil { return nil, err } engineExpr.SampleBy = sampleBy engineEnd = sampleBy.End() case p.matchKeyword(KeywordTtl): ttl, err := p.tryParseTTLClause(p.Pos(), true) if err != nil { return nil, err } engineExpr.TTL = ttl engineEnd = ttl.End() case p.matchKeyword(KeywordSettings): settingsClause, err := p.tryParseSettingsClause(p.Pos()) if err != nil { return nil, err } engineExpr.Settings = settingsClause engineEnd = settingsClause.End() default: engineExpr.EngineEnd = engineEnd return engineExpr, nil } } engineExpr.EngineEnd = engineEnd return engineExpr, nil } func (p *Parser) parseStmt(pos Pos) (Expr, error) { var err error var expr Expr switch { case p.matchKeyword(KeywordCreate), p.matchKeyword(KeywordAttach), p.matchKeyword(KeywordAlter), p.matchKeyword(KeywordDrop), p.matchKeyword(KeywordDetach), p.matchKeyword(KeywordTruncate), p.matchKeyword(KeywordRename): expr, err = p.parseDDL(pos) case p.matchKeyword(KeywordSelect), p.matchKeyword(KeywordWith): expr, err = p.parseSelectQuery(pos) case p.matchKeyword(KeywordDelete): expr, err = p.parseDeleteClause(pos) case p.matchKeyword(KeywordInsert): expr, err = p.parseInsertStmt(p.Pos()) case p.matchKeyword(KeywordUse): expr, err = p.parseUseStmt(pos) case p.matchKeyword(KeywordSet): expr, err = p.parseSetStmt(pos) case p.matchKeyword(KeywordSettings): expr, err = p.parseSettingsStmt(pos) case p.matchKeyword(KeywordSystem): expr, err = p.parseSystemStmt(pos) case p.matchKeyword(KeywordOptimize): expr, err = p.parseOptimizeStmt(pos) case p.matchKeyword(KeywordCheck): expr, err = p.parseCheckStmt(pos) case p.matchKeyword(KeywordExplain): expr, err = p.parseExplainStmt(pos) case p.matchKeyword(KeywordGrant): expr, err = p.parseGrantPrivilegeStmt(pos) case p.matchKeyword(KeywordShow): expr, err = p.parseShowStmt(pos) case p.matchKeyword(KeywordDesc), p.matchKeyword(KeywordDescribe): expr, err = p.parseDescribeStmt(pos) default: if p.last() == nil { return nil, errors.New("unexpected end of input") } return nil, fmt.Errorf("unexpected token: %q", p.last().String) } if err != nil { return nil, err } _, err = p.tryParseFormat(p.Pos()) if err != nil { return nil, err } // Statement can be terminated by ';' or EOF if p.last() != nil && !p.matchTokenKind(";") { return nil, fmt.Errorf(" or ';' was expected, but got: %q", p.last().String) } return expr, nil } func (p *Parser) ParseStmts() ([]Expr, error) { var stmts []Expr for { if err := p.lexer.consumeToken(); err != nil { return nil, p.wrapError(err) } if p.lexer.isEOF() { break } if p.matchTokenKind(";") { continue } stmt, err := p.parseStmt(p.Pos()) if err != nil { return nil, p.wrapError(err) } stmts = append(stmts, stmt) } return stmts, nil } func (p *Parser) parseUseStmt(pos Pos) (*UseStmt, error) { if err := p.expectKeyword(KeywordUse); err != nil { return nil, err } database, err := p.parseIdent() if err != nil { return nil, err } return &UseStmt{ UsePos: pos, Database: database, StatementEnd: database.End(), }, nil } func (p *Parser) parseShowStmt(pos Pos) (*ShowStmt, error) { if err := p.expectKeyword(KeywordShow); err != nil { return nil, err } var showType string var target *TableIdentifier // Parse the type of SHOW statement switch { case p.matchKeyword(KeywordCreate): // SHOW CREATE TABLE table_name showType = "CREATE" _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } showType += " TABLE" tableIdent, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } target = tableIdent case p.matchKeyword(KeywordDatabases): // SHOW DATABASES [optional clauses] showType = "DATABASES" _ = p.lexer.consumeToken() case p.matchKeyword(KeywordTables): // SHOW TABLES showType = "TABLES" _ = p.lexer.consumeToken() default: return nil, fmt.Errorf("expected CREATE, DATABASES, or TABLES after SHOW, got %q", p.last().String) } stmt := &ShowStmt{ ShowPos: pos, ShowType: showType, Target: target, } // Parse optional clauses for SHOW DATABASES if showType == "DATABASES" { // Parse [[NOT] LIKE | ILIKE ''] if p.matchKeyword(KeywordNot) { stmt.NotLike = true _ = p.lexer.consumeToken() } if p.matchKeyword(KeywordLike) || p.matchKeyword(KeywordIlike) { if p.matchKeyword(KeywordLike) { stmt.LikeType = "LIKE" } else { stmt.LikeType = "ILIKE" } _ = p.lexer.consumeToken() // Parse pattern expression pattern, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } stmt.LikePattern = pattern } // Parse [LIMIT ] if p.matchKeyword(KeywordLimit) { _ = p.lexer.consumeToken() limit, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } stmt.Limit = limit } // Parse [INTO OUTFILE filename] if p.matchKeyword(KeywordInto) { _ = p.lexer.consumeToken() if err := p.expectKeyword(KeywordOutfile); err != nil { return nil, err } // Parse filename as a string literal outFile, err := p.parseString(p.Pos()) if err != nil { return nil, err } stmt.OutFile = outFile } // Parse [FORMAT format] if p.matchKeyword(KeywordFormat) { _ = p.lexer.consumeToken() // Format can be an identifier or a string if p.matchTokenKind(TokenKindString) { format, err := p.parseString(p.Pos()) if err != nil { return nil, err } stmt.Format = format } else if p.matchTokenKind(TokenKindIdent) { // Handle format as identifier (like JSON, CSV, etc.) token := p.last() _ = p.lexer.consumeToken() stmt.Format = &StringLiteral{ LiteralPos: token.Pos, LiteralEnd: token.End, Literal: token.String, } } else { return nil, fmt.Errorf("expected format specification after FORMAT, got %q", p.last().String) } } } // Set statement end position stmt.StatementEnd = p.End() return stmt, nil } func (p *Parser) parseDescribeStmt(pos Pos) (*DescribeStmt, error) { // DESC and DESCRIBE are both supported if !p.matchKeyword(KeywordDesc) && !p.matchKeyword(KeywordDescribe) { return nil, fmt.Errorf("expected DESC or DESCRIBE") } _ = p.lexer.consumeToken() // TABLE keyword is optional after DESC/DESCRIBE var describeType string if p.matchKeyword(KeywordTable) { _ = p.lexer.consumeToken() describeType = "TABLE" } tableIdent, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &DescribeStmt{ DescribePos: pos, StatementEnd: tableIdent.End(), DescribeType: describeType, Target: tableIdent, }, nil } // syntax: TRUNCATE TEMPORARY? TABLE (IF EXISTS)? tableIdentifier clusterClause?; func (p *Parser) parseTruncateTable(pos Pos) (*TruncateTable, error) { if err := p.expectKeyword(KeywordTruncate); err != nil { return nil, err } isTemporary := p.tryConsumeKeywords(KeywordTemporary) if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } ifExists, err := p.tryParseIfExists() if err != nil { return nil, err } tableName, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } truncateTable := &TruncateTable{ TruncatePos: pos, IsTemporary: isTemporary, IfExists: ifExists, Name: tableName, OnCluster: onCluster, StatementEnd: tableName.End(), } if onCluster != nil { truncateTable.StatementEnd = onCluster.End() } return truncateTable, nil } func (p *Parser) parseDeleteClause(pos Pos) (*DeleteClause, error) { if err := p.expectKeyword(KeywordDelete); err != nil { return nil, err } if err := p.expectKeyword(KeywordFrom); err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if err := p.expectKeyword(KeywordWhere); err != nil { return nil, err } whereExpr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &DeleteClause{ DeletePos: pos, Table: tableIdentifier, OnCluster: onCluster, WhereExpr: whereExpr, }, nil } func (p *Parser) parseColumnNamesExpr(pos Pos) (*ColumnNamesExpr, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } var columnNames []NestedIdentifier for !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindRParen) == nil { name, err := p.ParseNestedIdentifier(p.Pos()) if err != nil { return nil, err } columnNames = append(columnNames, *name) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &ColumnNamesExpr{ LeftParenPos: pos, RightParenPos: rightParenPos, ColumnNames: columnNames, }, nil } func (p *Parser) parseTypedPlaceholder(pos Pos) (Expr, error) { if err := p.expectTokenKind(TokenKindLBrace); err != nil { return nil, err } name, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindColon); err != nil { return nil, err } columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindRBrace); err != nil { return nil, err } return &TypedPlaceholder{ LeftBracePos: pos, RightBracePos: p.Pos(), Name: name, Type: columnType, }, nil } func (p *Parser) parseAssignmentValues(pos Pos) (*AssignmentValues, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } var value Expr var err error values := make([]Expr, 0) for !p.lexer.isEOF() && p.tryConsumeTokenKind(TokenKindRParen) == nil { switch { case p.matchTokenKind(TokenKindLParen): value, err = p.parseAssignmentValues(p.Pos()) case p.matchTokenKind(TokenKindLBrace): // placeholder with type, e.g. {a :Int32}, {b :DateTime(6)} value, err = p.parseTypedPlaceholder(p.Pos()) default: value, err = p.parseExpr(p.Pos()) } if err != nil { return nil, err } values = append(values, value) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } rightParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &AssignmentValues{ LeftParenPos: pos, RightParenPos: rightParenPos, Values: values, }, nil } func (p *Parser) parseInsertStmt(pos Pos) (*InsertStmt, error) { if err := p.expectKeyword(KeywordInsert); err != nil { return nil, err } if err := p.expectKeyword(KeywordInto); err != nil { return nil, err } insertExpr := &InsertStmt{InsertPos: pos} insertExpr.HasTableKeyword = p.tryConsumeKeywords(KeywordTable) var table Expr var err error if p.tryConsumeKeywords(KeywordFunction) { table, err = p.parseFunctionExpr(p.Pos()) } else { table, err = p.parseTableIdentifier(p.Pos()) } if err != nil { return nil, err } insertExpr.Table = table if p.matchTokenKind(TokenKindLParen) { // parse column names insertExpr.ColumnNames, err = p.parseColumnNamesExpr(p.Pos()) if err != nil { return nil, err } } switch { case p.matchKeyword(KeywordFormat): insertExpr.Format, err = p.parseFormat(p.Pos()) case p.matchKeyword(KeywordValues): // consume VALUES keyword _ = p.lexer.consumeToken() values := make([]*AssignmentValues, 0) for !p.lexer.isEOF() { value, err := p.parseAssignmentValues(p.Pos()) if err != nil { return nil, err } values = append(values, value) if p.tryConsumeTokenKind(TokenKindComma) == nil { break } } insertExpr.Values = values case p.matchKeyword(KeywordSelect): insertExpr.SelectExpr, err = p.parseSelectQuery(p.Pos()) default: // do nothing } if err != nil { return nil, err } return insertExpr, nil } func (p *Parser) parseRenameStmt(pos Pos) (*RenameStmt, error) { if err := p.expectKeyword(KeywordRename); err != nil { return nil, err } renameTarget := KeywordTable switch { case p.tryConsumeKeywords(KeywordDictionary): renameTarget = KeywordDictionary case p.tryConsumeKeywords(KeywordDatabase): renameTarget = KeywordDatabase default: if err := p.expectKeyword(KeywordTable); err != nil { return nil, err } } targetPair, err := p.parseTargetPair(p.Pos()) if err != nil { return nil, err } tablePairList := []*TargetPair{targetPair} for p.tryConsumeTokenKind(TokenKindComma) != nil { tablePair, err := p.parseTargetPair(p.Pos()) if err != nil { return nil, err } tablePairList = append(tablePairList, tablePair) } renameStmt := &RenameStmt{ RenamePos: pos, StatementEnd: tablePairList[len(tablePairList)-1].End(), RenameTarget: renameTarget, TargetPairList: tablePairList, } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if onCluster != nil { renameStmt.OnCluster = onCluster renameStmt.StatementEnd = onCluster.End() } return renameStmt, nil } func (p *Parser) parseTargetPair(_ Pos) (*TargetPair, error) { oldTable, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } if err = p.expectKeyword(KeywordTo); err != nil { return nil, err } newTable, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } return &TargetPair{ Old: oldTable, New: newTable, }, nil } func (p *Parser) parseCreateFunction(pos Pos, orReplace bool) (*CreateFunction, error) { if err := p.expectKeyword(KeywordFunction); err != nil { return nil, err } ifNotExists, err := p.tryParseIfNotExists() if err != nil { return nil, err } functionName, err := p.parseIdent() if err != nil { return nil, err } onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } if err := p.expectKeyword(KeywordAs); err != nil { return nil, err } params, err := p.parseFunctionParams(p.Pos()) if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindArrow); err != nil { return nil, err } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } return &CreateFunction{ CreatePos: pos, OrReplace: orReplace, IfNotExists: ifNotExists, FunctionName: functionName, OnCluster: onCluster, Params: params, Expr: expr, }, nil } // Dictionary parsing functions func (p *Parser) parseDictionarySchemaClause(pos Pos) (*DictionarySchemaClause, error) { if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } schema := &DictionarySchemaClause{ SchemaPos: pos, } // Parse first attribute attr, err := p.parseDictionaryAttribute(p.Pos()) if err != nil { return nil, err } schema.Attributes = append(schema.Attributes, attr) // Parse additional attributes for p.tryConsumeTokenKind(TokenKindComma) != nil { attr, err := p.parseDictionaryAttribute(p.Pos()) if err != nil { return nil, err } schema.Attributes = append(schema.Attributes, attr) } rParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } schema.RParenPos = rParenPos return schema, nil } func (p *Parser) parseDictionaryAttribute(pos Pos) (*DictionaryAttribute, error) { name, err := p.parseIdent() if err != nil { return nil, err } columnType, err := p.parseColumnType(p.Pos()) if err != nil { return nil, err } attr := &DictionaryAttribute{ NamePos: pos, Name: name, Type: columnType, } // Parse optional attribute properties for { switch { case p.tryConsumeKeywords(KeywordDefault): if attr.Default != nil { return nil, fmt.Errorf("duplicate DEFAULT clause") } literal, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } attr.Default = literal case p.tryConsumeKeywords(KeywordExpression): if attr.Expression != nil { return nil, fmt.Errorf("duplicate EXPRESSION clause") } expr, err := p.parseExpr(p.Pos()) if err != nil { return nil, err } attr.Expression = expr case p.tryConsumeKeywords(KeywordHierarchical): if attr.Hierarchical { return nil, fmt.Errorf("duplicate HIERARCHICAL clause") } attr.Hierarchical = true case p.tryConsumeKeywords(KeywordInjective): if attr.Injective { return nil, fmt.Errorf("duplicate INJECTIVE clause") } attr.Injective = true case p.tryConsumeKeywords(KeywordIs_object_id): if attr.IsObjectId { return nil, fmt.Errorf("duplicate IS_OBJECT_ID clause") } attr.IsObjectId = true default: // No more attribute properties return attr, nil } } } func (p *Parser) parseDictionaryEngineClause(pos Pos) (*DictionaryEngineClause, error) { engine := &DictionaryEngineClause{ EnginePos: pos, } // Parse PRIMARY KEY clause (optional) if p.matchKeyword(KeywordPrimary) { primaryKey, err := p.parseDictionaryPrimaryKeyClause(p.Pos()) if err != nil { return nil, err } engine.PrimaryKey = primaryKey } // Parse engine clauses (SOURCE, LIFETIME, LAYOUT, RANGE, SETTINGS) for { switch { case p.matchKeyword(KeywordSource): if engine.Source != nil { return nil, fmt.Errorf("duplicate SOURCE clause") } source, err := p.parseDictionarySourceClause(p.Pos()) if err != nil { return nil, err } engine.Source = source case p.matchKeyword(KeywordLifetime): if engine.Lifetime != nil { return nil, fmt.Errorf("duplicate LIFETIME clause") } lifetime, err := p.parseDictionaryLifetimeClause(p.Pos()) if err != nil { return nil, err } engine.Lifetime = lifetime case p.matchKeyword(KeywordLayout): if engine.Layout != nil { return nil, fmt.Errorf("duplicate LAYOUT clause") } layout, err := p.parseDictionaryLayoutClause(p.Pos()) if err != nil { return nil, err } engine.Layout = layout case p.matchKeyword(KeywordRange): if engine.Range != nil { return nil, fmt.Errorf("duplicate RANGE clause") } rangeClause, err := p.parseDictionaryRangeClause(p.Pos()) if err != nil { return nil, err } engine.Range = rangeClause case p.matchKeyword(KeywordSettings): if engine.Settings != nil { return nil, fmt.Errorf("duplicate SETTINGS clause") } settings, err := p.parseDictionarySettingsClause(p.Pos()) if err != nil { return nil, err } engine.Settings = settings default: // No more engine clauses if engine.Source == nil { return nil, fmt.Errorf("SOURCE clause is required for dictionary") } return engine, nil } } } func (p *Parser) parseDictionaryPrimaryKeyClause(pos Pos) (*DictionaryPrimaryKeyClause, error) { if err := p.expectKeyword(KeywordPrimary); err != nil { return nil, err } if err := p.expectKeyword(KeywordKey); err != nil { return nil, err } keys, err := p.parseColumnExprList(p.Pos()) if err != nil { return nil, err } return &DictionaryPrimaryKeyClause{ PrimaryKeyPos: pos, Keys: keys, RParenPos: keys.End() - 1, }, nil } func (p *Parser) parseDictionarySourceClause(pos Pos) (*DictionarySourceClause, error) { if err := p.expectKeyword(KeywordSource); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } sourceName, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } var args []*DictionaryArgExpr // Parse optional arguments for !p.matchTokenKind(TokenKindRParen) { arg, err := p.parseDictionaryArgExpr(p.Pos()) if err != nil { return nil, err } args = append(args, arg) // If there's no right paren, we expect another arg (no comma needed) if p.matchTokenKind(TokenKindRParen) { break } } if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } rParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &DictionarySourceClause{ SourcePos: pos, Source: sourceName, Args: args, RParenPos: rParenPos, }, nil } func (p *Parser) parseDictionaryArgExpr(pos Pos) (*DictionaryArgExpr, error) { name, err := p.parseIdent() if err != nil { return nil, err } var value Expr // Parse the value part switch { case p.matchTokenKind(TokenKindString): literal, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } value = literal case p.matchTokenKind(TokenKindInt), p.matchTokenKind(TokenKindFloat): literal, err := p.parseLiteral(p.Pos()) if err != nil { return nil, err } value = literal case p.matchTokenKind(TokenKindIdent): ident, err := p.parseIdent() if err != nil { return nil, err } // Check if it's followed by optional parentheses if p.matchTokenKind(TokenKindLParen) { _ = p.lexer.consumeToken() // consume ( if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } value = &FunctionExpr{ Name: ident, } } else { value = ident } default: return nil, fmt.Errorf("expected identifier, string or number in dictionary argument, got %s", p.lastTokenKind()) } return &DictionaryArgExpr{ ArgPos: pos, Name: name, Value: value, }, nil } func (p *Parser) parseDictionaryLifetimeClause(pos Pos) (*DictionaryLifetimeClause, error) { if err := p.expectKeyword(KeywordLifetime); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } lifetime := &DictionaryLifetimeClause{ LifetimePos: pos, } // Check for MIN/MAX form if p.matchKeyword(KeywordMin) || p.matchKeyword(KeywordMax) { isMinFirst := p.matchKeyword(KeywordMin) _ = p.lexer.consumeToken() // consume MIN or MAX first, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } // Expect the other keyword if isMinFirst { if err := p.expectKeyword(KeywordMax); err != nil { return nil, err } } else { if err := p.expectKeyword(KeywordMin); err != nil { return nil, err } } second, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } if isMinFirst { lifetime.Min = first lifetime.Max = second } else { lifetime.Min = second lifetime.Max = first } } else { // Simple form: LIFETIME(value) value, err := p.parseNumber(p.Pos()) if err != nil { return nil, err } lifetime.Value = value } rParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } lifetime.RParenPos = rParenPos return lifetime, nil } func (p *Parser) parseDictionaryLayoutClause(pos Pos) (*DictionaryLayoutClause, error) { if err := p.expectKeyword(KeywordLayout); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } layoutName, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } var args []*DictionaryArgExpr // Parse optional arguments for !p.matchTokenKind(TokenKindRParen) { arg, err := p.parseDictionaryArgExpr(p.Pos()) if err != nil { return nil, err } args = append(args, arg) // If there's no right paren, we expect another arg (no comma needed) if p.matchTokenKind(TokenKindRParen) { break } } if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } rParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return &DictionaryLayoutClause{ LayoutPos: pos, Layout: layoutName, Args: args, RParenPos: rParenPos, }, nil } func (p *Parser) parseDictionaryRangeClause(pos Pos) (*DictionaryRangeClause, error) { if err := p.expectKeyword(KeywordRange); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } rangeClause := &DictionaryRangeClause{ RangePos: pos, } // Parse MIN identifier MAX identifier or MAX identifier MIN identifier if p.matchKeyword(KeywordMin) { if err := p.expectKeyword(KeywordMin); err != nil { return nil, err } min, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectKeyword(KeywordMax); err != nil { return nil, err } max, err := p.parseIdent() if err != nil { return nil, err } rangeClause.Min = min rangeClause.Max = max } else if p.matchKeyword(KeywordMax) { if err := p.expectKeyword(KeywordMax); err != nil { return nil, err } max, err := p.parseIdent() if err != nil { return nil, err } if err := p.expectKeyword(KeywordMin); err != nil { return nil, err } min, err := p.parseIdent() if err != nil { return nil, err } rangeClause.Min = min rangeClause.Max = max } else { return nil, fmt.Errorf("expected MIN or MAX in RANGE clause") } rParenPos := p.Pos() if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } rangeClause.RParenPos = rParenPos return rangeClause, nil } func (p *Parser) parseDictionarySettingsClause(pos Pos) (*SettingsClause, error) { if err := p.expectKeyword(KeywordSettings); err != nil { return nil, err } if err := p.expectTokenKind(TokenKindLParen); err != nil { return nil, err } settings := &SettingsClause{SettingsPos: pos, ListEnd: pos} items := make([]*SettingExpr, 0) // Parse first setting expr, err := p.parseSettingsExpr(p.Pos()) if err != nil { return nil, err } items = append(items, expr) // Parse additional settings for p.tryConsumeTokenKind(TokenKindComma) != nil { expr, err := p.parseSettingsExpr(p.Pos()) if err != nil { return nil, err } items = append(items, expr) } if len(items) > 0 { settings.ListEnd = items[len(items)-1].End() } settings.Items = items if err := p.expectTokenKind(TokenKindRParen); err != nil { return nil, err } return settings, nil } ================================================ FILE: parser/parser_test.go ================================================ package parser import ( "encoding/json" "flag" "os" "path/filepath" "strings" "testing" "github.com/sebdah/goldie/v2" "github.com/stretchr/testify/require" ) var runCompatible = flag.Bool("compatible", false, "run compatible test") func TestParser_Compatible(t *testing.T) { if !*runCompatible { t.Skip("Compatible test runs only if -compatible is set") } dir := "./testdata/query/compatible/1_stateful" entries, err := os.ReadDir(dir) if err != nil { require.NoError(t, err) } for _, entry := range entries { if !strings.HasSuffix(entry.Name(), ".sql") { continue } t.Run(entry.Name(), func(t *testing.T) { fileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name())) require.NoError(t, err) parser := Parser{ lexer: NewLexer(string(fileBytes)), } _, err = parser.ParseStmts() require.NoError(t, err) }) } } func TestParser_ParseStatements(t *testing.T) { for _, dir := range []string{"./testdata/dml", "./testdata/ddl", "./testdata/query", "./testdata/basic"} { outputDir := dir + "/output" entries, err := os.ReadDir(dir) if err != nil { require.NoError(t, err) } for _, entry := range entries { if !strings.HasSuffix(entry.Name(), ".sql") { continue } t.Run(entry.Name(), func(t *testing.T) { fileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name())) require.NoError(t, err) parser := Parser{ lexer: NewLexer(string(fileBytes)), } stmts, err := parser.ParseStmts() require.NoError(t, err) outputBytes, _ := json.MarshalIndent(stmts, "", " ") g := goldie.New(t, goldie.WithNameSuffix(".golden.json"), goldie.WithDiffEngine(goldie.ColoredDiff), goldie.WithFixtureDir(outputDir)) g.Assert(t, entry.Name(), outputBytes) }) } } } func TestParser_Format(t *testing.T) { for _, dir := range []string{"./testdata/dml", "./testdata/ddl", "./testdata/query", "./testdata/basic"} { outputDir := dir + "/format" entries, err := os.ReadDir(dir) if err != nil { require.NoError(t, err) } for _, entry := range entries { if !strings.HasSuffix(entry.Name(), ".sql") { continue } t.Run(entry.Name(), func(t *testing.T) { fileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name())) require.NoError(t, err) parser := Parser{ lexer: NewLexer(string(fileBytes)), } stmts, err := parser.ParseStmts() require.NoError(t, err) var builder strings.Builder builder.WriteString("-- Origin SQL:\n") builder.Write(fileBytes) builder.WriteString("\n\n-- Format SQL:\n") var formatSQLBuilder strings.Builder for _, stmt := range stmts { formatSQLBuilder.WriteString(Format(stmt)) formatSQLBuilder.WriteByte(';') formatSQLBuilder.WriteByte('\n') } formatSQL := formatSQLBuilder.String() builder.WriteString(formatSQL) validFormatSQL(t, formatSQL) g := goldie.New(t, goldie.WithNameSuffix(""), goldie.WithDiffEngine(goldie.ColoredDiff), goldie.WithFixtureDir(outputDir)) g.Assert(t, entry.Name(), []byte(builder.String())) }) } } } func TestParser_FormatBeautify(t *testing.T) { for _, dir := range []string{"./testdata/dml", "./testdata/ddl", "./testdata/query", "./testdata/basic"} { outputDir := dir + "/format/beautify" entries, err := os.ReadDir(dir) if err != nil { require.NoError(t, err) } for _, entry := range entries { if !strings.HasSuffix(entry.Name(), ".sql") { continue } t.Run(entry.Name(), func(t *testing.T) { fileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name())) require.NoError(t, err) parser := Parser{ lexer: NewLexer(string(fileBytes)), } stmts, err := parser.ParseStmts() require.NoError(t, err) var builder strings.Builder builder.WriteString("-- Origin SQL:\n") builder.Write(fileBytes) builder.WriteString("\n\n-- Beautify SQL:\n") for _, stmt := range stmts { formatter := NewFormatter() formatter.WithBeautify() formatter.WriteExpr(stmt) builder.WriteString(formatter.String()) builder.WriteByte(';') builder.WriteByte('\n') } g := goldie.New(t, goldie.WithNameSuffix(""), goldie.WithDiffEngine(goldie.ColoredDiff), goldie.WithFixtureDir(outputDir)) g.Assert(t, entry.Name(), []byte(builder.String())) }) } } } // validFormatSQL Verify that the format sql can be re-parsed with consistent results func validFormatSQL(t *testing.T, sql string) { parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) var builder strings.Builder for _, stmt := range stmts { builder.WriteString(Format(stmt)) builder.WriteByte(';') builder.WriteByte('\n') } require.Equal(t, sql, builder.String()) } func TestParser_InvalidSyntax(t *testing.T) { invalidSQLs := []string{ "SELECT * FROM", // WITH FILL error cases "SELECT n FROM t ORDER BY n WITH", // WITH without FILL "SELECT n FROM t ORDER BY n FILL", // FILL without WITH "SELECT n FROM t ORDER BY n WITH FILL FROM", // FROM without value "SELECT n FROM t ORDER BY n WITH FILL TO", // TO without value "SELECT n FROM t ORDER BY n WITH FILL STEP", // STEP without value "SELECT n FROM t ORDER BY n WITH FILL STALENESS", // STALENESS without value "SELECT n FROM t ORDER BY n WITH FILL INTERPOLATE (x", // Missing closing paren "SELECT n FROM t ORDER BY n WITH FILL INTERPOLATE x AS x + 1", // Missing parens around column list "ALTER TABLE foo_mv MODIFY QUERY AS SELECT * FROM baz", // MODIFY QUERY followed by an invalid query // Invalid ARRAY JOIN types (only ARRAY JOIN, LEFT ARRAY JOIN, and INNER ARRAY JOIN are valid) "SELECT * FROM t RIGHT ARRAY JOIN arr AS a", // RIGHT ARRAY JOIN not supported "SELECT * FROM t FULL ARRAY JOIN arr AS a", // FULL ARRAY JOIN not supported "00e1d", // invalid number that leaves lastToken nil } for _, sql := range invalidSQLs { parser := NewParser(sql) _, err := parser.ParseStmts() require.Error(t, err, "Expected error for SQL: %s", sql) } } ================================================ FILE: parser/parser_view.go ================================================ package parser import "fmt" // parseCreateMaterializedView parses a CREATE MATERIALIZED VIEW statement. // // The syntax is as follows: // CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] // REFRESH EVERY|AFTER interval [OFFSET interval] // [RANDOMIZE FOR interval] // [DEPENDS ON [db.]name [, [db.]name [, ...]]] // [SETTINGS name = value [, name = value [, ...]]] // [APPEND] // [TO[db.]name] [(columns)] [ENGINE = engine] // [EMPTY] // [DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | NONE }] // AS SELECT ... // [COMMENT 'comment'] func (p *Parser) parseCreateMaterializedView(pos Pos) (*CreateMaterializedView, error) { if err := p.expectKeyword(KeywordMaterialized); err != nil { return nil, err } if err := p.expectKeyword(KeywordView); err != nil { return nil, err } createMaterializedView := &CreateMaterializedView{CreatePos: pos} // parse IF NOT EXISTS clause if exists var err error createMaterializedView.IfNotExists, err = p.tryParseIfNotExists() if err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } createMaterializedView.Name = tableIdentifier onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } createMaterializedView.OnCluster = onCluster refreshExpr, err := p.tryParseRefreshExpr(p.Pos()) if err != nil { return nil, err } createMaterializedView.Refresh = refreshExpr if p.tryConsumeKeywords(KeywordRandomize, KeywordFor) { randomizeFor, err := p.parseInterval(false) if err != nil { return nil, err } createMaterializedView.RandomizeFor = randomizeFor } if p.tryConsumeKeywords(KeywordDepends, KeywordOn) { dependsOnTables := make([]*TableIdentifier, 0) table, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } dependsOnTables = append(dependsOnTables, table) for p.matchTokenKind(TokenKindComma) { table, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } dependsOnTables = append(dependsOnTables, table) } createMaterializedView.DependsOn = dependsOnTables } settings, err := p.tryParseSettingsClause(p.Pos()) if err != nil { return nil, err } createMaterializedView.Settings = settings createMaterializedView.HasAppend = p.tryConsumeKeywords(KeywordAppend) switch { case p.matchKeyword(KeywordTo): destination, err := p.parseDestinationClause(p.Pos()) if err != nil { return nil, err } createMaterializedView.Destination = destination createMaterializedView.StatementEnd = destination.End() if p.matchTokenKind(TokenKindLParen) { tableSchema, err := p.parseTableSchemaClause(p.Pos()) if err != nil { return nil, err } createMaterializedView.Destination.TableSchema = tableSchema } case p.matchKeyword(KeywordEngine): engineExpr, err := p.parseEngineExpr(p.Pos()) if err != nil { return nil, err } createMaterializedView.Engine = engineExpr createMaterializedView.StatementEnd = engineExpr.End() default: return nil, fmt.Errorf("unexpected token: %q, expected TO or ENGINE", p.lastTokenKind()) } createMaterializedView.HasEmpty = p.tryConsumeKeywords(KeywordEmpty) // Parse DEFINER clause if p.tryConsumeKeywords(KeywordDefiner) { if err := p.expectTokenKind(TokenKindSingleEQ); err != nil { return nil, err } definer, err := p.parseIdent() if err != nil { return nil, err } createMaterializedView.Definer = definer } // Parse SQL SECURITY clause if p.tryConsumeKeywords(KeywordSQL, KeywordSecurity) { if !p.matchOneOfKeywords(KeywordDefiner, KeywordNone) { return nil, fmt.Errorf("expected DEFINER or NONE after SQL SECURITY, got %q", p.lastTokenKind()) } createMaterializedView.SQLSecurity = p.last().String _ = p.lexer.consumeToken() } // Check for POPULATE before AS SELECT - only valid with ENGINE and no Destination if p.tryConsumeKeywords(KeywordPopulate) { if createMaterializedView.Destination != nil { return nil, fmt.Errorf("POPULATE is only allowed when using ENGINE, not with TO clause") } if createMaterializedView.Engine == nil { return nil, fmt.Errorf("POPULATE requires ENGINE to be specified") } createMaterializedView.Populate = true createMaterializedView.StatementEnd = p.Pos() } // COMMENT can appear either before or after AS SELECT. // ClickHouse 26.2+ outputs COMMENT before AS SELECT in SHOW CREATE TABLE, // while 25.8 outputs it after AS SELECT. comment, err := p.tryParseComment() if err != nil { return nil, err } createMaterializedView.Comment = comment if p.tryConsumeKeywords(KeywordAs) { subQuery, err := p.parseSubQuery(p.Pos()) if err != nil { return nil, err } createMaterializedView.SubQuery = subQuery createMaterializedView.StatementEnd = subQuery.End() } // Also try parsing COMMENT after AS SELECT (ClickHouse 25.x format) if createMaterializedView.Comment == nil { comment, err = p.tryParseComment() if err != nil { return nil, err } createMaterializedView.Comment = comment } return createMaterializedView, nil } func (p *Parser) tryParseRefreshExpr(pos Pos) (*RefreshExpr, error) { if !p.tryConsumeKeywords(KeywordRefresh) { return nil, nil // nolint } // REFRESH EVERY|AFTER interval refreshExpr := &RefreshExpr{RefreshPos: pos} if !p.matchOneOfKeywords(KeywordEvery, KeywordAfter) { return nil, fmt.Errorf("expected EVERY or AFTER, but got %q", p.lastTokenKind()) } refreshExpr.Frequency = p.last().String _ = p.lexer.consumeToken() interval, err := p.parseInterval(false) if err != nil { return nil, err } refreshExpr.Interval = interval // [OFFSET interval] if p.tryConsumeKeywords(KeywordOffset) { offset, err := p.parseInterval(false) if err != nil { return nil, err } refreshExpr.Offset = offset } return refreshExpr, nil } // (ATTACH | CREATE) (OR REPLACE)? VIEW (IF NOT EXISTS)? tableIdentifier uuidClause? clusterClause? tableSchemaClause? subqueryClause func (p *Parser) parseCreateView(pos Pos, orReplace bool) (*CreateView, error) { createView := &CreateView{CreatePos: pos, OrReplace: orReplace} if err := p.expectKeyword(KeywordView); err != nil { return nil, err } var err error createView.IfNotExists, err = p.tryParseIfNotExists() if err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } createView.Name = tableIdentifier uuid, err := p.tryParseUUID() if err != nil { return nil, err } createView.UUID = uuid onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } createView.OnCluster = onCluster if p.matchTokenKind(TokenKindLParen) { tableSchema, err := p.parseTableSchemaClause(p.Pos()) if err != nil { return nil, err } createView.TableSchema = tableSchema } // parse COMMENT clause if exists (before AS SELECT) comment, err := p.tryParseComment() if err != nil { return nil, err } createView.Comment = comment if p.tryConsumeKeywords(KeywordAs) { subQuery, err := p.parseSubQuery(p.Pos()) if err != nil { return nil, err } createView.SubQuery = subQuery createView.StatementEnd = subQuery.End() } return createView, nil } // # CreateLiveViewStmt // (ATTACH | CREATE) LIVE VIEW (IF NOT EXISTS)? tableIdentifier uuidClause? // clusterClause? (WITH TIMEOUT DECIMAL_LITERAL?)? destinationClause? tableSchemaClause? subqueryClause func (p *Parser) parseCreateLiveView(pos Pos) (*CreateLiveView, error) { if err := p.expectKeyword(KeywordLive); err != nil { return nil, err } if err := p.expectKeyword(KeywordView); err != nil { return nil, err } createLiveView := &CreateLiveView{CreatePos: pos} // parse IF NOT EXISTS clause if exists var err error createLiveView.IfNotExists, err = p.tryParseIfNotExists() if err != nil { return nil, err } tableIdentifier, err := p.parseTableIdentifier(p.Pos()) if err != nil { return nil, err } createLiveView.Name = tableIdentifier // try parse UUID clause if exists uuid, err := p.tryParseUUID() if err != nil { return nil, err } createLiveView.UUID = uuid // parse ON CLUSTER clause if exists onCluster, err := p.tryParseClusterClause(p.Pos()) if err != nil { return nil, err } createLiveView.OnCluster = onCluster withTimeout, err := p.tryParseWithTimeout(p.Pos()) if err != nil { return nil, err } createLiveView.WithTimeout = withTimeout if p.matchKeyword(KeywordTo) { destination, err := p.parseDestinationClause(p.Pos()) if err != nil { return nil, err } createLiveView.Destination = destination } if p.matchTokenKind(TokenKindLParen) { tableSchema, err := p.parseTableSchemaClause(p.Pos()) if err != nil { return nil, err } createLiveView.TableSchema = tableSchema } if p.tryConsumeKeywords(KeywordAs) { subQuery, err := p.parseSubQuery(p.Pos()) if err != nil { return nil, err } createLiveView.SubQuery = subQuery createLiveView.StatementEnd = subQuery.End() } return createLiveView, nil } func (p *Parser) tryParseWithTimeout(pos Pos) (*WithTimeoutClause, error) { if !p.tryConsumeKeywords(KeywordWith) { return nil, nil // nolint } if err := p.expectKeyword(KeywordTimeout); err != nil { return nil, err } withTimeout := &WithTimeoutClause{WithTimeoutPos: pos} if p.matchTokenKind(TokenKindInt) { decimalNumber, err := p.parseDecimal(p.Pos()) if err != nil { return nil, err } withTimeout.Number = decimalNumber } return withTimeout, nil } ================================================ FILE: parser/set.go ================================================ package parser type Set[T comparable] struct { m map[T]struct{} } func NewSet[T comparable](members ...T) *Set[T] { m := make(map[T]struct{}) for _, member := range members { m[member] = struct{}{} } return &Set[T]{m: m} } func (s *Set[T]) Add(member T) { s.m[member] = struct{}{} } func (s *Set[T]) Remove(member T) { delete(s.m, member) } func (s *Set[T]) Contains(member T) bool { _, ok := s.m[member] return ok } func (s *Set[T]) Members() []T { members := make([]T, 0, len(s.m)) for member := range s.m { members = append(members, member) } return members } ================================================ FILE: parser/set_test.go ================================================ package parser import ( "testing" "github.com/stretchr/testify/require" ) func TestSet(t *testing.T) { s := NewSet[int](1, 2, 3) if !s.Contains(1) { t.Errorf("Set should contain 1") } if s.Contains(4) { t.Errorf("Set should not contain 4") } s.Add(4) if !s.Contains(4) { t.Errorf("Set should contain 4") } s.Remove(4) if s.Contains(4) { t.Errorf("Set should not contain 4") } require.Equal(t, 3, len(s.Members())) } ================================================ FILE: parser/testdata/basic/format/beautify/quantile_functions.sql ================================================ -- Origin SQL: SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x); -- Beautify SQL: SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x); ================================================ FILE: parser/testdata/basic/format/beautify/set_statement.sql ================================================ -- Origin SQL: SET allow_suspicious_low_cardinality_types = true; SET max_block_size = 65536; SET output_format_json_quote_64bit_integers = 'true'; SET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false; SET allow_experimental_analyzer = true; -- Beautify SQL: SET allow_suspicious_low_cardinality_types=true; SET max_block_size=65536; SET output_format_json_quote_64bit_integers='true'; SET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false; SET allow_experimental_analyzer=true; ================================================ FILE: parser/testdata/basic/format/beautify/settings_statement.sql ================================================ -- Origin SQL: SETTINGS allow_suspicious_low_cardinality_types = true; SETTINGS max_block_size = 65536; SETTINGS output_format_json_quote_64bit_integers = 'true'; SETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false; SETTINGS allow_experimental_analyzer = true; -- Beautify SQL: SET allow_suspicious_low_cardinality_types=true; SET max_block_size=65536; SET output_format_json_quote_64bit_integers='true'; SET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false; SET allow_experimental_analyzer=true; ================================================ FILE: parser/testdata/basic/format/beautify/use_database.sql ================================================ -- Origin SQL: USE test; -- Beautify SQL: USE test; ================================================ FILE: parser/testdata/basic/format/quantile_functions.sql ================================================ -- Origin SQL: SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x); -- Format SQL: SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x); ================================================ FILE: parser/testdata/basic/format/set_statement.sql ================================================ -- Origin SQL: SET allow_suspicious_low_cardinality_types = true; SET max_block_size = 65536; SET output_format_json_quote_64bit_integers = 'true'; SET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false; SET allow_experimental_analyzer = true; -- Format SQL: SET allow_suspicious_low_cardinality_types=true; SET max_block_size=65536; SET output_format_json_quote_64bit_integers='true'; SET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false; SET allow_experimental_analyzer=true; ================================================ FILE: parser/testdata/basic/format/settings_statement.sql ================================================ -- Origin SQL: SETTINGS allow_suspicious_low_cardinality_types = true; SETTINGS max_block_size = 65536; SETTINGS output_format_json_quote_64bit_integers = 'true'; SETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false; SETTINGS allow_experimental_analyzer = true; -- Format SQL: SET allow_suspicious_low_cardinality_types=true; SET max_block_size=65536; SET output_format_json_quote_64bit_integers='true'; SET max_threads=8, max_memory_usage=10000000000, enable_optimize_predicate_expression=false; SET allow_experimental_analyzer=true; ================================================ FILE: parser/testdata/basic/format/use_database.sql ================================================ -- Origin SQL: USE test; -- Format SQL: USE test; ================================================ FILE: parser/testdata/basic/output/quantile_functions.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 43, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "quantile", "QuoteType": 1, "NamePos": 7, "NameEnd": 15 }, "Params": { "LeftParenPos": 15, "RightParenPos": 19, "Items": { "ListPos": 16, "ListEnd": 19, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 16, "NumEnd": 19, "Literal": "0.9", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": { "Distinct": false, "LeftParenPos": 20, "RightParenPos": 22, "Items": [ { "Name": "x", "QuoteType": 1, "NamePos": 21, "NameEnd": 22 } ] } } }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "quantiles", "QuoteType": 1, "NamePos": 25, "NameEnd": 34 }, "Params": { "LeftParenPos": 34, "RightParenPos": 43, "Items": { "ListPos": 35, "ListEnd": 43, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 35, "NumEnd": 38, "Literal": "0.5", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 40, "NumEnd": 43, "Literal": "0.9", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": { "Distinct": false, "LeftParenPos": 44, "RightParenPos": 46, "Items": [ { "Name": "x", "QuoteType": 1, "NamePos": 45, "NameEnd": 46 } ] } } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/basic/output/set_statement.sql.golden.json ================================================ [ { "SetPos": 0, "Settings": { "SettingsPos": 4, "ListEnd": 49, "Items": [ { "SettingsPos": 4, "Name": { "Name": "allow_suspicious_low_cardinality_types", "QuoteType": 1, "NamePos": 4, "NameEnd": 42 }, "Expr": { "LiteralPos": 45, "LiteralEnd": 49, "Literal": "true" } } ] } }, { "SetPos": 52, "Settings": { "SettingsPos": 56, "ListEnd": 78, "Items": [ { "SettingsPos": 56, "Name": { "Name": "max_block_size", "QuoteType": 1, "NamePos": 56, "NameEnd": 70 }, "Expr": { "NumPos": 73, "NumEnd": 78, "Literal": "65536", "Base": 10 } } ] } }, { "SetPos": 81, "Settings": { "SettingsPos": 85, "ListEnd": 132, "Items": [ { "SettingsPos": 85, "Name": { "Name": "output_format_json_quote_64bit_integers", "QuoteType": 1, "NamePos": 85, "NameEnd": 124 }, "Expr": { "LiteralPos": 128, "LiteralEnd": 132, "Literal": "true" } } ] } }, { "SetPos": 136, "Settings": { "SettingsPos": 140, "ListEnd": 233, "Items": [ { "SettingsPos": 140, "Name": { "Name": "max_threads", "QuoteType": 1, "NamePos": 140, "NameEnd": 151 }, "Expr": { "NumPos": 154, "NumEnd": 155, "Literal": "8", "Base": 10 } }, { "SettingsPos": 157, "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 157, "NameEnd": 173 }, "Expr": { "NumPos": 176, "NumEnd": 187, "Literal": "10000000000", "Base": 10 } }, { "SettingsPos": 189, "Name": { "Name": "enable_optimize_predicate_expression", "QuoteType": 1, "NamePos": 189, "NameEnd": 225 }, "Expr": { "LiteralPos": 228, "LiteralEnd": 233, "Literal": "false" } } ] } }, { "SetPos": 236, "Settings": { "SettingsPos": 240, "ListEnd": 274, "Items": [ { "SettingsPos": 240, "Name": { "Name": "allow_experimental_analyzer", "QuoteType": 1, "NamePos": 240, "NameEnd": 267 }, "Expr": { "LiteralPos": 270, "LiteralEnd": 274, "Literal": "true" } } ] } } ] ================================================ FILE: parser/testdata/basic/output/settings_statement.sql.golden.json ================================================ [ { "SetPos": 0, "Settings": { "SettingsPos": 9, "ListEnd": 54, "Items": [ { "SettingsPos": 9, "Name": { "Name": "allow_suspicious_low_cardinality_types", "QuoteType": 1, "NamePos": 9, "NameEnd": 47 }, "Expr": { "LiteralPos": 50, "LiteralEnd": 54, "Literal": "true" } } ] } }, { "SetPos": 57, "Settings": { "SettingsPos": 66, "ListEnd": 88, "Items": [ { "SettingsPos": 66, "Name": { "Name": "max_block_size", "QuoteType": 1, "NamePos": 66, "NameEnd": 80 }, "Expr": { "NumPos": 83, "NumEnd": 88, "Literal": "65536", "Base": 10 } } ] } }, { "SetPos": 91, "Settings": { "SettingsPos": 100, "ListEnd": 147, "Items": [ { "SettingsPos": 100, "Name": { "Name": "output_format_json_quote_64bit_integers", "QuoteType": 1, "NamePos": 100, "NameEnd": 139 }, "Expr": { "LiteralPos": 143, "LiteralEnd": 147, "Literal": "true" } } ] } }, { "SetPos": 151, "Settings": { "SettingsPos": 160, "ListEnd": 253, "Items": [ { "SettingsPos": 160, "Name": { "Name": "max_threads", "QuoteType": 1, "NamePos": 160, "NameEnd": 171 }, "Expr": { "NumPos": 174, "NumEnd": 175, "Literal": "8", "Base": 10 } }, { "SettingsPos": 177, "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 177, "NameEnd": 193 }, "Expr": { "NumPos": 196, "NumEnd": 207, "Literal": "10000000000", "Base": 10 } }, { "SettingsPos": 209, "Name": { "Name": "enable_optimize_predicate_expression", "QuoteType": 1, "NamePos": 209, "NameEnd": 245 }, "Expr": { "LiteralPos": 248, "LiteralEnd": 253, "Literal": "false" } } ] } }, { "SetPos": 256, "Settings": { "SettingsPos": 265, "ListEnd": 299, "Items": [ { "SettingsPos": 265, "Name": { "Name": "allow_experimental_analyzer", "QuoteType": 1, "NamePos": 265, "NameEnd": 292 }, "Expr": { "LiteralPos": 295, "LiteralEnd": 299, "Literal": "true" } } ] } } ] ================================================ FILE: parser/testdata/basic/output/use_database.sql.golden.json ================================================ [ { "UsePos": 0, "StatementEnd": 8, "Database": { "Name": "test", "QuoteType": 1, "NamePos": 4, "NameEnd": 8 } } ] ================================================ FILE: parser/testdata/basic/quantile_functions.sql ================================================ SELECT quantile(0.9)(x), quantiles(0.5, 0.9)(x); ================================================ FILE: parser/testdata/basic/set_statement.sql ================================================ SET allow_suspicious_low_cardinality_types = true; SET max_block_size = 65536; SET output_format_json_quote_64bit_integers = 'true'; SET max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false; SET allow_experimental_analyzer = true; ================================================ FILE: parser/testdata/basic/settings_statement.sql ================================================ SETTINGS allow_suspicious_low_cardinality_types = true; SETTINGS max_block_size = 65536; SETTINGS output_format_json_quote_64bit_integers = 'true'; SETTINGS max_threads = 8, max_memory_usage = 10000000000, enable_optimize_predicate_expression = false; SETTINGS allow_experimental_analyzer = true; ================================================ FILE: parser/testdata/basic/use_database.sql ================================================ USE test; ================================================ FILE: parser/testdata/benchdata/posthog_huge_0.sql ================================================ /* user_id:0 request:_snapshot_ */ SELECT fill.bin_from_seconds AS bin_from_seconds, results.person_count AS person_count, (SELECT histogram_params.average_conversion_time AS average_conversion_time FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params) AS average_conversion_time FROM (SELECT plus( (SELECT histogram_params.from_seconds AS from_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(floor(divide(minus(step_runs.step_1_average_conversion_time_inner, (SELECT histogram_params.from_seconds AS from_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params)), (SELECT histogram_params.bin_width_seconds AS bin_width_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))), (SELECT histogram_params.bin_width_seconds AS bin_width_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds, count() AS person_count FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs GROUP BY bin_from_seconds) AS results RIGHT OUTER JOIN (SELECT plus( (SELECT histogram_params.from_seconds AS from_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(numbers.number, (SELECT histogram_params.bin_width_seconds AS bin_width_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds FROM numbers(plus(ifNull( (SELECT histogram_params.bin_count AS bin_count FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), 0), 1)) AS numbers) AS fill ON equals(results.bin_from_seconds, fill.bin_from_seconds) ORDER BY fill.bin_from_seconds ASC LIMIT 100 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, format_csv_allow_double_quotes=0, max_ast_elements=4000000, max_expanded_ast_elements=4000000, max_bytes_before_external_group_by=23622320128, allow_experimental_analyzer=1 ================================================ FILE: parser/testdata/benchdata/posthog_huge_1.sql ================================================ /* user_id:0 request:_snapshot_ */ SELECT fill.bin_from_seconds AS bin_from_seconds, results.person_count AS person_count, (SELECT histogram_params.average_conversion_time AS average_conversion_time FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params) AS average_conversion_time FROM (SELECT plus( (SELECT histogram_params.from_seconds AS from_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(floor(divide(minus(step_runs.step_1_average_conversion_time_inner, (SELECT histogram_params.from_seconds AS from_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params)), (SELECT histogram_params.bin_width_seconds AS bin_width_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))), (SELECT histogram_params.bin_width_seconds AS bin_width_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds, count() AS person_count FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs GROUP BY bin_from_seconds) AS results RIGHT OUTER JOIN (SELECT plus( (SELECT histogram_params.from_seconds AS from_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), multiply(numbers.number, (SELECT histogram_params.bin_width_seconds AS bin_width_seconds FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params))) AS bin_from_seconds FROM numbers(plus(ifNull( (SELECT histogram_params.bin_count AS bin_count FROM (SELECT ifNull(floor(min(step_runs.step_1_average_conversion_time_inner)), 0) AS from_seconds, ifNull(ceil(max(step_runs.step_1_average_conversion_time_inner)), 1) AS to_seconds, round(avg(step_runs.step_1_average_conversion_time_inner), 2) AS average_conversion_time, count() AS sample_count, least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, ceil(divide(minus(to_seconds, from_seconds), bin_count)) AS bin_width_seconds_raw, if(ifNull(greater(bin_width_seconds_raw, 0), 0), bin_width_seconds_raw, 60) AS bin_width_seconds FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, median(step_1_conversion_time) AS step_1_median_conversion_time_inner, median(step_2_conversion_time) AS step_2_median_conversion_time_inner FROM (SELECT aggregation_target AS aggregation_target, steps AS steps, max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, step_1_conversion_time AS step_1_conversion_time, step_2_conversion_time AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, latest_2 AS latest_2, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time FROM (SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, min(latest_1) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) AS latest_2 FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'step three'), 1, 0) AS step_2, if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id FROM person_distinct_id_overrides WHERE equals(person_distinct_id_overrides.team_id, 99999) GROUP BY person_distinct_id_overrides.distinct_id HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 99999), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('explicit_redacted_timestamp.999999', 6, 'UTC')))))) WHERE ifNull(equals(step_0, 1), 0))) GROUP BY aggregation_target, steps HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) and isNull(max(max_steps)))) AS step_runs WHERE isNotNull(step_runs.step_1_average_conversion_time_inner)) AS histogram_params), 0), 1)) AS numbers) AS fill ON equals(results.bin_from_seconds, fill.bin_from_seconds) ORDER BY fill.bin_from_seconds ASC LIMIT 100 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, format_csv_allow_double_quotes=0, max_ast_elements=4000000, max_expanded_ast_elements=4000000, max_bytes_before_external_group_by=23622320128, allow_experimental_analyzer=1 ================================================ FILE: parser/testdata/ddl/alter_role.sql ================================================ -- Tags: no-parallel ALTER ROLE r1_01293; ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293; ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293; ALTER ROLE r1_01293 SETTINGS NONE; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000; ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST; ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; ALTER ROLE r1_01293, r2_01293; ALTER ROLE r1_01293 SETTINGS readonly=1; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; ALTER ROLE r5_01293 SETTINGS NONE; ALTER ROLE r1_01293@'%'; ALTER ROLE r2_01293@'%.myhost.com'; ================================================ FILE: parser/testdata/ddl/alter_table_add_column.sql ================================================ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2; ================================================ FILE: parser/testdata/ddl/alter_table_add_index.sql ================================================ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2; ================================================ FILE: parser/testdata/ddl/alter_table_add_projection.sql ================================================ ALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id; ================================================ FILE: parser/testdata/ddl/alter_table_add_projection_group_by_only.sql ================================================ ALTER TABLE events ADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type); ================================================ FILE: parser/testdata/ddl/alter_table_attach_partition.sql ================================================ ALTER TABLE test ATTACH PARTITION '20210114'; ALTER TABLE test ATTACH PARTITION '20210114' FROM test1; ALTER TABLE test ATTACH PARTITION ID '20210114'; ================================================ FILE: parser/testdata/ddl/alter_table_clear_column.sql ================================================ ALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/alter_table_clear_index.sql ================================================ ALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/alter_table_clear_projection.sql ================================================ ALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/alter_table_delete.sql ================================================ ALTER TABLE test.events DELETE WHERE created_at < '2023-01-01'; ================================================ FILE: parser/testdata/ddl/alter_table_delete_with_cluster.sql ================================================ ALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted'; ================================================ FILE: parser/testdata/ddl/alter_table_detach_partition.sql ================================================ ALTER TABLE db.test DETACH PARTITION '2021-10-01'; ================================================ FILE: parser/testdata/ddl/alter_table_drop_column.sql ================================================ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1; ================================================ FILE: parser/testdata/ddl/alter_table_drop_detach_partition.sql ================================================ ALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached = 1; ================================================ FILE: parser/testdata/ddl/alter_table_drop_index.sql ================================================ ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1; ================================================ FILE: parser/testdata/ddl/alter_table_drop_partition.sql ================================================ ALTER TABLE test.events ON CLUSTER 'default_cluster' drop partition '2023-07-18'; ================================================ FILE: parser/testdata/ddl/alter_table_drop_projection.sql ================================================ ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1; ================================================ FILE: parser/testdata/ddl/alter_table_freeze_no_specify_partition.sql ================================================ ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze; ================================================ FILE: parser/testdata/ddl/alter_table_freeze_partition.sql ================================================ ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze partition '2023-07-18';; ================================================ FILE: parser/testdata/ddl/alter_table_materialize_index.sql ================================================ ALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403'; ================================================ FILE: parser/testdata/ddl/alter_table_materialize_projection.sql ================================================ ALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403'; ================================================ FILE: parser/testdata/ddl/alter_table_modify_column.sql ================================================ ALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test'; ================================================ FILE: parser/testdata/ddl/alter_table_modify_column_remove.sql ================================================ ALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT; ================================================ FILE: parser/testdata/ddl/alter_table_modify_setting.sql ================================================ ALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000; ================================================ FILE: parser/testdata/ddl/alter_table_remove_ttl.sql ================================================ ALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL; ================================================ FILE: parser/testdata/ddl/alter_table_rename_column.sql ================================================ ALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name; ================================================ FILE: parser/testdata/ddl/alter_table_replace_partition.sql ================================================ ALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1; ================================================ FILE: parser/testdata/ddl/alter_table_reset_multiple_settings.sql ================================================ ALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting; ================================================ FILE: parser/testdata/ddl/alter_table_reset_setting.sql ================================================ ALTER TABLE example_table RESET SETTING max_part_loading_threads; ================================================ FILE: parser/testdata/ddl/alter_table_update.sql ================================================ ALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending'; ================================================ FILE: parser/testdata/ddl/alter_table_update_in_partition.sql ================================================ ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active'; ================================================ FILE: parser/testdata/ddl/alter_table_update_with_cluster.sql ================================================ ALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100; ================================================ FILE: parser/testdata/ddl/attach_table_basic.sql ================================================ ATTACH TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); ================================================ FILE: parser/testdata/ddl/bug_001.sql ================================================ CREATE MATERIALIZED VIEW IF NOT EXISTS db.table ON CLUSTER 'default_cluster' TO db.table_mv AS SELECT event_ts, org_id, visitParamExtractString(properties, 'x') AS x, visitParamExtractString(properties, 'y') AS y, visitParamExtractString(properties, 'z') AS z, visitParamExtractString(properties, 'a') AS a, visitParamExtractString(properties, 'b') AS b, visitParamExtractString(properties, 'c') AS c, visitParamExtractString(properties, 'd') AS d, visitParamExtractInt(properties, 'e') AS e, visitParamExtractInt(properties, 'f') AS f FROM db.table WHERE db.table.event = 'hello'; ================================================ FILE: parser/testdata/ddl/check.sql ================================================ CHECK TABLE test_table; CHECK TABLE test_table PARTITION 'col'; ================================================ FILE: parser/testdata/ddl/create_database.sql ================================================ CREATE DATABASE IF NOT EXISTS `test` ================================================ FILE: parser/testdata/ddl/create_database_replicated.sql ================================================ CREATE DATABASE IF NOT EXISTS `test` ENGINE=Replicated('/root/test_local', 'shard', 'replica'); ================================================ FILE: parser/testdata/ddl/create_dictionary_basic.sql ================================================ CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192); ================================================ FILE: parser/testdata/ddl/create_dictionary_comprehensive.sql ================================================ CREATE OR REPLACE DICTIONARY test.comprehensive_dict UUID '12345678-1234-1234-1234-123456789012' ON CLUSTER production_cluster ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192, max_insert_block_size = 1048576); ================================================ FILE: parser/testdata/ddl/create_dictionary_with_comment.sql ================================================ CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192) COMMENT 'This is a test dictionary with comment'; ================================================ FILE: parser/testdata/ddl/create_distributed_table.sql ================================================ create table test.event_all ON CLUSTER 'default_cluster' AS test.evnets_local ENGINE = Distributed( default_cluster, test, events_local, rand() ) SETTINGS fsync_after_insert=0; ================================================ FILE: parser/testdata/ddl/create_function_simple.sql ================================================ CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b; ================================================ FILE: parser/testdata/ddl/create_live_view_basic.sql ================================================ CREATE LIVE VIEW my_live_view WITH TIMEOUT 10 TO my_destination(id String) AS SELECT id FROM my_table; ================================================ FILE: parser/testdata/ddl/create_materialized_view_basic.sql ================================================ CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' COMMENT 'Comment for table'; ================================================ FILE: parser/testdata/ddl/create_materialized_view_with_comment_before_as.sql ================================================ CREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table ( `shop_id` UInt64, `event_type` LowCardinality(String), `created_at` DateTime64(9) ) COMMENT '{"blueprint_hash":"abc123","timestamp":"2026-04-08T12:00:00Z"}' AS SELECT shop_id, event_type, created_at FROM db.src_table; ================================================ FILE: parser/testdata/ddl/create_materialized_view_with_definer.sql ================================================ CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export ( `timestamp` DateTime64(9), `field_1` String, `field_2` String, ) DEFINER = default SQL SECURITY DEFINER AS (SELECT timestamp, field_1, field_2, FROM event_table WHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1))) COMMENT 'Test comment' ================================================ FILE: parser/testdata/ddl/create_materialized_view_with_empty_table_schema.sql ================================================ CREATE MATERIALIZED VIEW test.t0 on cluster default_cluster ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}') PARTITION BY toYYYYMM(f0) ORDER BY (f0) POPULATE AS select f0,f1,f2,coalesce(f0,f1) as f333 from (select f0,f1,f2, ROW_NUMBER() over(partition by f0 order by coalesce(f1,f2)) as rn from test.t where f3 in ('foo', 'bar', 'test') and env ='test' ) as tmp where rn = 1; ================================================ FILE: parser/testdata/ddl/create_materialized_view_with_gcs.sql ================================================ CREATE MATERIALIZED VIEW database_name.view_name REFRESH EVERY 5 MINUTE TO database_name.table_name AS SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/'); ================================================ FILE: parser/testdata/ddl/create_materialized_view_with_refresh.sql ================================================ CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE RANDOMIZE FOR 1 SECOND DEPENDS ON table_v5 SETTINGS randomize_for = 1, randomize_offset = 10, randomize_period = 1 APPEND TO target_table_name EMPTY AS SELECT `field_1`, `field_2`, `field_3`, FROM table_v5 ================================================ FILE: parser/testdata/ddl/create_mv_with_not_op.sql ================================================ CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' AND NOT isZeroOrNull(f2) AND f6-2 > 0 ================================================ FILE: parser/testdata/ddl/create_mv_with_order_by.sql ================================================ CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) ORDER BY (id) AS SELECT * FROM test_table; CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) AS SELECT * FROM test_table; ================================================ FILE: parser/testdata/ddl/create_named_collection_basic.sql ================================================ CREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin'; ================================================ FILE: parser/testdata/ddl/create_named_collection_simple.sql ================================================ CREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2'; ================================================ FILE: parser/testdata/ddl/create_named_collection_with_cluster.sql ================================================ CREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3'; ================================================ FILE: parser/testdata/ddl/create_named_collection_with_overridable.sql ================================================ CREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456'; ================================================ FILE: parser/testdata/ddl/create_or_replace.sql ================================================ -- It's a short link events table /** * @name Short link events * @description It's a short link events table */ CREATE OR REPLACE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), ) ENGINE = MergeTree PRIMARY KEY (f0, f1, f2) PARTITION BY toYYYYMMDD(f1) TTL f1 + INTERVAL 6 MONTH ORDER BY (f1,f2) COMMENT 'Comment for table'; CREATE OR REPLACE VIEW IF NOT EXISTS my_view(col1 String, col2 String) AS SELECT id, name FROM my_table; CREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y; ================================================ FILE: parser/testdata/ddl/create_role.sql ================================================ -- Tags: no-parallel CREATE ROLE r1_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2; CREATE ROLE r1_01293 SETTINGS NONE; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000; CREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; CREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; CREATE ROLE r6_01293 SETTINGS max_memory_usage CONST; CREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; CREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; CREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 SETTINGS readonly=1; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; CREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; CREATE ROLE r5_01293 SETTINGS NONE; CREATE ROLE r1_01293@'%'; CREATE ROLE r2_01293@'%.myhost.com'; ================================================ FILE: parser/testdata/ddl/create_table_as_remote_function.sql ================================================ -- CREATE TABLE with columns AS table function (remoteSecure) CREATE TABLE test_remote ( id UInt64, name String, value Int32 ) AS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password'); -- Simpler test case with remote() CREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table'); ================================================ FILE: parser/testdata/ddl/create_table_basic.sql ================================================ -- It's a short link events table /** * @name Short link events * @description It's a short link events table */ CREATE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Nested ( f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String ), f8 Datetime DEFAULT now(), f9 String MATERIALIZED toString(f7['f70']), f10 String ALIAS f11, f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello'), ) ENGINE = MergeTree PRIMARY KEY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH ORDER BY (f1,f2,f3) COMMENT 'Comment for table'; ================================================ FILE: parser/testdata/ddl/create_table_codec_no_args.sql ================================================ CREATE TABLE shark_attacks ( timestamp DateTime CODEC(DoubleDelta), ); ================================================ FILE: parser/testdata/ddl/create_table_json_typehints.sql ================================================ CREATE TABLE t ( j JSON(message String, a.b UInt64, max_dynamic_paths=0, SKIP x, SKIP REGEXP 're') ) ENGINE = MergeTree ORDER BY tuple(); ================================================ FILE: parser/testdata/ddl/create_table_with_codec_delta.sql ================================================ CREATE TABLE IF NOT EXISTS test_local ( `id` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `app_id` UInt64 CODEC(Delta(9), ZSTD(1)), `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)), `guage` Float64 CODEC(Gorilla, LZ4), `value` UInt64 CODEC(T64, LZ4), `timestamp` DateTime64(9) CODEC(ZSTD(1)), INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') PARTITION BY toStartOfHour(`timestamp`) ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/create_table_with_enum_fields.sql ================================================ CREATE TABLE t0 on cluster default_cluster ( `method` Enum8('GET'=1 , 'POST'=2, 'HEAD'=3, 'PUT'=4,'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)), `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') PARTITION BY toDate(timestamp) ORDER BY (method,timestamp) TTL toDate(timestamp) + toIntervalDay(3) SETTINGS index_granularity = 8192; ================================================ FILE: parser/testdata/ddl/create_table_with_index.sql ================================================ CREATE TABLE IF NOT EXISTS test_local ( `common.id` String CODEC(ZSTD(1)), `id` UInt64 CODEC(Delta, ZSTD(1)), `idx` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `arr` Array(Int64), `content` String CODEC(ZSTD(1)), `output` String, INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1, INDEX id_idx id TYPE minmax GRANULARITY 10, INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1, INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2, INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3, INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1, INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') PARTITION BY toStartOfHour(`timestamp`) ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/create_table_with_keyword_partition_by.sql ================================================ CREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' ( `date` Date, `f1` String, `f2` String, `f3` UInt64 ) ENGINE = ReplacingMergeTree PARTITION BY date ORDER BY (f1, f2) SETTINGS index_granularity = 8192; ================================================ FILE: parser/testdata/ddl/create_table_with_null_engine.sql ================================================ CREATE TABLE logs.t0 on cluster default ( `trace_id` String CODEC(ZSTD(1)), INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64 ) ENGINE = Null(); ================================================ FILE: parser/testdata/ddl/create_table_with_nullable.sql ================================================ CREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5' ( `f0` String, `f1` String, `f2` LowCardinality(String), `f3` LowCardinality(String), `f4` DateTime64(3), `f5` Nullable(DateTime64(3)), `succeed_at` Nullable(DateTime64(3)) ) ENGINE = MergeTree PARTITION BY xxHash32(tag_id) % 20 ORDER BY label_id SETTINGS index_granularity = 8192; ================================================ FILE: parser/testdata/ddl/create_table_with_on_clsuter.sql ================================================ CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); ================================================ FILE: parser/testdata/ddl/create_table_with_projection.sql ================================================ CREATE TABLE events ( `event_time` DateTime, `event_id` UInt64, `user_id` UInt64, `huge_string` String, PROJECTION order_by_user_id ( SELECT _part_offset ORDER BY user_id ) ) ENGINE = MergeTree() ORDER BY (event_id); ================================================ FILE: parser/testdata/ddl/create_table_with_projection_group_by_only.sql ================================================ CREATE TABLE events ( `event_time` DateTime, `event_type` String, `user_id` UInt64, `value` Float64, PROJECTION hourly_aggregates ( SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY hour, event_type ) ) ENGINE = MergeTree() ORDER BY (event_time, event_type); ================================================ FILE: parser/testdata/ddl/create_table_with_qbit.sql ================================================ CREATE TABLE test.qbit_example ( id UInt32, vec QBit(Float32, 8) ) ENGINE = Memory; ================================================ FILE: parser/testdata/ddl/create_table_with_sample_by.sql ================================================ CREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e' ( `f0` DateTime, `f1` UInt32, `f3` UInt32 ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}') PARTITION BY toYYYYMM(timestamp) ORDER BY (contractid, toDate(timestamp), userid) SAMPLE BY userid SETTINGS index_granularity = 8192; ================================================ FILE: parser/testdata/ddl/create_table_with_ttl_policy.sql ================================================ CREATE TABLE tab ( d DateTime, a Int ) ENGINE = MergeTree PARTITION BY toYYYYMM(d) ORDER BY d TTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb'; CREATE TABLE table_with_where ( d DateTime, a Int ) ENGINE = MergeTree PARTITION BY toYYYYMM(d) ORDER BY d TTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1; CREATE TABLE table_for_recompression ( d DateTime, key UInt64, value String ) ENGINE MergeTree() ORDER BY tuple() PARTITION BY key TTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10)) SETTINGS min_rows_for_wide_part = 0, min_bytes_for_wide_part = 0, allow_experimental_replacing_merge_with_cleanup = true; ================================================ FILE: parser/testdata/ddl/create_table_with_tuple_fields.sql ================================================ CREATE TABLE t0 on cluster default_cluster ( `tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String)) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity = 8192; ================================================ FILE: parser/testdata/ddl/create_table_with_uuid.sql ================================================ CREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); ================================================ FILE: parser/testdata/ddl/create_user.sql ================================================ -- Basic CREATE USER tests CREATE USER user1; CREATE USER IF NOT EXISTS user2; CREATE USER OR REPLACE user3; CREATE USER user4, user5; -- CREATE USER with authentication CREATE USER user6 NOT IDENTIFIED; CREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123'; CREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123'; CREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server'; CREATE USER user10 IDENTIFIED WITH kerberos; CREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM'; -- CREATE USER with VALID UNTIL CREATE USER user33 VALID UNTIL '2026-12-12 00:00:00'; CREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15'; CREATE USER user35 VALID UNTIL 'infinity'; -- CREATE USER with host restrictions CREATE USER user12 HOST LOCAL; CREATE USER user13 HOST ANY; CREATE USER user14 HOST NONE; CREATE USER user15 HOST NAME 'localhost'; CREATE USER user16 HOST REGEXP '.*\.example\.com'; CREATE USER user17 HOST IP '192.168.1.1'; CREATE USER user18 HOST LIKE 'test%'; -- CREATE USER with default roles CREATE USER user19 DEFAULT ROLE role1; CREATE USER user20 DEFAULT ROLE role1, role2; CREATE USER user21 DEFAULT ROLE NONE; -- CREATE USER with default database CREATE USER user22 DEFAULT DATABASE test_db; CREATE USER user23 DEFAULT DATABASE NONE; -- CREATE USER with grantees CREATE USER user24 GRANTEES user1; CREATE USER user25 GRANTEES user1, user2; CREATE USER user26 GRANTEES ANY; CREATE USER user27 GRANTEES NONE; CREATE USER user28 GRANTEES user1, user2 EXCEPT user3; -- CREATE USER with settings CREATE USER user29 SETTINGS max_memory_usage=5000000; CREATE USER user30 SETTINGS PROFILE 'default'; CREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000; -- Complex CREATE USER with multiple clauses CREATE USER user32 IDENTIFIED WITH plaintext_password BY 'password' VALID UNTIL '2025-12-31' HOST NAME 'localhost' DEFAULT ROLE role1, role2 DEFAULT DATABASE test_db GRANTEES user1, user2 EXCEPT user3 SETTINGS max_memory_usage=5000000, readonly=1; ================================================ FILE: parser/testdata/ddl/create_view_basic.sql ================================================ CREATE VIEW IF NOT EXISTS my_view(col1 String, col2 String) AS SELECT id, name FROM my_table; ================================================ FILE: parser/testdata/ddl/create_view_on_cluster_with_uuid.sql ================================================ CREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS ( SELECT column1, column2 FROM my_other_table ); ================================================ FILE: parser/testdata/ddl/create_view_with_comment.sql ================================================ CREATE VIEW IF NOT EXISTS db.my_view ( `id` Int64, `name` String ) COMMENT '{"blueprint_hash":"abc123"}' AS SELECT id, name FROM db.my_table; ================================================ FILE: parser/testdata/ddl/create_with_time_zone.sql ================================================ CREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster ( `f0` Array(Tuple( f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1) ), `f1` UInt64 CODEC(Delta(8), LZ4), `f2` FixedString(16) CODEC(LZ4), `f3` FixedString(8) CODEC(LZ4), `f4` FixedString(8) CODEC(LZ4), `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4), `f6` UInt64 CODEC(Delta(8), LZ4), `f7` LowCardinality(String) CODEC(ZSTD(1)), `f8` String CODEC(ZSTD(1)), `f9` LowCardinality(String) CODEC(ZSTD(1)), `f10` String CODEC(ZSTD(1)), `f11` LowCardinality(String) CODEC(ZSTD(1)), `f12` LowCardinality(String) CODEC(ZSTD(1)), `f13` String CODEC(ZSTD(1)), `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)), `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)), `f18` Array(Tuple( f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)), `f184` String CODEC(ZSTD(1)), `f185` String CODEC(ZSTD(1)), `f186` String CODEC(ZSTD(1)), `f187` UInt32 CODEC(ZSTD(1)), `f188` DATETIME DEFAULT now(), INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f2 f2 TYPE minmax GRANULARITY 1, INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4, INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1, INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4 ) ENGINE = MergeTree PARTITION BY toDate(timestamp) ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp)) TTL toDate(timestamp) + toIntervalDay(15) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1 ================================================ FILE: parser/testdata/ddl/desc_table_with_table_keyword.sql ================================================ DESC TABLE mytable ================================================ FILE: parser/testdata/ddl/desc_table_without_table_keyword.sql ================================================ DESC mytable ================================================ FILE: parser/testdata/ddl/describe_table_with_table_keyword.sql ================================================ DESCRIBE TABLE mytable ================================================ FILE: parser/testdata/ddl/describe_table_without_table_keyword.sql ================================================ DESCRIBE mytable ================================================ FILE: parser/testdata/ddl/drop_database.sql ================================================ DROP DATABASE IF EXISTS datbase_name; ================================================ FILE: parser/testdata/ddl/drop_role.sql ================================================ DROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293; DROP ROLE IF EXISTS r2_01293_renamed; DROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com'; ================================================ FILE: parser/testdata/ddl/drop_table_basic.sql ================================================ DROP TABLE IF EXISTS test.table_name; ================================================ FILE: parser/testdata/ddl/drop_table_with_no_delay.sql ================================================ DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY; ================================================ FILE: parser/testdata/ddl/drop_table_with_on_clsuter.sql ================================================ DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/format/alter_role.sql ================================================ -- Origin SQL: -- Tags: no-parallel ALTER ROLE r1_01293; ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293; ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293; ALTER ROLE r1_01293 SETTINGS NONE; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000; ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST; ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; ALTER ROLE r1_01293, r2_01293; ALTER ROLE r1_01293 SETTINGS readonly=1; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; ALTER ROLE r5_01293 SETTINGS NONE; ALTER ROLE r1_01293@'%'; ALTER ROLE r2_01293@'%.myhost.com'; -- Format SQL: ALTER ROLE r1_01293; ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293; ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293; ALTER ROLE r1_01293 SETTINGS NONE; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000; ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST; ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; ALTER ROLE r1_01293, r2_01293; ALTER ROLE r1_01293 SETTINGS readonly=1; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; ALTER ROLE r5_01293 SETTINGS NONE; ALTER ROLE r1_01293@'%'; ALTER ROLE r2_01293@'%.myhost.com'; ================================================ FILE: parser/testdata/ddl/format/alter_table_add_column.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2; -- Format SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync=2; ================================================ FILE: parser/testdata/ddl/format/alter_table_add_index.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2; -- Format SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2; ================================================ FILE: parser/testdata/ddl/format/alter_table_add_projection.sql ================================================ -- Origin SQL: ALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id; -- Format SQL: ALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id; ================================================ FILE: parser/testdata/ddl/format/alter_table_add_projection_group_by_only.sql ================================================ -- Origin SQL: ALTER TABLE events ADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type); -- Format SQL: ALTER TABLE events ADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type); ================================================ FILE: parser/testdata/ddl/format/alter_table_attach_partition.sql ================================================ -- Origin SQL: ALTER TABLE test ATTACH PARTITION '20210114'; ALTER TABLE test ATTACH PARTITION '20210114' FROM test1; ALTER TABLE test ATTACH PARTITION ID '20210114'; -- Format SQL: ALTER TABLE test ATTACH PARTITION '20210114'; ALTER TABLE test ATTACH PARTITION '20210114' FROM test1; ALTER TABLE test ATTACH PARTITION '20210114'; ================================================ FILE: parser/testdata/ddl/format/alter_table_clear_column.sql ================================================ -- Origin SQL: ALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name; -- Format SQL: ALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/format/alter_table_clear_index.sql ================================================ -- Origin SQL: ALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name; -- Format SQL: ALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/format/alter_table_clear_projection.sql ================================================ -- Origin SQL: ALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name; -- Format SQL: ALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/format/alter_table_delete.sql ================================================ -- Origin SQL: ALTER TABLE test.events DELETE WHERE created_at < '2023-01-01'; -- Format SQL: ALTER TABLE test.events DELETE WHERE created_at < '2023-01-01'; ================================================ FILE: parser/testdata/ddl/format/alter_table_delete_with_cluster.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted'; -- Format SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted'; ================================================ FILE: parser/testdata/ddl/format/alter_table_detach_partition.sql ================================================ -- Origin SQL: ALTER TABLE db.test DETACH PARTITION '2021-10-01'; -- Format SQL: ALTER TABLE db.test DETACH PARTITION '2021-10-01'; ================================================ FILE: parser/testdata/ddl/format/alter_table_drop_column.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1; -- Format SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1; ================================================ FILE: parser/testdata/ddl/format/alter_table_drop_detach_partition.sql ================================================ -- Origin SQL: ALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached = 1; -- Format SQL: ALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached=1; ================================================ FILE: parser/testdata/ddl/format/alter_table_drop_index.sql ================================================ -- Origin SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1; -- Format SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1; ================================================ FILE: parser/testdata/ddl/format/alter_table_drop_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' drop partition '2023-07-18'; -- Format SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' DROP PARTITION '2023-07-18'; ================================================ FILE: parser/testdata/ddl/format/alter_table_drop_projection.sql ================================================ -- Origin SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1; -- Format SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1; ================================================ FILE: parser/testdata/ddl/format/alter_table_freeze_no_specify_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze; -- Format SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' FREEZE; ================================================ FILE: parser/testdata/ddl/format/alter_table_freeze_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze partition '2023-07-18';; -- Format SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' FREEZE PARTITION '2023-07-18'; ================================================ FILE: parser/testdata/ddl/format/alter_table_materialize_index.sql ================================================ -- Origin SQL: ALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403'; -- Format SQL: ALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403'; ================================================ FILE: parser/testdata/ddl/format/alter_table_materialize_projection.sql ================================================ -- Origin SQL: ALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403'; -- Format SQL: ALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403'; ================================================ FILE: parser/testdata/ddl/format/alter_table_modify_column.sql ================================================ -- Origin SQL: ALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test'; -- Format SQL: ALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test'; ================================================ FILE: parser/testdata/ddl/format/alter_table_modify_column_remove.sql ================================================ -- Origin SQL: ALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT; -- Format SQL: ALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT; ================================================ FILE: parser/testdata/ddl/format/alter_table_modify_setting.sql ================================================ -- Origin SQL: ALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000; -- Format SQL: ALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000; ================================================ FILE: parser/testdata/ddl/format/alter_table_remove_ttl.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL; -- Format SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL; ================================================ FILE: parser/testdata/ddl/format/alter_table_rename_column.sql ================================================ -- Origin SQL: ALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name; -- Format SQL: ALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name; ================================================ FILE: parser/testdata/ddl/format/alter_table_replace_partition.sql ================================================ -- Origin SQL: ALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1; -- Format SQL: ALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1; ================================================ FILE: parser/testdata/ddl/format/alter_table_reset_multiple_settings.sql ================================================ -- Origin SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting; -- Format SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting; ================================================ FILE: parser/testdata/ddl/format/alter_table_reset_setting.sql ================================================ -- Origin SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads; -- Format SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads; ================================================ FILE: parser/testdata/ddl/format/alter_table_update.sql ================================================ -- Origin SQL: ALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending'; -- Format SQL: ALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending'; ================================================ FILE: parser/testdata/ddl/format/alter_table_update_in_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active'; -- Format SQL: ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active'; ================================================ FILE: parser/testdata/ddl/format/alter_table_update_with_cluster.sql ================================================ -- Origin SQL: ALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100; -- Format SQL: ALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100; ================================================ FILE: parser/testdata/ddl/format/attach_table_basic.sql ================================================ -- Origin SQL: ATTACH TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); -- Format SQL: CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now()) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_role.sql ================================================ -- Origin SQL: -- Tags: no-parallel ALTER ROLE r1_01293; ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293; ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293; ALTER ROLE r1_01293 SETTINGS NONE; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000; ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST; ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; ALTER ROLE r1_01293, r2_01293; ALTER ROLE r1_01293 SETTINGS readonly=1; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; ALTER ROLE r5_01293 SETTINGS NONE; ALTER ROLE r1_01293@'%'; ALTER ROLE r2_01293@'%.myhost.com'; -- Beautify SQL: ALTER ROLE r1_01293; ALTER ROLE r1_01293 ON CLUSTER cluster_1 RENAME TO r2_01293; ALTER ROLE r1_01293 RENAME TO r2_01293, r3_01293 RENAME TO r4_01293; ALTER ROLE r1_01293 SETTINGS NONE; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000; ALTER ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; ALTER ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; ALTER ROLE r6_01293 SETTINGS max_memory_usage CONST; ALTER ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; ALTER ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; ALTER ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; ALTER ROLE r1_01293, r2_01293; ALTER ROLE r1_01293 SETTINGS readonly=1; ALTER ROLE r2_01293 SETTINGS PROFILE 'default'; ALTER ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; ALTER ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; ALTER ROLE r5_01293 SETTINGS NONE; ALTER ROLE r1_01293@'%'; ALTER ROLE r2_01293@'%.myhost.com'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_add_column.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync = 2; -- Beautify SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN f1 String AFTER f0 SETTINGS alter_sync=2; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_add_index.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2; -- Beautify SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX my_index(f0) TYPE minmax GRANULARITY 1024; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_add_projection.sql ================================================ -- Origin SQL: ALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id; -- Beautify SQL: ALTER TABLE visits_order ADD PROJECTION IF NOT EXISTS user_name_projection (SELECT * GROUP BY user_name ORDER BY user_name) AFTER a.user_id; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_add_projection_group_by_only.sql ================================================ -- Origin SQL: ALTER TABLE events ADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type); -- Beautify SQL: ALTER TABLE events ADD PROJECTION IF NOT EXISTS hourly_stats (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS count, uniq(user_id) AS users GROUP BY hour, event_type); ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_attach_partition.sql ================================================ -- Origin SQL: ALTER TABLE test ATTACH PARTITION '20210114'; ALTER TABLE test ATTACH PARTITION '20210114' FROM test1; ALTER TABLE test ATTACH PARTITION ID '20210114'; -- Beautify SQL: ALTER TABLE test ATTACH PARTITION '20210114'; ALTER TABLE test ATTACH PARTITION '20210114' FROM test1; ALTER TABLE test ATTACH PARTITION '20210114'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_clear_column.sql ================================================ -- Origin SQL: ALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name; -- Beautify SQL: ALTER TABLE my_table CLEAR COLUMN my_column_name IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_clear_index.sql ================================================ -- Origin SQL: ALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name; -- Beautify SQL: ALTER TABLE my_table CLEAR INDEX my_index_name IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_clear_projection.sql ================================================ -- Origin SQL: ALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name; -- Beautify SQL: ALTER TABLE my_table CLEAR PROJECTION hello IN PARTITION partition_name; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_delete.sql ================================================ -- Origin SQL: ALTER TABLE test.events DELETE WHERE created_at < '2023-01-01'; -- Beautify SQL: ALTER TABLE test.events DELETE WHERE created_at < '2023-01-01'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_delete_with_cluster.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted'; -- Beautify SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' DELETE WHERE id = 123 AND status = 'deleted'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_detach_partition.sql ================================================ -- Origin SQL: ALTER TABLE db.test DETACH PARTITION '2021-10-01'; -- Beautify SQL: ALTER TABLE db.test DETACH PARTITION '2021-10-01'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_drop_column.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1; -- Beautify SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' DROP COLUMN IF EXISTS f1; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_drop_detach_partition.sql ================================================ -- Origin SQL: ALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached = 1; -- Beautify SQL: ALTER TABLE app_utc_00.app_message_as_notification_organization_sent_stats_i_d_local DROP DETACHED PARTITION '2022-05-24' SETTINGS allow_drop_detached=1; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_drop_index.sql ================================================ -- Origin SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1; -- Beautify SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP INDEX f1; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_drop_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' drop partition '2023-07-18'; -- Beautify SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' DROP PARTITION '2023-07-18'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_drop_projection.sql ================================================ -- Origin SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1; -- Beautify SQL: ALTER TABLE test.event_local ON CLUSTER 'default_cluster' DROP PROJECTION f1; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_freeze_no_specify_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze; -- Beautify SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' FREEZE; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_freeze_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' freeze partition '2023-07-18';; -- Beautify SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' FREEZE PARTITION '2023-07-18'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_materialize_index.sql ================================================ -- Origin SQL: ALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403'; -- Beautify SQL: ALTER TABLE visits_order MATERIALIZE INDEX IF EXISTS user_name_index IN PARTITION '20240403'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_materialize_projection.sql ================================================ -- Origin SQL: ALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403'; -- Beautify SQL: ALTER TABLE visits_order MATERIALIZE PROJECTION IF EXISTS user_name_projection IN PARTITION '20240403'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_modify_column.sql ================================================ -- Origin SQL: ALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test'; -- Beautify SQL: ALTER TABLE t1 MODIFY COLUMN f1 String COMMENT 'test'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_modify_column_remove.sql ================================================ -- Origin SQL: ALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT; -- Beautify SQL: ALTER TABLE t1 MODIFY COLUMN f1 REMOVE COMMENT; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_modify_setting.sql ================================================ -- Origin SQL: ALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000; -- Beautify SQL: ALTER TABLE example_table MODIFY SETTING max_part_loading_threads=8, max_parts_in_total=50000; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_remove_ttl.sql ================================================ -- Origin SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL; -- Beautify SQL: ALTER TABLE test.events ON CLUSTER 'default_cluster' REMOVE TTL; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_rename_column.sql ================================================ -- Origin SQL: ALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name; -- Beautify SQL: ALTER TABLE my_table RENAME COLUMN old_column_name TO new_column_name; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_replace_partition.sql ================================================ -- Origin SQL: ALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1; -- Beautify SQL: ALTER TABLE t2 REPLACE PARTITION 'partition' FROM t1; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_reset_multiple_settings.sql ================================================ -- Origin SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting; -- Beautify SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads, max_parts_in_total, another_setting; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_reset_setting.sql ================================================ -- Origin SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads; -- Beautify SQL: ALTER TABLE example_table RESET SETTING max_part_loading_threads; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_update.sql ================================================ -- Origin SQL: ALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending'; -- Beautify SQL: ALTER TABLE test.users UPDATE status = 'active', updated_at = now() WHERE status = 'pending'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_update_in_partition.sql ================================================ -- Origin SQL: ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active'; -- Beautify SQL: ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active'; ================================================ FILE: parser/testdata/ddl/format/beautify/alter_table_update_with_cluster.sql ================================================ -- Origin SQL: ALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100; -- Beautify SQL: ALTER TABLE db.table ON CLUSTER cluster1 UPDATE column1 = column1 + 1 WHERE id > 100; ================================================ FILE: parser/testdata/ddl/format/beautify/attach_table_basic.sql ================================================ -- Origin SQL: ATTACH TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); -- Beautify SQL: CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH; ================================================ FILE: parser/testdata/ddl/format/beautify/bug_001.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS db.table ON CLUSTER 'default_cluster' TO db.table_mv AS SELECT event_ts, org_id, visitParamExtractString(properties, 'x') AS x, visitParamExtractString(properties, 'y') AS y, visitParamExtractString(properties, 'z') AS z, visitParamExtractString(properties, 'a') AS a, visitParamExtractString(properties, 'b') AS b, visitParamExtractString(properties, 'c') AS c, visitParamExtractString(properties, 'd') AS d, visitParamExtractInt(properties, 'e') AS e, visitParamExtractInt(properties, 'f') AS f FROM db.table WHERE db.table.event = 'hello'; -- Beautify SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS db.table ON CLUSTER 'default_cluster' TO db.table_mv AS SELECT event_ts, org_id, visitParamExtractString(properties, 'x') AS x, visitParamExtractString(properties, 'y') AS y, visitParamExtractString(properties, 'z') AS z, visitParamExtractString(properties, 'a') AS a, visitParamExtractString(properties, 'b') AS b, visitParamExtractString(properties, 'c') AS c, visitParamExtractString(properties, 'd') AS d, visitParamExtractInt(properties, 'e') AS e, visitParamExtractInt(properties, 'f') AS f FROM db.table WHERE db.table.event = 'hello'; ================================================ FILE: parser/testdata/ddl/format/beautify/check.sql ================================================ -- Origin SQL: CHECK TABLE test_table; CHECK TABLE test_table PARTITION 'col'; -- Beautify SQL: CHECK TABLE test_table; CHECK TABLE test_table PARTITION 'col'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_database.sql ================================================ -- Origin SQL: CREATE DATABASE IF NOT EXISTS `test` -- Beautify SQL: CREATE DATABASE IF NOT EXISTS `test`; ================================================ FILE: parser/testdata/ddl/format/beautify/create_database_replicated.sql ================================================ -- Origin SQL: CREATE DATABASE IF NOT EXISTS `test` ENGINE=Replicated('/root/test_local', 'shard', 'replica'); -- Beautify SQL: CREATE DATABASE IF NOT EXISTS `test` ENGINE = Replicated('/root/test_local', 'shard', 'replica'); ================================================ FILE: parser/testdata/ddl/format/beautify/create_dictionary_basic.sql ================================================ -- Origin SQL: CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192); -- Beautify SQL: CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192); ================================================ FILE: parser/testdata/ddl/format/beautify/create_dictionary_comprehensive.sql ================================================ -- Origin SQL: CREATE OR REPLACE DICTIONARY test.comprehensive_dict UUID '12345678-1234-1234-1234-123456789012' ON CLUSTER production_cluster ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192, max_insert_block_size = 1048576); -- Beautify SQL: CREATE OR REPLACE DICTIONARY test.comprehensive_dict UUID '12345678-1234-1234-1234-123456789012' ON CLUSTER production_cluster ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192, max_insert_block_size=1048576); ================================================ FILE: parser/testdata/ddl/format/beautify/create_dictionary_with_comment.sql ================================================ -- Origin SQL: CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192) COMMENT 'This is a test dictionary with comment'; -- Beautify SQL: CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192) COMMENT 'This is a test dictionary with comment'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_distributed_table.sql ================================================ -- Origin SQL: create table test.event_all ON CLUSTER 'default_cluster' AS test.evnets_local ENGINE = Distributed( default_cluster, test, events_local, rand() ) SETTINGS fsync_after_insert=0; -- Beautify SQL: CREATE TABLE test.event_all ON CLUSTER 'default_cluster' AS test.evnets_local ENGINE = Distributed(default_cluster, test, events_local, rand()) SETTINGS fsync_after_insert=0; ================================================ FILE: parser/testdata/ddl/format/beautify/create_function_simple.sql ================================================ -- Origin SQL: CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b; -- Beautify SQL: CREATE FUNCTION linear_equation AS (x, k, b) -> k * x + b; ================================================ FILE: parser/testdata/ddl/format/beautify/create_live_view_basic.sql ================================================ -- Origin SQL: CREATE LIVE VIEW my_live_view WITH TIMEOUT 10 TO my_destination(id String) AS SELECT id FROM my_table; -- Beautify SQL: CREATE LIVE VIEW my_live_view WITH TIMEOUT 10 TO my_destination ( id String ) AS SELECT id FROM my_table; ================================================ FILE: parser/testdata/ddl/format/beautify/create_materialized_view_basic.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' COMMENT 'Comment for table'; -- Beautify SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' COMMENT 'Comment for table'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_materialized_view_with_comment_before_as.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table ( `shop_id` UInt64, `event_type` LowCardinality(String), `created_at` DateTime64(9) ) COMMENT '{"blueprint_hash":"abc123","timestamp":"2026-04-08T12:00:00Z"}' AS SELECT shop_id, event_type, created_at FROM db.src_table; -- Beautify SQL: CREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table ( `shop_id` UInt64, `event_type` LowCardinality(String), `created_at` DateTime64(9) ) AS SELECT shop_id, event_type, created_at FROM db.src_table COMMENT '{"blueprint_hash":"abc123","timestamp":"2026-04-08T12:00:00Z"}'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_materialized_view_with_definer.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export ( `timestamp` DateTime64(9), `field_1` String, `field_2` String, ) DEFINER = default SQL SECURITY DEFINER AS (SELECT timestamp, field_1, field_2, FROM event_table WHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1))) COMMENT 'Test comment' -- Beautify SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export ( `timestamp` DateTime64(9), `field_1` String, `field_2` String ) DEFINER = default SQL SECURITY DEFINER AS (SELECT timestamp, field_1, field_2, FROM AS event_table WHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1))) COMMENT 'Test comment'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_materialized_view_with_empty_table_schema.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW test.t0 on cluster default_cluster ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}') PARTITION BY toYYYYMM(f0) ORDER BY (f0) POPULATE AS select f0,f1,f2,coalesce(f0,f1) as f333 from (select f0,f1,f2, ROW_NUMBER() over(partition by f0 order by coalesce(f1,f2)) as rn from test.t where f3 in ('foo', 'bar', 'test') and env ='test' ) as tmp where rn = 1; -- Beautify SQL: CREATE MATERIALIZED VIEW test.t0 ON CLUSTER default_cluster ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}') ORDER BY (f0) PARTITION BY toYYYYMM(f0) POPULATE AS SELECT f0, f1, f2, coalesce(f0, f1) AS f333 FROM (SELECT f0, f1, f2, ROW_NUMBER() OVER (PARTITION BY f0 ORDER BY coalesce(f1, f2)) AS rn FROM test.t WHERE f3 IN ('foo', 'bar', 'test') AND env = 'test') AS tmp WHERE rn = 1; ================================================ FILE: parser/testdata/ddl/format/beautify/create_materialized_view_with_gcs.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW database_name.view_name REFRESH EVERY 5 MINUTE TO database_name.table_name AS SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/'); -- Beautify SQL: CREATE MATERIALIZED VIEW database_name.view_name REFRESH EVERY 5 MINUTE TO database_name.table_name AS SELECT * FROM gcs(gcs_creds, url='https://storage.googleapis.com/some-bucket/some-path/'); ================================================ FILE: parser/testdata/ddl/format/beautify/create_materialized_view_with_refresh.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE RANDOMIZE FOR 1 SECOND DEPENDS ON table_v5 SETTINGS randomize_for = 1, randomize_offset = 10, randomize_period = 1 APPEND TO target_table_name EMPTY AS SELECT `field_1`, `field_2`, `field_3`, FROM table_v5 -- Beautify SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE RANDOMIZE FOR 1 SECOND DEPENDS ON table_v5 SETTINGS randomize_for=1, randomize_offset=10, randomize_period=1 APPEND TO target_table_name EMPTY AS SELECT `field_1`, `field_2`, `field_3`, FROM AS table_v5; ================================================ FILE: parser/testdata/ddl/format/beautify/create_mv_with_not_op.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' AND NOT isZeroOrNull(f2) AND f6-2 > 0 -- Beautify SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' AND NOT isZeroOrNull(f2) AND f6 - 2 > 0; ================================================ FILE: parser/testdata/ddl/format/beautify/create_mv_with_order_by.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) ORDER BY (id) AS SELECT * FROM test_table; CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) AS SELECT * FROM test_table; -- Beautify SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() ORDER BY (id) PRIMARY KEY (id) AS SELECT * FROM test_table; CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) AS SELECT * FROM test_table; ================================================ FILE: parser/testdata/ddl/format/beautify/create_named_collection_basic.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin'; -- Beautify SQL: CREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_named_collection_simple.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2'; -- Beautify SQL: CREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_named_collection_with_cluster.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3'; -- Beautify SQL: CREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_named_collection_with_overridable.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456'; -- Beautify SQL: CREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_or_replace.sql ================================================ -- Origin SQL: -- It's a short link events table /** * @name Short link events * @description It's a short link events table */ CREATE OR REPLACE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), ) ENGINE = MergeTree PRIMARY KEY (f0, f1, f2) PARTITION BY toYYYYMMDD(f1) TTL f1 + INTERVAL 6 MONTH ORDER BY (f1,f2) COMMENT 'Comment for table'; CREATE OR REPLACE VIEW IF NOT EXISTS my_view(col1 String, col2 String) AS SELECT id, name FROM my_table; CREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y; -- Beautify SQL: CREATE OR REPLACE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255) ) ENGINE = MergeTree ORDER BY (f1, f2) PARTITION BY toYYYYMMDD(f1) PRIMARY KEY (f0, f1, f2) TTL f1 + INTERVAL 6 MONTH COMMENT 'Comment for table'; CREATE OR REPLACE VIEW IF NOT EXISTS my_view ( col1 String, col2 String ) AS SELECT id, name FROM my_table; CREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y; ================================================ FILE: parser/testdata/ddl/format/beautify/create_role.sql ================================================ -- Origin SQL: -- Tags: no-parallel CREATE ROLE r1_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2; CREATE ROLE r1_01293 SETTINGS NONE; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000; CREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; CREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; CREATE ROLE r6_01293 SETTINGS max_memory_usage CONST; CREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; CREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; CREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 SETTINGS readonly=1; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; CREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; CREATE ROLE r5_01293 SETTINGS NONE; CREATE ROLE r1_01293@'%'; CREATE ROLE r2_01293@'%.myhost.com'; -- Beautify SQL: CREATE ROLE r1_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2; CREATE ROLE r1_01293 SETTINGS NONE; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000; CREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; CREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; CREATE ROLE r6_01293 SETTINGS max_memory_usage CONST; CREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; CREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; CREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 SETTINGS readonly=1; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; CREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; CREATE ROLE r5_01293 SETTINGS NONE; CREATE ROLE r1_01293@'%'; CREATE ROLE r2_01293@'%.myhost.com'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_as_remote_function.sql ================================================ -- Origin SQL: -- CREATE TABLE with columns AS table function (remoteSecure) CREATE TABLE test_remote ( id UInt64, name String, value Int32 ) AS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password'); -- Simpler test case with remote() CREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table'); -- Beautify SQL: CREATE TABLE test_remote ( id UInt64, name String, value Int32 ) AS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password'); CREATE TABLE test_table ( id UInt64, name String ) AS remote('localhost', 'db', 'source_table'); ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_basic.sql ================================================ -- Origin SQL: -- It's a short link events table /** * @name Short link events * @description It's a short link events table */ CREATE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Nested ( f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String ), f8 Datetime DEFAULT now(), f9 String MATERIALIZED toString(f7['f70']), f10 String ALIAS f11, f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello'), ) ENGINE = MergeTree PRIMARY KEY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH ORDER BY (f1,f2,f3) COMMENT 'Comment for table'; -- Beautify SQL: CREATE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Nested(f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String), f8 Datetime DEFAULT now(), f9 String MATERIALIZED toString(f7['f70']), f10 String ALIAS f11, f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello') ) ENGINE = MergeTree ORDER BY (f1, f2, f3) PARTITION BY toYYYYMMDD(f3) PRIMARY KEY (f0, f1, f2) TTL f3 + INTERVAL 6 MONTH COMMENT 'Comment for table'; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_codec_no_args.sql ================================================ -- Origin SQL: CREATE TABLE shark_attacks ( timestamp DateTime CODEC(DoubleDelta), ); -- Beautify SQL: CREATE TABLE shark_attacks ( timestamp DateTime CODEC(DoubleDelta) ); ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_json_typehints.sql ================================================ -- Origin SQL: CREATE TABLE t ( j JSON(message String, a.b UInt64, max_dynamic_paths=0, SKIP x, SKIP REGEXP 're') ) ENGINE = MergeTree ORDER BY tuple(); -- Beautify SQL: CREATE TABLE t ( j JSON(max_dynamic_paths=0, message String, a.b UInt64, SKIP x, SKIP REGEXP 're') ) ENGINE = MergeTree ORDER BY tuple(); ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_codec_delta.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test_local ( `id` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `app_id` UInt64 CODEC(Delta(9), ZSTD(1)), `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)), `guage` Float64 CODEC(Gorilla, LZ4), `value` UInt64 CODEC(T64, LZ4), `timestamp` DateTime64(9) CODEC(ZSTD(1)), INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') PARTITION BY toStartOfHour(`timestamp`) ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; -- Beautify SQL: CREATE TABLE IF NOT EXISTS test_local ( `id` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `app_id` UInt64 CODEC(Delta(9), ZSTD(1)), `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)), `guage` Float64 CODEC(Gorilla, LZ4), `value` UInt64 CODEC(T64, LZ4), `timestamp` DateTime64(9) CODEC(ZSTD(1)), INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) PARTITION BY toStartOfHour(`timestamp`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_enum_fields.sql ================================================ -- Origin SQL: CREATE TABLE t0 on cluster default_cluster ( `method` Enum8('GET'=1 , 'POST'=2, 'HEAD'=3, 'PUT'=4,'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)), `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') PARTITION BY toDate(timestamp) ORDER BY (method,timestamp) TTL toDate(timestamp) + toIntervalDay(3) SETTINGS index_granularity = 8192; -- Beautify SQL: CREATE TABLE t0 ON CLUSTER default_cluster ( `method` Enum8('GET'=1, 'POST'=2, 'HEAD'=3, 'PUT'=4, 'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)), `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (method, timestamp) PARTITION BY toDate(timestamp) TTL toDate(timestamp) + toIntervalDay(3) SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_index.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test_local ( `common.id` String CODEC(ZSTD(1)), `id` UInt64 CODEC(Delta, ZSTD(1)), `idx` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `arr` Array(Int64), `content` String CODEC(ZSTD(1)), `output` String, INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1, INDEX id_idx id TYPE minmax GRANULARITY 10, INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1, INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2, INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3, INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1, INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') PARTITION BY toStartOfHour(`timestamp`) ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; -- Beautify SQL: CREATE TABLE IF NOT EXISTS test_local ( `common.id` String CODEC(ZSTD(1)), `id` UInt64 CODEC(Delta, ZSTD(1)), `idx` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `arr` Array(Int64), `content` String CODEC(ZSTD(1)), `output` String, INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1, INDEX id_idx id TYPE minmax GRANULARITY 10, INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1, INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2, INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3, INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1, INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) PARTITION BY toStartOfHour(`timestamp`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_keyword_partition_by.sql ================================================ -- Origin SQL: CREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' ( `date` Date, `f1` String, `f2` String, `f3` UInt64 ) ENGINE = ReplacingMergeTree PARTITION BY date ORDER BY (f1, f2) SETTINGS index_granularity = 8192; -- Beautify SQL: CREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' ( `date` Date, `f1` String, `f2` String, `f3` UInt64 ) ENGINE = ReplacingMergeTree ORDER BY (f1, f2) PARTITION BY date SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_null_engine.sql ================================================ -- Origin SQL: CREATE TABLE logs.t0 on cluster default ( `trace_id` String CODEC(ZSTD(1)), INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64 ) ENGINE = Null(); -- Beautify SQL: CREATE TABLE logs.t0 ON CLUSTER default ( `trace_id` String CODEC(ZSTD(1)), INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64 ) ENGINE = Null(); ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_nullable.sql ================================================ -- Origin SQL: CREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5' ( `f0` String, `f1` String, `f2` LowCardinality(String), `f3` LowCardinality(String), `f4` DateTime64(3), `f5` Nullable(DateTime64(3)), `succeed_at` Nullable(DateTime64(3)) ) ENGINE = MergeTree PARTITION BY xxHash32(tag_id) % 20 ORDER BY label_id SETTINGS index_granularity = 8192; -- Beautify SQL: CREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5' ( `f0` String, `f1` String, `f2` LowCardinality(String), `f3` LowCardinality(String), `f4` DateTime64(3), `f5` Nullable(DateTime64(3)), `succeed_at` Nullable(DateTime64(3)) ) ENGINE = MergeTree ORDER BY label_id PARTITION BY xxHash32(tag_id) % 20 SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_on_clsuter.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); -- Beautify SQL: CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_projection.sql ================================================ -- Origin SQL: CREATE TABLE events ( `event_time` DateTime, `event_id` UInt64, `user_id` UInt64, `huge_string` String, PROJECTION order_by_user_id ( SELECT _part_offset ORDER BY user_id ) ) ENGINE = MergeTree() ORDER BY (event_id); -- Beautify SQL: CREATE TABLE events ( `event_time` DateTime, `event_id` UInt64, `user_id` UInt64, `huge_string` String, PROJECTION order_by_user_id (SELECT _part_offset ORDER BY user_id) ) ENGINE = MergeTree() ORDER BY (event_id); ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_projection_group_by_only.sql ================================================ -- Origin SQL: CREATE TABLE events ( `event_time` DateTime, `event_type` String, `user_id` UInt64, `value` Float64, PROJECTION hourly_aggregates ( SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY hour, event_type ) ) ENGINE = MergeTree() ORDER BY (event_time, event_type); -- Beautify SQL: CREATE TABLE events ( `event_time` DateTime, `event_type` String, `user_id` UInt64, `value` Float64, PROJECTION hourly_aggregates (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY hour, event_type) ) ENGINE = MergeTree() ORDER BY (event_time, event_type); ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_qbit.sql ================================================ -- Origin SQL: CREATE TABLE test.qbit_example ( id UInt32, vec QBit(Float32, 8) ) ENGINE = Memory; -- Beautify SQL: CREATE TABLE test.qbit_example ( id UInt32, vec QBit(Float32, 8) ) ENGINE = Memory; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_sample_by.sql ================================================ -- Origin SQL: CREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e' ( `f0` DateTime, `f1` UInt32, `f3` UInt32 ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}') PARTITION BY toYYYYMM(timestamp) ORDER BY (contractid, toDate(timestamp), userid) SAMPLE BY userid SETTINGS index_granularity = 8192; -- Beautify SQL: CREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e' ( `f0` DateTime, `f1` UInt32, `f3` UInt32 ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}') ORDER BY (contractid, toDate(timestamp), userid) PARTITION BY toYYYYMM(timestamp) SAMPLE BY userid SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_ttl_policy.sql ================================================ -- Origin SQL: CREATE TABLE tab ( d DateTime, a Int ) ENGINE = MergeTree PARTITION BY toYYYYMM(d) ORDER BY d TTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb'; CREATE TABLE table_with_where ( d DateTime, a Int ) ENGINE = MergeTree PARTITION BY toYYYYMM(d) ORDER BY d TTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1; CREATE TABLE table_for_recompression ( d DateTime, key UInt64, value String ) ENGINE MergeTree() ORDER BY tuple() PARTITION BY key TTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10)) SETTINGS min_rows_for_wide_part = 0, min_bytes_for_wide_part = 0, allow_experimental_replacing_merge_with_cleanup = true; -- Beautify SQL: CREATE TABLE tab ( d DateTime, a Int ) ENGINE = MergeTree ORDER BY d PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb'; CREATE TABLE table_with_where ( d DateTime, a Int ) ENGINE = MergeTree ORDER BY d PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1; CREATE TABLE table_for_recompression ( d DateTime, key UInt64, value String ) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY key TTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10)) SETTINGS min_rows_for_wide_part=0, min_bytes_for_wide_part=0, allow_experimental_replacing_merge_with_cleanup=true; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_tuple_fields.sql ================================================ -- Origin SQL: CREATE TABLE t0 on cluster default_cluster ( `tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String)) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity = 8192; -- Beautify SQL: CREATE TABLE t0 ON CLUSTER default_cluster ( `tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String)) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/beautify/create_table_with_uuid.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); -- Beautify SQL: CREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH; ================================================ FILE: parser/testdata/ddl/format/beautify/create_user.sql ================================================ -- Origin SQL: -- Basic CREATE USER tests CREATE USER user1; CREATE USER IF NOT EXISTS user2; CREATE USER OR REPLACE user3; CREATE USER user4, user5; -- CREATE USER with authentication CREATE USER user6 NOT IDENTIFIED; CREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123'; CREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123'; CREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server'; CREATE USER user10 IDENTIFIED WITH kerberos; CREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM'; -- CREATE USER with VALID UNTIL CREATE USER user33 VALID UNTIL '2026-12-12 00:00:00'; CREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15'; CREATE USER user35 VALID UNTIL 'infinity'; -- CREATE USER with host restrictions CREATE USER user12 HOST LOCAL; CREATE USER user13 HOST ANY; CREATE USER user14 HOST NONE; CREATE USER user15 HOST NAME 'localhost'; CREATE USER user16 HOST REGEXP '.*\.example\.com'; CREATE USER user17 HOST IP '192.168.1.1'; CREATE USER user18 HOST LIKE 'test%'; -- CREATE USER with default roles CREATE USER user19 DEFAULT ROLE role1; CREATE USER user20 DEFAULT ROLE role1, role2; CREATE USER user21 DEFAULT ROLE NONE; -- CREATE USER with default database CREATE USER user22 DEFAULT DATABASE test_db; CREATE USER user23 DEFAULT DATABASE NONE; -- CREATE USER with grantees CREATE USER user24 GRANTEES user1; CREATE USER user25 GRANTEES user1, user2; CREATE USER user26 GRANTEES ANY; CREATE USER user27 GRANTEES NONE; CREATE USER user28 GRANTEES user1, user2 EXCEPT user3; -- CREATE USER with settings CREATE USER user29 SETTINGS max_memory_usage=5000000; CREATE USER user30 SETTINGS PROFILE 'default'; CREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000; -- Complex CREATE USER with multiple clauses CREATE USER user32 IDENTIFIED WITH plaintext_password BY 'password' VALID UNTIL '2025-12-31' HOST NAME 'localhost' DEFAULT ROLE role1, role2 DEFAULT DATABASE test_db GRANTEES user1, user2 EXCEPT user3 SETTINGS max_memory_usage=5000000, readonly=1; -- Beautify SQL: CREATE USER user1; CREATE USER IF NOT EXISTS user2; CREATE USER OR REPLACE user3; CREATE USER user4, user5; CREATE USER user6 NOT IDENTIFIED; CREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123'; CREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123'; CREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server'; CREATE USER user10 IDENTIFIED WITH kerberos; CREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM'; CREATE USER user33 VALID UNTIL '2026-12-12 00:00:00'; CREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15'; CREATE USER user35 VALID UNTIL 'infinity'; CREATE USER user12 HOST LOCAL; CREATE USER user13 HOST ANY; CREATE USER user14 HOST NONE; CREATE USER user15 HOST NAME 'localhost'; CREATE USER user16 HOST REGEXP '.*\.example\.com'; CREATE USER user17 HOST IP '192.168.1.1'; CREATE USER user18 HOST LIKE 'test%'; CREATE USER user19 DEFAULT ROLE role1; CREATE USER user20 DEFAULT ROLE role1, role2; CREATE USER user21 DEFAULT ROLE NONE; CREATE USER user22 DEFAULT DATABASE test_db; CREATE USER user23 DEFAULT DATABASE NONE; CREATE USER user24 GRANTEES user1; CREATE USER user25 GRANTEES user1, user2; CREATE USER user26 GRANTEES ANY; CREATE USER user27 GRANTEES NONE; CREATE USER user28 GRANTEES user1, user2 EXCEPT user3; CREATE USER user29 SETTINGS max_memory_usage=5000000; CREATE USER user30 SETTINGS PROFILE 'default'; CREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000; CREATE USER user32 IDENTIFIED WITH plaintext_password BY 'password' VALID UNTIL '2025-12-31' HOST NAME 'localhost' DEFAULT ROLE role1, role2 DEFAULT DATABASE test_db GRANTEES user1, user2 EXCEPT user3 SETTINGS max_memory_usage=5000000, readonly=1; ================================================ FILE: parser/testdata/ddl/format/beautify/create_view_basic.sql ================================================ -- Origin SQL: CREATE VIEW IF NOT EXISTS my_view(col1 String, col2 String) AS SELECT id, name FROM my_table; -- Beautify SQL: CREATE VIEW IF NOT EXISTS my_view ( col1 String, col2 String ) AS SELECT id, name FROM my_table; ================================================ FILE: parser/testdata/ddl/format/beautify/create_view_on_cluster_with_uuid.sql ================================================ -- Origin SQL: CREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS ( SELECT column1, column2 FROM my_other_table ); -- Beautify SQL: CREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS (SELECT column1, column2 FROM my_other_table); ================================================ FILE: parser/testdata/ddl/format/beautify/create_view_with_comment.sql ================================================ -- Origin SQL: CREATE VIEW IF NOT EXISTS db.my_view ( `id` Int64, `name` String ) COMMENT '{"blueprint_hash":"abc123"}' AS SELECT id, name FROM db.my_table; -- Beautify SQL: CREATE VIEW IF NOT EXISTS db.my_view ( `id` Int64, `name` String ) COMMENT '{"blueprint_hash":"abc123"}' AS SELECT id, name FROM db.my_table; ================================================ FILE: parser/testdata/ddl/format/beautify/create_with_time_zone.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster ( `f0` Array(Tuple( f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1) ), `f1` UInt64 CODEC(Delta(8), LZ4), `f2` FixedString(16) CODEC(LZ4), `f3` FixedString(8) CODEC(LZ4), `f4` FixedString(8) CODEC(LZ4), `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4), `f6` UInt64 CODEC(Delta(8), LZ4), `f7` LowCardinality(String) CODEC(ZSTD(1)), `f8` String CODEC(ZSTD(1)), `f9` LowCardinality(String) CODEC(ZSTD(1)), `f10` String CODEC(ZSTD(1)), `f11` LowCardinality(String) CODEC(ZSTD(1)), `f12` LowCardinality(String) CODEC(ZSTD(1)), `f13` String CODEC(ZSTD(1)), `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)), `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)), `f18` Array(Tuple( f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)), `f184` String CODEC(ZSTD(1)), `f185` String CODEC(ZSTD(1)), `f186` String CODEC(ZSTD(1)), `f187` UInt32 CODEC(ZSTD(1)), `f188` DATETIME DEFAULT now(), INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f2 f2 TYPE minmax GRANULARITY 1, INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4, INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1, INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4 ) ENGINE = MergeTree PARTITION BY toDate(timestamp) ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp)) TTL toDate(timestamp) + toIntervalDay(15) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1 -- Beautify SQL: CREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster ( `f0` Array(Tuple(f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1)), `f1` UInt64 CODEC(Delta(8), LZ4), `f2` FixedString(16) CODEC(LZ4), `f3` FixedString(8) CODEC(LZ4), `f4` FixedString(8) CODEC(LZ4), `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4), `f6` UInt64 CODEC(Delta(8), LZ4), `f7` LowCardinality(String) CODEC(ZSTD(1)), `f8` String CODEC(ZSTD(1)), `f9` LowCardinality(String) CODEC(ZSTD(1)), `f10` String CODEC(ZSTD(1)), `f11` LowCardinality(String) CODEC(ZSTD(1)), `f12` LowCardinality(String) CODEC(ZSTD(1)), `f13` String CODEC(ZSTD(1)), `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)), `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)), `f18` Array(Tuple(f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)), `f184` String CODEC(ZSTD(1)), `f185` String CODEC(ZSTD(1)), `f186` String CODEC(ZSTD(1)), `f187` UInt32 CODEC(ZSTD(1)), `f188` DATETIME DEFAULT now(), INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f2 f2 TYPE minmax GRANULARITY 1, INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4, INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1, INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4 ) ENGINE = MergeTree ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp)) PARTITION BY toDate(timestamp) TTL toDate(timestamp) + toIntervalDay(15) SETTINGS index_granularity=8192, ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/format/beautify/desc_table_with_table_keyword.sql ================================================ -- Origin SQL: DESC TABLE mytable -- Beautify SQL: DESCRIBE TABLE mytable; ================================================ FILE: parser/testdata/ddl/format/beautify/desc_table_without_table_keyword.sql ================================================ -- Origin SQL: DESC mytable -- Beautify SQL: DESCRIBE mytable; ================================================ FILE: parser/testdata/ddl/format/beautify/describe_table_with_table_keyword.sql ================================================ -- Origin SQL: DESCRIBE TABLE mytable -- Beautify SQL: DESCRIBE TABLE mytable; ================================================ FILE: parser/testdata/ddl/format/beautify/describe_table_without_table_keyword.sql ================================================ -- Origin SQL: DESCRIBE mytable -- Beautify SQL: DESCRIBE mytable; ================================================ FILE: parser/testdata/ddl/format/beautify/drop_database.sql ================================================ -- Origin SQL: DROP DATABASE IF EXISTS datbase_name; -- Beautify SQL: DROP DATABASE IF EXISTS datbase_name; ================================================ FILE: parser/testdata/ddl/format/beautify/drop_role.sql ================================================ -- Origin SQL: DROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293; DROP ROLE IF EXISTS r2_01293_renamed; DROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com'; -- Beautify SQL: DROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293; DROP ROLE IF EXISTS r2_01293_renamed; DROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com'; ================================================ FILE: parser/testdata/ddl/format/beautify/drop_table_basic.sql ================================================ -- Origin SQL: DROP TABLE IF EXISTS test.table_name; -- Beautify SQL: DROP TABLE IF EXISTS test.table_name; ================================================ FILE: parser/testdata/ddl/format/beautify/drop_table_with_no_delay.sql ================================================ -- Origin SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY; -- Beautify SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY; ================================================ FILE: parser/testdata/ddl/format/beautify/drop_table_with_on_clsuter.sql ================================================ -- Origin SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; -- Beautify SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/format/beautify/grant_privilege.sql ================================================ -- Origin SQL: GRANT SELECT(x,y) ON db.table TO john; GRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION; GRANT SELECT(x,y) ON db.* TO john; GRANT SELECT(x,y) ON *.table TO john; GRANT SELECT(x,y) ON *.* TO john; GRANT SELECT(x,y) ON *.table TO CURRENT_USER; GRANT SELECT(x,y) ON *.table TO CURRENT_USER,john,mary; GRANT ALL ON *.* TO admin_role WITH GRANT OPTION; GRANT SELECT,INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT(x, y, z),INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT, dictGet ON *.* TO select_all_role; GRANT ADMIN OPTION ON *.* TO select_all_role; -- Beautify SQL: GRANT SELECT(x, y) ON db.table TO john; GRANT SELECT(x, y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION; GRANT SELECT(x, y) ON db.* TO john; GRANT SELECT(x, y) ON *.table TO john; GRANT SELECT(x, y) ON *.* TO john; GRANT SELECT(x, y) ON *.table TO CURRENT_USER; GRANT SELECT(x, y) ON *.table TO CURRENT_USER, john, mary; GRANT ALL ON *.* TO admin_role WITH GRANT OPTION; GRANT SELECT, INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT(x, y, z), INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT, dictGet ON *.* TO select_all_role; GRANT ADMIN OPTION ON *.* TO select_all_role; ================================================ FILE: parser/testdata/ddl/format/beautify/optimize.sql ================================================ -- Origin SQL: OPTIMIZE TABLE table DEDUPLICATE; -- all columns OPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns OPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex'); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY); -- Beautify SQL: OPTIMIZE TABLE table DEDUPLICATE; OPTIMIZE TABLE table DEDUPLICATE BY *; OPTIMIZE TABLE table DEDUPLICATE BY colX, colY, colZ; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex'); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY); ================================================ FILE: parser/testdata/ddl/format/beautify/rename.sql ================================================ -- Origin SQL: -- rename table RENAME TABLE t1 TO t11; RENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME TABLE t1 TO t11, t2 TO t22; RENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- rename dictionary RENAME DICTIONARY t1 TO t11; RENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11, t2 TO t22; RENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- rename database RENAME DATABASE t1 TO t11; RENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11, t2 TO t22; RENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- Beautify SQL: RENAME TABLE t1 TO t11; RENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME TABLE t1 TO t11, t2 TO t22; RENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11; RENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11, t2 TO t22; RENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11; RENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11, t2 TO t22; RENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_create_table.sql ================================================ -- Origin SQL: SHOW CREATE TABLE mytable -- Beautify SQL: SHOW CREATE TABLE mytable; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases.sql ================================================ -- Origin SQL: SHOW DATABASES -- Beautify SQL: SHOW DATABASES; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_comprehensive.sql ================================================ -- Origin SQL: SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON -- Beautify SQL: SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT 'JSON'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_format.sql ================================================ -- Origin SQL: SHOW DATABASES FORMAT JSON -- Beautify SQL: SHOW DATABASES FORMAT 'JSON'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_format_string.sql ================================================ -- Origin SQL: SHOW DATABASES FORMAT 'TabSeparated' -- Beautify SQL: SHOW DATABASES FORMAT 'TabSeparated'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_ilike.sql ================================================ -- Origin SQL: SHOW DATABASES ILIKE 'Test%' -- Beautify SQL: SHOW DATABASES ILIKE 'Test%'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_like.sql ================================================ -- Origin SQL: SHOW DATABASES LIKE 'test%' -- Beautify SQL: SHOW DATABASES LIKE 'test%'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_limit.sql ================================================ -- Origin SQL: SHOW DATABASES LIMIT 10 -- Beautify SQL: SHOW DATABASES LIMIT 10; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_not_ilike.sql ================================================ -- Origin SQL: SHOW DATABASES NOT ILIKE 'Temp%' -- Beautify SQL: SHOW DATABASES NOT ILIKE 'Temp%'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_not_like.sql ================================================ -- Origin SQL: SHOW DATABASES NOT LIKE 'temp%' -- Beautify SQL: SHOW DATABASES NOT LIKE 'temp%'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_databases_outfile.sql ================================================ -- Origin SQL: SHOW DATABASES INTO OUTFILE '/tmp/databases.txt' -- Beautify SQL: SHOW DATABASES INTO OUTFILE '/tmp/databases.txt'; ================================================ FILE: parser/testdata/ddl/format/beautify/show_tables.sql ================================================ -- Origin SQL: SHOW TABLES -- Beautify SQL: SHOW TABLES; ================================================ FILE: parser/testdata/ddl/format/beautify/systems.sql ================================================ -- Origin SQL: SYSTEM FLUSH LOGS; SYSTEM DROP UNCOMPRESSED CACHE; SYSTEM DROP FILESYSTEM CACHE; -- Beautify SQL: SYSTEM FLUSH LOGS; SYSTEM DROP UNCOMPRESSED CACHE; SYSTEM DROP FILESYSTEM CACHE; ================================================ FILE: parser/testdata/ddl/format/beautify/truncate_table_basic.sql ================================================ -- Origin SQL: TRUNCATE TABLE IF EXISTS test.table_name; -- Beautify SQL: TRUNCATE TABLE IF EXISTS test.table_name; ================================================ FILE: parser/testdata/ddl/format/beautify/truncate_temporary_table_on_clsuter.sql ================================================ -- Origin SQL: TRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; -- Beautify SQL: TRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/format/bug_001.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS db.table ON CLUSTER 'default_cluster' TO db.table_mv AS SELECT event_ts, org_id, visitParamExtractString(properties, 'x') AS x, visitParamExtractString(properties, 'y') AS y, visitParamExtractString(properties, 'z') AS z, visitParamExtractString(properties, 'a') AS a, visitParamExtractString(properties, 'b') AS b, visitParamExtractString(properties, 'c') AS c, visitParamExtractString(properties, 'd') AS d, visitParamExtractInt(properties, 'e') AS e, visitParamExtractInt(properties, 'f') AS f FROM db.table WHERE db.table.event = 'hello'; -- Format SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS db.table ON CLUSTER 'default_cluster' TO db.table_mv AS SELECT event_ts, org_id, visitParamExtractString(properties, 'x') AS x, visitParamExtractString(properties, 'y') AS y, visitParamExtractString(properties, 'z') AS z, visitParamExtractString(properties, 'a') AS a, visitParamExtractString(properties, 'b') AS b, visitParamExtractString(properties, 'c') AS c, visitParamExtractString(properties, 'd') AS d, visitParamExtractInt(properties, 'e') AS e, visitParamExtractInt(properties, 'f') AS f FROM db.table WHERE db.table.event = 'hello'; ================================================ FILE: parser/testdata/ddl/format/check.sql ================================================ -- Origin SQL: CHECK TABLE test_table; CHECK TABLE test_table PARTITION 'col'; -- Format SQL: CHECK TABLE test_table; CHECK TABLE test_table PARTITION 'col'; ================================================ FILE: parser/testdata/ddl/format/create_database.sql ================================================ -- Origin SQL: CREATE DATABASE IF NOT EXISTS `test` -- Format SQL: CREATE DATABASE IF NOT EXISTS `test`; ================================================ FILE: parser/testdata/ddl/format/create_database_replicated.sql ================================================ -- Origin SQL: CREATE DATABASE IF NOT EXISTS `test` ENGINE=Replicated('/root/test_local', 'shard', 'replica'); -- Format SQL: CREATE DATABASE IF NOT EXISTS `test` ENGINE = Replicated('/root/test_local', 'shard', 'replica'); ================================================ FILE: parser/testdata/ddl/format/create_dictionary_basic.sql ================================================ -- Origin SQL: CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192); -- Format SQL: CREATE DICTIONARY test.my_dict (id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192); ================================================ FILE: parser/testdata/ddl/format/create_dictionary_comprehensive.sql ================================================ -- Origin SQL: CREATE OR REPLACE DICTIONARY test.comprehensive_dict UUID '12345678-1234-1234-1234-123456789012' ON CLUSTER production_cluster ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192, max_insert_block_size = 1048576); -- Format SQL: CREATE OR REPLACE DICTIONARY test.comprehensive_dict UUID '12345678-1234-1234-1234-123456789012' ON CLUSTER production_cluster (id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'root' password 'secret' db 'test_db' table 'dictionary_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192, max_insert_block_size=1048576); ================================================ FILE: parser/testdata/ddl/format/create_dictionary_with_comment.sql ================================================ -- Origin SQL: CREATE DICTIONARY test.my_dict ( id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID ) PRIMARY KEY id SOURCE(MYSQL( host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table' )) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size = 8192) COMMENT 'This is a test dictionary with comment'; -- Format SQL: CREATE DICTIONARY test.my_dict (id UInt64, name String DEFAULT '', value Float64 EXPRESSION toFloat64OrZero(name), parent_id UInt64 HIERARCHICAL, is_active UInt8 INJECTIVE, object_id UInt64 IS_OBJECT_ID) PRIMARY KEY id SOURCE(MYSQL(host 'localhost' port 3306 user 'default' password '' db 'test' table 'dict_table')) LIFETIME(MIN 1000 MAX 2000) LAYOUT(HASHED()) SETTINGS(max_block_size=8192) COMMENT 'This is a test dictionary with comment'; ================================================ FILE: parser/testdata/ddl/format/create_distributed_table.sql ================================================ -- Origin SQL: create table test.event_all ON CLUSTER 'default_cluster' AS test.evnets_local ENGINE = Distributed( default_cluster, test, events_local, rand() ) SETTINGS fsync_after_insert=0; -- Format SQL: CREATE TABLE test.event_all ON CLUSTER 'default_cluster' AS test.evnets_local ENGINE = Distributed(default_cluster, test, events_local, rand()) SETTINGS fsync_after_insert=0; ================================================ FILE: parser/testdata/ddl/format/create_function_simple.sql ================================================ -- Origin SQL: CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b; -- Format SQL: CREATE FUNCTION linear_equation AS (x, k, b) -> k * x + b; ================================================ FILE: parser/testdata/ddl/format/create_live_view_basic.sql ================================================ -- Origin SQL: CREATE LIVE VIEW my_live_view WITH TIMEOUT 10 TO my_destination(id String) AS SELECT id FROM my_table; -- Format SQL: CREATE LIVE VIEW my_live_view WITH TIMEOUT 10 TO my_destination (id String) AS SELECT id FROM my_table; ================================================ FILE: parser/testdata/ddl/format/create_materialized_view_basic.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' COMMENT 'Comment for table'; -- Format SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name (`f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' COMMENT 'Comment for table'; ================================================ FILE: parser/testdata/ddl/format/create_materialized_view_with_comment_before_as.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table ( `shop_id` UInt64, `event_type` LowCardinality(String), `created_at` DateTime64(9) ) COMMENT '{"blueprint_hash":"abc123","timestamp":"2026-04-08T12:00:00Z"}' AS SELECT shop_id, event_type, created_at FROM db.src_table; -- Format SQL: CREATE MATERIALIZED VIEW db.mv_with_comment TO db.dst_table (`shop_id` UInt64, `event_type` LowCardinality(String), `created_at` DateTime64(9)) AS SELECT shop_id, event_type, created_at FROM db.src_table COMMENT '{"blueprint_hash":"abc123","timestamp":"2026-04-08T12:00:00Z"}'; ================================================ FILE: parser/testdata/ddl/format/create_materialized_view_with_definer.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export ( `timestamp` DateTime64(9), `field_1` String, `field_2` String, ) DEFINER = default SQL SECURITY DEFINER AS (SELECT timestamp, field_1, field_2, FROM event_table WHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1))) COMMENT 'Test comment' -- Format SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE APPEND TO events_export (`timestamp` DateTime64(9), `field_1` String, `field_2` String) DEFINER = default SQL SECURITY DEFINER AS (SELECT timestamp, field_1, field_2, FROM AS event_table WHERE toStartOfHour(timestamp) = toStartOfHour(now() - toIntervalHour(1))) COMMENT 'Test comment'; ================================================ FILE: parser/testdata/ddl/format/create_materialized_view_with_empty_table_schema.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW test.t0 on cluster default_cluster ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}') PARTITION BY toYYYYMM(f0) ORDER BY (f0) POPULATE AS select f0,f1,f2,coalesce(f0,f1) as f333 from (select f0,f1,f2, ROW_NUMBER() over(partition by f0 order by coalesce(f1,f2)) as rn from test.t where f3 in ('foo', 'bar', 'test') and env ='test' ) as tmp where rn = 1; -- Format SQL: CREATE MATERIALIZED VIEW test.t0 ON CLUSTER default_cluster ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/{layer}-{shard}/test/t0', '{replica}') ORDER BY (f0) PARTITION BY toYYYYMM(f0) POPULATE AS SELECT f0, f1, f2, coalesce(f0, f1) AS f333 FROM (SELECT f0, f1, f2, ROW_NUMBER() OVER (PARTITION BY f0 ORDER BY coalesce(f1, f2)) AS rn FROM test.t WHERE f3 IN ('foo', 'bar', 'test') AND env = 'test') AS tmp WHERE rn = 1; ================================================ FILE: parser/testdata/ddl/format/create_materialized_view_with_gcs.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW database_name.view_name REFRESH EVERY 5 MINUTE TO database_name.table_name AS SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/'); -- Format SQL: CREATE MATERIALIZED VIEW database_name.view_name REFRESH EVERY 5 MINUTE TO database_name.table_name AS SELECT * FROM gcs(gcs_creds, url='https://storage.googleapis.com/some-bucket/some-path/'); ================================================ FILE: parser/testdata/ddl/format/create_materialized_view_with_refresh.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE RANDOMIZE FOR 1 SECOND DEPENDS ON table_v5 SETTINGS randomize_for = 1, randomize_offset = 10, randomize_period = 1 APPEND TO target_table_name EMPTY AS SELECT `field_1`, `field_2`, `field_3`, FROM table_v5 -- Format SQL: CREATE MATERIALIZED VIEW fresh_mv REFRESH EVERY 1 HOUR OFFSET 10 MINUTE RANDOMIZE FOR 1 SECOND DEPENDS ON table_v5 SETTINGS randomize_for=1, randomize_offset=10, randomize_period=1 APPEND TO target_table_name EMPTY AS SELECT `field_1`, `field_2`, `field_3`, FROM AS table_v5; ================================================ FILE: parser/testdata/ddl/format/create_mv_with_not_op.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name ( `f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64 ) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' AND NOT isZeroOrNull(f2) AND f6-2 > 0 -- Format SQL: CREATE MATERIALIZED VIEW infra_bm.view_name ON CLUSTER 'default_cluster' TO infra_bm.table_name (`f1` DateTime64(3), `f2` String, `f3` String, `f4` String, `f5` String, `f6` Int64) AS SELECT f1, f2, visitParamExtractString(properties, 'f3') AS f3, visitParamExtractString(properties, 'f4') AS f4, visitParamExtractString(properties, 'f5') AS f5, visitParamExtractInt(properties, 'f6') AS f6 FROM infra_bm.table_name1 WHERE infra_bm.table_name1.event = 'test-event' AND NOT isZeroOrNull(f2) AND f6 - 2 > 0; ================================================ FILE: parser/testdata/ddl/format/create_mv_with_order_by.sql ================================================ -- Origin SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) ORDER BY (id) AS SELECT * FROM test_table; CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) AS SELECT * FROM test_table; -- Format SQL: CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() ORDER BY (id) PRIMARY KEY (id) AS SELECT * FROM test_table; CREATE MATERIALIZED VIEW IF NOT EXISTS test_mv ENGINE = ReplacingMergeTree() PRIMARY KEY (id) AS SELECT * FROM test_table; ================================================ FILE: parser/testdata/ddl/format/create_named_collection_basic.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin'; -- Format SQL: CREATE NAMED COLLECTION IF NOT EXISTS servercore_s3_config AS url = 'http://local-minio:9000/*', access_key_id = 'minioadmin', secret_access_key = 'minioadmin'; ================================================ FILE: parser/testdata/ddl/format/create_named_collection_simple.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2'; -- Format SQL: CREATE NAMED COLLECTION my_collection AS key1 = 'value1', key2 = 'value2'; ================================================ FILE: parser/testdata/ddl/format/create_named_collection_with_cluster.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3'; -- Format SQL: CREATE NAMED COLLECTION IF NOT EXISTS my_collection ON CLUSTER my_cluster AS key1 = 'value1' OVERRIDABLE, key2 = 'value2' NOT OVERRIDABLE, key3 = 'value3'; ================================================ FILE: parser/testdata/ddl/format/create_named_collection_with_overridable.sql ================================================ -- Origin SQL: CREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456'; -- Format SQL: CREATE NAMED COLLECTION test_collection AS url = 'http://example.com' OVERRIDABLE, access_key = 'key123' NOT OVERRIDABLE, secret_key = 'secret456'; ================================================ FILE: parser/testdata/ddl/format/create_or_replace.sql ================================================ -- Origin SQL: -- It's a short link events table /** * @name Short link events * @description It's a short link events table */ CREATE OR REPLACE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), ) ENGINE = MergeTree PRIMARY KEY (f0, f1, f2) PARTITION BY toYYYYMMDD(f1) TTL f1 + INTERVAL 6 MONTH ORDER BY (f1,f2) COMMENT 'Comment for table'; CREATE OR REPLACE VIEW IF NOT EXISTS my_view(col1 String, col2 String) AS SELECT id, name FROM my_table; CREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y; -- Format SQL: CREATE OR REPLACE TABLE IF NOT EXISTS test.events_local (f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255)) ENGINE = MergeTree ORDER BY (f1, f2) PARTITION BY toYYYYMMDD(f1) PRIMARY KEY (f0, f1, f2) TTL f1 + INTERVAL 6 MONTH COMMENT 'Comment for table'; CREATE OR REPLACE VIEW IF NOT EXISTS my_view (col1 String, col2 String) AS SELECT id, name FROM my_table; CREATE OR REPLACE FUNCTION IF NOT EXISTS my_function AS (x, y) -> x + y; ================================================ FILE: parser/testdata/ddl/format/create_role.sql ================================================ -- Origin SQL: -- Tags: no-parallel CREATE ROLE r1_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2; CREATE ROLE r1_01293 SETTINGS NONE; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000; CREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; CREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; CREATE ROLE r6_01293 SETTINGS max_memory_usage CONST; CREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; CREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; CREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 SETTINGS readonly=1; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; CREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; CREATE ROLE r5_01293 SETTINGS NONE; CREATE ROLE r1_01293@'%'; CREATE ROLE r2_01293@'%.myhost.com'; -- Format SQL: CREATE ROLE r1_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293; CREATE ROLE r1_01293 ON CLUSTER cluster_1, r2_01293 ON CLUSTER cluster_2; CREATE ROLE r1_01293 SETTINGS NONE; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000; CREATE ROLE r4_01293 SETTINGS max_memory_usage MIN=5000000; CREATE ROLE r5_01293 SETTINGS max_memory_usage MAX=5000000; CREATE ROLE r6_01293 SETTINGS max_memory_usage CONST; CREATE ROLE r7_01293 SETTINGS max_memory_usage WRITABLE; CREATE ROLE r8_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 CONST; CREATE ROLE r9_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000 WRITABLE; CREATE ROLE r1_01293, r2_01293; CREATE ROLE r1_01293 SETTINGS readonly=1; CREATE ROLE r2_01293 SETTINGS PROFILE 'default'; CREATE ROLE r3_01293 SETTINGS max_memory_usage=5000000 MIN 4000000 MAX 6000000 WRITABLE; CREATE ROLE r4_01293 SETTINGS PROFILE 'default', max_memory_usage=5000000, readonly=1; CREATE ROLE r5_01293 SETTINGS NONE; CREATE ROLE r1_01293@'%'; CREATE ROLE r2_01293@'%.myhost.com'; ================================================ FILE: parser/testdata/ddl/format/create_table_as_remote_function.sql ================================================ -- Origin SQL: -- CREATE TABLE with columns AS table function (remoteSecure) CREATE TABLE test_remote ( id UInt64, name String, value Int32 ) AS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password'); -- Simpler test case with remote() CREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table'); -- Format SQL: CREATE TABLE test_remote (id UInt64, name String, value Int32) AS remoteSecure('host.example.com', 'source_db', 'source_table', 'user', 'password'); CREATE TABLE test_table (id UInt64, name String) AS remote('localhost', 'db', 'source_table'); ================================================ FILE: parser/testdata/ddl/format/create_table_basic.sql ================================================ -- Origin SQL: -- It's a short link events table /** * @name Short link events * @description It's a short link events table */ CREATE TABLE IF NOT EXISTS test.events_local ( f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Nested ( f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String ), f8 Datetime DEFAULT now(), f9 String MATERIALIZED toString(f7['f70']), f10 String ALIAS f11, f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello'), ) ENGINE = MergeTree PRIMARY KEY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH ORDER BY (f1,f2,f3) COMMENT 'Comment for table'; -- Format SQL: CREATE TABLE IF NOT EXISTS test.events_local (f0 String, f1 String CODEC(ZSTD(1)), f2 VARCHAR(255), f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Nested(f70 UInt32, f71 UInt32, f72 DateTime, f73 Int64, f74 Int64, f75 String), f8 Datetime DEFAULT now(), f9 String MATERIALIZED toString(f7['f70']), f10 String ALIAS f11, f12 JSON(max_dynamic_types=10, max_dynamic_paths=3, SKIP a, SKIP a.b.c, SKIP REGEXP 'hello')) ENGINE = MergeTree ORDER BY (f1, f2, f3) PARTITION BY toYYYYMMDD(f3) PRIMARY KEY (f0, f1, f2) TTL f3 + INTERVAL 6 MONTH COMMENT 'Comment for table'; ================================================ FILE: parser/testdata/ddl/format/create_table_codec_no_args.sql ================================================ -- Origin SQL: CREATE TABLE shark_attacks ( timestamp DateTime CODEC(DoubleDelta), ); -- Format SQL: CREATE TABLE shark_attacks (timestamp DateTime CODEC(DoubleDelta)); ================================================ FILE: parser/testdata/ddl/format/create_table_json_typehints.sql ================================================ -- Origin SQL: CREATE TABLE t ( j JSON(message String, a.b UInt64, max_dynamic_paths=0, SKIP x, SKIP REGEXP 're') ) ENGINE = MergeTree ORDER BY tuple(); -- Format SQL: CREATE TABLE t (j JSON(max_dynamic_paths=0, message String, a.b UInt64, SKIP x, SKIP REGEXP 're')) ENGINE = MergeTree ORDER BY tuple(); ================================================ FILE: parser/testdata/ddl/format/create_table_with_codec_delta.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test_local ( `id` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `app_id` UInt64 CODEC(Delta(9), ZSTD(1)), `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)), `guage` Float64 CODEC(Gorilla, LZ4), `value` UInt64 CODEC(T64, LZ4), `timestamp` DateTime64(9) CODEC(ZSTD(1)), INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') PARTITION BY toStartOfHour(`timestamp`) ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; -- Format SQL: CREATE TABLE IF NOT EXISTS test_local (`id` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `app_id` UInt64 CODEC(Delta(9), ZSTD(1)), `device_id` UInt64 CODEC(DoubleDelta, ZSTD(1)), `guage` Float64 CODEC(Gorilla, LZ4), `value` UInt64 CODEC(T64, LZ4), `timestamp` DateTime64(9) CODEC(ZSTD(1)), INDEX timestamp_index(timestamp) TYPE minmax GRANULARITY 4) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) PARTITION BY toStartOfHour(`timestamp`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/format/create_table_with_enum_fields.sql ================================================ -- Origin SQL: CREATE TABLE t0 on cluster default_cluster ( `method` Enum8('GET'=1 , 'POST'=2, 'HEAD'=3, 'PUT'=4,'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)), `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') PARTITION BY toDate(timestamp) ORDER BY (method,timestamp) TTL toDate(timestamp) + toIntervalDay(3) SETTINGS index_granularity = 8192; -- Format SQL: CREATE TABLE t0 ON CLUSTER default_cluster (`method` Enum8('GET'=1, 'POST'=2, 'HEAD'=3, 'PUT'=4, 'PATCH'=5, 'DELETE'=6, 'CONNECT'=7, 'OPTIONS'=8, 'TRACE'=9) CODEC(ZSTD(1)), `timestamp` DateTime64(3) CODEC(DoubleDelta, ZSTD)) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (method, timestamp) PARTITION BY toDate(timestamp) TTL toDate(timestamp) + toIntervalDay(3) SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/create_table_with_index.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test_local ( `common.id` String CODEC(ZSTD(1)), `id` UInt64 CODEC(Delta, ZSTD(1)), `idx` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `arr` Array(Int64), `content` String CODEC(ZSTD(1)), `output` String, INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1, INDEX id_idx id TYPE minmax GRANULARITY 10, INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1, INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2, INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3, INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1, INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2 ) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') PARTITION BY toStartOfHour(`timestamp`) ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY,toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; -- Format SQL: CREATE TABLE IF NOT EXISTS test_local (`common.id` String CODEC(ZSTD(1)), `id` UInt64 CODEC(Delta, ZSTD(1)), `idx` UInt64 CODEC(Delta, ZSTD(1)), `api_id` UInt64 CODEC(ZSTD(1)), `arr` Array(Int64), `content` String CODEC(ZSTD(1)), `output` String, INDEX id_common_id_bloom_filter common.id TYPE bloom_filter(0.001) GRANULARITY 1, INDEX id_idx id TYPE minmax GRANULARITY 10, INDEX idx_id idx TYPE bloom_filter() GRANULARITY 1, INDEX api_id_idx api_id TYPE set(100) GRANULARITY 2, INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3, INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1, INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2) ENGINE = ReplicatedMergeTree('/root/test_local', '{replica}') ORDER BY (toUnixTimestamp64Nano(`timestamp`), `api_id`) PARTITION BY toStartOfHour(`timestamp`) TTL toStartOfHour(`timestamp`) + INTERVAL 7 DAY, toStartOfHour(`timestamp`) + INTERVAL 2 DAY SETTINGS execute_merges_on_single_replica_time_threshold=1200, index_granularity=16384, max_bytes_to_merge_at_max_space_in_pool=64424509440, storage_policy='main', ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/format/create_table_with_keyword_partition_by.sql ================================================ -- Origin SQL: CREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' ( `date` Date, `f1` String, `f2` String, `f3` UInt64 ) ENGINE = ReplacingMergeTree PARTITION BY date ORDER BY (f1, f2) SETTINGS index_granularity = 8192; -- Format SQL: CREATE TABLE test.events_local UUID 'dad17568-b070-49d0-9ad1-7568b07029d0' (`date` Date, `f1` String, `f2` String, `f3` UInt64) ENGINE = ReplacingMergeTree ORDER BY (f1, f2) PARTITION BY date SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/create_table_with_null_engine.sql ================================================ -- Origin SQL: CREATE TABLE logs.t0 on cluster default ( `trace_id` String CODEC(ZSTD(1)), INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64 ) ENGINE = Null(); -- Format SQL: CREATE TABLE logs.t0 ON CLUSTER default (`trace_id` String CODEC(ZSTD(1)), INDEX trace_id_bloom_idx trace_id TYPE bloom_filter(0.01) GRANULARITY 64) ENGINE = Null(); ================================================ FILE: parser/testdata/ddl/format/create_table_with_nullable.sql ================================================ -- Origin SQL: CREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5' ( `f0` String, `f1` String, `f2` LowCardinality(String), `f3` LowCardinality(String), `f4` DateTime64(3), `f5` Nullable(DateTime64(3)), `succeed_at` Nullable(DateTime64(3)) ) ENGINE = MergeTree PARTITION BY xxHash32(tag_id) % 20 ORDER BY label_id SETTINGS index_granularity = 8192; -- Format SQL: CREATE TABLE test.`.inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5` UUID '27673372-7973-44f5-a767-33727973c4f5' (`f0` String, `f1` String, `f2` LowCardinality(String), `f3` LowCardinality(String), `f4` DateTime64(3), `f5` Nullable(DateTime64(3)), `succeed_at` Nullable(DateTime64(3))) ENGINE = MergeTree ORDER BY label_id PARTITION BY xxHash32(tag_id) % 20 SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/create_table_with_on_clsuter.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); -- Format SQL: CREATE TABLE IF NOT EXISTS test.events_local ON CLUSTER 'default_cluster' (f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now()) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH; ================================================ FILE: parser/testdata/ddl/format/create_table_with_projection.sql ================================================ -- Origin SQL: CREATE TABLE events ( `event_time` DateTime, `event_id` UInt64, `user_id` UInt64, `huge_string` String, PROJECTION order_by_user_id ( SELECT _part_offset ORDER BY user_id ) ) ENGINE = MergeTree() ORDER BY (event_id); -- Format SQL: CREATE TABLE events (`event_time` DateTime, `event_id` UInt64, `user_id` UInt64, `huge_string` String, PROJECTION order_by_user_id (SELECT _part_offset ORDER BY user_id)) ENGINE = MergeTree() ORDER BY (event_id); ================================================ FILE: parser/testdata/ddl/format/create_table_with_projection_group_by_only.sql ================================================ -- Origin SQL: CREATE TABLE events ( `event_time` DateTime, `event_type` String, `user_id` UInt64, `value` Float64, PROJECTION hourly_aggregates ( SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY hour, event_type ) ) ENGINE = MergeTree() ORDER BY (event_time, event_type); -- Format SQL: CREATE TABLE events (`event_time` DateTime, `event_type` String, `user_id` UInt64, `value` Float64, PROJECTION hourly_aggregates (SELECT toStartOfHour(event_time) AS hour, event_type, count() AS event_count, sum(value) AS total_value GROUP BY hour, event_type)) ENGINE = MergeTree() ORDER BY (event_time, event_type); ================================================ FILE: parser/testdata/ddl/format/create_table_with_qbit.sql ================================================ -- Origin SQL: CREATE TABLE test.qbit_example ( id UInt32, vec QBit(Float32, 8) ) ENGINE = Memory; -- Format SQL: CREATE TABLE test.qbit_example (id UInt32, vec QBit(Float32, 8)) ENGINE = Memory; ================================================ FILE: parser/testdata/ddl/format/create_table_with_sample_by.sql ================================================ -- Origin SQL: CREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e' ( `f0` DateTime, `f1` UInt32, `f3` UInt32 ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}') PARTITION BY toYYYYMM(timestamp) ORDER BY (contractid, toDate(timestamp), userid) SAMPLE BY userid SETTINGS index_granularity = 8192; -- Format SQL: CREATE TABLE default.test UUID '87887901-e33c-497e-8788-7901e33c997e' (`f0` DateTime, `f1` UInt32, `f3` UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}/{shard}/default/test', '{replica}') ORDER BY (contractid, toDate(timestamp), userid) PARTITION BY toYYYYMM(timestamp) SAMPLE BY userid SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/create_table_with_ttl_policy.sql ================================================ -- Origin SQL: CREATE TABLE tab ( d DateTime, a Int ) ENGINE = MergeTree PARTITION BY toYYYYMM(d) ORDER BY d TTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb'; CREATE TABLE table_with_where ( d DateTime, a Int ) ENGINE = MergeTree PARTITION BY toYYYYMM(d) ORDER BY d TTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1; CREATE TABLE table_for_recompression ( d DateTime, key UInt64, value String ) ENGINE MergeTree() ORDER BY tuple() PARTITION BY key TTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10)) SETTINGS min_rows_for_wide_part = 0, min_bytes_for_wide_part = 0, allow_experimental_replacing_merge_with_cleanup = true; -- Format SQL: CREATE TABLE tab (d DateTime, a Int) ENGINE = MergeTree ORDER BY d PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH DELETE, d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb'; CREATE TABLE table_with_where (d DateTime, a Int) ENGINE = MergeTree ORDER BY d PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH DELETE WHERE toDayOfWeek(d) = 1; CREATE TABLE table_for_recompression (d DateTime, key UInt64, value String) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY key TTL d + INTERVAL 1 MONTH RECOMPRESS CODEC(ZSTD(17)), d + INTERVAL 1 YEAR RECOMPRESS CODEC(LZ4HC(10)) SETTINGS min_rows_for_wide_part=0, min_bytes_for_wide_part=0, allow_experimental_replacing_merge_with_cleanup=true; ================================================ FILE: parser/testdata/ddl/format/create_table_with_tuple_fields.sql ================================================ -- Origin SQL: CREATE TABLE t0 on cluster default_cluster ( `tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String)) ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity = 8192; -- Format SQL: CREATE TABLE t0 ON CLUSTER default_cluster (`tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String))) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity=8192; ================================================ FILE: parser/testdata/ddl/format/create_table_with_uuid.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' ( f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String,String), f6 String, f7 Datetime DEFAULT now() ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') TTL f3 + INTERVAL 6 MONTH PARTITION BY toYYYYMMDD(f3) ORDER BY (f0,f1,f2); -- Format SQL: CREATE TABLE IF NOT EXISTS test.events_local UUID '1234' ON CLUSTER 'default_cluster' (f0 String, f1 String, f2 String, f3 Datetime, f4 Datetime, f5 Map(String, String), f6 String, f7 Datetime DEFAULT now()) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/test/events_local', '{replica}') ORDER BY (f0, f1, f2) PARTITION BY toYYYYMMDD(f3) TTL f3 + INTERVAL 6 MONTH; ================================================ FILE: parser/testdata/ddl/format/create_user.sql ================================================ -- Origin SQL: -- Basic CREATE USER tests CREATE USER user1; CREATE USER IF NOT EXISTS user2; CREATE USER OR REPLACE user3; CREATE USER user4, user5; -- CREATE USER with authentication CREATE USER user6 NOT IDENTIFIED; CREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123'; CREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123'; CREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server'; CREATE USER user10 IDENTIFIED WITH kerberos; CREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM'; -- CREATE USER with VALID UNTIL CREATE USER user33 VALID UNTIL '2026-12-12 00:00:00'; CREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15'; CREATE USER user35 VALID UNTIL 'infinity'; -- CREATE USER with host restrictions CREATE USER user12 HOST LOCAL; CREATE USER user13 HOST ANY; CREATE USER user14 HOST NONE; CREATE USER user15 HOST NAME 'localhost'; CREATE USER user16 HOST REGEXP '.*\.example\.com'; CREATE USER user17 HOST IP '192.168.1.1'; CREATE USER user18 HOST LIKE 'test%'; -- CREATE USER with default roles CREATE USER user19 DEFAULT ROLE role1; CREATE USER user20 DEFAULT ROLE role1, role2; CREATE USER user21 DEFAULT ROLE NONE; -- CREATE USER with default database CREATE USER user22 DEFAULT DATABASE test_db; CREATE USER user23 DEFAULT DATABASE NONE; -- CREATE USER with grantees CREATE USER user24 GRANTEES user1; CREATE USER user25 GRANTEES user1, user2; CREATE USER user26 GRANTEES ANY; CREATE USER user27 GRANTEES NONE; CREATE USER user28 GRANTEES user1, user2 EXCEPT user3; -- CREATE USER with settings CREATE USER user29 SETTINGS max_memory_usage=5000000; CREATE USER user30 SETTINGS PROFILE 'default'; CREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000; -- Complex CREATE USER with multiple clauses CREATE USER user32 IDENTIFIED WITH plaintext_password BY 'password' VALID UNTIL '2025-12-31' HOST NAME 'localhost' DEFAULT ROLE role1, role2 DEFAULT DATABASE test_db GRANTEES user1, user2 EXCEPT user3 SETTINGS max_memory_usage=5000000, readonly=1; -- Format SQL: CREATE USER user1; CREATE USER IF NOT EXISTS user2; CREATE USER OR REPLACE user3; CREATE USER user4, user5; CREATE USER user6 NOT IDENTIFIED; CREATE USER user7 IDENTIFIED WITH plaintext_password BY 'password123'; CREATE USER user8 IDENTIFIED WITH sha256_password BY 'hash123'; CREATE USER user9 IDENTIFIED WITH ldap SERVER 'ldap_server'; CREATE USER user10 IDENTIFIED WITH kerberos; CREATE USER user11 IDENTIFIED WITH kerberos REALM 'EXAMPLE.COM'; CREATE USER user33 VALID UNTIL '2026-12-12 00:00:00'; CREATE USER user34 IDENTIFIED WITH plaintext_password BY 'password123' VALID UNTIL '2026-06-15'; CREATE USER user35 VALID UNTIL 'infinity'; CREATE USER user12 HOST LOCAL; CREATE USER user13 HOST ANY; CREATE USER user14 HOST NONE; CREATE USER user15 HOST NAME 'localhost'; CREATE USER user16 HOST REGEXP '.*\.example\.com'; CREATE USER user17 HOST IP '192.168.1.1'; CREATE USER user18 HOST LIKE 'test%'; CREATE USER user19 DEFAULT ROLE role1; CREATE USER user20 DEFAULT ROLE role1, role2; CREATE USER user21 DEFAULT ROLE NONE; CREATE USER user22 DEFAULT DATABASE test_db; CREATE USER user23 DEFAULT DATABASE NONE; CREATE USER user24 GRANTEES user1; CREATE USER user25 GRANTEES user1, user2; CREATE USER user26 GRANTEES ANY; CREATE USER user27 GRANTEES NONE; CREATE USER user28 GRANTEES user1, user2 EXCEPT user3; CREATE USER user29 SETTINGS max_memory_usage=5000000; CREATE USER user30 SETTINGS PROFILE 'default'; CREATE USER user31 SETTINGS readonly=1, max_memory_usage=5000000; CREATE USER user32 IDENTIFIED WITH plaintext_password BY 'password' VALID UNTIL '2025-12-31' HOST NAME 'localhost' DEFAULT ROLE role1, role2 DEFAULT DATABASE test_db GRANTEES user1, user2 EXCEPT user3 SETTINGS max_memory_usage=5000000, readonly=1; ================================================ FILE: parser/testdata/ddl/format/create_view_basic.sql ================================================ -- Origin SQL: CREATE VIEW IF NOT EXISTS my_view(col1 String, col2 String) AS SELECT id, name FROM my_table; -- Format SQL: CREATE VIEW IF NOT EXISTS my_view (col1 String, col2 String) AS SELECT id, name FROM my_table; ================================================ FILE: parser/testdata/ddl/format/create_view_on_cluster_with_uuid.sql ================================================ -- Origin SQL: CREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS ( SELECT column1, column2 FROM my_other_table ); -- Format SQL: CREATE VIEW IF NOT EXISTS cluster_name.my_view UUID '3493e374-e2bb-481b-b493-e374e2bb981b' ON CLUSTER 'my_cluster' AS (SELECT column1, column2 FROM my_other_table); ================================================ FILE: parser/testdata/ddl/format/create_view_with_comment.sql ================================================ -- Origin SQL: CREATE VIEW IF NOT EXISTS db.my_view ( `id` Int64, `name` String ) COMMENT '{"blueprint_hash":"abc123"}' AS SELECT id, name FROM db.my_table; -- Format SQL: CREATE VIEW IF NOT EXISTS db.my_view (`id` Int64, `name` String) COMMENT '{"blueprint_hash":"abc123"}' AS SELECT id, name FROM db.my_table; ================================================ FILE: parser/testdata/ddl/format/create_with_time_zone.sql ================================================ -- Origin SQL: CREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster ( `f0` Array(Tuple( f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1) ), `f1` UInt64 CODEC(Delta(8), LZ4), `f2` FixedString(16) CODEC(LZ4), `f3` FixedString(8) CODEC(LZ4), `f4` FixedString(8) CODEC(LZ4), `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4), `f6` UInt64 CODEC(Delta(8), LZ4), `f7` LowCardinality(String) CODEC(ZSTD(1)), `f8` String CODEC(ZSTD(1)), `f9` LowCardinality(String) CODEC(ZSTD(1)), `f10` String CODEC(ZSTD(1)), `f11` LowCardinality(String) CODEC(ZSTD(1)), `f12` LowCardinality(String) CODEC(ZSTD(1)), `f13` String CODEC(ZSTD(1)), `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)), `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)), `f18` Array(Tuple( f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)), `f184` String CODEC(ZSTD(1)), `f185` String CODEC(ZSTD(1)), `f186` String CODEC(ZSTD(1)), `f187` UInt32 CODEC(ZSTD(1)), `f188` DATETIME DEFAULT now(), INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f2 f2 TYPE minmax GRANULARITY 1, INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4, INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1, INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4 ) ENGINE = MergeTree PARTITION BY toDate(timestamp) ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp)) TTL toDate(timestamp) + toIntervalDay(15) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1 -- Format SQL: CREATE TABLE IF NOT EXISTS test.db ON CLUSTER default_cluster (`f0` Array(Tuple(f00 DateTime64(9, 'UTC'), f01 String, f02 Map(String, String), f03 Map(String, Float64), f04 Map(String, BOOL))) CODEC(ZSTD(1)), `f1` UInt64 CODEC(Delta(8), LZ4), `f2` FixedString(16) CODEC(LZ4), `f3` FixedString(8) CODEC(LZ4), `f4` FixedString(8) CODEC(LZ4), `f6` DateTime64(9, 'UTC') CODEC(Delta(8), LZ4), `f6` UInt64 CODEC(Delta(8), LZ4), `f7` LowCardinality(String) CODEC(ZSTD(1)), `f8` String CODEC(ZSTD(1)), `f9` LowCardinality(String) CODEC(ZSTD(1)), `f10` String CODEC(ZSTD(1)), `f11` LowCardinality(String) CODEC(ZSTD(1)), `f12` LowCardinality(String) CODEC(ZSTD(1)), `f13` String CODEC(ZSTD(1)), `f14` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f15` Map(LowCardinality(String), String) CODEC(ZSTD(1)), `f16` Map(LowCardinality(String), Float64) CODEC(ZSTD(1)), `f17` Map(LowCardinality(String), BOOL) CODEC(ZSTD(1)), `f18` Array(Tuple(f180 FixedString(16), f181 FixedString(8), f182 String, f183 Map(String, String))) CODEC(ZSTD(1)), `f184` String CODEC(ZSTD(1)), `f185` String CODEC(ZSTD(1)), `f186` String CODEC(ZSTD(1)), `f187` UInt32 CODEC(ZSTD(1)), `f188` DATETIME DEFAULT now(), INDEX idx_0 f0 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f1 f1 TYPE bloom_filter(0.001) GRANULARITY 1, INDEX idx_f2 f2 TYPE minmax GRANULARITY 1, INDEX idx_f3 f3 TYPE set(0) GRANULARITY 4, INDEX idx_f4 mapValues(f4) TYPE bloom_filter(0.01) GRANULARITY 1, INDEX idx_f5 name TYPE tokenbf_v1(4096, 3, 0) GRANULARITY 4) ENGINE = MergeTree ORDER BY (ts_bucket, service_name, name, toUnixTimestamp64Nano(timestamp)) PARTITION BY toDate(timestamp) TTL toDate(timestamp) + toIntervalDay(15) SETTINGS index_granularity=8192, ttl_only_drop_parts=1; ================================================ FILE: parser/testdata/ddl/format/desc_table_with_table_keyword.sql ================================================ -- Origin SQL: DESC TABLE mytable -- Format SQL: DESCRIBE TABLE mytable; ================================================ FILE: parser/testdata/ddl/format/desc_table_without_table_keyword.sql ================================================ -- Origin SQL: DESC mytable -- Format SQL: DESCRIBE mytable; ================================================ FILE: parser/testdata/ddl/format/describe_table_with_table_keyword.sql ================================================ -- Origin SQL: DESCRIBE TABLE mytable -- Format SQL: DESCRIBE TABLE mytable; ================================================ FILE: parser/testdata/ddl/format/describe_table_without_table_keyword.sql ================================================ -- Origin SQL: DESCRIBE mytable -- Format SQL: DESCRIBE mytable; ================================================ FILE: parser/testdata/ddl/format/drop_database.sql ================================================ -- Origin SQL: DROP DATABASE IF EXISTS datbase_name; -- Format SQL: DROP DATABASE IF EXISTS datbase_name; ================================================ FILE: parser/testdata/ddl/format/drop_role.sql ================================================ -- Origin SQL: DROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293; DROP ROLE IF EXISTS r2_01293_renamed; DROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com'; -- Format SQL: DROP ROLE IF EXISTS r1_01293, r2_01293, r3_01293, r4_01293, r5_01293, r6_01293, r7_01293, r8_01293, r9_01293; DROP ROLE IF EXISTS r2_01293_renamed; DROP ROLE IF EXISTS r1_01293@'%', 'r2_01293@%.myhost.com'; ================================================ FILE: parser/testdata/ddl/format/drop_table_basic.sql ================================================ -- Origin SQL: DROP TABLE IF EXISTS test.table_name; -- Format SQL: DROP TABLE IF EXISTS test.table_name; ================================================ FILE: parser/testdata/ddl/format/drop_table_with_no_delay.sql ================================================ -- Origin SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY; -- Format SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster' NO DELAY; ================================================ FILE: parser/testdata/ddl/format/drop_table_with_on_clsuter.sql ================================================ -- Origin SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; -- Format SQL: DROP TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/format/grant_privilege.sql ================================================ -- Origin SQL: GRANT SELECT(x,y) ON db.table TO john; GRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION; GRANT SELECT(x,y) ON db.* TO john; GRANT SELECT(x,y) ON *.table TO john; GRANT SELECT(x,y) ON *.* TO john; GRANT SELECT(x,y) ON *.table TO CURRENT_USER; GRANT SELECT(x,y) ON *.table TO CURRENT_USER,john,mary; GRANT ALL ON *.* TO admin_role WITH GRANT OPTION; GRANT SELECT,INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT(x, y, z),INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT, dictGet ON *.* TO select_all_role; GRANT ADMIN OPTION ON *.* TO select_all_role; -- Format SQL: GRANT SELECT(x, y) ON db.table TO john; GRANT SELECT(x, y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION; GRANT SELECT(x, y) ON db.* TO john; GRANT SELECT(x, y) ON *.table TO john; GRANT SELECT(x, y) ON *.* TO john; GRANT SELECT(x, y) ON *.table TO CURRENT_USER; GRANT SELECT(x, y) ON *.table TO CURRENT_USER, john, mary; GRANT ALL ON *.* TO admin_role WITH GRANT OPTION; GRANT SELECT, INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT(x, y, z), INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT, dictGet ON *.* TO select_all_role; GRANT ADMIN OPTION ON *.* TO select_all_role; ================================================ FILE: parser/testdata/ddl/format/optimize.sql ================================================ -- Origin SQL: OPTIMIZE TABLE table DEDUPLICATE; -- all columns OPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns OPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex'); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY); -- Format SQL: OPTIMIZE TABLE table DEDUPLICATE; OPTIMIZE TABLE table DEDUPLICATE BY *; OPTIMIZE TABLE table DEDUPLICATE BY colX, colY, colZ; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex'); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY); ================================================ FILE: parser/testdata/ddl/format/rename.sql ================================================ -- Origin SQL: -- rename table RENAME TABLE t1 TO t11; RENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME TABLE t1 TO t11, t2 TO t22; RENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- rename dictionary RENAME DICTIONARY t1 TO t11; RENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11, t2 TO t22; RENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- rename database RENAME DATABASE t1 TO t11; RENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11, t2 TO t22; RENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- Format SQL: RENAME TABLE t1 TO t11; RENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME TABLE t1 TO t11, t2 TO t22; RENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11; RENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11, t2 TO t22; RENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11; RENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11, t2 TO t22; RENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/format/show_create_table.sql ================================================ -- Origin SQL: SHOW CREATE TABLE mytable -- Format SQL: SHOW CREATE TABLE mytable; ================================================ FILE: parser/testdata/ddl/format/show_databases.sql ================================================ -- Origin SQL: SHOW DATABASES -- Format SQL: SHOW DATABASES; ================================================ FILE: parser/testdata/ddl/format/show_databases_comprehensive.sql ================================================ -- Origin SQL: SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON -- Format SQL: SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT 'JSON'; ================================================ FILE: parser/testdata/ddl/format/show_databases_format.sql ================================================ -- Origin SQL: SHOW DATABASES FORMAT JSON -- Format SQL: SHOW DATABASES FORMAT 'JSON'; ================================================ FILE: parser/testdata/ddl/format/show_databases_format_string.sql ================================================ -- Origin SQL: SHOW DATABASES FORMAT 'TabSeparated' -- Format SQL: SHOW DATABASES FORMAT 'TabSeparated'; ================================================ FILE: parser/testdata/ddl/format/show_databases_ilike.sql ================================================ -- Origin SQL: SHOW DATABASES ILIKE 'Test%' -- Format SQL: SHOW DATABASES ILIKE 'Test%'; ================================================ FILE: parser/testdata/ddl/format/show_databases_like.sql ================================================ -- Origin SQL: SHOW DATABASES LIKE 'test%' -- Format SQL: SHOW DATABASES LIKE 'test%'; ================================================ FILE: parser/testdata/ddl/format/show_databases_limit.sql ================================================ -- Origin SQL: SHOW DATABASES LIMIT 10 -- Format SQL: SHOW DATABASES LIMIT 10; ================================================ FILE: parser/testdata/ddl/format/show_databases_not_ilike.sql ================================================ -- Origin SQL: SHOW DATABASES NOT ILIKE 'Temp%' -- Format SQL: SHOW DATABASES NOT ILIKE 'Temp%'; ================================================ FILE: parser/testdata/ddl/format/show_databases_not_like.sql ================================================ -- Origin SQL: SHOW DATABASES NOT LIKE 'temp%' -- Format SQL: SHOW DATABASES NOT LIKE 'temp%'; ================================================ FILE: parser/testdata/ddl/format/show_databases_outfile.sql ================================================ -- Origin SQL: SHOW DATABASES INTO OUTFILE '/tmp/databases.txt' -- Format SQL: SHOW DATABASES INTO OUTFILE '/tmp/databases.txt'; ================================================ FILE: parser/testdata/ddl/format/show_tables.sql ================================================ -- Origin SQL: SHOW TABLES -- Format SQL: SHOW TABLES; ================================================ FILE: parser/testdata/ddl/format/systems.sql ================================================ -- Origin SQL: SYSTEM FLUSH LOGS; SYSTEM DROP UNCOMPRESSED CACHE; SYSTEM DROP FILESYSTEM CACHE; -- Format SQL: SYSTEM FLUSH LOGS; SYSTEM DROP UNCOMPRESSED CACHE; SYSTEM DROP FILESYSTEM CACHE; ================================================ FILE: parser/testdata/ddl/format/truncate_table_basic.sql ================================================ -- Origin SQL: TRUNCATE TABLE IF EXISTS test.table_name; -- Format SQL: TRUNCATE TABLE IF EXISTS test.table_name; ================================================ FILE: parser/testdata/ddl/format/truncate_temporary_table_on_clsuter.sql ================================================ -- Origin SQL: TRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; -- Format SQL: TRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/grant_privilege.sql ================================================ GRANT SELECT(x,y) ON db.table TO john; GRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION WITH ADMIN OPTION; GRANT SELECT(x,y) ON db.* TO john; GRANT SELECT(x,y) ON *.table TO john; GRANT SELECT(x,y) ON *.* TO john; GRANT SELECT(x,y) ON *.table TO CURRENT_USER; GRANT SELECT(x,y) ON *.table TO CURRENT_USER,john,mary; GRANT ALL ON *.* TO admin_role WITH GRANT OPTION; GRANT SELECT,INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT(x, y, z),INSERT ON database.table_1 TO table_1_select_role; GRANT SELECT, dictGet ON *.* TO select_all_role; GRANT ADMIN OPTION ON *.* TO select_all_role; ================================================ FILE: parser/testdata/ddl/optimize.sql ================================================ OPTIMIZE TABLE table DEDUPLICATE; -- all columns OPTIMIZE TABLE table DEDUPLICATE BY *; -- excludes MATERIALIZED and ALIAS columns OPTIMIZE TABLE table DEDUPLICATE BY colX,colY,colZ; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY * EXCEPT (colX, colY); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex'); OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT colX; OPTIMIZE TABLE table DEDUPLICATE BY COLUMNS('column-matched-by-regex') EXCEPT (colX, colY); ================================================ FILE: parser/testdata/ddl/output/alter_role.sql.golden.json ================================================ [ { "AlterPos": 22, "StatementEnd": 41, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 33, "NameEnd": 41 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 41 } ], "Settings": null }, { "AlterPos": 43, "StatementEnd": 102, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 54, "NameEnd": 62 }, "Scope": null, "OnCluster": { "OnPos": 63, "Expr": { "Name": "cluster_1", "QuoteType": 1, "NamePos": 74, "NameEnd": 83 } } }, "NewName": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 94, "NameEnd": 102 }, "StatementEnd": 102 } ], "Settings": null }, { "AlterPos": 104, "StatementEnd": 171, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 115, "NameEnd": 123 }, "Scope": null, "OnCluster": null }, "NewName": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 134, "NameEnd": 142 }, "StatementEnd": 142 }, { "RoleName": { "Name": { "Name": "r3_01293", "QuoteType": 1, "NamePos": 144, "NameEnd": 152 }, "Scope": null, "OnCluster": null }, "NewName": { "Name": "r4_01293", "QuoteType": 1, "NamePos": 163, "NameEnd": 171 }, "StatementEnd": 171 } ], "Settings": null }, { "AlterPos": 173, "StatementEnd": 206, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 184, "NameEnd": 192 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 192 } ], "Settings": [ { "SettingPairs": [], "Modifier": { "Name": "NONE", "QuoteType": 1, "NamePos": 202, "NameEnd": 206 } } ] }, { "AlterPos": 208, "StatementEnd": 253, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 219, "NameEnd": 227 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 227 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 237, "NameEnd": 244 }, "Operation": "", "Value": { "LiteralPos": 246, "LiteralEnd": 253, "Literal": "default" } } ], "Modifier": null } ] }, { "AlterPos": 256, "StatementEnd": 309, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r3_01293", "QuoteType": 1, "NamePos": 267, "NameEnd": 275 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 275 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 285, "NameEnd": 301 }, "Operation": "=", "Value": { "NumPos": 302, "NumEnd": 309, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "AlterPos": 311, "StatementEnd": 368, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r4_01293", "QuoteType": 1, "NamePos": 322, "NameEnd": 330 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 330 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 340, "NameEnd": 356 }, "Operation": "", "Value": null }, { "Name": { "Name": "MIN", "QuoteType": 1, "NamePos": 357, "NameEnd": 360 }, "Operation": "=", "Value": { "NumPos": 361, "NumEnd": 368, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "AlterPos": 370, "StatementEnd": 427, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r5_01293", "QuoteType": 1, "NamePos": 381, "NameEnd": 389 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 389 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 399, "NameEnd": 415 }, "Operation": "", "Value": null }, { "Name": { "Name": "MAX", "QuoteType": 1, "NamePos": 416, "NameEnd": 419 }, "Operation": "=", "Value": { "NumPos": 420, "NumEnd": 427, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "AlterPos": 429, "StatementEnd": 480, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r6_01293", "QuoteType": 1, "NamePos": 440, "NameEnd": 448 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 448 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 458, "NameEnd": 474 }, "Operation": "", "Value": null } ], "Modifier": { "Name": "CONST", "QuoteType": 1, "NamePos": 475, "NameEnd": 480 } } ] }, { "AlterPos": 482, "StatementEnd": 536, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r7_01293", "QuoteType": 1, "NamePos": 493, "NameEnd": 501 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 501 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 511, "NameEnd": 527 }, "Operation": "", "Value": null } ], "Modifier": { "Name": "WRITABLE", "QuoteType": 1, "NamePos": 528, "NameEnd": 536 } } ] }, { "AlterPos": 538, "StatementEnd": 621, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r8_01293", "QuoteType": 1, "NamePos": 549, "NameEnd": 557 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 557 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 567, "NameEnd": 583 }, "Operation": "=", "Value": { "NumPos": 584, "NumEnd": 591, "Literal": "5000000", "Base": 10 } }, { "Name": { "Name": "MIN", "QuoteType": 1, "NamePos": 592, "NameEnd": 595 }, "Operation": "", "Value": { "NumPos": 596, "NumEnd": 603, "Literal": "4000000", "Base": 10 } }, { "Name": { "Name": "MAX", "QuoteType": 1, "NamePos": 604, "NameEnd": 607 }, "Operation": "", "Value": { "NumPos": 608, "NumEnd": 615, "Literal": "6000000", "Base": 10 } } ], "Modifier": { "Name": "CONST", "QuoteType": 1, "NamePos": 616, "NameEnd": 621 } } ] }, { "AlterPos": 623, "StatementEnd": 704, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r9_01293", "QuoteType": 1, "NamePos": 634, "NameEnd": 642 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 642 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 652, "NameEnd": 659 }, "Operation": "", "Value": { "LiteralPos": 661, "LiteralEnd": 668, "Literal": "default" } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 671, "NameEnd": 687 }, "Operation": "=", "Value": { "NumPos": 688, "NumEnd": 695, "Literal": "5000000", "Base": 10 } } ], "Modifier": { "Name": "WRITABLE", "QuoteType": 1, "NamePos": 696, "NameEnd": 704 } } ] }, { "AlterPos": 706, "StatementEnd": 735, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 717, "NameEnd": 725 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 725 }, { "RoleName": { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 727, "NameEnd": 735 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 735 } ], "Settings": null }, { "AlterPos": 737, "StatementEnd": 776, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 748, "NameEnd": 756 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 756 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "readonly", "QuoteType": 1, "NamePos": 766, "NameEnd": 774 }, "Operation": "=", "Value": { "NumPos": 775, "NumEnd": 776, "Literal": "1", "Base": 10 } } ], "Modifier": null } ] }, { "AlterPos": 778, "StatementEnd": 823, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 789, "NameEnd": 797 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 797 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 807, "NameEnd": 814 }, "Operation": "", "Value": { "LiteralPos": 816, "LiteralEnd": 823, "Literal": "default" } } ], "Modifier": null } ] }, { "AlterPos": 826, "StatementEnd": 912, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r3_01293", "QuoteType": 1, "NamePos": 837, "NameEnd": 845 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 845 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 855, "NameEnd": 871 }, "Operation": "=", "Value": { "NumPos": 872, "NumEnd": 879, "Literal": "5000000", "Base": 10 } }, { "Name": { "Name": "MIN", "QuoteType": 1, "NamePos": 880, "NameEnd": 883 }, "Operation": "", "Value": { "NumPos": 884, "NumEnd": 891, "Literal": "4000000", "Base": 10 } }, { "Name": { "Name": "MAX", "QuoteType": 1, "NamePos": 892, "NameEnd": 895 }, "Operation": "", "Value": { "NumPos": 896, "NumEnd": 903, "Literal": "6000000", "Base": 10 } } ], "Modifier": { "Name": "WRITABLE", "QuoteType": 1, "NamePos": 904, "NameEnd": 912 } } ] }, { "AlterPos": 914, "StatementEnd": 998, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r4_01293", "QuoteType": 1, "NamePos": 925, "NameEnd": 933 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 933 } ], "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 943, "NameEnd": 950 }, "Operation": "", "Value": { "LiteralPos": 952, "LiteralEnd": 959, "Literal": "default" } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 962, "NameEnd": 978 }, "Operation": "=", "Value": { "NumPos": 979, "NumEnd": 986, "Literal": "5000000", "Base": 10 } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "readonly", "QuoteType": 1, "NamePos": 988, "NameEnd": 996 }, "Operation": "=", "Value": { "NumPos": 997, "NumEnd": 998, "Literal": "1", "Base": 10 } } ], "Modifier": null } ] }, { "AlterPos": 1000, "StatementEnd": 1033, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r5_01293", "QuoteType": 1, "NamePos": 1011, "NameEnd": 1019 }, "Scope": null, "OnCluster": null }, "NewName": null, "StatementEnd": 1019 } ], "Settings": [ { "SettingPairs": [], "Modifier": { "Name": "NONE", "QuoteType": 1, "NamePos": 1029, "NameEnd": 1033 } } ] }, { "AlterPos": 1035, "StatementEnd": 1057, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 1046, "NameEnd": 1054 }, "Scope": { "LiteralPos": 1056, "LiteralEnd": 1057, "Literal": "%" }, "OnCluster": null }, "NewName": null, "StatementEnd": 1057 } ], "Settings": null }, { "AlterPos": 1060, "StatementEnd": 1093, "IfExists": false, "RoleRenamePairs": [ { "RoleName": { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 1071, "NameEnd": 1079 }, "Scope": { "LiteralPos": 1081, "LiteralEnd": 1093, "Literal": "%.myhost.com" }, "OnCluster": null }, "NewName": null, "StatementEnd": 1093 } ], "Settings": null } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_add_column.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 112, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 17, "NameEnd": 29 } }, "OnCluster": { "OnPos": 30, "Expr": { "LiteralPos": 42, "LiteralEnd": 57, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 59, "StatementEnd": 112, "Column": { "NamePos": 70, "ColumnEnd": 79, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 70, "NameEnd": 72 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 73, "NameEnd": 79 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, "IfNotExists": false, "After": { "Ident": { "Name": "f0", "QuoteType": 1, "NamePos": 86, "NameEnd": 88 }, "DotIdent": null }, "Settings": { "SettingsPos": 89, "ListEnd": 112, "Items": [ { "SettingsPos": 98, "Name": { "Name": "alter_sync", "QuoteType": 1, "NamePos": 98, "NameEnd": 108 }, "Expr": { "NumPos": 111, "NumEnd": 112, "Literal": "2", "Base": 10 } } ] } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_add_index.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 110, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 17, "NameEnd": 29 } }, "OnCluster": { "OnPos": 30, "Expr": { "LiteralPos": 42, "LiteralEnd": 57, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 59, "StatementEnd": 110, "Index": { "IndexPos": 63, "Name": { "Ident": { "Name": "my_index", "QuoteType": 1, "NamePos": 69, "NameEnd": 77 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "LeftParenPos": 77, "RightParenPos": 80, "Items": { "ListPos": 78, "ListEnd": 80, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 78, "NameEnd": 80 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null }, "ColumnType": { "Name": { "Name": "minmax", "QuoteType": 1, "NamePos": 87, "NameEnd": 93 } }, "Granularity": { "NumPos": 106, "NumEnd": 110, "Literal": "1024", "Base": 10 } }, "IfNotExists": false, "After": null } ] }, { "AlterPos": 112, "StatementEnd": 226, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 124, "NameEnd": 128 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 129, "NameEnd": 141 } }, "OnCluster": { "OnPos": 142, "Expr": { "LiteralPos": 154, "LiteralEnd": 169, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 171, "StatementEnd": 226, "Index": { "IndexPos": 175, "Name": { "Ident": { "Name": "api_id_idx", "QuoteType": 1, "NamePos": 181, "NameEnd": 191 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "api_id", "QuoteType": 1, "NamePos": 192, "NameEnd": 198 }, "Alias": null }, "ColumnType": { "LeftParenPos": 208, "RightParenPos": 211, "Name": { "Name": "set", "QuoteType": 1, "NamePos": 204, "NameEnd": 207 }, "Params": [ { "NumPos": 208, "NumEnd": 211, "Literal": "100", "Base": 10 } ] }, "Granularity": { "NumPos": 225, "NumEnd": 226, "Literal": "2", "Base": 10 } }, "IfNotExists": false, "After": null } ] }, { "AlterPos": 228, "StatementEnd": 346, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 240, "NameEnd": 244 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 245, "NameEnd": 257 } }, "OnCluster": { "OnPos": 258, "Expr": { "LiteralPos": 270, "LiteralEnd": 285, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 287, "StatementEnd": 346, "Index": { "IndexPos": 291, "Name": { "Ident": { "Name": "arr_idx", "QuoteType": 1, "NamePos": 297, "NameEnd": 304 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "arr", "QuoteType": 1, "NamePos": 305, "NameEnd": 308 }, "Alias": null }, "ColumnType": { "LeftParenPos": 327, "RightParenPos": 331, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 314, "NameEnd": 326 }, "Params": [ { "NumPos": 327, "NumEnd": 331, "Literal": "0.01", "Base": 10 } ] }, "Granularity": { "NumPos": 345, "NumEnd": 346, "Literal": "3", "Base": 10 } }, "IfNotExists": false, "After": null } ] }, { "AlterPos": 348, "StatementEnd": 479, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 360, "NameEnd": 364 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 365, "NameEnd": 377 } }, "OnCluster": { "OnPos": 378, "Expr": { "LiteralPos": 390, "LiteralEnd": 405, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 407, "StatementEnd": 479, "Index": { "IndexPos": 411, "Name": { "Ident": { "Name": "content_idx", "QuoteType": 1, "NamePos": 417, "NameEnd": 428 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "content", "QuoteType": 1, "NamePos": 429, "NameEnd": 436 }, "Alias": null }, "ColumnType": { "LeftParenPos": 453, "RightParenPos": 464, "Name": { "Name": "tokenbf_v1", "QuoteType": 1, "NamePos": 442, "NameEnd": 452 }, "Params": [ { "NumPos": 453, "NumEnd": 458, "Literal": "30720", "Base": 10 }, { "NumPos": 460, "NumEnd": 461, "Literal": "2", "Base": 10 }, { "NumPos": 463, "NumEnd": 464, "Literal": "0", "Base": 10 } ] }, "Granularity": { "NumPos": 478, "NumEnd": 479, "Literal": "1", "Base": 10 } }, "IfNotExists": false, "After": null } ] }, { "AlterPos": 481, "StatementEnd": 613, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 493, "NameEnd": 497 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 498, "NameEnd": 510 } }, "OnCluster": { "OnPos": 511, "Expr": { "LiteralPos": 523, "LiteralEnd": 538, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 540, "StatementEnd": 613, "Index": { "IndexPos": 544, "Name": { "Ident": { "Name": "output_idx", "QuoteType": 1, "NamePos": 550, "NameEnd": 560 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "output", "QuoteType": 1, "NamePos": 561, "NameEnd": 567 }, "Alias": null }, "ColumnType": { "LeftParenPos": 584, "RightParenPos": 598, "Name": { "Name": "ngrambf_v1", "QuoteType": 1, "NamePos": 573, "NameEnd": 583 }, "Params": [ { "NumPos": 584, "NumEnd": 585, "Literal": "3", "Base": 10 }, { "NumPos": 587, "NumEnd": 592, "Literal": "10000", "Base": 10 }, { "NumPos": 594, "NumEnd": 595, "Literal": "2", "Base": 10 }, { "NumPos": 597, "NumEnd": 598, "Literal": "1", "Base": 10 } ] }, "Granularity": { "NumPos": 612, "NumEnd": 613, "Literal": "2", "Base": 10 } }, "IfNotExists": false, "After": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_add_projection.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 140, "TableIdentifier": { "Database": null, "Table": { "Name": "visits_order", "QuoteType": 1, "NamePos": 12, "NameEnd": 24 } }, "OnCluster": null, "AlterExprs": [ { "AddPos": 25, "StatementEnd": 140, "IfNotExists": true, "TableProjection": { "IncludeProjectionKeyword": false, "ProjectionPos": 55, "Identifier": { "Ident": { "Name": "user_name_projection", "QuoteType": 1, "NamePos": 55, "NameEnd": 75 }, "DotIdent": null }, "Select": { "LeftParenPos": 76, "RightParenPos": 123, "With": null, "SelectColumns": { "ListPos": 84, "ListEnd": 84, "HasDistinct": false, "Items": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 84, "NameEnd": 84 }, "Alias": null } ] }, "GroupBy": { "GroupByPos": 86, "GroupByEnd": 105, "AggregateType": "", "Expr": { "ListPos": 95, "ListEnd": 104, "HasDistinct": false, "Items": [ { "Expr": { "Name": "user_name", "QuoteType": 1, "NamePos": 95, "NameEnd": 104 }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "OrderBy": { "OrderByPos": 105, "Columns": { "ListPos": 114, "ListEnd": 123, "HasDistinct": false, "Items": [ { "Expr": { "Name": "user_name", "QuoteType": 1, "NamePos": 114, "NameEnd": 123 }, "Alias": null } ] } } } }, "After": { "Ident": { "Name": "a", "QuoteType": 1, "NamePos": 131, "NameEnd": 132 }, "DotIdent": { "Name": "user_id", "QuoteType": 1, "NamePos": 133, "NameEnd": 140 } } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_add_projection_group_by_only.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 182, "TableIdentifier": { "Database": null, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 12, "NameEnd": 18 } }, "OnCluster": null, "AlterExprs": [ { "AddPos": 19, "StatementEnd": 182, "IfNotExists": true, "TableProjection": { "IncludeProjectionKeyword": false, "ProjectionPos": 48, "Identifier": { "Ident": { "Name": "hourly_stats", "QuoteType": 1, "NamePos": 48, "NameEnd": 60 }, "DotIdent": null }, "Select": { "LeftParenPos": 61, "RightParenPos": 182, "With": null, "SelectColumns": { "ListPos": 69, "ListEnd": 156, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 69, "NameEnd": 82 }, "Params": { "LeftParenPos": 82, "RightParenPos": 93, "Items": { "ListPos": 83, "ListEnd": 93, "HasDistinct": false, "Items": [ { "Expr": { "Name": "event_time", "QuoteType": 1, "NamePos": 83, "NameEnd": 93 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "hour", "QuoteType": 1, "NamePos": 98, "NameEnd": 102 } }, { "Expr": { "Name": "event_type", "QuoteType": 1, "NamePos": 104, "NameEnd": 114 }, "Alias": null }, { "Expr": { "Name": { "Name": "count", "QuoteType": 1, "NamePos": 116, "NameEnd": 121 }, "Params": { "LeftParenPos": 121, "RightParenPos": 122, "Items": { "ListPos": 122, "ListEnd": 122, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Alias": { "Name": "count", "QuoteType": 1, "NamePos": 127, "NameEnd": 132 } }, { "Expr": { "Name": { "Name": "uniq", "QuoteType": 1, "NamePos": 134, "NameEnd": 138 }, "Params": { "LeftParenPos": 138, "RightParenPos": 146, "Items": { "ListPos": 139, "ListEnd": 146, "HasDistinct": false, "Items": [ { "Expr": { "Name": "user_id", "QuoteType": 1, "NamePos": 139, "NameEnd": 146 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "users", "QuoteType": 1, "NamePos": 151, "NameEnd": 156 } } ] }, "GroupBy": { "GroupByPos": 157, "GroupByEnd": 182, "AggregateType": "", "Expr": { "ListPos": 166, "ListEnd": 182, "HasDistinct": false, "Items": [ { "Expr": { "Name": "hour", "QuoteType": 1, "NamePos": 166, "NameEnd": 170 }, "Alias": null }, { "Expr": { "Name": "event_type", "QuoteType": 1, "NamePos": 172, "NameEnd": 182 }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "OrderBy": null } }, "After": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_attach_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 43, "TableIdentifier": { "Database": null, "Table": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 } }, "OnCluster": null, "AlterExprs": [ { "AttachPos": 17, "Partition": { "PartitionPos": 24, "Expr": { "LiteralPos": 35, "LiteralEnd": 43, "Literal": "20210114" }, "ID": null, "All": false }, "From": null } ] }, { "AlterPos": 46, "StatementEnd": 101, "TableIdentifier": { "Database": null, "Table": { "Name": "test", "QuoteType": 1, "NamePos": 58, "NameEnd": 62 } }, "OnCluster": null, "AlterExprs": [ { "AttachPos": 63, "Partition": { "PartitionPos": 70, "Expr": { "LiteralPos": 81, "LiteralEnd": 89, "Literal": "20210114" }, "ID": null, "All": false }, "From": { "Database": null, "Table": { "Name": "test1", "QuoteType": 1, "NamePos": 96, "NameEnd": 101 } } } ] }, { "AlterPos": 103, "StatementEnd": 149, "TableIdentifier": { "Database": null, "Table": { "Name": "test", "QuoteType": 1, "NamePos": 115, "NameEnd": 119 } }, "OnCluster": null, "AlterExprs": [ { "AttachPos": 120, "Partition": { "PartitionPos": 127, "Expr": null, "ID": { "LiteralPos": 141, "LiteralEnd": 149, "Literal": "20210114" }, "All": false }, "From": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_clear_column.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 76, "TableIdentifier": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 20 } }, "OnCluster": null, "AlterExprs": [ { "ClearPos": 21, "StatementEnd": 76, "IfExists": false, "ColumnName": { "Ident": { "Name": "my_column_name", "QuoteType": 1, "NamePos": 34, "NameEnd": 48 }, "DotIdent": null }, "PartitionExpr": { "PartitionPos": 52, "Expr": { "Name": "partition_name", "QuoteType": 1, "NamePos": 62, "NameEnd": 76 }, "ID": null, "All": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_clear_index.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 74, "TableIdentifier": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 20 } }, "OnCluster": null, "AlterExprs": [ { "ClearPos": 21, "StatementEnd": 74, "IfExists": false, "IndexName": { "Ident": { "Name": "my_index_name", "QuoteType": 1, "NamePos": 33, "NameEnd": 46 }, "DotIdent": null }, "PartitionExpr": { "PartitionPos": 50, "Expr": { "Name": "partition_name", "QuoteType": 1, "NamePos": 60, "NameEnd": 74 }, "ID": null, "All": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_clear_projection.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 71, "TableIdentifier": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 20 } }, "OnCluster": null, "AlterExprs": [ { "ClearPos": 21, "StatementEnd": 71, "IfExists": false, "ProjectionName": { "Ident": { "Name": "hello", "QuoteType": 1, "NamePos": 38, "NameEnd": 43 }, "DotIdent": null }, "PartitionExpr": { "PartitionPos": 47, "Expr": { "Name": "partition_name", "QuoteType": 1, "NamePos": 57, "NameEnd": 71 }, "ID": null, "All": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_delete.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 61, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 17, "NameEnd": 23 } }, "OnCluster": null, "AlterExprs": [ { "DeletePos": 24, "StatementEnd": 61, "WhereClause": { "LeftExpr": { "Name": "created_at", "QuoteType": 1, "NamePos": 37, "NameEnd": 47 }, "Operation": "\u003c", "RightExpr": { "LiteralPos": 51, "LiteralEnd": 61, "Literal": "2023-01-01" }, "HasGlobal": false, "HasNot": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_delete_with_cluster.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 96, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 17, "NameEnd": 23 } }, "OnCluster": { "OnPos": 24, "Expr": { "LiteralPos": 36, "LiteralEnd": 51, "Literal": "default_cluster" } }, "AlterExprs": [ { "DeletePos": 53, "StatementEnd": 96, "WhereClause": { "LeftExpr": { "LeftExpr": { "Name": "id", "QuoteType": 1, "NamePos": 66, "NameEnd": 68 }, "Operation": "=", "RightExpr": { "NumPos": 71, "NumEnd": 74, "Literal": "123", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Name": "status", "QuoteType": 1, "NamePos": 79, "NameEnd": 85 }, "Operation": "=", "RightExpr": { "LiteralPos": 89, "LiteralEnd": 96, "Literal": "deleted" }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_detach_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 48, "TableIdentifier": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 }, "Table": { "Name": "test", "QuoteType": 1, "NamePos": 15, "NameEnd": 19 } }, "OnCluster": null, "AlterExprs": [ { "DetachPos": 27, "Partition": { "PartitionPos": 27, "Expr": { "LiteralPos": 38, "LiteralEnd": 48, "Literal": "2021-10-01" }, "ID": null, "All": false }, "Settings": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_drop_column.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 83, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 17, "NameEnd": 29 } }, "OnCluster": { "OnPos": 30, "Expr": { "LiteralPos": 42, "LiteralEnd": 57, "Literal": "default_cluster" } }, "AlterExprs": [ { "DropPos": 59, "ColumnName": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 81, "NameEnd": 83 }, "DotIdent": null }, "IfExists": true } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_drop_detach_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 120, "TableIdentifier": { "Database": { "Name": "app_utc_00", "QuoteType": 1, "NamePos": 12, "NameEnd": 22 }, "Table": { "Name": "app_message_as_notification_organization_sent_stats_i_d_local", "QuoteType": 1, "NamePos": 23, "NameEnd": 84 } }, "OnCluster": null, "AlterExprs": [ { "DropPos": 85, "HasDetached": true, "Partition": { "PartitionPos": 99, "Expr": { "LiteralPos": 110, "LiteralEnd": 120, "Literal": "2022-05-24" }, "ID": null, "All": false }, "Settings": { "SettingsPos": 122, "ListEnd": 154, "Items": [ { "SettingsPos": 131, "Name": { "Name": "allow_drop_detached", "QuoteType": 1, "NamePos": 131, "NameEnd": 150 }, "Expr": { "NumPos": 153, "NumEnd": 154, "Literal": "1", "Base": 10 } } ] } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_drop_index.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 71, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "event_local", "QuoteType": 1, "NamePos": 17, "NameEnd": 28 } }, "OnCluster": { "OnPos": 29, "Expr": { "LiteralPos": 41, "LiteralEnd": 56, "Literal": "default_cluster" } }, "AlterExprs": [ { "DropPos": 58, "IndexName": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 69, "NameEnd": 71 }, "DotIdent": null }, "IfExists": false } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_drop_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 79, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 17, "NameEnd": 23 } }, "OnCluster": { "OnPos": 24, "Expr": { "LiteralPos": 36, "LiteralEnd": 51, "Literal": "default_cluster" } }, "AlterExprs": [ { "DropPos": 53, "HasDetached": false, "Partition": { "PartitionPos": 58, "Expr": { "LiteralPos": 69, "LiteralEnd": 79, "Literal": "2023-07-18" }, "ID": null, "All": false }, "Settings": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_drop_projection.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 76, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "event_local", "QuoteType": 1, "NamePos": 17, "NameEnd": 28 } }, "OnCluster": { "OnPos": 29, "Expr": { "LiteralPos": 41, "LiteralEnd": 56, "Literal": "default_cluster" } }, "AlterExprs": [ { "DropPos": 58, "ProjectionName": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 74, "NameEnd": 76 }, "DotIdent": null }, "IfExists": false } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_freeze_no_specify_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 59, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 17, "NameEnd": 23 } }, "OnCluster": { "OnPos": 24, "Expr": { "LiteralPos": 36, "LiteralEnd": 51, "Literal": "default_cluster" } }, "AlterExprs": [ { "FreezePos": 53, "StatementEnd": 59, "Partition": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_freeze_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 81, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 17, "NameEnd": 23 } }, "OnCluster": { "OnPos": 24, "Expr": { "LiteralPos": 36, "LiteralEnd": 51, "Literal": "default_cluster" } }, "AlterExprs": [ { "FreezePos": 53, "StatementEnd": 81, "Partition": { "PartitionPos": 60, "Expr": { "LiteralPos": 71, "LiteralEnd": 81, "Literal": "2023-07-18" }, "ID": null, "All": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_materialize_index.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 91, "TableIdentifier": { "Database": null, "Table": { "Name": "visits_order", "QuoteType": 1, "NamePos": 12, "NameEnd": 24 } }, "OnCluster": null, "AlterExprs": [ { "MaterializedPos": 25, "StatementEnd": 91, "IfExists": true, "IndexName": { "Ident": { "Name": "user_name_index", "QuoteType": 1, "NamePos": 53, "NameEnd": 68 }, "DotIdent": null }, "Partition": { "PartitionPos": 72, "Expr": { "LiteralPos": 83, "LiteralEnd": 91, "Literal": "20240403" }, "ID": null, "All": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_materialize_projection.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 101, "TableIdentifier": { "Database": null, "Table": { "Name": "visits_order", "QuoteType": 1, "NamePos": 12, "NameEnd": 24 } }, "OnCluster": null, "AlterExprs": [ { "MaterializedPos": 25, "StatementEnd": 101, "IfExists": true, "ProjectionName": { "Ident": { "Name": "user_name_projection", "QuoteType": 1, "NamePos": 58, "NameEnd": 78 }, "DotIdent": null }, "Partition": { "PartitionPos": 82, "Expr": { "LiteralPos": 93, "LiteralEnd": 101, "Literal": "20240403" }, "ID": null, "All": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_modify_column.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 52, "TableIdentifier": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 } }, "OnCluster": null, "AlterExprs": [ { "ModifyPos": 15, "StatementEnd": 52, "IfExists": false, "Column": { "NamePos": 29, "ColumnEnd": 52, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 29, "NameEnd": 31 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 32, "NameEnd": 38 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": { "LiteralPos": 39, "LiteralEnd": 52, "Literal": "test" }, "CompressionCodec": null }, "RemovePropertyType": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_modify_column_remove.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 31, "TableIdentifier": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 } }, "OnCluster": null, "AlterExprs": [ { "ModifyPos": 15, "StatementEnd": 31, "IfExists": false, "Column": { "NamePos": 29, "ColumnEnd": 31, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 29, "NameEnd": 31 }, "DotIdent": null }, "Type": null, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, "RemovePropertyType": { "RemovePos": 32, "PropertyType": { "Name": { "Name": "COMMENT", "QuoteType": 1, "NamePos": 39, "NameEnd": 46 } } } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_modify_setting.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 93, "TableIdentifier": { "Database": null, "Table": { "Name": "example_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 25 } }, "OnCluster": null, "AlterExprs": [ { "ModifyPos": 26, "StatementEnd": 93, "Settings": [ { "SettingsPos": 41, "Name": { "Name": "max_part_loading_threads", "QuoteType": 1, "NamePos": 41, "NameEnd": 65 }, "Expr": { "NumPos": 66, "NumEnd": 67, "Literal": "8", "Base": 10 } }, { "SettingsPos": 69, "Name": { "Name": "max_parts_in_total", "QuoteType": 1, "NamePos": 69, "NameEnd": 87 }, "Expr": { "NumPos": 88, "NumEnd": 93, "Literal": "50000", "Base": 10 } } ] } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_remove_ttl.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 63, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 17, "NameEnd": 23 } }, "OnCluster": { "OnPos": 24, "Expr": { "LiteralPos": 36, "LiteralEnd": 51, "Literal": "default_cluster" } }, "AlterExprs": [ { "RemovePos": 53, "StatementEnd": 63 } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_rename_column.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 69, "TableIdentifier": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 20 } }, "OnCluster": null, "AlterExprs": [ { "RenamePos": 21, "IfExists": false, "OldColumnName": { "Ident": { "Name": "old_column_name", "QuoteType": 1, "NamePos": 35, "NameEnd": 50 }, "DotIdent": null }, "NewColumnName": { "Ident": { "Name": "new_column_name", "QuoteType": 1, "NamePos": 54, "NameEnd": 69 }, "DotIdent": null } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_replace_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 52, "TableIdentifier": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 } }, "OnCluster": null, "AlterExprs": [ { "ReplacePos": 15, "Partition": { "PartitionPos": 23, "Expr": { "LiteralPos": 34, "LiteralEnd": 43, "Literal": "partition" }, "ID": null, "All": false }, "Table": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 50, "NameEnd": 52 } } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_reset_multiple_settings.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 101, "TableIdentifier": { "Database": null, "Table": { "Name": "example_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 25 } }, "OnCluster": null, "AlterExprs": [ { "ResetPos": 26, "StatementEnd": 101, "Settings": [ { "Name": "max_part_loading_threads", "QuoteType": 1, "NamePos": 40, "NameEnd": 64 }, { "Name": "max_parts_in_total", "QuoteType": 1, "NamePos": 66, "NameEnd": 84 }, { "Name": "another_setting", "QuoteType": 1, "NamePos": 86, "NameEnd": 101 } ] } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_reset_setting.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 64, "TableIdentifier": { "Database": null, "Table": { "Name": "example_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 25 } }, "OnCluster": null, "AlterExprs": [ { "ResetPos": 26, "StatementEnd": 64, "Settings": [ { "Name": "max_part_loading_threads", "QuoteType": 1, "NamePos": 40, "NameEnd": 64 } ] } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_update.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 91, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "users", "QuoteType": 1, "NamePos": 17, "NameEnd": 22 } }, "OnCluster": null, "AlterExprs": [ { "UpdatePos": 23, "StatementEnd": 91, "Assignments": [ { "AssignmentPos": 30, "Column": { "Ident": { "Name": "status", "QuoteType": 1, "NamePos": 30, "NameEnd": 36 }, "DotIdent": null }, "Expr": { "LiteralPos": 40, "LiteralEnd": 46, "Literal": "active" } }, { "AssignmentPos": 49, "Column": { "Ident": { "Name": "updated_at", "QuoteType": 1, "NamePos": 49, "NameEnd": 59 }, "DotIdent": null }, "Expr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 62, "NameEnd": 65 }, "Params": { "LeftParenPos": 65, "RightParenPos": 66, "Items": { "ListPos": 66, "ListEnd": 66, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } } } ], "InPartition": null, "WhereClause": { "LeftExpr": { "Name": "status", "QuoteType": 1, "NamePos": 74, "NameEnd": 80 }, "Operation": "=", "RightExpr": { "LiteralPos": 84, "LiteralEnd": 91, "Literal": "pending" }, "HasGlobal": false, "HasNot": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_update_in_partition.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 98, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "users", "QuoteType": 1, "NamePos": 17, "NameEnd": 22 } }, "OnCluster": null, "AlterExprs": [ { "UpdatePos": 23, "StatementEnd": 98, "Assignments": [ { "AssignmentPos": 30, "Column": { "Ident": { "Name": "status", "QuoteType": 1, "NamePos": 30, "NameEnd": 36 }, "DotIdent": null }, "Expr": { "LiteralPos": 40, "LiteralEnd": 48, "Literal": "inactive" } } ], "InPartition": { "PartitionPos": 53, "Expr": { "LiteralPos": 64, "LiteralEnd": 74, "Literal": "2024-01-01" }, "ID": null, "All": false }, "WhereClause": { "LeftExpr": { "Name": "status", "QuoteType": 1, "NamePos": 82, "NameEnd": 88 }, "Operation": "=", "RightExpr": { "LiteralPos": 92, "LiteralEnd": 98, "Literal": "active" }, "HasGlobal": false, "HasNot": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/alter_table_update_with_cluster.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 84, "TableIdentifier": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 15, "NameEnd": 20 } }, "OnCluster": { "OnPos": 21, "Expr": { "Name": "cluster1", "QuoteType": 1, "NamePos": 32, "NameEnd": 40 } }, "AlterExprs": [ { "UpdatePos": 41, "StatementEnd": 84, "Assignments": [ { "AssignmentPos": 48, "Column": { "Ident": { "Name": "column1", "QuoteType": 1, "NamePos": 48, "NameEnd": 55 }, "DotIdent": null }, "Expr": { "LeftExpr": { "Name": "column1", "QuoteType": 1, "NamePos": 58, "NameEnd": 65 }, "Operation": "+", "RightExpr": { "NumPos": 68, "NumEnd": 69, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } } ], "InPartition": null, "WhereClause": { "LeftExpr": { "Name": "id", "QuoteType": 1, "NamePos": 76, "NameEnd": 78 }, "Operation": "\u003e", "RightExpr": { "NumPos": 81, "NumEnd": 84, "Literal": "100", "Base": 10 }, "HasGlobal": false, "HasNot": false } } ] } ] ================================================ FILE: parser/testdata/ddl/output/attach_table_basic.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 399, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 27, "NameEnd": 31 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 32, "NameEnd": 44 } }, "IfNotExists": true, "UUID": null, "OnCluster": { "OnPos": 45, "Expr": { "LiteralPos": 57, "LiteralEnd": 72, "Literal": "default_cluster" } }, "TableSchema": { "SchemaPos": 74, "SchemaEnd": 227, "Columns": [ { "NamePos": 80, "ColumnEnd": 89, "Name": { "Ident": { "Name": "f0", "QuoteType": 1, "NamePos": 80, "NameEnd": 82 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 83, "NameEnd": 89 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 95, "ColumnEnd": 104, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 95, "NameEnd": 97 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 98, "NameEnd": 104 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 110, "ColumnEnd": 119, "Name": { "Ident": { "Name": "f2", "QuoteType": 1, "NamePos": 110, "NameEnd": 112 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 113, "NameEnd": 119 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 125, "ColumnEnd": 136, "Name": { "Ident": { "Name": "f3", "QuoteType": 1, "NamePos": 125, "NameEnd": 127 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 128, "NameEnd": 136 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 142, "ColumnEnd": 153, "Name": { "Ident": { "Name": "f4", "QuoteType": 1, "NamePos": 142, "NameEnd": 144 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 145, "NameEnd": 153 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 159, "ColumnEnd": 179, "Name": { "Ident": { "Name": "f5", "QuoteType": 1, "NamePos": 159, "NameEnd": 161 }, "DotIdent": null }, "Type": { "LeftParenPos": 166, "RightParenPos": 179, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 162, "NameEnd": 165 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 166, "NameEnd": 172 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 173, "NameEnd": 179 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 186, "ColumnEnd": 195, "Name": { "Ident": { "Name": "f6", "QuoteType": 1, "NamePos": 186, "NameEnd": 188 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 189, "NameEnd": 195 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 201, "ColumnEnd": 225, "Name": { "Ident": { "Name": "f7", "QuoteType": 1, "NamePos": 201, "NameEnd": 203 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 204, "NameEnd": 212 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 221, "NameEnd": 224 }, "Params": { "LeftParenPos": 224, "RightParenPos": 225, "Items": { "ListPos": 225, "ListEnd": 225, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 229, "EngineEnd": 399, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 257, "RightParenPos": 325, "Items": { "ListPos": 259, "ListEnd": 324, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 259, "LiteralEnd": 311, "Literal": "/clickhouse/tables/{layer}-{shard}/test/events_local" }, "Alias": null }, { "Expr": { "LiteralPos": 315, "LiteralEnd": 324, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 353, "Expr": { "ListPos": 366, "ListEnd": 379, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMMDD", "QuoteType": 1, "NamePos": 366, "NameEnd": 376 }, "Params": { "LeftParenPos": 376, "RightParenPos": 379, "Items": { "ListPos": 377, "ListEnd": 379, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 377, "NameEnd": 379 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 327, "ListEnd": 352, "Items": [ { "TTLPos": 327, "Expr": { "LeftExpr": { "Name": "f3", "QuoteType": 1, "NamePos": 331, "NameEnd": 333 }, "Operation": "+", "RightExpr": { "IntervalPos": 336, "Expr": { "NumPos": 345, "NumEnd": 346, "Literal": "6", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 347, "NameEnd": 352 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": null, "OrderBy": { "OrderPos": 381, "ListEnd": 399, "Items": [ { "OrderPos": 381, "Expr": { "LeftParenPos": 390, "RightParenPos": 399, "Items": { "ListPos": 391, "ListEnd": 399, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 391, "NameEnd": 393 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 394, "NameEnd": 396 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 397, "NameEnd": 399 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/bug_001.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 635, "Name": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 39, "NameEnd": 41 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 42, "NameEnd": 47 } }, "IfNotExists": true, "OnCluster": { "OnPos": 60, "Expr": { "LiteralPos": 72, "LiteralEnd": 87, "Literal": "default_cluster" } }, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": null, "HasEmpty": false, "Destination": { "ToPos": 89, "TableIdentifier": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 92, "NameEnd": 94 }, "Table": { "Name": "table_mv", "QuoteType": 1, "NamePos": 95, "NameEnd": 103 } }, "TableSchema": null }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 107, "StatementEnd": 635, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "event_ts", "QuoteType": 1, "NamePos": 118, "NameEnd": 126 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "org_id", "QuoteType": 1, "NamePos": 132, "NameEnd": 138 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 144, "NameEnd": 167 }, "Params": { "LeftParenPos": 167, "RightParenPos": 183, "Items": { "ListPos": 168, "ListEnd": 182, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 168, "NameEnd": 178 }, "Alias": null }, { "Expr": { "LiteralPos": 181, "LiteralEnd": 182, "Literal": "x" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "x", "QuoteType": 1, "NamePos": 188, "NameEnd": 189 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 195, "NameEnd": 218 }, "Params": { "LeftParenPos": 218, "RightParenPos": 234, "Items": { "ListPos": 219, "ListEnd": 233, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 219, "NameEnd": 229 }, "Alias": null }, { "Expr": { "LiteralPos": 232, "LiteralEnd": 233, "Literal": "y" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "y", "QuoteType": 1, "NamePos": 239, "NameEnd": 240 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 246, "NameEnd": 269 }, "Params": { "LeftParenPos": 269, "RightParenPos": 285, "Items": { "ListPos": 270, "ListEnd": 284, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 270, "NameEnd": 280 }, "Alias": null }, { "Expr": { "LiteralPos": 283, "LiteralEnd": 284, "Literal": "z" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "z", "QuoteType": 1, "NamePos": 290, "NameEnd": 291 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 297, "NameEnd": 320 }, "Params": { "LeftParenPos": 320, "RightParenPos": 336, "Items": { "ListPos": 321, "ListEnd": 335, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 321, "NameEnd": 331 }, "Alias": null }, { "Expr": { "LiteralPos": 334, "LiteralEnd": 335, "Literal": "a" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "a", "QuoteType": 1, "NamePos": 341, "NameEnd": 342 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 348, "NameEnd": 371 }, "Params": { "LeftParenPos": 371, "RightParenPos": 387, "Items": { "ListPos": 372, "ListEnd": 386, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 372, "NameEnd": 382 }, "Alias": null }, { "Expr": { "LiteralPos": 385, "LiteralEnd": 386, "Literal": "b" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "b", "QuoteType": 1, "NamePos": 392, "NameEnd": 393 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 399, "NameEnd": 422 }, "Params": { "LeftParenPos": 422, "RightParenPos": 438, "Items": { "ListPos": 423, "ListEnd": 437, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 423, "NameEnd": 433 }, "Alias": null }, { "Expr": { "LiteralPos": 436, "LiteralEnd": 437, "Literal": "c" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "c", "QuoteType": 1, "NamePos": 443, "NameEnd": 444 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 450, "NameEnd": 473 }, "Params": { "LeftParenPos": 473, "RightParenPos": 489, "Items": { "ListPos": 474, "ListEnd": 488, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 474, "NameEnd": 484 }, "Alias": null }, { "Expr": { "LiteralPos": 487, "LiteralEnd": 488, "Literal": "d" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "d", "QuoteType": 1, "NamePos": 494, "NameEnd": 495 } }, { "Expr": { "Name": { "Name": "visitParamExtractInt", "QuoteType": 1, "NamePos": 501, "NameEnd": 521 }, "Params": { "LeftParenPos": 521, "RightParenPos": 537, "Items": { "ListPos": 522, "ListEnd": 536, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 522, "NameEnd": 532 }, "Alias": null }, { "Expr": { "LiteralPos": 535, "LiteralEnd": 536, "Literal": "e" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "e", "QuoteType": 1, "NamePos": 542, "NameEnd": 543 } }, { "Expr": { "Name": { "Name": "visitParamExtractInt", "QuoteType": 1, "NamePos": 549, "NameEnd": 569 }, "Params": { "LeftParenPos": 569, "RightParenPos": 585, "Items": { "ListPos": 570, "ListEnd": 584, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 570, "NameEnd": 580 }, "Alias": null }, { "Expr": { "LiteralPos": 583, "LiteralEnd": 584, "Literal": "f" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f", "QuoteType": 1, "NamePos": 590, "NameEnd": 591 } } ], "From": { "FromPos": 592, "Expr": { "Table": { "TablePos": 597, "TableEnd": 605, "Alias": null, "Expr": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 597, "NameEnd": 599 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 600, "NameEnd": 605 } }, "HasFinal": false }, "StatementEnd": 605, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 606, "Expr": { "LeftExpr": { "Fields": [ { "Name": "db", "QuoteType": 1, "NamePos": 612, "NameEnd": 614 }, { "Name": "table", "QuoteType": 1, "NamePos": 615, "NameEnd": 620 }, { "Name": "event", "QuoteType": 1, "NamePos": 621, "NameEnd": 626 } ] }, "Operation": "=", "RightExpr": { "LiteralPos": 630, "LiteralEnd": 635, "Literal": "hello" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": null, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/check.sql.golden.json ================================================ [ { "CheckPos": 0, "Table": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 12, "NameEnd": 22 } }, "Partition": null }, { "CheckPos": 24, "Table": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 36, "NameEnd": 46 } }, "Partition": { "PartitionPos": 47, "Expr": { "LiteralPos": 58, "LiteralEnd": 61, "Literal": "col" }, "ID": null, "All": false } } ] ================================================ FILE: parser/testdata/ddl/output/create_database.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 35, "Name": { "Name": "test", "QuoteType": 3, "NamePos": 31, "NameEnd": 35 }, "IfNotExists": true, "OnCluster": null, "Engine": null, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_database_replicated.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 54, "Name": { "Name": "test", "QuoteType": 3, "NamePos": 31, "NameEnd": 35 }, "IfNotExists": true, "OnCluster": null, "Engine": { "EnginePos": 37, "EngineEnd": 54, "Name": "Replicated", "Params": { "LeftParenPos": 54, "RightParenPos": 93, "Items": { "ListPos": 56, "ListEnd": 92, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 56, "LiteralEnd": 72, "Literal": "/root/test_local" }, "Alias": null }, { "Expr": { "LiteralPos": 76, "LiteralEnd": 81, "Literal": "shard" }, "Alias": null }, { "Expr": { "LiteralPos": 85, "LiteralEnd": 92, "Literal": "replica" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": null }, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_dictionary_basic.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 444, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 18, "NameEnd": 22 }, "Table": { "Name": "my_dict", "QuoteType": 1, "NamePos": 23, "NameEnd": 30 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "Schema": { "SchemaPos": 31, "Attributes": [ { "NamePos": 37, "Name": { "Name": "id", "QuoteType": 1, "NamePos": 37, "NameEnd": 39 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 40, "NameEnd": 46 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 52, "Name": { "Name": "name", "QuoteType": 1, "NamePos": 52, "NameEnd": 56 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 57, "NameEnd": 63 } }, "Default": { "LiteralPos": 73, "LiteralEnd": 73, "Literal": "" }, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 80, "Name": { "Name": "value", "QuoteType": 1, "NamePos": 80, "NameEnd": 85 }, "Type": { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 86, "NameEnd": 93 } }, "Default": null, "Expression": { "Name": { "Name": "toFloat64OrZero", "QuoteType": 1, "NamePos": 105, "NameEnd": 120 }, "Params": { "LeftParenPos": 120, "RightParenPos": 125, "Items": { "ListPos": 121, "ListEnd": 125, "HasDistinct": false, "Items": [ { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 121, "NameEnd": 125 }, "Alias": null } ] }, "ColumnArgList": null } }, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 132, "Name": { "Name": "parent_id", "QuoteType": 1, "NamePos": 132, "NameEnd": 141 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 142, "NameEnd": 148 } }, "Default": null, "Expression": null, "Hierarchical": true, "Injective": false, "IsObjectId": false }, { "NamePos": 167, "Name": { "Name": "is_active", "QuoteType": 1, "NamePos": 167, "NameEnd": 176 }, "Type": { "Name": { "Name": "UInt8", "QuoteType": 1, "NamePos": 177, "NameEnd": 182 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": true, "IsObjectId": false }, { "NamePos": 198, "Name": { "Name": "object_id", "QuoteType": 1, "NamePos": 198, "NameEnd": 207 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 208, "NameEnd": 214 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": true } ], "RParenPos": 228 }, "Engine": { "EnginePos": 230, "PrimaryKey": { "PrimaryKeyPos": 230, "Keys": { "ListPos": 242, "ListEnd": 244, "HasDistinct": false, "Items": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 242, "NameEnd": 244 }, "Alias": null } ] }, "RParenPos": 243 }, "Source": { "SourcePos": 245, "Source": { "Name": "MYSQL", "QuoteType": 1, "NamePos": 252, "NameEnd": 257 }, "Args": [ { "ArgPos": 263, "Name": { "Name": "host", "QuoteType": 1, "NamePos": 263, "NameEnd": 267 }, "Value": { "LiteralPos": 269, "LiteralEnd": 278, "Literal": "localhost" } }, { "ArgPos": 284, "Name": { "Name": "port", "QuoteType": 1, "NamePos": 284, "NameEnd": 288 }, "Value": { "NumPos": 289, "NumEnd": 293, "Literal": "3306", "Base": 10 } }, { "ArgPos": 298, "Name": { "Name": "user", "QuoteType": 1, "NamePos": 298, "NameEnd": 302 }, "Value": { "LiteralPos": 304, "LiteralEnd": 311, "Literal": "default" } }, { "ArgPos": 317, "Name": { "Name": "password", "QuoteType": 1, "NamePos": 317, "NameEnd": 325 }, "Value": { "LiteralPos": 327, "LiteralEnd": 327, "Literal": "" } }, { "ArgPos": 333, "Name": { "Name": "db", "QuoteType": 1, "NamePos": 333, "NameEnd": 335 }, "Value": { "LiteralPos": 337, "LiteralEnd": 341, "Literal": "test" } }, { "ArgPos": 347, "Name": { "Name": "table", "QuoteType": 1, "NamePos": 347, "NameEnd": 352 }, "Value": { "LiteralPos": 354, "LiteralEnd": 364, "Literal": "dict_table" } } ], "RParenPos": 367 }, "Lifetime": { "LifetimePos": 369, "Min": { "NumPos": 382, "NumEnd": 386, "Literal": "1000", "Base": 10 }, "Max": { "NumPos": 391, "NumEnd": 395, "Literal": "2000", "Base": 10 }, "Value": null, "RParenPos": 395 }, "Layout": { "LayoutPos": 397, "Layout": { "Name": "HASHED", "QuoteType": 1, "NamePos": 404, "NameEnd": 410 }, "Args": null, "RParenPos": 412 }, "Range": null, "Settings": { "SettingsPos": 414, "ListEnd": 444, "Items": [ { "SettingsPos": 423, "Name": { "Name": "max_block_size", "QuoteType": 1, "NamePos": 423, "NameEnd": 437 }, "Expr": { "NumPos": 440, "NumEnd": 444, "Literal": "8192", "Base": 10 } } ] } }, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_dictionary_comprehensive.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 586, "OrReplace": true, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 29, "NameEnd": 33 }, "Table": { "Name": "comprehensive_dict", "QuoteType": 1, "NamePos": 34, "NameEnd": 52 } }, "IfNotExists": false, "UUID": { "Value": { "LiteralPos": 60, "LiteralEnd": 96, "Literal": "12345678-1234-1234-1234-123456789012" } }, "OnCluster": { "OnPos": 98, "Expr": { "Name": "production_cluster", "QuoteType": 1, "NamePos": 109, "NameEnd": 127 } }, "Schema": { "SchemaPos": 128, "Attributes": [ { "NamePos": 134, "Name": { "Name": "id", "QuoteType": 1, "NamePos": 134, "NameEnd": 136 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 137, "NameEnd": 143 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 149, "Name": { "Name": "name", "QuoteType": 1, "NamePos": 149, "NameEnd": 153 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 154, "NameEnd": 160 } }, "Default": { "LiteralPos": 170, "LiteralEnd": 170, "Literal": "" }, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 177, "Name": { "Name": "value", "QuoteType": 1, "NamePos": 177, "NameEnd": 182 }, "Type": { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 183, "NameEnd": 190 } }, "Default": null, "Expression": { "Name": { "Name": "toFloat64OrZero", "QuoteType": 1, "NamePos": 202, "NameEnd": 217 }, "Params": { "LeftParenPos": 217, "RightParenPos": 222, "Items": { "ListPos": 218, "ListEnd": 222, "HasDistinct": false, "Items": [ { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 218, "NameEnd": 222 }, "Alias": null } ] }, "ColumnArgList": null } }, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 229, "Name": { "Name": "parent_id", "QuoteType": 1, "NamePos": 229, "NameEnd": 238 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 239, "NameEnd": 245 } }, "Default": null, "Expression": null, "Hierarchical": true, "Injective": false, "IsObjectId": false }, { "NamePos": 264, "Name": { "Name": "is_active", "QuoteType": 1, "NamePos": 264, "NameEnd": 273 }, "Type": { "Name": { "Name": "UInt8", "QuoteType": 1, "NamePos": 274, "NameEnd": 279 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": true, "IsObjectId": false }, { "NamePos": 295, "Name": { "Name": "object_id", "QuoteType": 1, "NamePos": 295, "NameEnd": 304 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 305, "NameEnd": 311 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": true } ], "RParenPos": 325 }, "Engine": { "EnginePos": 327, "PrimaryKey": { "PrimaryKeyPos": 327, "Keys": { "ListPos": 339, "ListEnd": 341, "HasDistinct": false, "Items": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 339, "NameEnd": 341 }, "Alias": null } ] }, "RParenPos": 340 }, "Source": { "SourcePos": 342, "Source": { "Name": "MYSQL", "QuoteType": 1, "NamePos": 349, "NameEnd": 354 }, "Args": [ { "ArgPos": 360, "Name": { "Name": "host", "QuoteType": 1, "NamePos": 360, "NameEnd": 364 }, "Value": { "LiteralPos": 366, "LiteralEnd": 375, "Literal": "localhost" } }, { "ArgPos": 381, "Name": { "Name": "port", "QuoteType": 1, "NamePos": 381, "NameEnd": 385 }, "Value": { "NumPos": 386, "NumEnd": 390, "Literal": "3306", "Base": 10 } }, { "ArgPos": 395, "Name": { "Name": "user", "QuoteType": 1, "NamePos": 395, "NameEnd": 399 }, "Value": { "LiteralPos": 401, "LiteralEnd": 405, "Literal": "root" } }, { "ArgPos": 411, "Name": { "Name": "password", "QuoteType": 1, "NamePos": 411, "NameEnd": 419 }, "Value": { "LiteralPos": 421, "LiteralEnd": 427, "Literal": "secret" } }, { "ArgPos": 433, "Name": { "Name": "db", "QuoteType": 1, "NamePos": 433, "NameEnd": 435 }, "Value": { "LiteralPos": 437, "LiteralEnd": 444, "Literal": "test_db" } }, { "ArgPos": 450, "Name": { "Name": "table", "QuoteType": 1, "NamePos": 450, "NameEnd": 455 }, "Value": { "LiteralPos": 457, "LiteralEnd": 473, "Literal": "dictionary_table" } } ], "RParenPos": 476 }, "Lifetime": { "LifetimePos": 478, "Min": { "NumPos": 491, "NumEnd": 495, "Literal": "1000", "Base": 10 }, "Max": { "NumPos": 500, "NumEnd": 504, "Literal": "2000", "Base": 10 }, "Value": null, "RParenPos": 504 }, "Layout": { "LayoutPos": 506, "Layout": { "Name": "HASHED", "QuoteType": 1, "NamePos": 513, "NameEnd": 519 }, "Args": null, "RParenPos": 521 }, "Range": null, "Settings": { "SettingsPos": 523, "ListEnd": 586, "Items": [ { "SettingsPos": 532, "Name": { "Name": "max_block_size", "QuoteType": 1, "NamePos": 532, "NameEnd": 546 }, "Expr": { "NumPos": 549, "NumEnd": 553, "Literal": "8192", "Base": 10 } }, { "SettingsPos": 555, "Name": { "Name": "max_insert_block_size", "QuoteType": 1, "NamePos": 555, "NameEnd": 576 }, "Expr": { "NumPos": 579, "NumEnd": 586, "Literal": "1048576", "Base": 10 } } ] } }, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_dictionary_with_comment.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 493, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 18, "NameEnd": 22 }, "Table": { "Name": "my_dict", "QuoteType": 1, "NamePos": 23, "NameEnd": 30 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "Schema": { "SchemaPos": 31, "Attributes": [ { "NamePos": 37, "Name": { "Name": "id", "QuoteType": 1, "NamePos": 37, "NameEnd": 39 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 40, "NameEnd": 46 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 52, "Name": { "Name": "name", "QuoteType": 1, "NamePos": 52, "NameEnd": 56 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 57, "NameEnd": 63 } }, "Default": { "LiteralPos": 73, "LiteralEnd": 73, "Literal": "" }, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 80, "Name": { "Name": "value", "QuoteType": 1, "NamePos": 80, "NameEnd": 85 }, "Type": { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 86, "NameEnd": 93 } }, "Default": null, "Expression": { "Name": { "Name": "toFloat64OrZero", "QuoteType": 1, "NamePos": 105, "NameEnd": 120 }, "Params": { "LeftParenPos": 120, "RightParenPos": 125, "Items": { "ListPos": 121, "ListEnd": 125, "HasDistinct": false, "Items": [ { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 121, "NameEnd": 125 }, "Alias": null } ] }, "ColumnArgList": null } }, "Hierarchical": false, "Injective": false, "IsObjectId": false }, { "NamePos": 132, "Name": { "Name": "parent_id", "QuoteType": 1, "NamePos": 132, "NameEnd": 141 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 142, "NameEnd": 148 } }, "Default": null, "Expression": null, "Hierarchical": true, "Injective": false, "IsObjectId": false }, { "NamePos": 167, "Name": { "Name": "is_active", "QuoteType": 1, "NamePos": 167, "NameEnd": 176 }, "Type": { "Name": { "Name": "UInt8", "QuoteType": 1, "NamePos": 177, "NameEnd": 182 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": true, "IsObjectId": false }, { "NamePos": 198, "Name": { "Name": "object_id", "QuoteType": 1, "NamePos": 198, "NameEnd": 207 }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 208, "NameEnd": 214 } }, "Default": null, "Expression": null, "Hierarchical": false, "Injective": false, "IsObjectId": true } ], "RParenPos": 228 }, "Engine": { "EnginePos": 230, "PrimaryKey": { "PrimaryKeyPos": 230, "Keys": { "ListPos": 242, "ListEnd": 244, "HasDistinct": false, "Items": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 242, "NameEnd": 244 }, "Alias": null } ] }, "RParenPos": 243 }, "Source": { "SourcePos": 245, "Source": { "Name": "MYSQL", "QuoteType": 1, "NamePos": 252, "NameEnd": 257 }, "Args": [ { "ArgPos": 263, "Name": { "Name": "host", "QuoteType": 1, "NamePos": 263, "NameEnd": 267 }, "Value": { "LiteralPos": 269, "LiteralEnd": 278, "Literal": "localhost" } }, { "ArgPos": 284, "Name": { "Name": "port", "QuoteType": 1, "NamePos": 284, "NameEnd": 288 }, "Value": { "NumPos": 289, "NumEnd": 293, "Literal": "3306", "Base": 10 } }, { "ArgPos": 298, "Name": { "Name": "user", "QuoteType": 1, "NamePos": 298, "NameEnd": 302 }, "Value": { "LiteralPos": 304, "LiteralEnd": 311, "Literal": "default" } }, { "ArgPos": 317, "Name": { "Name": "password", "QuoteType": 1, "NamePos": 317, "NameEnd": 325 }, "Value": { "LiteralPos": 327, "LiteralEnd": 327, "Literal": "" } }, { "ArgPos": 333, "Name": { "Name": "db", "QuoteType": 1, "NamePos": 333, "NameEnd": 335 }, "Value": { "LiteralPos": 337, "LiteralEnd": 341, "Literal": "test" } }, { "ArgPos": 347, "Name": { "Name": "table", "QuoteType": 1, "NamePos": 347, "NameEnd": 352 }, "Value": { "LiteralPos": 354, "LiteralEnd": 364, "Literal": "dict_table" } } ], "RParenPos": 367 }, "Lifetime": { "LifetimePos": 369, "Min": { "NumPos": 382, "NumEnd": 386, "Literal": "1000", "Base": 10 }, "Max": { "NumPos": 391, "NumEnd": 395, "Literal": "2000", "Base": 10 }, "Value": null, "RParenPos": 395 }, "Layout": { "LayoutPos": 397, "Layout": { "Name": "HASHED", "QuoteType": 1, "NamePos": 404, "NameEnd": 410 }, "Args": null, "RParenPos": 412 }, "Range": null, "Settings": { "SettingsPos": 414, "ListEnd": 444, "Items": [ { "SettingsPos": 423, "Name": { "Name": "max_block_size", "QuoteType": 1, "NamePos": 423, "NameEnd": 437 }, "Expr": { "NumPos": 440, "NumEnd": 444, "Literal": "8192", "Base": 10 } } ] } }, "Comment": { "LiteralPos": 455, "LiteralEnd": 493, "Literal": "This is a test dictionary with comment" } } ] ================================================ FILE: parser/testdata/ddl/output/create_distributed_table.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 191, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 }, "Table": { "Name": "event_all", "QuoteType": 1, "NamePos": 18, "NameEnd": 27 } }, "IfNotExists": false, "UUID": null, "OnCluster": { "OnPos": 28, "Expr": { "LiteralPos": 40, "LiteralEnd": 55, "Literal": "default_cluster" } }, "TableSchema": { "SchemaPos": 57, "SchemaEnd": 77, "Columns": null, "AliasTable": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 60, "NameEnd": 64 }, "Table": { "Name": "evnets_local", "QuoteType": 1, "NamePos": 65, "NameEnd": 77 } }, "TableFunction": null }, "Engine": { "EnginePos": 78, "EngineEnd": 191, "Name": "Distributed", "Params": { "LeftParenPos": 98, "RightParenPos": 160, "Items": { "ListPos": 104, "ListEnd": 158, "HasDistinct": false, "Items": [ { "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 104, "NameEnd": 119 }, "Alias": null }, { "Expr": { "Name": "test", "QuoteType": 1, "NamePos": 125, "NameEnd": 129 }, "Alias": null }, { "Expr": { "Name": "events_local", "QuoteType": 1, "NamePos": 135, "NameEnd": 147 }, "Alias": null }, { "Expr": { "Name": { "Name": "rand", "QuoteType": 1, "NamePos": 153, "NameEnd": 157 }, "Params": { "LeftParenPos": 157, "RightParenPos": 158, "Items": { "ListPos": 158, "ListEnd": 158, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": { "SettingsPos": 162, "ListEnd": 191, "Items": [ { "SettingsPos": 171, "Name": { "Name": "fsync_after_insert", "QuoteType": 1, "NamePos": 171, "NameEnd": 189 }, "Expr": { "NumPos": 190, "NumEnd": 191, "Literal": "0", "Base": 10 } } ] }, "OrderBy": null }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_function_simple.sql.golden.json ================================================ [ { "CreatePos": 0, "OrReplace": false, "IfNotExists": false, "FunctionName": { "Name": "linear_equation", "QuoteType": 1, "NamePos": 16, "NameEnd": 31 }, "OnCluster": null, "Params": { "LeftParenPos": 35, "RightParenPos": 43, "Items": { "ListPos": 36, "ListEnd": 43, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 36, "NameEnd": 37 }, "Alias": null }, { "Expr": { "Name": "k", "QuoteType": 1, "NamePos": 39, "NameEnd": 40 }, "Alias": null }, { "Expr": { "Name": "b", "QuoteType": 1, "NamePos": 42, "NameEnd": 43 }, "Alias": null } ] }, "ColumnArgList": null }, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "k", "QuoteType": 1, "NamePos": 48, "NameEnd": 49 }, "Operation": "*", "RightExpr": { "Name": "x", "QuoteType": 1, "NamePos": 50, "NameEnd": 51 }, "HasGlobal": false, "HasNot": false }, "Operation": "+", "RightExpr": { "Name": "b", "QuoteType": 1, "NamePos": 54, "NameEnd": 55 }, "HasGlobal": false, "HasNot": false } } ] ================================================ FILE: parser/testdata/ddl/output/create_live_view_basic.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 101, "Name": { "Database": null, "Table": { "Name": "my_live_view", "QuoteType": 1, "NamePos": 17, "NameEnd": 29 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "Destination": { "ToPos": 46, "TableIdentifier": { "Database": null, "Table": { "Name": "my_destination", "QuoteType": 1, "NamePos": 49, "NameEnd": 63 } }, "TableSchema": null }, "TableSchema": { "SchemaPos": 63, "SchemaEnd": 73, "Columns": [ { "NamePos": 64, "ColumnEnd": 73, "Name": { "Ident": { "Name": "id", "QuoteType": 1, "NamePos": 64, "NameEnd": 66 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 67, "NameEnd": 73 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "WithTimeout": { "WithTimeoutPos": 30, "Expr": null, "Number": { "NumPos": 43, "NumEnd": 45, "Literal": "10", "Base": 10 } }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 78, "StatementEnd": 101, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 85, "NameEnd": 87 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 88, "Expr": { "Table": { "TablePos": 93, "TableEnd": 101, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 93, "NameEnd": 101 } }, "HasFinal": false }, "StatementEnd": 101, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } } ] ================================================ FILE: parser/testdata/ddl/output/create_materialized_view_basic.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 537, "Name": { "Database": { "Name": "infra_bm", "QuoteType": 1, "NamePos": 25, "NameEnd": 33 }, "Table": { "Name": "view_name", "QuoteType": 1, "NamePos": 34, "NameEnd": 43 } }, "IfNotExists": false, "OnCluster": { "OnPos": 49, "Expr": { "LiteralPos": 61, "LiteralEnd": 76, "Literal": "default_cluster" } }, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": null, "HasEmpty": false, "Destination": { "ToPos": 78, "TableIdentifier": { "Database": { "Name": "infra_bm", "QuoteType": 1, "NamePos": 81, "NameEnd": 89 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 90, "NameEnd": 100 } }, "TableSchema": { "SchemaPos": 101, "SchemaEnd": 203, "Columns": [ { "NamePos": 106, "ColumnEnd": 122, "Name": { "Ident": { "Name": "f1", "QuoteType": 3, "NamePos": 106, "NameEnd": 108 }, "DotIdent": null }, "Type": { "LeftParenPos": 121, "RightParenPos": 122, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 110, "NameEnd": 120 }, "Params": [ { "NumPos": 121, "NumEnd": 122, "Literal": "3", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 129, "ColumnEnd": 139, "Name": { "Ident": { "Name": "f2", "QuoteType": 3, "NamePos": 129, "NameEnd": 131 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 133, "NameEnd": 139 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 145, "ColumnEnd": 155, "Name": { "Ident": { "Name": "f3", "QuoteType": 3, "NamePos": 145, "NameEnd": 147 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 149, "NameEnd": 155 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 161, "ColumnEnd": 171, "Name": { "Ident": { "Name": "f4", "QuoteType": 3, "NamePos": 161, "NameEnd": 163 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 165, "NameEnd": 171 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 177, "ColumnEnd": 187, "Name": { "Ident": { "Name": "f5", "QuoteType": 3, "NamePos": 177, "NameEnd": 179 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 181, "NameEnd": 187 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 193, "ColumnEnd": 202, "Name": { "Ident": { "Name": "f6", "QuoteType": 3, "NamePos": 193, "NameEnd": 195 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 197, "NameEnd": 202 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null } }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 208, "StatementEnd": 537, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 215, "NameEnd": 217 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 226, "NameEnd": 228 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 237, "NameEnd": 260 }, "Params": { "LeftParenPos": 260, "RightParenPos": 277, "Items": { "ListPos": 261, "ListEnd": 276, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 261, "NameEnd": 271 }, "Alias": null }, { "Expr": { "LiteralPos": 274, "LiteralEnd": 276, "Literal": "f3" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f3", "QuoteType": 1, "NamePos": 284, "NameEnd": 286 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 295, "NameEnd": 318 }, "Params": { "LeftParenPos": 318, "RightParenPos": 335, "Items": { "ListPos": 319, "ListEnd": 334, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 319, "NameEnd": 329 }, "Alias": null }, { "Expr": { "LiteralPos": 332, "LiteralEnd": 334, "Literal": "f4" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f4", "QuoteType": 1, "NamePos": 345, "NameEnd": 347 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 356, "NameEnd": 379 }, "Params": { "LeftParenPos": 379, "RightParenPos": 396, "Items": { "ListPos": 380, "ListEnd": 395, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 380, "NameEnd": 390 }, "Alias": null }, { "Expr": { "LiteralPos": 393, "LiteralEnd": 395, "Literal": "f5" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f5", "QuoteType": 1, "NamePos": 404, "NameEnd": 406 } }, { "Expr": { "Name": { "Name": "visitParamExtractInt", "QuoteType": 1, "NamePos": 412, "NameEnd": 432 }, "Params": { "LeftParenPos": 432, "RightParenPos": 449, "Items": { "ListPos": 433, "ListEnd": 448, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 433, "NameEnd": 443 }, "Alias": null }, { "Expr": { "LiteralPos": 446, "LiteralEnd": 448, "Literal": "f6" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f6", "QuoteType": 1, "NamePos": 454, "NameEnd": 456 } } ], "From": { "FromPos": 457, "Expr": { "Table": { "TablePos": 466, "TableEnd": 486, "Alias": null, "Expr": { "Database": { "Name": "infra_bm", "QuoteType": 1, "NamePos": 466, "NameEnd": 474 }, "Table": { "Name": "table_name1", "QuoteType": 1, "NamePos": 475, "NameEnd": 486 } }, "HasFinal": false }, "StatementEnd": 486, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 487, "Expr": { "LeftExpr": { "Fields": [ { "Name": "infra_bm", "QuoteType": 1, "NamePos": 497, "NameEnd": 505 }, { "Name": "table_name1", "QuoteType": 1, "NamePos": 506, "NameEnd": 517 }, { "Name": "event", "QuoteType": 1, "NamePos": 518, "NameEnd": 523 } ] }, "Operation": "=", "RightExpr": { "LiteralPos": 527, "LiteralEnd": 537, "Literal": "test-event" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": { "LiteralPos": 548, "LiteralEnd": 565, "Literal": "Comment for table" }, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_materialized_view_with_comment_before_as.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 302, "Name": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 25, "NameEnd": 27 }, "Table": { "Name": "mv_with_comment", "QuoteType": 1, "NamePos": 28, "NameEnd": 43 } }, "IfNotExists": false, "OnCluster": null, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": null, "HasEmpty": false, "Destination": { "ToPos": 44, "TableIdentifier": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 47, "NameEnd": 49 }, "Table": { "Name": "dst_table", "QuoteType": 1, "NamePos": 50, "NameEnd": 59 } }, "TableSchema": { "SchemaPos": 60, "SchemaEnd": 156, "Columns": [ { "NamePos": 67, "ColumnEnd": 82, "Name": { "Ident": { "Name": "shop_id", "QuoteType": 3, "NamePos": 67, "NameEnd": 74 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 76, "NameEnd": 82 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 89, "ColumnEnd": 122, "Name": { "Ident": { "Name": "event_type", "QuoteType": 3, "NamePos": 89, "NameEnd": 99 }, "DotIdent": null }, "Type": { "LeftParenPos": 116, "RightParenPos": 122, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 101, "NameEnd": 115 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 116, "NameEnd": 122 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 130, "ColumnEnd": 154, "Name": { "Ident": { "Name": "created_at", "QuoteType": 3, "NamePos": 130, "NameEnd": 140 }, "DotIdent": null }, "Type": { "LeftParenPos": 153, "RightParenPos": 154, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 142, "NameEnd": 152 }, "Params": [ { "NumPos": 153, "NumEnd": 154, "Literal": "9", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null } }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 234, "StatementEnd": 302, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "shop_id", "QuoteType": 1, "NamePos": 245, "NameEnd": 252 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "event_type", "QuoteType": 1, "NamePos": 258, "NameEnd": 268 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "created_at", "QuoteType": 1, "NamePos": 274, "NameEnd": 284 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 285, "Expr": { "Table": { "TablePos": 290, "TableEnd": 302, "Alias": null, "Expr": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 290, "NameEnd": 292 }, "Table": { "Name": "src_table", "QuoteType": 1, "NamePos": 293, "NameEnd": 302 } }, "HasFinal": false }, "StatementEnd": 302, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": { "LiteralPos": 167, "LiteralEnd": 229, "Literal": "{\"blueprint_hash\":\"abc123\",\"timestamp\":\"2026-04-08T12:00:00Z\"}" }, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_materialized_view_with_definer.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 355, "Name": { "Database": null, "Table": { "Name": "fresh_mv", "QuoteType": 1, "NamePos": 25, "NameEnd": 33 } }, "IfNotExists": false, "OnCluster": null, "Refresh": { "RefreshPos": 34, "Frequency": "EVERY", "Interval": { "IntervalPos": 0, "Expr": { "NumPos": 48, "NumEnd": 49, "Literal": "1", "Base": 10 }, "Unit": { "Name": "HOUR", "QuoteType": 1, "NamePos": 50, "NameEnd": 54 } }, "Offset": { "IntervalPos": 0, "Expr": { "NumPos": 62, "NumEnd": 64, "Literal": "10", "Base": 10 }, "Unit": { "Name": "MINUTE", "QuoteType": 1, "NamePos": 65, "NameEnd": 71 } } }, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": true, "Engine": null, "HasEmpty": false, "Destination": { "ToPos": 79, "TableIdentifier": { "Database": null, "Table": { "Name": "events_export", "QuoteType": 1, "NamePos": 82, "NameEnd": 95 } }, "TableSchema": { "SchemaPos": 96, "SchemaEnd": 173, "Columns": [ { "NamePos": 103, "ColumnEnd": 126, "Name": { "Ident": { "Name": "timestamp", "QuoteType": 3, "NamePos": 103, "NameEnd": 112 }, "DotIdent": null }, "Type": { "LeftParenPos": 125, "RightParenPos": 126, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 114, "NameEnd": 124 }, "Params": [ { "NumPos": 125, "NumEnd": 126, "Literal": "9", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 134, "ColumnEnd": 149, "Name": { "Ident": { "Name": "field_1", "QuoteType": 3, "NamePos": 134, "NameEnd": 141 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 143, "NameEnd": 149 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 156, "ColumnEnd": 171, "Name": { "Ident": { "Name": "field_2", "QuoteType": 3, "NamePos": 156, "NameEnd": 163 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 165, "NameEnd": 171 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null } }, "SubQuery": { "HasParen": true, "Select": { "SelectPos": 218, "StatementEnd": 355, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 229, "NameEnd": 238 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "field_1", "QuoteType": 1, "NamePos": 244, "NameEnd": 251 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "field_2", "QuoteType": 1, "NamePos": 257, "NameEnd": 264 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "FROM", "QuoteType": 1, "NamePos": 266, "NameEnd": 270 }, "Modifiers": [], "Alias": { "Name": "event_table", "QuoteType": 1, "NamePos": 271, "NameEnd": 282 } } ], "From": null, "Window": null, "Prewhere": null, "Where": { "WherePos": 283, "Expr": { "LeftExpr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 289, "NameEnd": 302 }, "Params": { "LeftParenPos": 302, "RightParenPos": 312, "Items": { "ListPos": 303, "ListEnd": 312, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 303, "NameEnd": 312 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "=", "RightExpr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 316, "NameEnd": 329 }, "Params": { "LeftParenPos": 329, "RightParenPos": 355, "Items": { "ListPos": 330, "ListEnd": 354, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 330, "NameEnd": 333 }, "Params": { "LeftParenPos": 333, "RightParenPos": 334, "Items": { "ListPos": 334, "ListEnd": 334, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Operation": "-", "RightExpr": { "Name": { "Name": "toIntervalHour", "QuoteType": 1, "NamePos": 338, "NameEnd": 352 }, "Params": { "LeftParenPos": 352, "RightParenPos": 354, "Items": { "ListPos": 353, "ListEnd": 354, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 353, "NumEnd": 354, "Literal": "1", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": { "LiteralPos": 367, "LiteralEnd": 379, "Literal": "Test comment" }, "Definer": { "Name": "default", "QuoteType": 1, "NamePos": 185, "NameEnd": 192 }, "SQLSecurity": "DEFINER" } ] ================================================ FILE: parser/testdata/ddl/output/create_materialized_view_with_empty_table_schema.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 460, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 25, "NameEnd": 29 }, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 30, "NameEnd": 32 } }, "IfNotExists": false, "OnCluster": { "OnPos": 33, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 44, "NameEnd": 59 } }, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": { "EnginePos": 60, "EngineEnd": 190, "Name": "ReplicatedAggregatingMergeTree", "Params": { "LeftParenPos": 99, "RightParenPos": 150, "Items": { "ListPos": 101, "ListEnd": 149, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 101, "LiteralEnd": 136, "Literal": "/clickhouse/{layer}-{shard}/test/t0" }, "Alias": null }, { "Expr": { "LiteralPos": 140, "LiteralEnd": 149, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 152, "Expr": { "ListPos": 165, "ListEnd": 176, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMM", "QuoteType": 1, "NamePos": 165, "NameEnd": 173 }, "Params": { "LeftParenPos": 173, "RightParenPos": 176, "Items": { "ListPos": 174, "ListEnd": 176, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 174, "NameEnd": 176 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": { "OrderPos": 178, "ListEnd": 190, "Items": [ { "OrderPos": 178, "Expr": { "LeftParenPos": 187, "RightParenPos": 190, "Items": { "ListPos": 188, "ListEnd": 190, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 188, "NameEnd": 190 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "HasEmpty": false, "Destination": null, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 204, "StatementEnd": 460, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 211, "NameEnd": 213 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 214, "NameEnd": 216 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 217, "NameEnd": 219 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "coalesce", "QuoteType": 1, "NamePos": 220, "NameEnd": 228 }, "Params": { "LeftParenPos": 228, "RightParenPos": 234, "Items": { "ListPos": 229, "ListEnd": 234, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 229, "NameEnd": 231 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 232, "NameEnd": 234 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f333", "QuoteType": 1, "NamePos": 239, "NameEnd": 243 } } ], "From": { "FromPos": 244, "Expr": { "Table": { "TablePos": 253, "TableEnd": 447, "Alias": null, "Expr": { "Expr": { "HasParen": true, "Select": { "SelectPos": 254, "StatementEnd": 433, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 270, "NameEnd": 272 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 273, "NameEnd": 275 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 276, "NameEnd": 278 }, "Modifiers": [], "Alias": null }, { "Expr": { "Function": { "Name": { "Name": "ROW_NUMBER", "QuoteType": 1, "NamePos": 289, "NameEnd": 299 }, "Params": { "LeftParenPos": 299, "RightParenPos": 300, "Items": { "ListPos": 300, "ListEnd": 300, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 302, "OverExpr": { "LeftParenPos": 306, "RightParenPos": 347, "WindowName": null, "PartitionBy": { "PartitionPos": 306, "Expr": { "ListPos": 320, "ListEnd": 322, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 320, "NameEnd": 322 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 323, "ListEnd": 346, "Items": [ { "OrderPos": 323, "Expr": { "Name": { "Name": "coalesce", "QuoteType": 1, "NamePos": 332, "NameEnd": 340 }, "Params": { "LeftParenPos": 340, "RightParenPos": 346, "Items": { "ListPos": 341, "ListEnd": 346, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 341, "NameEnd": 343 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 344, "NameEnd": 346 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "rn", "QuoteType": 1, "NamePos": 352, "NameEnd": 354 } } ], "From": { "FromPos": 360, "Expr": { "Table": { "TablePos": 365, "TableEnd": 371, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 365, "NameEnd": 369 }, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 370, "NameEnd": 371 } }, "HasFinal": false }, "StatementEnd": 371, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 377, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "f3", "QuoteType": 1, "NamePos": 383, "NameEnd": 385 }, "Operation": "IN", "RightExpr": { "LeftParenPos": 389, "RightParenPos": 410, "Items": { "ListPos": 391, "ListEnd": 409, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 391, "LiteralEnd": 394, "Literal": "foo" }, "Alias": null }, { "Expr": { "LiteralPos": 398, "LiteralEnd": 401, "Literal": "bar" }, "Alias": null }, { "Expr": { "LiteralPos": 405, "LiteralEnd": 409, "Literal": "test" }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Name": "env", "QuoteType": 1, "NamePos": 423, "NameEnd": 426 }, "Operation": "=", "RightExpr": { "LiteralPos": 429, "LiteralEnd": 433, "Literal": "test" }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "AliasPos": 444, "Alias": { "Name": "tmp", "QuoteType": 1, "NamePos": 444, "NameEnd": 447 } }, "HasFinal": false }, "StatementEnd": 447, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 448, "Expr": { "LeftExpr": { "Name": "rn", "QuoteType": 1, "NamePos": 454, "NameEnd": 456 }, "Operation": "=", "RightExpr": { "NumPos": 459, "NumEnd": 460, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": true, "Comment": null, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_materialized_view_with_gcs.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 206, "Name": { "Database": { "Name": "database_name", "QuoteType": 1, "NamePos": 25, "NameEnd": 38 }, "Table": { "Name": "view_name", "QuoteType": 1, "NamePos": 39, "NameEnd": 48 } }, "IfNotExists": false, "OnCluster": null, "Refresh": { "RefreshPos": 57, "Frequency": "EVERY", "Interval": { "IntervalPos": 0, "Expr": { "NumPos": 71, "NumEnd": 72, "Literal": "5", "Base": 10 }, "Unit": { "Name": "MINUTE", "QuoteType": 1, "NamePos": 73, "NameEnd": 79 } }, "Offset": null }, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": null, "HasEmpty": false, "Destination": { "ToPos": 80, "TableIdentifier": { "Database": { "Name": "database_name", "QuoteType": 1, "NamePos": 83, "NameEnd": 96 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 97, "NameEnd": 107 } }, "TableSchema": null }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 119, "StatementEnd": 206, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 126, "NameEnd": 126 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 128, "Expr": { "Table": { "TablePos": 133, "TableEnd": 206, "Alias": null, "Expr": { "Name": { "Name": "gcs", "QuoteType": 1, "NamePos": 133, "NameEnd": 136 }, "Args": { "LeftParenPos": 136, "RightParenPos": 206, "Args": [ { "Name": "gcs_creds", "QuoteType": 1, "NamePos": 137, "NameEnd": 146 }, { "NamePos": 147, "Name": { "Name": "url", "QuoteType": 0, "NamePos": 147, "NameEnd": 150 }, "Value": { "LiteralPos": 152, "LiteralEnd": 205, "Literal": "https://storage.googleapis.com/some-bucket/some-path/" } } ] } }, "HasFinal": false }, "StatementEnd": 206, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": null, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_materialized_view_with_refresh.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 302, "Name": { "Database": null, "Table": { "Name": "fresh_mv", "QuoteType": 1, "NamePos": 25, "NameEnd": 33 } }, "IfNotExists": false, "OnCluster": null, "Refresh": { "RefreshPos": 34, "Frequency": "EVERY", "Interval": { "IntervalPos": 0, "Expr": { "NumPos": 48, "NumEnd": 49, "Literal": "1", "Base": 10 }, "Unit": { "Name": "HOUR", "QuoteType": 1, "NamePos": 50, "NameEnd": 54 } }, "Offset": { "IntervalPos": 0, "Expr": { "NumPos": 62, "NumEnd": 64, "Literal": "10", "Base": 10 }, "Unit": { "Name": "MINUTE", "QuoteType": 1, "NamePos": 65, "NameEnd": 71 } } }, "RandomizeFor": { "IntervalPos": 0, "Expr": { "NumPos": 86, "NumEnd": 87, "Literal": "1", "Base": 10 }, "Unit": { "Name": "SECOND", "QuoteType": 1, "NamePos": 88, "NameEnd": 94 } }, "DependsOn": [ { "Database": null, "Table": { "Name": "table_v5", "QuoteType": 1, "NamePos": 107, "NameEnd": 115 } } ], "Settings": { "SettingsPos": 116, "ListEnd": 199, "Items": [ { "SettingsPos": 129, "Name": { "Name": "randomize_for", "QuoteType": 1, "NamePos": 129, "NameEnd": 142 }, "Expr": { "NumPos": 145, "NumEnd": 146, "Literal": "1", "Base": 10 } }, { "SettingsPos": 152, "Name": { "Name": "randomize_offset", "QuoteType": 1, "NamePos": 152, "NameEnd": 168 }, "Expr": { "NumPos": 171, "NumEnd": 173, "Literal": "10", "Base": 10 } }, { "SettingsPos": 179, "Name": { "Name": "randomize_period", "QuoteType": 1, "NamePos": 179, "NameEnd": 195 }, "Expr": { "NumPos": 198, "NumEnd": 199, "Literal": "1", "Base": 10 } } ] }, "HasAppend": true, "Engine": null, "HasEmpty": true, "Destination": { "ToPos": 207, "TableIdentifier": { "Database": null, "Table": { "Name": "target_table_name", "QuoteType": 1, "NamePos": 210, "NameEnd": 227 } }, "TableSchema": null }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 237, "StatementEnd": 302, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "field_1", "QuoteType": 3, "NamePos": 249, "NameEnd": 256 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "field_2", "QuoteType": 3, "NamePos": 264, "NameEnd": 271 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "field_3", "QuoteType": 3, "NamePos": 279, "NameEnd": 286 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "FROM", "QuoteType": 1, "NamePos": 289, "NameEnd": 293 }, "Modifiers": [], "Alias": { "Name": "table_v5", "QuoteType": 1, "NamePos": 294, "NameEnd": 302 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": null, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_mv_with_not_op.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 559, "Name": { "Database": { "Name": "infra_bm", "QuoteType": 1, "NamePos": 25, "NameEnd": 33 }, "Table": { "Name": "view_name", "QuoteType": 1, "NamePos": 34, "NameEnd": 43 } }, "IfNotExists": false, "OnCluster": { "OnPos": 48, "Expr": { "LiteralPos": 60, "LiteralEnd": 75, "Literal": "default_cluster" } }, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": null, "HasEmpty": false, "Destination": { "ToPos": 77, "TableIdentifier": { "Database": { "Name": "infra_bm", "QuoteType": 1, "NamePos": 80, "NameEnd": 88 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 89, "NameEnd": 99 } }, "TableSchema": { "SchemaPos": 100, "SchemaEnd": 197, "Columns": [ { "NamePos": 105, "ColumnEnd": 121, "Name": { "Ident": { "Name": "f1", "QuoteType": 3, "NamePos": 105, "NameEnd": 107 }, "DotIdent": null }, "Type": { "LeftParenPos": 120, "RightParenPos": 121, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 109, "NameEnd": 119 }, "Params": [ { "NumPos": 120, "NumEnd": 121, "Literal": "3", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 127, "ColumnEnd": 137, "Name": { "Ident": { "Name": "f2", "QuoteType": 3, "NamePos": 127, "NameEnd": 129 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 131, "NameEnd": 137 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 142, "ColumnEnd": 152, "Name": { "Ident": { "Name": "f3", "QuoteType": 3, "NamePos": 142, "NameEnd": 144 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 146, "NameEnd": 152 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 157, "ColumnEnd": 167, "Name": { "Ident": { "Name": "f4", "QuoteType": 3, "NamePos": 157, "NameEnd": 159 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 161, "NameEnd": 167 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 172, "ColumnEnd": 182, "Name": { "Ident": { "Name": "f5", "QuoteType": 3, "NamePos": 172, "NameEnd": 174 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 176, "NameEnd": 182 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 187, "ColumnEnd": 196, "Name": { "Ident": { "Name": "f6", "QuoteType": 3, "NamePos": 187, "NameEnd": 189 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 191, "NameEnd": 196 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null } }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 202, "StatementEnd": 559, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 209, "NameEnd": 211 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 220, "NameEnd": 222 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 231, "NameEnd": 254 }, "Params": { "LeftParenPos": 254, "RightParenPos": 271, "Items": { "ListPos": 255, "ListEnd": 270, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 255, "NameEnd": 265 }, "Alias": null }, { "Expr": { "LiteralPos": 268, "LiteralEnd": 270, "Literal": "f3" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f3", "QuoteType": 1, "NamePos": 276, "NameEnd": 278 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 287, "NameEnd": 310 }, "Params": { "LeftParenPos": 310, "RightParenPos": 327, "Items": { "ListPos": 311, "ListEnd": 326, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 311, "NameEnd": 321 }, "Alias": null }, { "Expr": { "LiteralPos": 324, "LiteralEnd": 326, "Literal": "f4" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f4", "QuoteType": 1, "NamePos": 332, "NameEnd": 334 } }, { "Expr": { "Name": { "Name": "visitParamExtractString", "QuoteType": 1, "NamePos": 343, "NameEnd": 366 }, "Params": { "LeftParenPos": 366, "RightParenPos": 383, "Items": { "ListPos": 367, "ListEnd": 382, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 367, "NameEnd": 377 }, "Alias": null }, { "Expr": { "LiteralPos": 380, "LiteralEnd": 382, "Literal": "f5" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f5", "QuoteType": 1, "NamePos": 388, "NameEnd": 390 } }, { "Expr": { "Name": { "Name": "visitParamExtractInt", "QuoteType": 1, "NamePos": 399, "NameEnd": 419 }, "Params": { "LeftParenPos": 419, "RightParenPos": 436, "Items": { "ListPos": 420, "ListEnd": 435, "HasDistinct": false, "Items": [ { "Expr": { "Name": "properties", "QuoteType": 1, "NamePos": 420, "NameEnd": 430 }, "Alias": null }, { "Expr": { "LiteralPos": 433, "LiteralEnd": 435, "Literal": "f6" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f6", "QuoteType": 1, "NamePos": 441, "NameEnd": 443 } } ], "From": { "FromPos": 444, "Expr": { "Table": { "TablePos": 449, "TableEnd": 469, "Alias": null, "Expr": { "Database": { "Name": "infra_bm", "QuoteType": 1, "NamePos": 449, "NameEnd": 457 }, "Table": { "Name": "table_name1", "QuoteType": 1, "NamePos": 458, "NameEnd": 469 } }, "HasFinal": false }, "StatementEnd": 469, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 470, "Expr": { "LeftExpr": { "LeftExpr": { "LeftExpr": { "Fields": [ { "Name": "infra_bm", "QuoteType": 1, "NamePos": 476, "NameEnd": 484 }, { "Name": "table_name1", "QuoteType": 1, "NamePos": 485, "NameEnd": 496 }, { "Name": "event", "QuoteType": 1, "NamePos": 497, "NameEnd": 502 } ] }, "Operation": "=", "RightExpr": { "LiteralPos": 506, "LiteralEnd": 516, "Literal": "test-event" }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "UnaryPos": 526, "Kind": "NOT", "Expr": { "Name": { "Name": "isZeroOrNull", "QuoteType": 1, "NamePos": 530, "NameEnd": 542 }, "Params": { "LeftParenPos": 542, "RightParenPos": 545, "Items": { "ListPos": 543, "ListEnd": 545, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 543, "NameEnd": 545 }, "Alias": null } ] }, "ColumnArgList": null } } }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "LeftExpr": { "Name": "f6", "QuoteType": 1, "NamePos": 551, "NameEnd": 553 }, "Operation": "-", "RightExpr": { "NumPos": 554, "NumEnd": 555, "Literal": "2", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "\u003e", "RightExpr": { "NumPos": 558, "NumEnd": 559, "Literal": "0", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": null, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_mv_with_order_by.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 135, "Name": { "Database": null, "Table": { "Name": "test_mv", "QuoteType": 1, "NamePos": 39, "NameEnd": 46 } }, "IfNotExists": true, "OnCluster": null, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": { "EnginePos": 47, "EngineEnd": 106, "Name": "ReplacingMergeTree", "Params": { "LeftParenPos": 74, "RightParenPos": 75, "Items": { "ListPos": 75, "ListEnd": 75, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "PrimaryKey": { "PrimaryPos": 77, "Expr": { "LeftParenPos": 89, "RightParenPos": 92, "Items": { "ListPos": 90, "ListEnd": 92, "HasDistinct": false, "Items": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 90, "NameEnd": 92 }, "Alias": null } ] }, "ColumnArgList": null } }, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": { "OrderPos": 94, "ListEnd": 106, "Items": [ { "OrderPos": 94, "Expr": { "LeftParenPos": 103, "RightParenPos": 106, "Items": { "ListPos": 104, "ListEnd": 106, "HasDistinct": false, "Items": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 104, "NameEnd": 106 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "HasEmpty": false, "Destination": null, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 111, "StatementEnd": 135, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 118, "NameEnd": 118 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 120, "Expr": { "Table": { "TablePos": 125, "TableEnd": 135, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 125, "NameEnd": 135 } }, "HasFinal": false }, "StatementEnd": 135, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": null, "Definer": null, "SQLSecurity": "" }, { "CreatePos": 138, "StatementEnd": 259, "Name": { "Database": null, "Table": { "Name": "test_mv", "QuoteType": 1, "NamePos": 177, "NameEnd": 184 } }, "IfNotExists": true, "OnCluster": null, "Refresh": null, "RandomizeFor": null, "DependsOn": null, "Settings": null, "HasAppend": false, "Engine": { "EnginePos": 185, "EngineEnd": 230, "Name": "ReplacingMergeTree", "Params": { "LeftParenPos": 212, "RightParenPos": 213, "Items": { "ListPos": 213, "ListEnd": 213, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "PrimaryKey": { "PrimaryPos": 215, "Expr": { "LeftParenPos": 227, "RightParenPos": 230, "Items": { "ListPos": 228, "ListEnd": 230, "HasDistinct": false, "Items": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 228, "NameEnd": 230 }, "Alias": null } ] }, "ColumnArgList": null } }, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": null }, "HasEmpty": false, "Destination": null, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 235, "StatementEnd": 259, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 242, "NameEnd": 242 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 244, "Expr": { "Table": { "TablePos": 249, "TableEnd": 259, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 249, "NameEnd": 259 } }, "HasFinal": false }, "StatementEnd": 259, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Populate": false, "Comment": null, "Definer": null, "SQLSecurity": "" } ] ================================================ FILE: parser/testdata/ddl/output/create_named_collection_basic.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 158, "Name": { "Name": "servercore_s3_config", "QuoteType": 1, "NamePos": 38, "NameEnd": 58 }, "IfNotExists": true, "OnCluster": null, "Params": [ { "ParamPos": 62, "Name": { "Name": "url", "QuoteType": 1, "NamePos": 62, "NameEnd": 65 }, "Value": { "LiteralPos": 69, "LiteralEnd": 94, "Literal": "http://local-minio:9000/*" }, "Overridable": false, "NotOverridable": false }, { "ParamPos": 97, "Name": { "Name": "access_key_id", "QuoteType": 1, "NamePos": 97, "NameEnd": 110 }, "Value": { "LiteralPos": 114, "LiteralEnd": 124, "Literal": "minioadmin" }, "Overridable": false, "NotOverridable": false }, { "ParamPos": 127, "Name": { "Name": "secret_access_key", "QuoteType": 1, "NamePos": 127, "NameEnd": 144 }, "Value": { "LiteralPos": 148, "LiteralEnd": 158, "Literal": "minioadmin" }, "Overridable": false, "NotOverridable": false } ] } ] ================================================ FILE: parser/testdata/ddl/output/create_named_collection_simple.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 72, "Name": { "Name": "my_collection", "QuoteType": 1, "NamePos": 24, "NameEnd": 37 }, "IfNotExists": false, "OnCluster": null, "Params": [ { "ParamPos": 41, "Name": { "Name": "key1", "QuoteType": 1, "NamePos": 41, "NameEnd": 45 }, "Value": { "LiteralPos": 49, "LiteralEnd": 55, "Literal": "value1" }, "Overridable": false, "NotOverridable": false }, { "ParamPos": 58, "Name": { "Name": "key2", "QuoteType": 1, "NamePos": 58, "NameEnd": 62 }, "Value": { "LiteralPos": 66, "LiteralEnd": 72, "Literal": "value2" }, "Overridable": false, "NotOverridable": false } ] } ] ================================================ FILE: parser/testdata/ddl/output/create_named_collection_with_cluster.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 153, "Name": { "Name": "my_collection", "QuoteType": 1, "NamePos": 38, "NameEnd": 51 }, "IfNotExists": true, "OnCluster": { "OnPos": 52, "Expr": { "Name": "my_cluster", "QuoteType": 1, "NamePos": 63, "NameEnd": 73 } }, "Params": [ { "ParamPos": 77, "Name": { "Name": "key1", "QuoteType": 1, "NamePos": 77, "NameEnd": 81 }, "Value": { "LiteralPos": 85, "LiteralEnd": 91, "Literal": "value1" }, "Overridable": true, "NotOverridable": false }, { "ParamPos": 106, "Name": { "Name": "key2", "QuoteType": 1, "NamePos": 106, "NameEnd": 110 }, "Value": { "LiteralPos": 114, "LiteralEnd": 120, "Literal": "value2" }, "Overridable": false, "NotOverridable": true }, { "ParamPos": 139, "Name": { "Name": "key3", "QuoteType": 1, "NamePos": 139, "NameEnd": 143 }, "Value": { "LiteralPos": 147, "LiteralEnd": 153, "Literal": "value3" }, "Overridable": false, "NotOverridable": false } ] } ] ================================================ FILE: parser/testdata/ddl/output/create_named_collection_with_overridable.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 145, "Name": { "Name": "test_collection", "QuoteType": 1, "NamePos": 24, "NameEnd": 39 }, "IfNotExists": false, "OnCluster": null, "Params": [ { "ParamPos": 43, "Name": { "Name": "url", "QuoteType": 1, "NamePos": 43, "NameEnd": 46 }, "Value": { "LiteralPos": 50, "LiteralEnd": 68, "Literal": "http://example.com" }, "Overridable": true, "NotOverridable": false }, { "ParamPos": 83, "Name": { "Name": "access_key", "QuoteType": 1, "NamePos": 83, "NameEnd": 93 }, "Value": { "LiteralPos": 97, "LiteralEnd": 103, "Literal": "key123" }, "Overridable": false, "NotOverridable": true }, { "ParamPos": 122, "Name": { "Name": "secret_key", "QuoteType": 1, "NamePos": 122, "NameEnd": 132 }, "Value": { "LiteralPos": 136, "LiteralEnd": 145, "Literal": "secret456" }, "Overridable": false, "NotOverridable": false } ] } ] ================================================ FILE: parser/testdata/ddl/output/create_or_replace.sql.golden.json ================================================ [ { "CreatePos": 122, "StatementEnd": 361, "OrReplace": true, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 160, "NameEnd": 164 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 165, "NameEnd": 177 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 178, "SchemaEnd": 246, "Columns": [ { "NamePos": 184, "ColumnEnd": 193, "Name": { "Ident": { "Name": "f0", "QuoteType": 1, "NamePos": 184, "NameEnd": 186 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 187, "NameEnd": 193 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 199, "ColumnEnd": 223, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 199, "NameEnd": 201 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 202, "NameEnd": 208 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 209, "RightParenPos": 223, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 215, "NameEnd": 219 }, "Level": { "NumPos": 219, "NumEnd": 221, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 229, "ColumnEnd": 243, "Name": { "Ident": { "Name": "f2", "QuoteType": 1, "NamePos": 229, "NameEnd": 231 }, "DotIdent": null }, "Type": { "LeftParenPos": 240, "RightParenPos": 243, "Name": { "Name": "VARCHAR", "QuoteType": 1, "NamePos": 232, "NameEnd": 239 }, "Params": [ { "NumPos": 240, "NumEnd": 243, "Literal": "255", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 248, "EngineEnd": 361, "Name": "MergeTree", "Params": null, "PrimaryKey": { "PrimaryPos": 267, "Expr": { "LeftParenPos": 279, "RightParenPos": 290, "Items": { "ListPos": 280, "ListEnd": 290, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 280, "NameEnd": 282 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 284, "NameEnd": 286 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 288, "NameEnd": 290 }, "Alias": null } ] }, "ColumnArgList": null } }, "PartitionBy": { "PartitionPos": 292, "Expr": { "ListPos": 305, "ListEnd": 318, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMMDD", "QuoteType": 1, "NamePos": 305, "NameEnd": 315 }, "Params": { "LeftParenPos": 315, "RightParenPos": 318, "Items": { "ListPos": 316, "ListEnd": 318, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 316, "NameEnd": 318 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 320, "ListEnd": 345, "Items": [ { "TTLPos": 320, "Expr": { "LeftExpr": { "Name": "f1", "QuoteType": 1, "NamePos": 324, "NameEnd": 326 }, "Operation": "+", "RightExpr": { "IntervalPos": 329, "Expr": { "NumPos": 338, "NumEnd": 339, "Literal": "6", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 340, "NameEnd": 345 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": null, "OrderBy": { "OrderPos": 346, "ListEnd": 361, "Items": [ { "OrderPos": 346, "Expr": { "LeftParenPos": 355, "RightParenPos": 361, "Items": { "ListPos": 356, "ListEnd": 361, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 356, "NameEnd": 358 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 359, "NameEnd": 361 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": { "LiteralPos": 372, "LiteralEnd": 389, "Literal": "Comment for table" } }, { "CreatePos": 393, "StatementEnd": 508, "OrReplace": true, "Name": { "Database": null, "Table": { "Name": "my_view", "QuoteType": 1, "NamePos": 430, "NameEnd": 437 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 437, "SchemaEnd": 462, "Columns": [ { "NamePos": 438, "ColumnEnd": 449, "Name": { "Ident": { "Name": "col1", "QuoteType": 1, "NamePos": 438, "NameEnd": 442 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 443, "NameEnd": 449 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 451, "ColumnEnd": 462, "Name": { "Ident": { "Name": "col2", "QuoteType": 1, "NamePos": 451, "NameEnd": 455 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 456, "NameEnd": 462 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Comment": null, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 467, "StatementEnd": 508, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 478, "NameEnd": 480 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 486, "NameEnd": 490 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 491, "Expr": { "Table": { "TablePos": 500, "TableEnd": 508, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 500, "NameEnd": 508 } }, "HasFinal": false }, "StatementEnd": 508, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } }, { "CreatePos": 511, "OrReplace": true, "IfNotExists": true, "FunctionName": { "Name": "my_function", "QuoteType": 1, "NamePos": 552, "NameEnd": 563 }, "OnCluster": null, "Params": { "LeftParenPos": 567, "RightParenPos": 572, "Items": { "ListPos": 568, "ListEnd": 572, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 568, "NameEnd": 569 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 571, "NameEnd": 572 }, "Alias": null } ] }, "ColumnArgList": null }, "Expr": { "LeftExpr": { "Name": "x", "QuoteType": 1, "NamePos": 577, "NameEnd": 578 }, "Operation": "+", "RightExpr": { "Name": "y", "QuoteType": 1, "NamePos": 581, "NameEnd": 582 }, "HasGlobal": false, "HasNot": false } } ] ================================================ FILE: parser/testdata/ddl/output/create_role.sql.golden.json ================================================ [ { "CreatePos": 22, "StatementEnd": 42, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 34, "NameEnd": 42 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 44, "StatementEnd": 85, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 56, "NameEnd": 64 }, "Scope": null, "OnCluster": { "OnPos": 65, "Expr": { "Name": "cluster_1", "QuoteType": 1, "NamePos": 76, "NameEnd": 85 } } } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 87, "StatementEnd": 117, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 99, "NameEnd": 107 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 109, "NameEnd": 117 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 119, "StatementEnd": 170, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 131, "NameEnd": 139 }, "Scope": null, "OnCluster": { "OnPos": 140, "Expr": { "Name": "cluster_1", "QuoteType": 1, "NamePos": 151, "NameEnd": 160 } } }, { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 162, "NameEnd": 170 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 172, "StatementEnd": 244, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 184, "NameEnd": 192 }, "Scope": null, "OnCluster": { "OnPos": 193, "Expr": { "Name": "cluster_1", "QuoteType": 1, "NamePos": 204, "NameEnd": 213 } } }, { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 215, "NameEnd": 223 }, "Scope": null, "OnCluster": { "OnPos": 224, "Expr": { "Name": "cluster_2", "QuoteType": 1, "NamePos": 235, "NameEnd": 244 } } } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 246, "StatementEnd": 280, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 258, "NameEnd": 266 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [], "Modifier": { "Name": "NONE", "QuoteType": 1, "NamePos": 276, "NameEnd": 280 } } ] }, { "CreatePos": 282, "StatementEnd": 328, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 294, "NameEnd": 302 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 312, "NameEnd": 319 }, "Operation": "", "Value": { "LiteralPos": 321, "LiteralEnd": 328, "Literal": "default" } } ], "Modifier": null } ] }, { "CreatePos": 331, "StatementEnd": 385, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r3_01293", "QuoteType": 1, "NamePos": 343, "NameEnd": 351 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 361, "NameEnd": 377 }, "Operation": "=", "Value": { "NumPos": 378, "NumEnd": 385, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 387, "StatementEnd": 445, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r4_01293", "QuoteType": 1, "NamePos": 399, "NameEnd": 407 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 417, "NameEnd": 433 }, "Operation": "", "Value": null }, { "Name": { "Name": "MIN", "QuoteType": 1, "NamePos": 434, "NameEnd": 437 }, "Operation": "=", "Value": { "NumPos": 438, "NumEnd": 445, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 447, "StatementEnd": 505, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r5_01293", "QuoteType": 1, "NamePos": 459, "NameEnd": 467 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 477, "NameEnd": 493 }, "Operation": "", "Value": null }, { "Name": { "Name": "MAX", "QuoteType": 1, "NamePos": 494, "NameEnd": 497 }, "Operation": "=", "Value": { "NumPos": 498, "NumEnd": 505, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 507, "StatementEnd": 559, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r6_01293", "QuoteType": 1, "NamePos": 519, "NameEnd": 527 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 537, "NameEnd": 553 }, "Operation": "", "Value": null } ], "Modifier": { "Name": "CONST", "QuoteType": 1, "NamePos": 554, "NameEnd": 559 } } ] }, { "CreatePos": 561, "StatementEnd": 616, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r7_01293", "QuoteType": 1, "NamePos": 573, "NameEnd": 581 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 591, "NameEnd": 607 }, "Operation": "", "Value": null } ], "Modifier": { "Name": "WRITABLE", "QuoteType": 1, "NamePos": 608, "NameEnd": 616 } } ] }, { "CreatePos": 618, "StatementEnd": 702, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r8_01293", "QuoteType": 1, "NamePos": 630, "NameEnd": 638 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 648, "NameEnd": 664 }, "Operation": "=", "Value": { "NumPos": 665, "NumEnd": 672, "Literal": "5000000", "Base": 10 } }, { "Name": { "Name": "MIN", "QuoteType": 1, "NamePos": 673, "NameEnd": 676 }, "Operation": "", "Value": { "NumPos": 677, "NumEnd": 684, "Literal": "4000000", "Base": 10 } }, { "Name": { "Name": "MAX", "QuoteType": 1, "NamePos": 685, "NameEnd": 688 }, "Operation": "", "Value": { "NumPos": 689, "NumEnd": 696, "Literal": "6000000", "Base": 10 } } ], "Modifier": { "Name": "CONST", "QuoteType": 1, "NamePos": 697, "NameEnd": 702 } } ] }, { "CreatePos": 704, "StatementEnd": 786, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r9_01293", "QuoteType": 1, "NamePos": 716, "NameEnd": 724 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 734, "NameEnd": 741 }, "Operation": "", "Value": { "LiteralPos": 743, "LiteralEnd": 750, "Literal": "default" } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 753, "NameEnd": 769 }, "Operation": "=", "Value": { "NumPos": 770, "NumEnd": 777, "Literal": "5000000", "Base": 10 } } ], "Modifier": { "Name": "WRITABLE", "QuoteType": 1, "NamePos": 778, "NameEnd": 786 } } ] }, { "CreatePos": 788, "StatementEnd": 818, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 800, "NameEnd": 808 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 810, "NameEnd": 818 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 820, "StatementEnd": 860, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 832, "NameEnd": 840 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "readonly", "QuoteType": 1, "NamePos": 850, "NameEnd": 858 }, "Operation": "=", "Value": { "NumPos": 859, "NumEnd": 860, "Literal": "1", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 862, "StatementEnd": 908, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 874, "NameEnd": 882 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 892, "NameEnd": 899 }, "Operation": "", "Value": { "LiteralPos": 901, "LiteralEnd": 908, "Literal": "default" } } ], "Modifier": null } ] }, { "CreatePos": 911, "StatementEnd": 998, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r3_01293", "QuoteType": 1, "NamePos": 923, "NameEnd": 931 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 941, "NameEnd": 957 }, "Operation": "=", "Value": { "NumPos": 958, "NumEnd": 965, "Literal": "5000000", "Base": 10 } }, { "Name": { "Name": "MIN", "QuoteType": 1, "NamePos": 966, "NameEnd": 969 }, "Operation": "", "Value": { "NumPos": 970, "NumEnd": 977, "Literal": "4000000", "Base": 10 } }, { "Name": { "Name": "MAX", "QuoteType": 1, "NamePos": 978, "NameEnd": 981 }, "Operation": "", "Value": { "NumPos": 982, "NumEnd": 989, "Literal": "6000000", "Base": 10 } } ], "Modifier": { "Name": "WRITABLE", "QuoteType": 1, "NamePos": 990, "NameEnd": 998 } } ] }, { "CreatePos": 1000, "StatementEnd": 1085, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r4_01293", "QuoteType": 1, "NamePos": 1012, "NameEnd": 1020 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 1030, "NameEnd": 1037 }, "Operation": "", "Value": { "LiteralPos": 1039, "LiteralEnd": 1046, "Literal": "default" } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 1049, "NameEnd": 1065 }, "Operation": "=", "Value": { "NumPos": 1066, "NumEnd": 1073, "Literal": "5000000", "Base": 10 } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "readonly", "QuoteType": 1, "NamePos": 1075, "NameEnd": 1083 }, "Operation": "=", "Value": { "NumPos": 1084, "NumEnd": 1085, "Literal": "1", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 1087, "StatementEnd": 1121, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r5_01293", "QuoteType": 1, "NamePos": 1099, "NameEnd": 1107 }, "Scope": null, "OnCluster": null } ], "AccessStorageType": null, "Settings": [ { "SettingPairs": [], "Modifier": { "Name": "NONE", "QuoteType": 1, "NamePos": 1117, "NameEnd": 1121 } } ] }, { "CreatePos": 1123, "StatementEnd": 1146, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 1135, "NameEnd": 1143 }, "Scope": { "LiteralPos": 1145, "LiteralEnd": 1146, "Literal": "%" }, "OnCluster": null } ], "AccessStorageType": null, "Settings": null }, { "CreatePos": 1149, "StatementEnd": 1183, "IfNotExists": false, "OrReplace": false, "RoleNames": [ { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 1161, "NameEnd": 1169 }, "Scope": { "LiteralPos": 1171, "LiteralEnd": 1183, "Literal": "%.myhost.com" }, "OnCluster": null } ], "AccessStorageType": null, "Settings": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_as_remote_function.sql.golden.json ================================================ [ { "CreatePos": 62, "StatementEnd": 222, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "test_remote", "QuoteType": 1, "NamePos": 75, "NameEnd": 86 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 87, "SchemaEnd": 137, "Columns": [ { "NamePos": 93, "ColumnEnd": 102, "Name": { "Ident": { "Name": "id", "QuoteType": 1, "NamePos": 93, "NameEnd": 95 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 96, "NameEnd": 102 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 108, "ColumnEnd": 119, "Name": { "Ident": { "Name": "name", "QuoteType": 1, "NamePos": 108, "NameEnd": 112 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 113, "NameEnd": 119 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 125, "ColumnEnd": 136, "Name": { "Ident": { "Name": "value", "QuoteType": 1, "NamePos": 125, "NameEnd": 130 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int32", "QuoteType": 1, "NamePos": 131, "NameEnd": 136 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": null, "SubQuery": null, "TableFunction": { "Name": { "Name": "remoteSecure", "QuoteType": 1, "NamePos": 142, "NameEnd": 154 }, "Args": { "LeftParenPos": 154, "RightParenPos": 222, "Args": [ { "LiteralPos": 156, "LiteralEnd": 172, "Literal": "host.example.com" }, { "LiteralPos": 176, "LiteralEnd": 185, "Literal": "source_db" }, { "LiteralPos": 189, "LiteralEnd": 201, "Literal": "source_table" }, { "LiteralPos": 205, "LiteralEnd": 209, "Literal": "user" }, { "LiteralPos": 213, "LiteralEnd": 221, "Literal": "password" } ] } }, "HasTemporary": false, "Comment": null }, { "CreatePos": 261, "StatementEnd": 353, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 274, "NameEnd": 284 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 285, "SchemaEnd": 308, "Columns": [ { "NamePos": 286, "ColumnEnd": 295, "Name": { "Ident": { "Name": "id", "QuoteType": 1, "NamePos": 286, "NameEnd": 288 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 289, "NameEnd": 295 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 297, "ColumnEnd": 308, "Name": { "Ident": { "Name": "name", "QuoteType": 1, "NamePos": 297, "NameEnd": 301 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 302, "NameEnd": 308 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": null, "SubQuery": null, "TableFunction": { "Name": { "Name": "remote", "QuoteType": 1, "NamePos": 313, "NameEnd": 319 }, "Args": { "LeftParenPos": 319, "RightParenPos": 353, "Args": [ { "LiteralPos": 321, "LiteralEnd": 330, "Literal": "localhost" }, { "LiteralPos": 334, "LiteralEnd": 336, "Literal": "db" }, { "LiteralPos": 340, "LiteralEnd": 352, "Literal": "source_table" } ] } }, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_basic.sql.golden.json ================================================ [ { "CreatePos": 122, "StatementEnd": 774, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 149, "NameEnd": 153 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 154, "NameEnd": 166 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 167, "SchemaEnd": 656, "Columns": [ { "NamePos": 173, "ColumnEnd": 182, "Name": { "Ident": { "Name": "f0", "QuoteType": 1, "NamePos": 173, "NameEnd": 175 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 176, "NameEnd": 182 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 188, "ColumnEnd": 212, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 188, "NameEnd": 190 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 191, "NameEnd": 197 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 198, "RightParenPos": 212, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 204, "NameEnd": 208 }, "Level": { "NumPos": 208, "NumEnd": 210, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 218, "ColumnEnd": 232, "Name": { "Ident": { "Name": "f2", "QuoteType": 1, "NamePos": 218, "NameEnd": 220 }, "DotIdent": null }, "Type": { "LeftParenPos": 229, "RightParenPos": 232, "Name": { "Name": "VARCHAR", "QuoteType": 1, "NamePos": 221, "NameEnd": 228 }, "Params": [ { "NumPos": 229, "NumEnd": 232, "Literal": "255", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 239, "ColumnEnd": 250, "Name": { "Ident": { "Name": "f3", "QuoteType": 1, "NamePos": 239, "NameEnd": 241 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 242, "NameEnd": 250 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 256, "ColumnEnd": 267, "Name": { "Ident": { "Name": "f4", "QuoteType": 1, "NamePos": 256, "NameEnd": 258 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 259, "NameEnd": 267 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 273, "ColumnEnd": 293, "Name": { "Ident": { "Name": "f5", "QuoteType": 1, "NamePos": 273, "NameEnd": 275 }, "DotIdent": null }, "Type": { "LeftParenPos": 280, "RightParenPos": 293, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 276, "NameEnd": 279 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 280, "NameEnd": 286 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 287, "NameEnd": 293 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 300, "ColumnEnd": 309, "Name": { "Ident": { "Name": "f6", "QuoteType": 1, "NamePos": 300, "NameEnd": 302 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 303, "NameEnd": 309 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 315, "ColumnEnd": 450, "Name": { "Ident": { "Name": "f7", "QuoteType": 1, "NamePos": 315, "NameEnd": 317 }, "DotIdent": null }, "Type": { "LeftParenPos": 335, "RightParenPos": 450, "Name": { "Name": "Nested", "QuoteType": 1, "NamePos": 318, "NameEnd": 324 }, "Columns": [ { "NamePos": 335, "ColumnEnd": 345, "Name": { "Ident": { "Name": "f70", "QuoteType": 1, "NamePos": 335, "NameEnd": 338 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 339, "NameEnd": 345 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 355, "ColumnEnd": 365, "Name": { "Ident": { "Name": "f71", "QuoteType": 1, "NamePos": 355, "NameEnd": 358 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 359, "NameEnd": 365 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 375, "ColumnEnd": 387, "Name": { "Ident": { "Name": "f72", "QuoteType": 1, "NamePos": 375, "NameEnd": 378 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 379, "NameEnd": 387 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 397, "ColumnEnd": 406, "Name": { "Ident": { "Name": "f73", "QuoteType": 1, "NamePos": 397, "NameEnd": 400 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 401, "NameEnd": 406 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 416, "ColumnEnd": 425, "Name": { "Ident": { "Name": "f74", "QuoteType": 1, "NamePos": 416, "NameEnd": 419 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 420, "NameEnd": 425 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 435, "ColumnEnd": 445, "Name": { "Ident": { "Name": "f75", "QuoteType": 1, "NamePos": 435, "NameEnd": 438 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 439, "NameEnd": 445 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 457, "ColumnEnd": 481, "Name": { "Ident": { "Name": "f8", "QuoteType": 1, "NamePos": 457, "NameEnd": 459 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 460, "NameEnd": 468 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 477, "NameEnd": 480 }, "Params": { "LeftParenPos": 480, "RightParenPos": 481, "Items": { "ListPos": 481, "ListEnd": 481, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 488, "ColumnEnd": 529, "Name": { "Ident": { "Name": "f9", "QuoteType": 1, "NamePos": 488, "NameEnd": 490 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 491, "NameEnd": 497 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": { "Name": { "Name": "toString", "QuoteType": 1, "NamePos": 511, "NameEnd": 519 }, "Params": { "LeftParenPos": 519, "RightParenPos": 529, "Items": { "ListPos": 520, "ListEnd": 528, "HasDistinct": false, "Items": [ { "Expr": { "Object": { "Name": "f7", "QuoteType": 1, "NamePos": 520, "NameEnd": 522 }, "Params": { "LeftBracketPos": 522, "RightBracketPos": 528, "Items": { "ListPos": 524, "ListEnd": 527, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 524, "LiteralEnd": 527, "Literal": "f70" }, "Alias": null } ] } } }, "Alias": null } ] }, "ColumnArgList": null } }, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 536, "ColumnEnd": 556, "Name": { "Ident": { "Name": "f10", "QuoteType": 1, "NamePos": 536, "NameEnd": 539 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 540, "NameEnd": 546 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": { "Name": "f11", "QuoteType": 1, "NamePos": 553, "NameEnd": 556 }, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 562, "ColumnEnd": 653, "Name": { "Ident": { "Name": "f12", "QuoteType": 1, "NamePos": 562, "NameEnd": 565 }, "DotIdent": null }, "Type": { "Name": { "Name": "JSON", "QuoteType": 1, "NamePos": 566, "NameEnd": 570 }, "Options": { "LParen": 571, "RParen": 653, "Items": [ { "SkipPath": null, "SkipRegex": null, "MaxDynamicPaths": null, "MaxDynamicTypes": { "NumPos": 589, "NumEnd": 591, "Literal": "10", "Base": 10 }, "Column": null }, { "SkipPath": null, "SkipRegex": null, "MaxDynamicPaths": { "NumPos": 611, "NumEnd": 612, "Literal": "3", "Base": 10 }, "MaxDynamicTypes": null, "Column": null }, { "SkipPath": { "Idents": [ { "Name": "a", "QuoteType": 1, "NamePos": 619, "NameEnd": 620 } ] }, "SkipRegex": null, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": null }, { "SkipPath": { "Idents": [ { "Name": "a", "QuoteType": 1, "NamePos": 627, "NameEnd": 628 }, { "Name": "b", "QuoteType": 1, "NamePos": 629, "NameEnd": 630 }, { "Name": "c", "QuoteType": 1, "NamePos": 631, "NameEnd": 632 } ] }, "SkipRegex": null, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": null }, { "SkipPath": null, "SkipRegex": { "LiteralPos": 647, "LiteralEnd": 652, "Literal": "hello" }, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": null } ] } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 658, "EngineEnd": 774, "Name": "MergeTree", "Params": null, "PrimaryKey": { "PrimaryPos": 677, "Expr": { "LeftParenPos": 689, "RightParenPos": 700, "Items": { "ListPos": 690, "ListEnd": 700, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 690, "NameEnd": 692 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 694, "NameEnd": 696 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 698, "NameEnd": 700 }, "Alias": null } ] }, "ColumnArgList": null } }, "PartitionBy": { "PartitionPos": 702, "Expr": { "ListPos": 715, "ListEnd": 728, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMMDD", "QuoteType": 1, "NamePos": 715, "NameEnd": 725 }, "Params": { "LeftParenPos": 725, "RightParenPos": 728, "Items": { "ListPos": 726, "ListEnd": 728, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 726, "NameEnd": 728 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 730, "ListEnd": 755, "Items": [ { "TTLPos": 730, "Expr": { "LeftExpr": { "Name": "f3", "QuoteType": 1, "NamePos": 734, "NameEnd": 736 }, "Operation": "+", "RightExpr": { "IntervalPos": 739, "Expr": { "NumPos": 748, "NumEnd": 749, "Literal": "6", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 750, "NameEnd": 755 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": null, "OrderBy": { "OrderPos": 756, "ListEnd": 774, "Items": [ { "OrderPos": 756, "Expr": { "LeftParenPos": 765, "RightParenPos": 774, "Items": { "ListPos": 766, "ListEnd": 774, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 766, "NameEnd": 768 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 769, "NameEnd": 771 }, "Alias": null }, { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 772, "NameEnd": 774 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": { "LiteralPos": 785, "LiteralEnd": 802, "Literal": "Comment for table" } } ] ================================================ FILE: parser/testdata/ddl/output/create_table_codec_no_args.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 0, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "shark_attacks", "QuoteType": 1, "NamePos": 13, "NameEnd": 26 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 27, "SchemaEnd": 72, "Columns": [ { "NamePos": 33, "ColumnEnd": 70, "Name": { "Ident": { "Name": "timestamp", "QuoteType": 1, "NamePos": 33, "NameEnd": 42 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 43, "NameEnd": 51 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 52, "RightParenPos": 70, "Type": null, "TypeLevel": null, "Name": { "Name": "DoubleDelta", "QuoteType": 1, "NamePos": 58, "NameEnd": 69 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": null, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_json_typehints.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 139, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 13, "NameEnd": 14 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 15, "SchemaEnd": 103, "Columns": [ { "NamePos": 21, "ColumnEnd": 101, "Name": { "Ident": { "Name": "j", "QuoteType": 1, "NamePos": 21, "NameEnd": 22 }, "DotIdent": null }, "Type": { "Name": { "Name": "JSON", "QuoteType": 1, "NamePos": 23, "NameEnd": 27 }, "Options": { "LParen": 28, "RParen": 101, "Items": [ { "SkipPath": null, "SkipRegex": null, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": { "Path": { "Idents": [ { "Name": "message", "QuoteType": 1, "NamePos": 28, "NameEnd": 35 } ] }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 36, "NameEnd": 42 } } } }, { "SkipPath": null, "SkipRegex": null, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": { "Path": { "Idents": [ { "Name": "a", "QuoteType": 1, "NamePos": 44, "NameEnd": 45 }, { "Name": "b", "QuoteType": 1, "NamePos": 46, "NameEnd": 47 } ] }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 48, "NameEnd": 54 } } } }, { "SkipPath": null, "SkipRegex": null, "MaxDynamicPaths": { "NumPos": 74, "NumEnd": 75, "Literal": "0", "Base": 10 }, "MaxDynamicTypes": null, "Column": null }, { "SkipPath": { "Idents": [ { "Name": "x", "QuoteType": 1, "NamePos": 82, "NameEnd": 83 } ] }, "SkipRegex": null, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": null }, { "SkipPath": null, "SkipRegex": { "LiteralPos": 98, "LiteralEnd": 100, "Literal": "re" }, "MaxDynamicPaths": null, "MaxDynamicTypes": null, "Column": null } ] } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 105, "EngineEnd": 139, "Name": "MergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": { "OrderPos": 124, "ListEnd": 139, "Items": [ { "OrderPos": 124, "Expr": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 133, "NameEnd": 138 }, "Params": { "LeftParenPos": 138, "RightParenPos": 139, "Items": { "ListPos": 139, "ListEnd": 139, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_codec_delta.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 812, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "test_local", "QuoteType": 1, "NamePos": 27, "NameEnd": 37 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 38, "SchemaEnd": 375, "Columns": [ { "NamePos": 42, "ColumnEnd": 74, "Name": { "Ident": { "Name": "id", "QuoteType": 3, "NamePos": 42, "NameEnd": 44 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 46, "NameEnd": 52 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 53, "RightParenPos": 74, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 59, "NameEnd": 64 }, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 66, "NameEnd": 70 }, "Level": { "NumPos": 70, "NumEnd": 72, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 78, "ColumnEnd": 107, "Name": { "Ident": { "Name": "api_id", "QuoteType": 3, "NamePos": 78, "NameEnd": 84 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 86, "NameEnd": 92 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 93, "RightParenPos": 107, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 99, "NameEnd": 103 }, "Level": { "NumPos": 103, "NumEnd": 105, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 111, "ColumnEnd": 150, "Name": { "Ident": { "Name": "app_id", "QuoteType": 3, "NamePos": 111, "NameEnd": 117 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 119, "NameEnd": 125 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 126, "RightParenPos": 150, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 132, "NameEnd": 137 }, "TypeLevel": { "NumPos": 137, "NumEnd": 139, "Literal": "9", "Base": 10 }, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 142, "NameEnd": 146 }, "Level": { "NumPos": 146, "NumEnd": 148, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 154, "ColumnEnd": 199, "Name": { "Ident": { "Name": "device_id", "QuoteType": 3, "NamePos": 154, "NameEnd": 163 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 165, "NameEnd": 171 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 172, "RightParenPos": 199, "Type": { "Name": "DoubleDelta", "QuoteType": 1, "NamePos": 178, "NameEnd": 189 }, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 191, "NameEnd": 195 }, "Level": { "NumPos": 195, "NumEnd": 197, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 203, "ColumnEnd": 237, "Name": { "Ident": { "Name": "guage", "QuoteType": 3, "NamePos": 203, "NameEnd": 208 }, "DotIdent": null }, "Type": { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 210, "NameEnd": 217 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 218, "RightParenPos": 237, "Type": { "Name": "Gorilla", "QuoteType": 1, "NamePos": 224, "NameEnd": 231 }, "TypeLevel": null, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 233, "NameEnd": 236 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 241, "ColumnEnd": 270, "Name": { "Ident": { "Name": "value", "QuoteType": 3, "NamePos": 241, "NameEnd": 246 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 248, "NameEnd": 254 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 255, "RightParenPos": 270, "Type": { "Name": "T64", "QuoteType": 1, "NamePos": 261, "NameEnd": 264 }, "TypeLevel": null, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 266, "NameEnd": 269 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 274, "ColumnEnd": 313, "Name": { "Ident": { "Name": "timestamp", "QuoteType": 3, "NamePos": 274, "NameEnd": 283 }, "DotIdent": null }, "Type": { "LeftParenPos": 296, "RightParenPos": 297, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 285, "NameEnd": 295 }, "Params": [ { "NumPos": 296, "NumEnd": 297, "Literal": "9", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 299, "RightParenPos": 313, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 305, "NameEnd": 309 }, "Level": { "NumPos": 309, "NumEnd": 311, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "IndexPos": 316, "Name": { "Ident": { "Name": "timestamp_index", "QuoteType": 1, "NamePos": 322, "NameEnd": 337 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "LeftParenPos": 337, "RightParenPos": 347, "Items": { "ListPos": 338, "ListEnd": 347, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 338, "NameEnd": 347 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null }, "ColumnType": { "Name": { "Name": "minmax", "QuoteType": 1, "NamePos": 354, "NameEnd": 360 } }, "Granularity": { "NumPos": 373, "NumEnd": 374, "Literal": "4", "Base": 10 } } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 377, "EngineEnd": 812, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 405, "RightParenPos": 437, "Items": { "ListPos": 407, "ListEnd": 436, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 407, "LiteralEnd": 423, "Literal": "/root/test_local" }, "Alias": null }, { "Expr": { "LiteralPos": 427, "LiteralEnd": 436, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 439, "Expr": { "ListPos": 452, "ListEnd": 477, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 452, "NameEnd": 465 }, "Params": { "LeftParenPos": 465, "RightParenPos": 477, "Items": { "ListPos": 467, "ListEnd": 476, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 467, "NameEnd": 476 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 535, "ListEnd": 626, "Items": [ { "TTLPos": 535, "Expr": { "LeftExpr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 539, "NameEnd": 552 }, "Params": { "LeftParenPos": 552, "RightParenPos": 564, "Items": { "ListPos": 554, "ListEnd": 563, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 554, "NameEnd": 563 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 568, "Expr": { "NumPos": 577, "NumEnd": 578, "Literal": "7", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 579, "NameEnd": 582 } }, "HasGlobal": false, "HasNot": false }, "Policy": null }, { "TTLPos": 535, "Expr": { "LeftExpr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 583, "NameEnd": 596 }, "Params": { "LeftParenPos": 596, "RightParenPos": 608, "Items": { "ListPos": 598, "ListEnd": 607, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 598, "NameEnd": 607 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 612, "Expr": { "NumPos": 621, "NumEnd": 622, "Literal": "2", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 623, "NameEnd": 626 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": { "SettingsPos": 627, "ListEnd": 812, "Items": [ { "SettingsPos": 636, "Name": { "Name": "execute_merges_on_single_replica_time_threshold", "QuoteType": 1, "NamePos": 636, "NameEnd": 683 }, "Expr": { "NumPos": 684, "NumEnd": 688, "Literal": "1200", "Base": 10 } }, { "SettingsPos": 690, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 690, "NameEnd": 707 }, "Expr": { "NumPos": 708, "NumEnd": 713, "Literal": "16384", "Base": 10 } }, { "SettingsPos": 715, "Name": { "Name": "max_bytes_to_merge_at_max_space_in_pool", "QuoteType": 1, "NamePos": 715, "NameEnd": 754 }, "Expr": { "NumPos": 755, "NumEnd": 766, "Literal": "64424509440", "Base": 10 } }, { "SettingsPos": 768, "Name": { "Name": "storage_policy", "QuoteType": 1, "NamePos": 768, "NameEnd": 782 }, "Expr": { "LiteralPos": 784, "LiteralEnd": 788, "Literal": "main" } }, { "SettingsPos": 791, "Name": { "Name": "ttl_only_drop_parts", "QuoteType": 1, "NamePos": 791, "NameEnd": 810 }, "Expr": { "NumPos": 811, "NumEnd": 812, "Literal": "1", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 479, "ListEnd": 533, "Items": [ { "OrderPos": 479, "Expr": { "LeftParenPos": 488, "RightParenPos": 533, "Items": { "ListPos": 489, "ListEnd": 532, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toUnixTimestamp64Nano", "QuoteType": 1, "NamePos": 489, "NameEnd": 510 }, "Params": { "LeftParenPos": 510, "RightParenPos": 522, "Items": { "ListPos": 512, "ListEnd": 521, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 512, "NameEnd": 521 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null }, { "Expr": { "Name": "api_id", "QuoteType": 3, "NamePos": 526, "NameEnd": 532 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_enum_fields.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 448, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 13, "NameEnd": 15 } }, "IfNotExists": false, "UUID": null, "OnCluster": { "OnPos": 16, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 27, "NameEnd": 42 } }, "TableSchema": { "SchemaPos": 43, "SchemaEnd": 233, "Columns": [ { "NamePos": 50, "ColumnEnd": 176, "Name": { "Ident": { "Name": "method", "QuoteType": 3, "NamePos": 50, "NameEnd": 56 }, "DotIdent": null }, "Type": { "Name": { "Name": "Enum8", "QuoteType": 1, "NamePos": 58, "NameEnd": 63 }, "ListPos": 65, "ListEnd": 160, "Values": [ { "Name": { "LiteralPos": 65, "LiteralEnd": 68, "Literal": "GET" }, "Value": { "NumPos": 70, "NumEnd": 71, "Literal": "1", "Base": 10 } }, { "Name": { "LiteralPos": 75, "LiteralEnd": 79, "Literal": "POST" }, "Value": { "NumPos": 81, "NumEnd": 82, "Literal": "2", "Base": 10 } }, { "Name": { "LiteralPos": 85, "LiteralEnd": 89, "Literal": "HEAD" }, "Value": { "NumPos": 91, "NumEnd": 92, "Literal": "3", "Base": 10 } }, { "Name": { "LiteralPos": 95, "LiteralEnd": 98, "Literal": "PUT" }, "Value": { "NumPos": 100, "NumEnd": 101, "Literal": "4", "Base": 10 } }, { "Name": { "LiteralPos": 103, "LiteralEnd": 108, "Literal": "PATCH" }, "Value": { "NumPos": 110, "NumEnd": 111, "Literal": "5", "Base": 10 } }, { "Name": { "LiteralPos": 114, "LiteralEnd": 120, "Literal": "DELETE" }, "Value": { "NumPos": 122, "NumEnd": 123, "Literal": "6", "Base": 10 } }, { "Name": { "LiteralPos": 126, "LiteralEnd": 133, "Literal": "CONNECT" }, "Value": { "NumPos": 135, "NumEnd": 136, "Literal": "7", "Base": 10 } }, { "Name": { "LiteralPos": 139, "LiteralEnd": 146, "Literal": "OPTIONS" }, "Value": { "NumPos": 148, "NumEnd": 149, "Literal": "8", "Base": 10 } }, { "Name": { "LiteralPos": 152, "LiteralEnd": 157, "Literal": "TRACE" }, "Value": { "NumPos": 159, "NumEnd": 160, "Literal": "9", "Base": 10 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 162, "RightParenPos": 176, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 168, "NameEnd": 172 }, "Level": { "NumPos": 172, "NumEnd": 174, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 183, "ColumnEnd": 232, "Name": { "Ident": { "Name": "timestamp", "QuoteType": 3, "NamePos": 183, "NameEnd": 192 }, "DotIdent": null }, "Type": { "LeftParenPos": 205, "RightParenPos": 206, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 194, "NameEnd": 204 }, "Params": [ { "NumPos": 205, "NumEnd": 206, "Literal": "3", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 208, "RightParenPos": 232, "Type": { "Name": "DoubleDelta", "QuoteType": 1, "NamePos": 214, "NameEnd": 225 }, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 227, "NameEnd": 231 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 235, "EngineEnd": 448, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 263, "RightParenPos": 313, "Items": { "ListPos": 265, "ListEnd": 312, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 265, "LiteralEnd": 299, "Literal": "/clickhouse/tables/{layer}-{shard}" }, "Alias": null }, { "Expr": { "LiteralPos": 303, "LiteralEnd": 312, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 315, "Expr": { "ListPos": 328, "ListEnd": 344, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 328, "NameEnd": 334 }, "Params": { "LeftParenPos": 334, "RightParenPos": 344, "Items": { "ListPos": 335, "ListEnd": 344, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 335, "NameEnd": 344 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 374, "ListEnd": 413, "Items": [ { "TTLPos": 374, "Expr": { "LeftExpr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 378, "NameEnd": 384 }, "Params": { "LeftParenPos": 384, "RightParenPos": 394, "Items": { "ListPos": 385, "ListEnd": 394, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 385, "NameEnd": 394 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "Name": { "Name": "toIntervalDay", "QuoteType": 1, "NamePos": 398, "NameEnd": 411 }, "Params": { "LeftParenPos": 411, "RightParenPos": 413, "Items": { "ListPos": 412, "ListEnd": 413, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 412, "NumEnd": 413, "Literal": "3", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": { "SettingsPos": 415, "ListEnd": 448, "Items": [ { "SettingsPos": 424, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 424, "NameEnd": 441 }, "Expr": { "NumPos": 444, "NumEnd": 448, "Literal": "8192", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 346, "ListEnd": 372, "Items": [ { "OrderPos": 346, "Expr": { "LeftParenPos": 355, "RightParenPos": 372, "Items": { "ListPos": 356, "ListEnd": 372, "HasDistinct": false, "Items": [ { "Expr": { "Name": "method", "QuoteType": 1, "NamePos": 356, "NameEnd": 362 }, "Alias": null }, { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 363, "NameEnd": 372 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_index.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 1127, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "test_local", "QuoteType": 1, "NamePos": 27, "NameEnd": 37 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 38, "SchemaEnd": 690, "Columns": [ { "NamePos": 42, "ColumnEnd": 74, "Name": { "Ident": { "Name": "common.id", "QuoteType": 3, "NamePos": 42, "NameEnd": 51 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 53, "NameEnd": 59 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 60, "RightParenPos": 74, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 66, "NameEnd": 70 }, "Level": { "NumPos": 70, "NumEnd": 72, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 78, "ColumnEnd": 110, "Name": { "Ident": { "Name": "id", "QuoteType": 3, "NamePos": 78, "NameEnd": 80 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 82, "NameEnd": 88 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 89, "RightParenPos": 110, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 95, "NameEnd": 100 }, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 102, "NameEnd": 106 }, "Level": { "NumPos": 106, "NumEnd": 108, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 114, "ColumnEnd": 147, "Name": { "Ident": { "Name": "idx", "QuoteType": 3, "NamePos": 114, "NameEnd": 117 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 119, "NameEnd": 125 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 126, "RightParenPos": 147, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 132, "NameEnd": 137 }, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 139, "NameEnd": 143 }, "Level": { "NumPos": 143, "NumEnd": 145, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 151, "ColumnEnd": 180, "Name": { "Ident": { "Name": "api_id", "QuoteType": 3, "NamePos": 151, "NameEnd": 157 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 159, "NameEnd": 165 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 166, "RightParenPos": 180, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 172, "NameEnd": 176 }, "Level": { "NumPos": 176, "NumEnd": 178, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 184, "ColumnEnd": 200, "Name": { "Ident": { "Name": "arr", "QuoteType": 3, "NamePos": 184, "NameEnd": 187 }, "DotIdent": null }, "Type": { "LeftParenPos": 195, "RightParenPos": 200, "Name": { "Name": "Array", "QuoteType": 1, "NamePos": 189, "NameEnd": 194 }, "Params": [ { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 195, "NameEnd": 200 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 205, "ColumnEnd": 235, "Name": { "Ident": { "Name": "content", "QuoteType": 3, "NamePos": 205, "NameEnd": 212 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 214, "NameEnd": 220 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 221, "RightParenPos": 235, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 227, "NameEnd": 231 }, "Level": { "NumPos": 231, "NumEnd": 233, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 239, "ColumnEnd": 253, "Name": { "Ident": { "Name": "output", "QuoteType": 3, "NamePos": 239, "NameEnd": 245 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 247, "NameEnd": 253 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "IndexPos": 256, "Name": { "Ident": { "Name": "id_common_id_bloom_filter", "QuoteType": 1, "NamePos": 262, "NameEnd": 287 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Fields": [ { "Name": "common", "QuoteType": 1, "NamePos": 288, "NameEnd": 294 }, { "Name": "id", "QuoteType": 1, "NamePos": 295, "NameEnd": 297 } ] }, "Alias": null }, "ColumnType": { "LeftParenPos": 316, "RightParenPos": 321, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 303, "NameEnd": 315 }, "Params": [ { "NumPos": 316, "NumEnd": 321, "Literal": "0.001", "Base": 10 } ] }, "Granularity": { "NumPos": 335, "NumEnd": 336, "Literal": "1", "Base": 10 } }, { "IndexPos": 339, "Name": { "Ident": { "Name": "id_idx", "QuoteType": 1, "NamePos": 345, "NameEnd": 351 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 352, "NameEnd": 354 }, "Alias": null }, "ColumnType": { "Name": { "Name": "minmax", "QuoteType": 1, "NamePos": 360, "NameEnd": 366 } }, "Granularity": { "NumPos": 379, "NumEnd": 381, "Literal": "10", "Base": 10 } }, { "IndexPos": 384, "Name": { "Ident": { "Name": "idx_id", "QuoteType": 1, "NamePos": 390, "NameEnd": 396 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "idx", "QuoteType": 1, "NamePos": 397, "NameEnd": 400 }, "Alias": null }, "ColumnType": { "LeftParenPos": 418, "RightParenPos": 419, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 406, "NameEnd": 418 }, "Params": null }, "Granularity": { "NumPos": 433, "NumEnd": 434, "Literal": "1", "Base": 10 } }, { "IndexPos": 437, "Name": { "Ident": { "Name": "api_id_idx", "QuoteType": 1, "NamePos": 443, "NameEnd": 453 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "api_id", "QuoteType": 1, "NamePos": 454, "NameEnd": 460 }, "Alias": null }, "ColumnType": { "LeftParenPos": 470, "RightParenPos": 473, "Name": { "Name": "set", "QuoteType": 1, "NamePos": 466, "NameEnd": 469 }, "Params": [ { "NumPos": 470, "NumEnd": 473, "Literal": "100", "Base": 10 } ] }, "Granularity": { "NumPos": 487, "NumEnd": 488, "Literal": "2", "Base": 10 } }, { "IndexPos": 491, "Name": { "Ident": { "Name": "arr_idx", "QuoteType": 1, "NamePos": 497, "NameEnd": 504 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "arr", "QuoteType": 1, "NamePos": 505, "NameEnd": 508 }, "Alias": null }, "ColumnType": { "LeftParenPos": 527, "RightParenPos": 531, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 514, "NameEnd": 526 }, "Params": [ { "NumPos": 527, "NumEnd": 531, "Literal": "0.01", "Base": 10 } ] }, "Granularity": { "NumPos": 545, "NumEnd": 546, "Literal": "3", "Base": 10 } }, { "IndexPos": 549, "Name": { "Ident": { "Name": "content_idx", "QuoteType": 1, "NamePos": 555, "NameEnd": 566 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "content", "QuoteType": 1, "NamePos": 567, "NameEnd": 574 }, "Alias": null }, "ColumnType": { "LeftParenPos": 591, "RightParenPos": 602, "Name": { "Name": "tokenbf_v1", "QuoteType": 1, "NamePos": 580, "NameEnd": 590 }, "Params": [ { "NumPos": 591, "NumEnd": 596, "Literal": "30720", "Base": 10 }, { "NumPos": 598, "NumEnd": 599, "Literal": "2", "Base": 10 }, { "NumPos": 601, "NumEnd": 602, "Literal": "0", "Base": 10 } ] }, "Granularity": { "NumPos": 616, "NumEnd": 617, "Literal": "1", "Base": 10 } }, { "IndexPos": 620, "Name": { "Ident": { "Name": "output_idx", "QuoteType": 1, "NamePos": 626, "NameEnd": 636 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "output", "QuoteType": 1, "NamePos": 637, "NameEnd": 643 }, "Alias": null }, "ColumnType": { "LeftParenPos": 660, "RightParenPos": 674, "Name": { "Name": "ngrambf_v1", "QuoteType": 1, "NamePos": 649, "NameEnd": 659 }, "Params": [ { "NumPos": 660, "NumEnd": 661, "Literal": "3", "Base": 10 }, { "NumPos": 663, "NumEnd": 668, "Literal": "10000", "Base": 10 }, { "NumPos": 670, "NumEnd": 671, "Literal": "2", "Base": 10 }, { "NumPos": 673, "NumEnd": 674, "Literal": "1", "Base": 10 } ] }, "Granularity": { "NumPos": 688, "NumEnd": 689, "Literal": "2", "Base": 10 } } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 692, "EngineEnd": 1127, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 720, "RightParenPos": 752, "Items": { "ListPos": 722, "ListEnd": 751, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 722, "LiteralEnd": 738, "Literal": "/root/test_local" }, "Alias": null }, { "Expr": { "LiteralPos": 742, "LiteralEnd": 751, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 754, "Expr": { "ListPos": 767, "ListEnd": 792, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 767, "NameEnd": 780 }, "Params": { "LeftParenPos": 780, "RightParenPos": 792, "Items": { "ListPos": 782, "ListEnd": 791, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 782, "NameEnd": 791 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 850, "ListEnd": 941, "Items": [ { "TTLPos": 850, "Expr": { "LeftExpr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 854, "NameEnd": 867 }, "Params": { "LeftParenPos": 867, "RightParenPos": 879, "Items": { "ListPos": 869, "ListEnd": 878, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 869, "NameEnd": 878 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 883, "Expr": { "NumPos": 892, "NumEnd": 893, "Literal": "7", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 894, "NameEnd": 897 } }, "HasGlobal": false, "HasNot": false }, "Policy": null }, { "TTLPos": 850, "Expr": { "LeftExpr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 898, "NameEnd": 911 }, "Params": { "LeftParenPos": 911, "RightParenPos": 923, "Items": { "ListPos": 913, "ListEnd": 922, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 913, "NameEnd": 922 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 927, "Expr": { "NumPos": 936, "NumEnd": 937, "Literal": "2", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 938, "NameEnd": 941 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": { "SettingsPos": 942, "ListEnd": 1127, "Items": [ { "SettingsPos": 951, "Name": { "Name": "execute_merges_on_single_replica_time_threshold", "QuoteType": 1, "NamePos": 951, "NameEnd": 998 }, "Expr": { "NumPos": 999, "NumEnd": 1003, "Literal": "1200", "Base": 10 } }, { "SettingsPos": 1005, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 1005, "NameEnd": 1022 }, "Expr": { "NumPos": 1023, "NumEnd": 1028, "Literal": "16384", "Base": 10 } }, { "SettingsPos": 1030, "Name": { "Name": "max_bytes_to_merge_at_max_space_in_pool", "QuoteType": 1, "NamePos": 1030, "NameEnd": 1069 }, "Expr": { "NumPos": 1070, "NumEnd": 1081, "Literal": "64424509440", "Base": 10 } }, { "SettingsPos": 1083, "Name": { "Name": "storage_policy", "QuoteType": 1, "NamePos": 1083, "NameEnd": 1097 }, "Expr": { "LiteralPos": 1099, "LiteralEnd": 1103, "Literal": "main" } }, { "SettingsPos": 1106, "Name": { "Name": "ttl_only_drop_parts", "QuoteType": 1, "NamePos": 1106, "NameEnd": 1125 }, "Expr": { "NumPos": 1126, "NumEnd": 1127, "Literal": "1", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 794, "ListEnd": 848, "Items": [ { "OrderPos": 794, "Expr": { "LeftParenPos": 803, "RightParenPos": 848, "Items": { "ListPos": 804, "ListEnd": 847, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toUnixTimestamp64Nano", "QuoteType": 1, "NamePos": 804, "NameEnd": 825 }, "Params": { "LeftParenPos": 825, "RightParenPos": 837, "Items": { "ListPos": 827, "ListEnd": 836, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 3, "NamePos": 827, "NameEnd": 836 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null }, { "Expr": { "Name": "api_id", "QuoteType": 3, "NamePos": 841, "NameEnd": 847 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_keyword_partition_by.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 259, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 18, "NameEnd": 30 } }, "IfNotExists": false, "UUID": { "Value": { "LiteralPos": 37, "LiteralEnd": 73, "Literal": "dad17568-b070-49d0-9ad1-7568b07029d0" } }, "OnCluster": null, "TableSchema": { "SchemaPos": 75, "SchemaEnd": 148, "Columns": [ { "NamePos": 82, "ColumnEnd": 92, "Name": { "Ident": { "Name": "date", "QuoteType": 3, "NamePos": 82, "NameEnd": 86 }, "DotIdent": null }, "Type": { "Name": { "Name": "Date", "QuoteType": 1, "NamePos": 88, "NameEnd": 92 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 99, "ColumnEnd": 109, "Name": { "Ident": { "Name": "f1", "QuoteType": 3, "NamePos": 99, "NameEnd": 101 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 103, "NameEnd": 109 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 116, "ColumnEnd": 126, "Name": { "Ident": { "Name": "f2", "QuoteType": 3, "NamePos": 116, "NameEnd": 118 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 120, "NameEnd": 126 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 133, "ColumnEnd": 143, "Name": { "Ident": { "Name": "f3", "QuoteType": 3, "NamePos": 133, "NameEnd": 135 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 137, "NameEnd": 143 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 150, "EngineEnd": 259, "Name": "ReplacingMergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 182, "Expr": { "ListPos": 195, "ListEnd": 199, "HasDistinct": false, "Items": [ { "Expr": { "Name": "date", "QuoteType": 1, "NamePos": 195, "NameEnd": 199 }, "Alias": null } ] } }, "SampleBy": null, "TTL": null, "Settings": { "SettingsPos": 226, "ListEnd": 259, "Items": [ { "SettingsPos": 235, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 235, "NameEnd": 252 }, "Expr": { "NumPos": 255, "NumEnd": 259, "Literal": "8192", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 204, "ListEnd": 220, "Items": [ { "OrderPos": 204, "Expr": { "LeftParenPos": 213, "RightParenPos": 220, "Items": { "ListPos": 214, "ListEnd": 220, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 214, "NameEnd": 216 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 218, "NameEnd": 220 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_null_engine.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 172, "OrReplace": false, "Name": { "Database": { "Name": "logs", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 }, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 18, "NameEnd": 20 } }, "IfNotExists": false, "UUID": null, "OnCluster": { "OnPos": 21, "Expr": { "Name": "default", "QuoteType": 1, "NamePos": 32, "NameEnd": 39 } }, "TableSchema": { "SchemaPos": 40, "SchemaEnd": 157, "Columns": [ { "NamePos": 47, "ColumnEnd": 78, "Name": { "Ident": { "Name": "trace_id", "QuoteType": 3, "NamePos": 47, "NameEnd": 55 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 57, "NameEnd": 63 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 64, "RightParenPos": 78, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 70, "NameEnd": 74 }, "Level": { "NumPos": 74, "NumEnd": 76, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "IndexPos": 84, "Name": { "Ident": { "Name": "trace_id_bloom_idx", "QuoteType": 1, "NamePos": 90, "NameEnd": 108 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "trace_id", "QuoteType": 1, "NamePos": 109, "NameEnd": 117 }, "Alias": null }, "ColumnType": { "LeftParenPos": 136, "RightParenPos": 140, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 123, "NameEnd": 135 }, "Params": [ { "NumPos": 136, "NumEnd": 140, "Literal": "0.01", "Base": 10 } ] }, "Granularity": { "NumPos": 154, "NumEnd": 156, "Literal": "64", "Base": 10 } } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 159, "EngineEnd": 172, "Name": "Null", "Params": { "LeftParenPos": 172, "RightParenPos": 173, "Items": { "ListPos": 173, "ListEnd": 173, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": null }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_nullable.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 420, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 }, "Table": { "Name": ".inner.752391fb-44cc-4dd5-b523-91fb44cc9dd5", "QuoteType": 3, "NamePos": 19, "NameEnd": 62 } }, "IfNotExists": false, "UUID": { "Value": { "LiteralPos": 74, "LiteralEnd": 110, "Literal": "27673372-7973-44f5-a767-33727973c4f5" } }, "OnCluster": null, "TableSchema": { "SchemaPos": 112, "SchemaEnd": 313, "Columns": [ { "NamePos": 119, "ColumnEnd": 129, "Name": { "Ident": { "Name": "f0", "QuoteType": 3, "NamePos": 119, "NameEnd": 121 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 123, "NameEnd": 129 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 136, "ColumnEnd": 146, "Name": { "Ident": { "Name": "f1", "QuoteType": 3, "NamePos": 136, "NameEnd": 138 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 140, "NameEnd": 146 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 153, "ColumnEnd": 178, "Name": { "Ident": { "Name": "f2", "QuoteType": 3, "NamePos": 153, "NameEnd": 155 }, "DotIdent": null }, "Type": { "LeftParenPos": 172, "RightParenPos": 178, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 157, "NameEnd": 171 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 172, "NameEnd": 178 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 186, "ColumnEnd": 211, "Name": { "Ident": { "Name": "f3", "QuoteType": 3, "NamePos": 186, "NameEnd": 188 }, "DotIdent": null }, "Type": { "LeftParenPos": 205, "RightParenPos": 211, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 190, "NameEnd": 204 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 205, "NameEnd": 211 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 219, "ColumnEnd": 235, "Name": { "Ident": { "Name": "f4", "QuoteType": 3, "NamePos": 219, "NameEnd": 221 }, "DotIdent": null }, "Type": { "LeftParenPos": 234, "RightParenPos": 235, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 223, "NameEnd": 233 }, "Params": [ { "NumPos": 234, "NumEnd": 235, "Literal": "3", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 243, "ColumnEnd": 269, "Name": { "Ident": { "Name": "f5", "QuoteType": 3, "NamePos": 243, "NameEnd": 245 }, "DotIdent": null }, "Type": { "LeftParenPos": 256, "RightParenPos": 269, "Name": { "Name": "Nullable", "QuoteType": 1, "NamePos": 247, "NameEnd": 255 }, "Params": [ { "LeftParenPos": 267, "RightParenPos": 268, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 256, "NameEnd": 266 }, "Params": [ { "NumPos": 267, "NumEnd": 268, "Literal": "3", "Base": 10 } ] } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 277, "ColumnEnd": 311, "Name": { "Ident": { "Name": "succeed_at", "QuoteType": 3, "NamePos": 277, "NameEnd": 287 }, "DotIdent": null }, "Type": { "LeftParenPos": 298, "RightParenPos": 311, "Name": { "Name": "Nullable", "QuoteType": 1, "NamePos": 289, "NameEnd": 297 }, "Params": [ { "LeftParenPos": 309, "RightParenPos": 310, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 298, "NameEnd": 308 }, "Params": [ { "NumPos": 309, "NumEnd": 310, "Literal": "3", "Base": 10 } ] } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 315, "EngineEnd": 420, "Name": "MergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 334, "Expr": { "ListPos": 347, "ListEnd": 368, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": { "Name": "xxHash32", "QuoteType": 1, "NamePos": 347, "NameEnd": 355 }, "Params": { "LeftParenPos": 355, "RightParenPos": 362, "Items": { "ListPos": 356, "ListEnd": 362, "HasDistinct": false, "Items": [ { "Expr": { "Name": "tag_id", "QuoteType": 1, "NamePos": 356, "NameEnd": 362 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "%", "RightExpr": { "NumPos": 366, "NumEnd": 368, "Literal": "20", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] } }, "SampleBy": null, "TTL": null, "Settings": { "SettingsPos": 387, "ListEnd": 420, "Items": [ { "SettingsPos": 396, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 396, "NameEnd": 413 }, "Expr": { "NumPos": 416, "NumEnd": 420, "Literal": "8192", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 369, "ListEnd": 386, "Items": [ { "OrderPos": 369, "Expr": { "Name": "label_id", "QuoteType": 1, "NamePos": 378, "NameEnd": 386 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_on_clsuter.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 399, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 27, "NameEnd": 31 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 32, "NameEnd": 44 } }, "IfNotExists": true, "UUID": null, "OnCluster": { "OnPos": 45, "Expr": { "LiteralPos": 57, "LiteralEnd": 72, "Literal": "default_cluster" } }, "TableSchema": { "SchemaPos": 74, "SchemaEnd": 227, "Columns": [ { "NamePos": 80, "ColumnEnd": 89, "Name": { "Ident": { "Name": "f0", "QuoteType": 1, "NamePos": 80, "NameEnd": 82 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 83, "NameEnd": 89 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 95, "ColumnEnd": 104, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 95, "NameEnd": 97 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 98, "NameEnd": 104 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 110, "ColumnEnd": 119, "Name": { "Ident": { "Name": "f2", "QuoteType": 1, "NamePos": 110, "NameEnd": 112 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 113, "NameEnd": 119 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 125, "ColumnEnd": 136, "Name": { "Ident": { "Name": "f3", "QuoteType": 1, "NamePos": 125, "NameEnd": 127 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 128, "NameEnd": 136 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 142, "ColumnEnd": 153, "Name": { "Ident": { "Name": "f4", "QuoteType": 1, "NamePos": 142, "NameEnd": 144 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 145, "NameEnd": 153 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 159, "ColumnEnd": 179, "Name": { "Ident": { "Name": "f5", "QuoteType": 1, "NamePos": 159, "NameEnd": 161 }, "DotIdent": null }, "Type": { "LeftParenPos": 166, "RightParenPos": 179, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 162, "NameEnd": 165 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 166, "NameEnd": 172 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 173, "NameEnd": 179 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 186, "ColumnEnd": 195, "Name": { "Ident": { "Name": "f6", "QuoteType": 1, "NamePos": 186, "NameEnd": 188 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 189, "NameEnd": 195 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 201, "ColumnEnd": 225, "Name": { "Ident": { "Name": "f7", "QuoteType": 1, "NamePos": 201, "NameEnd": 203 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 204, "NameEnd": 212 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 221, "NameEnd": 224 }, "Params": { "LeftParenPos": 224, "RightParenPos": 225, "Items": { "ListPos": 225, "ListEnd": 225, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 229, "EngineEnd": 399, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 257, "RightParenPos": 325, "Items": { "ListPos": 259, "ListEnd": 324, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 259, "LiteralEnd": 311, "Literal": "/clickhouse/tables/{layer}-{shard}/test/events_local" }, "Alias": null }, { "Expr": { "LiteralPos": 315, "LiteralEnd": 324, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 353, "Expr": { "ListPos": 366, "ListEnd": 379, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMMDD", "QuoteType": 1, "NamePos": 366, "NameEnd": 376 }, "Params": { "LeftParenPos": 376, "RightParenPos": 379, "Items": { "ListPos": 377, "ListEnd": 379, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 377, "NameEnd": 379 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 327, "ListEnd": 352, "Items": [ { "TTLPos": 327, "Expr": { "LeftExpr": { "Name": "f3", "QuoteType": 1, "NamePos": 331, "NameEnd": 333 }, "Operation": "+", "RightExpr": { "IntervalPos": 336, "Expr": { "NumPos": 345, "NumEnd": 346, "Literal": "6", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 347, "NameEnd": 352 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": null, "OrderBy": { "OrderPos": 381, "ListEnd": 399, "Items": [ { "OrderPos": 381, "Expr": { "LeftParenPos": 390, "RightParenPos": 399, "Items": { "ListPos": 391, "ListEnd": 399, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 391, "NameEnd": 393 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 394, "NameEnd": 396 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 397, "NameEnd": 399 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_projection.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 270, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 13, "NameEnd": 19 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 20, "SchemaEnd": 229, "Columns": [ { "NamePos": 27, "ColumnEnd": 47, "Name": { "Ident": { "Name": "event_time", "QuoteType": 3, "NamePos": 27, "NameEnd": 37 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 39, "NameEnd": 47 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 54, "ColumnEnd": 70, "Name": { "Ident": { "Name": "event_id", "QuoteType": 3, "NamePos": 54, "NameEnd": 62 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 64, "NameEnd": 70 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 77, "ColumnEnd": 92, "Name": { "Ident": { "Name": "user_id", "QuoteType": 3, "NamePos": 77, "NameEnd": 84 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 86, "NameEnd": 92 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 99, "ColumnEnd": 118, "Name": { "Ident": { "Name": "huge_string", "QuoteType": 3, "NamePos": 99, "NameEnd": 110 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 112, "NameEnd": 118 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "IncludeProjectionKeyword": true, "ProjectionPos": 124, "Identifier": { "Ident": { "Name": "order_by_user_id", "QuoteType": 1, "NamePos": 135, "NameEnd": 151 }, "DotIdent": null }, "Select": { "LeftParenPos": 156, "RightParenPos": 227, "With": null, "SelectColumns": { "ListPos": 185, "ListEnd": 197, "HasDistinct": false, "Items": [ { "Expr": { "Name": "_part_offset", "QuoteType": 1, "NamePos": 185, "NameEnd": 197 }, "Alias": null } ] }, "GroupBy": null, "OrderBy": { "OrderByPos": 206, "Columns": { "ListPos": 215, "ListEnd": 222, "HasDistinct": false, "Items": [ { "Expr": { "Name": "user_id", "QuoteType": 1, "NamePos": 215, "NameEnd": 222 }, "Alias": null } ] } } } } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 231, "EngineEnd": 270, "Name": "MergeTree", "Params": { "LeftParenPos": 249, "RightParenPos": 250, "Items": { "ListPos": 250, "ListEnd": 250, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": { "OrderPos": 252, "ListEnd": 270, "Items": [ { "OrderPos": 252, "Expr": { "LeftParenPos": 261, "RightParenPos": 270, "Items": { "ListPos": 262, "ListEnd": 270, "HasDistinct": false, "Items": [ { "Expr": { "Name": "event_id", "QuoteType": 1, "NamePos": 262, "NameEnd": 270 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_projection_group_by_only.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 411, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 13, "NameEnd": 19 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 20, "SchemaEnd": 356, "Columns": [ { "NamePos": 27, "ColumnEnd": 47, "Name": { "Ident": { "Name": "event_time", "QuoteType": 3, "NamePos": 27, "NameEnd": 37 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 39, "NameEnd": 47 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 54, "ColumnEnd": 72, "Name": { "Ident": { "Name": "event_type", "QuoteType": 3, "NamePos": 54, "NameEnd": 64 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 66, "NameEnd": 72 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 79, "ColumnEnd": 94, "Name": { "Ident": { "Name": "user_id", "QuoteType": 3, "NamePos": 79, "NameEnd": 86 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 88, "NameEnd": 94 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 101, "ColumnEnd": 115, "Name": { "Ident": { "Name": "value", "QuoteType": 3, "NamePos": 101, "NameEnd": 106 }, "DotIdent": null }, "Type": { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 108, "NameEnd": 115 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "IncludeProjectionKeyword": true, "ProjectionPos": 121, "Identifier": { "Ident": { "Name": "hourly_aggregates", "QuoteType": 1, "NamePos": 132, "NameEnd": 149 }, "DotIdent": null }, "Select": { "LeftParenPos": 154, "RightParenPos": 354, "With": null, "SelectColumns": { "ListPos": 183, "ListEnd": 315, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toStartOfHour", "QuoteType": 1, "NamePos": 183, "NameEnd": 196 }, "Params": { "LeftParenPos": 196, "RightParenPos": 207, "Items": { "ListPos": 197, "ListEnd": 207, "HasDistinct": false, "Items": [ { "Expr": { "Name": "event_time", "QuoteType": 1, "NamePos": 197, "NameEnd": 207 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "hour", "QuoteType": 1, "NamePos": 212, "NameEnd": 216 } }, { "Expr": { "Name": "event_type", "QuoteType": 1, "NamePos": 230, "NameEnd": 240 }, "Alias": null }, { "Expr": { "Name": { "Name": "count", "QuoteType": 1, "NamePos": 254, "NameEnd": 259 }, "Params": { "LeftParenPos": 259, "RightParenPos": 260, "Items": { "ListPos": 260, "ListEnd": 260, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Alias": { "Name": "event_count", "QuoteType": 1, "NamePos": 265, "NameEnd": 276 } }, { "Expr": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 290, "NameEnd": 293 }, "Params": { "LeftParenPos": 293, "RightParenPos": 299, "Items": { "ListPos": 294, "ListEnd": 299, "HasDistinct": false, "Items": [ { "Expr": { "Name": "value", "QuoteType": 1, "NamePos": 294, "NameEnd": 299 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "total_value", "QuoteType": 1, "NamePos": 304, "NameEnd": 315 } } ] }, "GroupBy": { "GroupByPos": 324, "GroupByEnd": 354, "AggregateType": "", "Expr": { "ListPos": 333, "ListEnd": 349, "HasDistinct": false, "Items": [ { "Expr": { "Name": "hour", "QuoteType": 1, "NamePos": 333, "NameEnd": 337 }, "Alias": null }, { "Expr": { "Name": "event_type", "QuoteType": 1, "NamePos": 339, "NameEnd": 349 }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "OrderBy": null } } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 358, "EngineEnd": 411, "Name": "MergeTree", "Params": { "LeftParenPos": 376, "RightParenPos": 377, "Items": { "ListPos": 377, "ListEnd": 377, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": { "OrderPos": 379, "ListEnd": 411, "Items": [ { "OrderPos": 379, "Expr": { "LeftParenPos": 388, "RightParenPos": 411, "Items": { "ListPos": 389, "ListEnd": 411, "HasDistinct": false, "Items": [ { "Expr": { "Name": "event_time", "QuoteType": 1, "NamePos": 389, "NameEnd": 399 }, "Alias": null }, { "Expr": { "Name": "event_type", "QuoteType": 1, "NamePos": 401, "NameEnd": 411 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_qbit.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 90, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 }, "Table": { "Name": "qbit_example", "QuoteType": 1, "NamePos": 18, "NameEnd": 30 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 31, "SchemaEnd": 73, "Columns": [ { "NamePos": 37, "ColumnEnd": 46, "Name": { "Ident": { "Name": "id", "QuoteType": 1, "NamePos": 37, "NameEnd": 39 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 40, "NameEnd": 46 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 52, "ColumnEnd": 71, "Name": { "Ident": { "Name": "vec", "QuoteType": 1, "NamePos": 52, "NameEnd": 55 }, "DotIdent": null }, "Type": { "LeftParenPos": 61, "RightParenPos": 71, "Name": { "Name": "QBit", "QuoteType": 1, "NamePos": 56, "NameEnd": 60 }, "Params": [ { "Name": "Float32", "QuoteType": 1, "NamePos": 61, "NameEnd": 68 }, { "NumPos": 70, "NumEnd": 71, "Literal": "8", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 75, "EngineEnd": 90, "Name": "Memory", "Params": null, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": null }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_sample_by.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 351, "OrReplace": false, "Name": { "Database": { "Name": "default", "QuoteType": 1, "NamePos": 13, "NameEnd": 20 }, "Table": { "Name": "test", "QuoteType": 1, "NamePos": 21, "NameEnd": 25 } }, "IfNotExists": false, "UUID": { "Value": { "LiteralPos": 32, "LiteralEnd": 68, "Literal": "87887901-e33c-497e-8788-7901e33c997e" } }, "OnCluster": null, "TableSchema": { "SchemaPos": 70, "SchemaEnd": 124, "Columns": [ { "NamePos": 77, "ColumnEnd": 89, "Name": { "Ident": { "Name": "f0", "QuoteType": 3, "NamePos": 77, "NameEnd": 79 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 81, "NameEnd": 89 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 96, "ColumnEnd": 106, "Name": { "Ident": { "Name": "f1", "QuoteType": 3, "NamePos": 96, "NameEnd": 98 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 100, "NameEnd": 106 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 113, "ColumnEnd": 123, "Name": { "Ident": { "Name": "f3", "QuoteType": 3, "NamePos": 113, "NameEnd": 115 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 117, "NameEnd": 123 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 126, "EngineEnd": 351, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 154, "RightParenPos": 217, "Items": { "ListPos": 156, "ListEnd": 216, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 156, "LiteralEnd": 203, "Literal": "/clickhouse/tables/{layer}/{shard}/default/test" }, "Alias": null }, { "Expr": { "LiteralPos": 207, "LiteralEnd": 216, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 219, "Expr": { "ListPos": 232, "ListEnd": 250, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMM", "QuoteType": 1, "NamePos": 232, "NameEnd": 240 }, "Params": { "LeftParenPos": 240, "RightParenPos": 250, "Items": { "ListPos": 241, "ListEnd": 250, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 241, "NameEnd": 250 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": { "SamplePos": 301, "Expr": { "Name": "userid", "QuoteType": 1, "NamePos": 311, "NameEnd": 317 } }, "TTL": null, "Settings": { "SettingsPos": 318, "ListEnd": 351, "Items": [ { "SettingsPos": 327, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 327, "NameEnd": 344 }, "Expr": { "NumPos": 347, "NumEnd": 351, "Literal": "8192", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 252, "ListEnd": 299, "Items": [ { "OrderPos": 252, "Expr": { "LeftParenPos": 261, "RightParenPos": 299, "Items": { "ListPos": 262, "ListEnd": 299, "HasDistinct": false, "Items": [ { "Expr": { "Name": "contractid", "QuoteType": 1, "NamePos": 262, "NameEnd": 272 }, "Alias": null }, { "Expr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 274, "NameEnd": 280 }, "Params": { "LeftParenPos": 280, "RightParenPos": 290, "Items": { "ListPos": 281, "ListEnd": 290, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 281, "NameEnd": 290 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null }, { "Expr": { "Name": "userid", "QuoteType": 1, "NamePos": 293, "NameEnd": 299 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_ttl_policy.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 203, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "tab", "QuoteType": 1, "NamePos": 13, "NameEnd": 16 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 17, "SchemaEnd": 45, "Columns": [ { "NamePos": 23, "ColumnEnd": 33, "Name": { "Ident": { "Name": "d", "QuoteType": 1, "NamePos": 23, "NameEnd": 24 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 25, "NameEnd": 33 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 39, "ColumnEnd": 44, "Name": { "Ident": { "Name": "a", "QuoteType": 1, "NamePos": 39, "NameEnd": 40 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int", "QuoteType": 1, "NamePos": 41, "NameEnd": 44 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 51, "EngineEnd": 203, "Name": "MergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 70, "Expr": { "ListPos": 83, "ListEnd": 93, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMM", "QuoteType": 1, "NamePos": 83, "NameEnd": 91 }, "Params": { "LeftParenPos": 91, "RightParenPos": 93, "Items": { "ListPos": 92, "ListEnd": 93, "HasDistinct": false, "Items": [ { "Expr": { "Name": "d", "QuoteType": 1, "NamePos": 92, "NameEnd": 93 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 106, "ListEnd": 203, "Items": [ { "TTLPos": 106, "Expr": { "LeftExpr": { "Name": "d", "QuoteType": 1, "NamePos": 110, "NameEnd": 111 }, "Operation": "+", "RightExpr": { "IntervalPos": 114, "Expr": { "NumPos": 123, "NumEnd": 124, "Literal": "1", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 125, "NameEnd": 130 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 131, "ToVolume": null, "ToDisk": null, "Action": { "ActionPos": 131, "ActionEnd": 137, "Action": "DELETE", "Codec": null } }, "Where": null, "GroupBy": null } }, { "TTLPos": 106, "Expr": { "LeftExpr": { "Name": "d", "QuoteType": 1, "NamePos": 143, "NameEnd": 144 }, "Operation": "+", "RightExpr": { "IntervalPos": 147, "Expr": { "NumPos": 156, "NumEnd": 157, "Literal": "1", "Base": 10 }, "Unit": { "Name": "WEEK", "QuoteType": 1, "NamePos": 158, "NameEnd": 162 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 163, "ToVolume": { "LiteralPos": 174, "LiteralEnd": 177, "Literal": "aaa" }, "ToDisk": null, "Action": null }, "Where": null, "GroupBy": null } }, { "TTLPos": 106, "Expr": { "LeftExpr": { "Name": "d", "QuoteType": 1, "NamePos": 184, "NameEnd": 185 }, "Operation": "+", "RightExpr": { "IntervalPos": 188, "Expr": { "NumPos": 197, "NumEnd": 198, "Literal": "2", "Base": 10 }, "Unit": { "Name": "WEEK", "QuoteType": 1, "NamePos": 199, "NameEnd": 203 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 204, "ToVolume": null, "ToDisk": { "LiteralPos": 213, "LiteralEnd": 216, "Literal": "bbb" }, "Action": null }, "Where": null, "GroupBy": null } } ] }, "Settings": null, "OrderBy": { "OrderPos": 95, "ListEnd": 105, "Items": [ { "OrderPos": 95, "Expr": { "Name": "d", "QuoteType": 1, "NamePos": 104, "NameEnd": 105 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null }, { "CreatePos": 221, "StatementEnd": 364, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "table_with_where", "QuoteType": 1, "NamePos": 234, "NameEnd": 250 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 251, "SchemaEnd": 279, "Columns": [ { "NamePos": 257, "ColumnEnd": 267, "Name": { "Ident": { "Name": "d", "QuoteType": 1, "NamePos": 257, "NameEnd": 258 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 259, "NameEnd": 267 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 273, "ColumnEnd": 278, "Name": { "Ident": { "Name": "a", "QuoteType": 1, "NamePos": 273, "NameEnd": 274 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int", "QuoteType": 1, "NamePos": 275, "NameEnd": 278 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 285, "EngineEnd": 364, "Name": "MergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 304, "Expr": { "ListPos": 317, "ListEnd": 327, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMM", "QuoteType": 1, "NamePos": 317, "NameEnd": 325 }, "Params": { "LeftParenPos": 325, "RightParenPos": 327, "Items": { "ListPos": 326, "ListEnd": 327, "HasDistinct": false, "Items": [ { "Expr": { "Name": "d", "QuoteType": 1, "NamePos": 326, "NameEnd": 327 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 340, "ListEnd": 364, "Items": [ { "TTLPos": 340, "Expr": { "LeftExpr": { "Name": "d", "QuoteType": 1, "NamePos": 344, "NameEnd": 345 }, "Operation": "+", "RightExpr": { "IntervalPos": 348, "Expr": { "NumPos": 357, "NumEnd": 358, "Literal": "1", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 359, "NameEnd": 364 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 365, "ToVolume": null, "ToDisk": null, "Action": { "ActionPos": 365, "ActionEnd": 371, "Action": "DELETE", "Codec": null } }, "Where": { "WherePos": 372, "Expr": { "LeftExpr": { "Name": { "Name": "toDayOfWeek", "QuoteType": 1, "NamePos": 378, "NameEnd": 389 }, "Params": { "LeftParenPos": 389, "RightParenPos": 391, "Items": { "ListPos": 390, "ListEnd": 391, "HasDistinct": false, "Items": [ { "Expr": { "Name": "d", "QuoteType": 1, "NamePos": 390, "NameEnd": 391 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "=", "RightExpr": { "NumPos": 395, "NumEnd": 396, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null } } ] }, "Settings": null, "OrderBy": { "OrderPos": 329, "ListEnd": 339, "Items": [ { "OrderPos": 329, "Expr": { "Name": "d", "QuoteType": 1, "NamePos": 338, "NameEnd": 339 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null }, { "CreatePos": 399, "StatementEnd": 763, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "table_for_recompression", "QuoteType": 1, "NamePos": 412, "NameEnd": 435 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 436, "SchemaEnd": 487, "Columns": [ { "NamePos": 442, "ColumnEnd": 452, "Name": { "Ident": { "Name": "d", "QuoteType": 1, "NamePos": 442, "NameEnd": 443 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 444, "NameEnd": 452 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 458, "ColumnEnd": 468, "Name": { "Ident": { "Name": "key", "QuoteType": 1, "NamePos": 458, "NameEnd": 461 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 462, "NameEnd": 468 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 474, "ColumnEnd": 486, "Name": { "Ident": { "Name": "value", "QuoteType": 1, "NamePos": 474, "NameEnd": 479 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 480, "NameEnd": 486 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 489, "EngineEnd": 763, "Name": "MergeTree", "Params": { "LeftParenPos": 505, "RightParenPos": 506, "Items": { "ListPos": 506, "ListEnd": 506, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 525, "Expr": { "ListPos": 538, "ListEnd": 541, "HasDistinct": false, "Items": [ { "Expr": { "Name": "key", "QuoteType": 1, "NamePos": 538, "NameEnd": 541 }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 542, "ListEnd": 614, "Items": [ { "TTLPos": 542, "Expr": { "LeftExpr": { "Name": "d", "QuoteType": 1, "NamePos": 546, "NameEnd": 547 }, "Operation": "+", "RightExpr": { "IntervalPos": 550, "Expr": { "NumPos": 559, "NumEnd": 560, "Literal": "1", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 561, "NameEnd": 566 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 567, "ToVolume": null, "ToDisk": null, "Action": { "ActionPos": 567, "ActionEnd": 577, "Action": "RECOMPRESS", "Codec": { "CodecPos": 578, "RightParenPos": 593, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 584, "NameEnd": 588 }, "Level": { "NumPos": 588, "NumEnd": 591, "Literal": "17", "Base": 10 } } } }, "Where": null, "GroupBy": null } }, { "TTLPos": 542, "Expr": { "LeftExpr": { "Name": "d", "QuoteType": 1, "NamePos": 595, "NameEnd": 596 }, "Operation": "+", "RightExpr": { "IntervalPos": 599, "Expr": { "NumPos": 608, "NumEnd": 609, "Literal": "1", "Base": 10 }, "Unit": { "Name": "YEAR", "QuoteType": 1, "NamePos": 610, "NameEnd": 614 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 615, "ToVolume": null, "ToDisk": null, "Action": { "ActionPos": 615, "ActionEnd": 625, "Action": "RECOMPRESS", "Codec": { "CodecPos": 626, "RightParenPos": 642, "Type": null, "TypeLevel": null, "Name": { "Name": "LZ4HC", "QuoteType": 1, "NamePos": 632, "NameEnd": 637 }, "Level": { "NumPos": 637, "NumEnd": 640, "Literal": "10", "Base": 10 } } } }, "Where": null, "GroupBy": null } } ] }, "Settings": { "SettingsPos": 643, "ListEnd": 763, "Items": [ { "SettingsPos": 652, "Name": { "Name": "min_rows_for_wide_part", "QuoteType": 1, "NamePos": 652, "NameEnd": 674 }, "Expr": { "NumPos": 677, "NumEnd": 678, "Literal": "0", "Base": 10 } }, { "SettingsPos": 680, "Name": { "Name": "min_bytes_for_wide_part", "QuoteType": 1, "NamePos": 680, "NameEnd": 703 }, "Expr": { "NumPos": 706, "NumEnd": 707, "Literal": "0", "Base": 10 } }, { "SettingsPos": 709, "Name": { "Name": "allow_experimental_replacing_merge_with_cleanup", "QuoteType": 1, "NamePos": 709, "NameEnd": 756 }, "Expr": { "LiteralPos": 759, "LiteralEnd": 763, "Literal": "true" } } ] }, "OrderBy": { "OrderPos": 508, "ListEnd": 523, "Items": [ { "OrderPos": 508, "Expr": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 517, "NameEnd": 522 }, "Params": { "LeftParenPos": 522, "RightParenPos": 523, "Items": { "ListPos": 523, "ListEnd": 523, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_tuple_fields.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 347, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 13, "NameEnd": 15 } }, "IfNotExists": false, "UUID": null, "OnCluster": { "OnPos": 16, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 27, "NameEnd": 42 } }, "TableSchema": { "SchemaPos": 43, "SchemaEnd": 204, "Columns": [ { "NamePos": 50, "ColumnEnd": 62, "Name": { "Ident": { "Name": "tup0", "QuoteType": 3, "NamePos": 50, "NameEnd": 54 }, "DotIdent": null }, "Type": { "LeftParenPos": 61, "RightParenPos": 62, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 56, "NameEnd": 61 }, "Params": null }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 70, "ColumnEnd": 95, "Name": { "Ident": { "Name": "tup1", "QuoteType": 3, "NamePos": 70, "NameEnd": 74 }, "DotIdent": null }, "Type": { "LeftParenPos": 82, "RightParenPos": 95, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 76, "NameEnd": 81 }, "Columns": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 82, "NameEnd": 88 } }, { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 90, "NameEnd": 95 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 103, "ColumnEnd": 144, "Name": { "Ident": { "Name": "tup2", "QuoteType": 3, "NamePos": 103, "NameEnd": 107 }, "DotIdent": null }, "Type": { "LeftParenPos": 115, "RightParenPos": 144, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 109, "NameEnd": 114 }, "Columns": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 115, "NameEnd": 121 } }, { "LeftParenPos": 129, "RightParenPos": 143, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 123, "NameEnd": 128 }, "Columns": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 129, "NameEnd": 135 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 137, "NameEnd": 143 } } ] } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 152, "ColumnEnd": 202, "Name": { "Ident": { "Name": "tup3", "QuoteType": 3, "NamePos": 152, "NameEnd": 156 }, "DotIdent": null }, "Type": { "LeftParenPos": 164, "RightParenPos": 202, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 158, "NameEnd": 163 }, "Columns": [ { "NamePos": 164, "ColumnEnd": 172, "Name": { "Ident": { "Name": "a", "QuoteType": 1, "NamePos": 164, "NameEnd": 165 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 166, "NameEnd": 172 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 174, "ColumnEnd": 201, "Name": { "Ident": { "Name": "cd", "QuoteType": 1, "NamePos": 174, "NameEnd": 176 }, "DotIdent": null }, "Type": { "LeftParenPos": 183, "RightParenPos": 201, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 177, "NameEnd": 182 }, "Columns": [ { "NamePos": 183, "ColumnEnd": 191, "Name": { "Ident": { "Name": "c", "QuoteType": 1, "NamePos": 183, "NameEnd": 184 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 185, "NameEnd": 191 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 193, "ColumnEnd": 201, "Name": { "Ident": { "Name": "d", "QuoteType": 1, "NamePos": 193, "NameEnd": 194 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 195, "NameEnd": 201 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 206, "EngineEnd": 347, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 234, "RightParenPos": 284, "Items": { "ListPos": 236, "ListEnd": 283, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 236, "LiteralEnd": 270, "Literal": "/clickhouse/tables/{layer}-{shard}" }, "Alias": null }, { "Expr": { "LiteralPos": 274, "LiteralEnd": 283, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": { "SettingsPos": 314, "ListEnd": 347, "Items": [ { "SettingsPos": 323, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 323, "NameEnd": 340 }, "Expr": { "NumPos": 343, "NumEnd": 347, "Literal": "8192", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 286, "ListEnd": 312, "Items": [ { "OrderPos": 286, "Expr": { "LeftParenPos": 295, "RightParenPos": 312, "Items": { "ListPos": 296, "ListEnd": 312, "HasDistinct": false, "Items": [ { "Expr": { "Name": "tup1", "QuoteType": 1, "NamePos": 296, "NameEnd": 300 }, "Alias": null }, { "Expr": { "Name": "tup2", "QuoteType": 1, "NamePos": 302, "NameEnd": 306 }, "Alias": null }, { "Expr": { "Name": "tup3", "QuoteType": 1, "NamePos": 308, "NameEnd": 312 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_table_with_uuid.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 411, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 27, "NameEnd": 31 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 32, "NameEnd": 44 } }, "IfNotExists": true, "UUID": { "Value": { "LiteralPos": 51, "LiteralEnd": 55, "Literal": "1234" } }, "OnCluster": { "OnPos": 57, "Expr": { "LiteralPos": 69, "LiteralEnd": 84, "Literal": "default_cluster" } }, "TableSchema": { "SchemaPos": 86, "SchemaEnd": 239, "Columns": [ { "NamePos": 92, "ColumnEnd": 101, "Name": { "Ident": { "Name": "f0", "QuoteType": 1, "NamePos": 92, "NameEnd": 94 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 95, "NameEnd": 101 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 107, "ColumnEnd": 116, "Name": { "Ident": { "Name": "f1", "QuoteType": 1, "NamePos": 107, "NameEnd": 109 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 110, "NameEnd": 116 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 122, "ColumnEnd": 131, "Name": { "Ident": { "Name": "f2", "QuoteType": 1, "NamePos": 122, "NameEnd": 124 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 125, "NameEnd": 131 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 137, "ColumnEnd": 148, "Name": { "Ident": { "Name": "f3", "QuoteType": 1, "NamePos": 137, "NameEnd": 139 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 140, "NameEnd": 148 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 154, "ColumnEnd": 165, "Name": { "Ident": { "Name": "f4", "QuoteType": 1, "NamePos": 154, "NameEnd": 156 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 157, "NameEnd": 165 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 171, "ColumnEnd": 191, "Name": { "Ident": { "Name": "f5", "QuoteType": 1, "NamePos": 171, "NameEnd": 173 }, "DotIdent": null }, "Type": { "LeftParenPos": 178, "RightParenPos": 191, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 174, "NameEnd": 177 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 178, "NameEnd": 184 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 185, "NameEnd": 191 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 198, "ColumnEnd": 207, "Name": { "Ident": { "Name": "f6", "QuoteType": 1, "NamePos": 198, "NameEnd": 200 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 201, "NameEnd": 207 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 213, "ColumnEnd": 237, "Name": { "Ident": { "Name": "f7", "QuoteType": 1, "NamePos": 213, "NameEnd": 215 }, "DotIdent": null }, "Type": { "Name": { "Name": "Datetime", "QuoteType": 1, "NamePos": 216, "NameEnd": 224 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 233, "NameEnd": 236 }, "Params": { "LeftParenPos": 236, "RightParenPos": 237, "Items": { "ListPos": 237, "ListEnd": 237, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 241, "EngineEnd": 411, "Name": "ReplicatedMergeTree", "Params": { "LeftParenPos": 269, "RightParenPos": 337, "Items": { "ListPos": 271, "ListEnd": 336, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 271, "LiteralEnd": 323, "Literal": "/clickhouse/tables/{layer}-{shard}/test/events_local" }, "Alias": null }, { "Expr": { "LiteralPos": 327, "LiteralEnd": 336, "Literal": "{replica}" }, "Alias": null } ] }, "ColumnArgList": null }, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 365, "Expr": { "ListPos": 378, "ListEnd": 391, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toYYYYMMDD", "QuoteType": 1, "NamePos": 378, "NameEnd": 388 }, "Params": { "LeftParenPos": 388, "RightParenPos": 391, "Items": { "ListPos": 389, "ListEnd": 391, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 389, "NameEnd": 391 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 339, "ListEnd": 364, "Items": [ { "TTLPos": 339, "Expr": { "LeftExpr": { "Name": "f3", "QuoteType": 1, "NamePos": 343, "NameEnd": 345 }, "Operation": "+", "RightExpr": { "IntervalPos": 348, "Expr": { "NumPos": 357, "NumEnd": 358, "Literal": "6", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 359, "NameEnd": 364 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": null, "OrderBy": { "OrderPos": 393, "ListEnd": 411, "Items": [ { "OrderPos": 393, "Expr": { "LeftParenPos": 402, "RightParenPos": 411, "Items": { "ListPos": 403, "ListEnd": 411, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 403, "NameEnd": 405 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 406, "NameEnd": 408 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 409, "NameEnd": 411 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/create_user.sql.golden.json ================================================ [ { "CreatePos": 28, "StatementEnd": 45, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user1", "QuoteType": 1, "NamePos": 40, "NameEnd": 45 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 47, "StatementEnd": 78, "IfNotExists": true, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user2", "QuoteType": 1, "NamePos": 73, "NameEnd": 78 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 80, "StatementEnd": 108, "IfNotExists": false, "OrReplace": true, "UserNames": [ { "Name": { "Name": "user3", "QuoteType": 1, "NamePos": 103, "NameEnd": 108 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 110, "StatementEnd": 134, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user4", "QuoteType": 1, "NamePos": 122, "NameEnd": 127 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "user5", "QuoteType": 1, "NamePos": 129, "NameEnd": 134 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 172, "StatementEnd": 205, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user6", "QuoteType": 1, "NamePos": 184, "NameEnd": 189 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 190, "AuthEnd": 205, "NotIdentified": true, "AuthType": "", "AuthValue": null, "LdapServer": null, "KerberosRealm": null, "IsKerberos": false }, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 206, "StatementEnd": 274, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user7", "QuoteType": 1, "NamePos": 218, "NameEnd": 223 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 224, "AuthEnd": 274, "NotIdentified": false, "AuthType": "plaintext_password", "AuthValue": { "LiteralPos": 263, "LiteralEnd": 274, "Literal": "password123" }, "LdapServer": null, "KerberosRealm": null, "IsKerberos": false }, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 277, "StatementEnd": 338, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user8", "QuoteType": 1, "NamePos": 289, "NameEnd": 294 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 295, "AuthEnd": 338, "NotIdentified": false, "AuthType": "sha256_password", "AuthValue": { "LiteralPos": 331, "LiteralEnd": 338, "Literal": "hash123" }, "LdapServer": null, "KerberosRealm": null, "IsKerberos": false }, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 341, "StatementEnd": 399, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user9", "QuoteType": 1, "NamePos": 353, "NameEnd": 358 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 359, "AuthEnd": 399, "NotIdentified": false, "AuthType": "", "AuthValue": null, "LdapServer": { "LiteralPos": 388, "LiteralEnd": 399, "Literal": "ldap_server" }, "KerberosRealm": null, "IsKerberos": false }, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 402, "StatementEnd": 446, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user10", "QuoteType": 1, "NamePos": 414, "NameEnd": 420 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 421, "AuthEnd": 446, "NotIdentified": false, "AuthType": "", "AuthValue": null, "LdapServer": null, "KerberosRealm": null, "IsKerberos": true }, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 447, "StatementEnd": 509, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user11", "QuoteType": 1, "NamePos": 459, "NameEnd": 465 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 466, "AuthEnd": 509, "NotIdentified": false, "AuthType": "", "AuthValue": null, "LdapServer": null, "KerberosRealm": { "LiteralPos": 498, "LiteralEnd": 509, "Literal": "EXAMPLE.COM" }, "IsKerberos": true }, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 545, "StatementEnd": 596, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user33", "QuoteType": 1, "NamePos": 557, "NameEnd": 563 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": { "LiteralPos": 577, "LiteralEnd": 596, "Literal": "2026-12-12 00:00:00" }, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 599, "StatementEnd": 693, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user34", "QuoteType": 1, "NamePos": 611, "NameEnd": 617 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 618, "AuthEnd": 668, "NotIdentified": false, "AuthType": "plaintext_password", "AuthValue": { "LiteralPos": 657, "LiteralEnd": 668, "Literal": "password123" }, "LdapServer": null, "KerberosRealm": null, "IsKerberos": false }, "ValidUntil": { "LiteralPos": 683, "LiteralEnd": 693, "Literal": "2026-06-15" }, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 696, "StatementEnd": 736, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user35", "QuoteType": 1, "NamePos": 708, "NameEnd": 714 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": { "LiteralPos": 728, "LiteralEnd": 736, "Literal": "infinity" }, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 778, "StatementEnd": 808, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user12", "QuoteType": 1, "NamePos": 790, "NameEnd": 796 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 797, "HostEnd": 808, "HostType": "LOCAL", "HostValue": null } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 809, "StatementEnd": 837, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user13", "QuoteType": 1, "NamePos": 821, "NameEnd": 827 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 828, "HostEnd": 837, "HostType": "ANY", "HostValue": null } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 838, "StatementEnd": 867, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user14", "QuoteType": 1, "NamePos": 850, "NameEnd": 856 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 857, "HostEnd": 867, "HostType": "NONE", "HostValue": null } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 868, "StatementEnd": 907, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user15", "QuoteType": 1, "NamePos": 880, "NameEnd": 886 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 887, "HostEnd": 907, "HostType": "NAME", "HostValue": { "LiteralPos": 898, "LiteralEnd": 907, "Literal": "localhost" } } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 910, "StatementEnd": 958, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user16", "QuoteType": 1, "NamePos": 922, "NameEnd": 928 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 929, "HostEnd": 958, "HostType": "REGEXP", "HostValue": { "LiteralPos": 942, "LiteralEnd": 958, "Literal": ".*\\.example\\.com" } } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 961, "StatementEnd": 1000, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user17", "QuoteType": 1, "NamePos": 973, "NameEnd": 979 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 980, "HostEnd": 1000, "HostType": "IP", "HostValue": { "LiteralPos": 989, "LiteralEnd": 1000, "Literal": "192.168.1.1" } } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 1003, "StatementEnd": 1038, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user18", "QuoteType": 1, "NamePos": 1015, "NameEnd": 1021 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": [ { "HostPos": 1022, "HostEnd": 1038, "HostType": "LIKE", "HostValue": { "LiteralPos": 1033, "LiteralEnd": 1038, "Literal": "test%" } } ], "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 1076, "StatementEnd": 1113, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user19", "QuoteType": 1, "NamePos": 1088, "NameEnd": 1094 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": { "DefaultPos": 1095, "DefaultEnd": 1113, "Roles": [ { "Name": { "Name": "role1", "QuoteType": 1, "NamePos": 1108, "NameEnd": 1113 }, "Scope": null, "OnCluster": null } ], "None": false }, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 1115, "StatementEnd": 1159, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user20", "QuoteType": 1, "NamePos": 1127, "NameEnd": 1133 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": { "DefaultPos": 1134, "DefaultEnd": 1159, "Roles": [ { "Name": { "Name": "role1", "QuoteType": 1, "NamePos": 1147, "NameEnd": 1152 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "role2", "QuoteType": 1, "NamePos": 1154, "NameEnd": 1159 }, "Scope": null, "OnCluster": null } ], "None": false }, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 1161, "StatementEnd": 1198, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user21", "QuoteType": 1, "NamePos": 1173, "NameEnd": 1179 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": { "DefaultPos": 1180, "DefaultEnd": 1198, "Roles": null, "None": true }, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 1237, "StatementEnd": 1280, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user22", "QuoteType": 1, "NamePos": 1249, "NameEnd": 1255 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": { "Name": "test_db", "QuoteType": 1, "NamePos": 1273, "NameEnd": 1280 }, "DefaultDbNone": false, "Grantees": null, "Settings": null }, { "CreatePos": 1282, "StatementEnd": 1323, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user23", "QuoteType": 1, "NamePos": 1294, "NameEnd": 1300 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": true, "Grantees": null, "Settings": null }, { "CreatePos": 1354, "StatementEnd": 1387, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user24", "QuoteType": 1, "NamePos": 1366, "NameEnd": 1372 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": { "GranteesPos": 1373, "GranteesEnd": 1387, "Grantees": [ { "Name": { "Name": "user1", "QuoteType": 1, "NamePos": 1382, "NameEnd": 1387 }, "Scope": null, "OnCluster": null } ], "ExceptUsers": null, "Any": false, "None": false }, "Settings": null }, { "CreatePos": 1389, "StatementEnd": 1429, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user25", "QuoteType": 1, "NamePos": 1401, "NameEnd": 1407 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": { "GranteesPos": 1408, "GranteesEnd": 1429, "Grantees": [ { "Name": { "Name": "user1", "QuoteType": 1, "NamePos": 1417, "NameEnd": 1422 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "user2", "QuoteType": 1, "NamePos": 1424, "NameEnd": 1429 }, "Scope": null, "OnCluster": null } ], "ExceptUsers": null, "Any": false, "None": false }, "Settings": null }, { "CreatePos": 1431, "StatementEnd": 1463, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user26", "QuoteType": 1, "NamePos": 1443, "NameEnd": 1449 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": { "GranteesPos": 1450, "GranteesEnd": 1463, "Grantees": null, "ExceptUsers": null, "Any": true, "None": false }, "Settings": null }, { "CreatePos": 1464, "StatementEnd": 1497, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user27", "QuoteType": 1, "NamePos": 1476, "NameEnd": 1482 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": { "GranteesPos": 1483, "GranteesEnd": 1497, "Grantees": null, "ExceptUsers": null, "Any": false, "None": true }, "Settings": null }, { "CreatePos": 1498, "StatementEnd": 1551, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user28", "QuoteType": 1, "NamePos": 1510, "NameEnd": 1516 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": { "GranteesPos": 1517, "GranteesEnd": 1551, "Grantees": [ { "Name": { "Name": "user1", "QuoteType": 1, "NamePos": 1526, "NameEnd": 1531 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "user2", "QuoteType": 1, "NamePos": 1533, "NameEnd": 1538 }, "Scope": null, "OnCluster": null } ], "ExceptUsers": [ { "Name": { "Name": "user3", "QuoteType": 1, "NamePos": 1546, "NameEnd": 1551 }, "Scope": null, "OnCluster": null } ], "Any": false, "None": false }, "Settings": null }, { "CreatePos": 1583, "StatementEnd": 1635, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user29", "QuoteType": 1, "NamePos": 1595, "NameEnd": 1601 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 1611, "NameEnd": 1627 }, "Operation": "=", "Value": { "NumPos": 1628, "NumEnd": 1635, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 1637, "StatementEnd": 1681, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user30", "QuoteType": 1, "NamePos": 1649, "NameEnd": 1655 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "PROFILE", "QuoteType": 1, "NamePos": 1665, "NameEnd": 1672 }, "Operation": "", "Value": { "LiteralPos": 1674, "LiteralEnd": 1681, "Literal": "default" } } ], "Modifier": null } ] }, { "CreatePos": 1684, "StatementEnd": 1748, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user31", "QuoteType": 1, "NamePos": 1696, "NameEnd": 1702 }, "Scope": null, "OnCluster": null } ], "Authentication": null, "ValidUntil": null, "Hosts": null, "DefaultRole": null, "DefaultDatabase": null, "DefaultDbNone": false, "Grantees": null, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "readonly", "QuoteType": 1, "NamePos": 1712, "NameEnd": 1720 }, "Operation": "=", "Value": { "NumPos": 1721, "NumEnd": 1722, "Literal": "1", "Base": 10 } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 1724, "NameEnd": 1740 }, "Operation": "=", "Value": { "NumPos": 1741, "NumEnd": 1748, "Literal": "5000000", "Base": 10 } } ], "Modifier": null } ] }, { "CreatePos": 1796, "StatementEnd": 2070, "IfNotExists": false, "OrReplace": false, "UserNames": [ { "Name": { "Name": "user32", "QuoteType": 1, "NamePos": 1808, "NameEnd": 1814 }, "Scope": null, "OnCluster": null } ], "Authentication": { "AuthPos": 1819, "AuthEnd": 1866, "NotIdentified": false, "AuthType": "plaintext_password", "AuthValue": { "LiteralPos": 1858, "LiteralEnd": 1866, "Literal": "password" }, "LdapServer": null, "KerberosRealm": null, "IsKerberos": false }, "ValidUntil": { "LiteralPos": 1885, "LiteralEnd": 1895, "Literal": "2025-12-31" }, "Hosts": [ { "HostPos": 1901, "HostEnd": 1921, "HostType": "NAME", "HostValue": { "LiteralPos": 1912, "LiteralEnd": 1921, "Literal": "localhost" } } ], "DefaultRole": { "DefaultPos": 1927, "DefaultEnd": 1952, "Roles": [ { "Name": { "Name": "role1", "QuoteType": 1, "NamePos": 1940, "NameEnd": 1945 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "role2", "QuoteType": 1, "NamePos": 1947, "NameEnd": 1952 }, "Scope": null, "OnCluster": null } ], "None": false }, "DefaultDatabase": { "Name": "test_db", "QuoteType": 1, "NamePos": 1974, "NameEnd": 1981 }, "DefaultDbNone": false, "Grantees": { "GranteesPos": 1986, "GranteesEnd": 2020, "Grantees": [ { "Name": { "Name": "user1", "QuoteType": 1, "NamePos": 1995, "NameEnd": 2000 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "user2", "QuoteType": 1, "NamePos": 2002, "NameEnd": 2007 }, "Scope": null, "OnCluster": null } ], "ExceptUsers": [ { "Name": { "Name": "user3", "QuoteType": 1, "NamePos": 2015, "NameEnd": 2020 }, "Scope": null, "OnCluster": null } ], "Any": false, "None": false }, "Settings": [ { "SettingPairs": [ { "Name": { "Name": "max_memory_usage", "QuoteType": 1, "NamePos": 2034, "NameEnd": 2050 }, "Operation": "=", "Value": { "NumPos": 2051, "NumEnd": 2058, "Literal": "5000000", "Base": 10 } } ], "Modifier": null }, { "SettingPairs": [ { "Name": { "Name": "readonly", "QuoteType": 1, "NamePos": 2060, "NameEnd": 2068 }, "Operation": "=", "Value": { "NumPos": 2069, "NumEnd": 2070, "Literal": "1", "Base": 10 } } ], "Modifier": null } ] } ] ================================================ FILE: parser/testdata/ddl/output/create_view_basic.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 104, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "my_view", "QuoteType": 1, "NamePos": 26, "NameEnd": 33 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 33, "SchemaEnd": 58, "Columns": [ { "NamePos": 34, "ColumnEnd": 45, "Name": { "Ident": { "Name": "col1", "QuoteType": 1, "NamePos": 34, "NameEnd": 38 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 39, "NameEnd": 45 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 47, "ColumnEnd": 58, "Name": { "Ident": { "Name": "col2", "QuoteType": 1, "NamePos": 47, "NameEnd": 51 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 52, "NameEnd": 58 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Comment": null, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 63, "StatementEnd": 104, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 74, "NameEnd": 76 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 82, "NameEnd": 86 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 87, "Expr": { "Table": { "TablePos": 96, "TableEnd": 104, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 96, "NameEnd": 104 } }, "HasFinal": false }, "StatementEnd": 104, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } } ] ================================================ FILE: parser/testdata/ddl/output/create_view_on_cluster_with_uuid.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 199, "OrReplace": false, "Name": { "Database": { "Name": "cluster_name", "QuoteType": 1, "NamePos": 26, "NameEnd": 38 }, "Table": { "Name": "my_view", "QuoteType": 1, "NamePos": 39, "NameEnd": 46 } }, "IfNotExists": true, "UUID": { "Value": { "LiteralPos": 61, "LiteralEnd": 97, "Literal": "3493e374-e2bb-481b-b493-e374e2bb981b" } }, "OnCluster": { "OnPos": 107, "Expr": { "LiteralPos": 119, "LiteralEnd": 129, "Literal": "my_cluster" } }, "TableSchema": null, "Comment": null, "SubQuery": { "HasParen": true, "Select": { "SelectPos": 140, "StatementEnd": 199, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "column1", "QuoteType": 1, "NamePos": 151, "NameEnd": 158 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "column2", "QuoteType": 1, "NamePos": 164, "NameEnd": 171 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 176, "Expr": { "Table": { "TablePos": 185, "TableEnd": 199, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "my_other_table", "QuoteType": 1, "NamePos": 185, "NameEnd": 199 } }, "HasFinal": false }, "StatementEnd": 199, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } } ] ================================================ FILE: parser/testdata/ddl/output/create_view_with_comment.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 156, "OrReplace": false, "Name": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 26, "NameEnd": 28 }, "Table": { "Name": "my_view", "QuoteType": 1, "NamePos": 29, "NameEnd": 36 } }, "IfNotExists": true, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 37, "SchemaEnd": 73, "Columns": [ { "NamePos": 44, "ColumnEnd": 53, "Name": { "Ident": { "Name": "id", "QuoteType": 3, "NamePos": 44, "NameEnd": 46 }, "DotIdent": null }, "Type": { "Name": { "Name": "Int64", "QuoteType": 1, "NamePos": 48, "NameEnd": 53 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 60, "ColumnEnd": 72, "Name": { "Ident": { "Name": "name", "QuoteType": 3, "NamePos": 60, "NameEnd": 64 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 66, "NameEnd": 72 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Comment": { "LiteralPos": 84, "LiteralEnd": 111, "Literal": "{\"blueprint_hash\":\"abc123\"}" }, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 116, "StatementEnd": 156, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 127, "NameEnd": 129 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 135, "NameEnd": 139 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 140, "Expr": { "Table": { "TablePos": 145, "TableEnd": 156, "Alias": null, "Expr": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 145, "NameEnd": 147 }, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 148, "NameEnd": 156 } }, "HasFinal": false }, "StatementEnd": 156, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } } ] ================================================ FILE: parser/testdata/ddl/output/create_with_time_zone.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 2003, "OrReplace": false, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 27, "NameEnd": 31 }, "Table": { "Name": "db", "QuoteType": 1, "NamePos": 32, "NameEnd": 34 } }, "IfNotExists": true, "UUID": null, "OnCluster": { "OnPos": 35, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 46, "NameEnd": 61 } }, "TableSchema": { "SchemaPos": 62, "SchemaEnd": 1756, "Columns": [ { "NamePos": 69, "ColumnEnd": 258, "Name": { "Ident": { "Name": "f0", "QuoteType": 3, "NamePos": 69, "NameEnd": 71 }, "DotIdent": null }, "Type": { "LeftParenPos": 79, "RightParenPos": 237, "Name": { "Name": "Array", "QuoteType": 1, "NamePos": 73, "NameEnd": 78 }, "Params": [ { "LeftParenPos": 94, "RightParenPos": 236, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 79, "NameEnd": 84 }, "Columns": [ { "NamePos": 94, "ColumnEnd": 117, "Name": { "Ident": { "Name": "f00", "QuoteType": 1, "NamePos": 94, "NameEnd": 97 }, "DotIdent": null }, "Type": { "LeftParenPos": 109, "RightParenPos": 117, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 98, "NameEnd": 108 }, "Params": [ { "NumPos": 109, "NumEnd": 110, "Literal": "9", "Base": 10 }, { "LiteralPos": 113, "LiteralEnd": 116, "Literal": "UTC" } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 128, "ColumnEnd": 138, "Name": { "Ident": { "Name": "f01", "QuoteType": 1, "NamePos": 128, "NameEnd": 131 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 132, "NameEnd": 138 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 148, "ColumnEnd": 170, "Name": { "Ident": { "Name": "f02", "QuoteType": 1, "NamePos": 148, "NameEnd": 151 }, "DotIdent": null }, "Type": { "LeftParenPos": 156, "RightParenPos": 170, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 152, "NameEnd": 155 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 156, "NameEnd": 162 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 164, "NameEnd": 170 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 181, "ColumnEnd": 204, "Name": { "Ident": { "Name": "f03", "QuoteType": 1, "NamePos": 181, "NameEnd": 184 }, "DotIdent": null }, "Type": { "LeftParenPos": 189, "RightParenPos": 204, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 185, "NameEnd": 188 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 189, "NameEnd": 195 } }, { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 197, "NameEnd": 204 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 215, "ColumnEnd": 235, "Name": { "Ident": { "Name": "f04", "QuoteType": 1, "NamePos": 215, "NameEnd": 218 }, "DotIdent": null }, "Type": { "LeftParenPos": 223, "RightParenPos": 235, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 219, "NameEnd": 222 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 223, "NameEnd": 229 } }, { "Name": { "Name": "BOOL", "QuoteType": 1, "NamePos": 231, "NameEnd": 235 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 239, "RightParenPos": 258, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 245, "NameEnd": 249 }, "Level": { "NumPos": 249, "NumEnd": 251, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 265, "ColumnEnd": 296, "Name": { "Ident": { "Name": "f1", "QuoteType": 3, "NamePos": 265, "NameEnd": 267 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 269, "NameEnd": 275 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 276, "RightParenPos": 296, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 282, "NameEnd": 287 }, "TypeLevel": { "NumPos": 287, "NumEnd": 289, "Literal": "8", "Base": 10 }, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 292, "NameEnd": 295 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 303, "ColumnEnd": 333, "Name": { "Ident": { "Name": "f2", "QuoteType": 3, "NamePos": 303, "NameEnd": 305 }, "DotIdent": null }, "Type": { "LeftParenPos": 319, "RightParenPos": 321, "Name": { "Name": "FixedString", "QuoteType": 1, "NamePos": 307, "NameEnd": 318 }, "Params": [ { "NumPos": 319, "NumEnd": 321, "Literal": "16", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 323, "RightParenPos": 333, "Type": null, "TypeLevel": null, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 329, "NameEnd": 332 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 340, "ColumnEnd": 369, "Name": { "Ident": { "Name": "f3", "QuoteType": 3, "NamePos": 340, "NameEnd": 342 }, "DotIdent": null }, "Type": { "LeftParenPos": 356, "RightParenPos": 357, "Name": { "Name": "FixedString", "QuoteType": 1, "NamePos": 344, "NameEnd": 355 }, "Params": [ { "NumPos": 356, "NumEnd": 357, "Literal": "8", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 359, "RightParenPos": 369, "Type": null, "TypeLevel": null, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 365, "NameEnd": 368 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 376, "ColumnEnd": 405, "Name": { "Ident": { "Name": "f4", "QuoteType": 3, "NamePos": 376, "NameEnd": 378 }, "DotIdent": null }, "Type": { "LeftParenPos": 392, "RightParenPos": 393, "Name": { "Name": "FixedString", "QuoteType": 1, "NamePos": 380, "NameEnd": 391 }, "Params": [ { "NumPos": 392, "NumEnd": 393, "Literal": "8", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 395, "RightParenPos": 405, "Type": null, "TypeLevel": null, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 401, "NameEnd": 404 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 412, "ColumnEnd": 457, "Name": { "Ident": { "Name": "f6", "QuoteType": 3, "NamePos": 412, "NameEnd": 414 }, "DotIdent": null }, "Type": { "LeftParenPos": 427, "RightParenPos": 435, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 416, "NameEnd": 426 }, "Params": [ { "NumPos": 427, "NumEnd": 428, "Literal": "9", "Base": 10 }, { "LiteralPos": 431, "LiteralEnd": 434, "Literal": "UTC" } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 437, "RightParenPos": 457, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 443, "NameEnd": 448 }, "TypeLevel": { "NumPos": 448, "NumEnd": 450, "Literal": "8", "Base": 10 }, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 453, "NameEnd": 456 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 464, "ColumnEnd": 495, "Name": { "Ident": { "Name": "f6", "QuoteType": 3, "NamePos": 464, "NameEnd": 466 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt64", "QuoteType": 1, "NamePos": 468, "NameEnd": 474 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 475, "RightParenPos": 495, "Type": { "Name": "Delta", "QuoteType": 1, "NamePos": 481, "NameEnd": 486 }, "TypeLevel": { "NumPos": 486, "NumEnd": 488, "Literal": "8", "Base": 10 }, "Name": { "Name": "LZ4", "QuoteType": 1, "NamePos": 491, "NameEnd": 494 }, "Level": null }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 502, "ColumnEnd": 543, "Name": { "Ident": { "Name": "f7", "QuoteType": 3, "NamePos": 502, "NameEnd": 504 }, "DotIdent": null }, "Type": { "LeftParenPos": 521, "RightParenPos": 527, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 506, "NameEnd": 520 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 521, "NameEnd": 527 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 529, "RightParenPos": 543, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 535, "NameEnd": 539 }, "Level": { "NumPos": 539, "NumEnd": 541, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 550, "ColumnEnd": 575, "Name": { "Ident": { "Name": "f8", "QuoteType": 3, "NamePos": 550, "NameEnd": 552 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 554, "NameEnd": 560 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 561, "RightParenPos": 575, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 567, "NameEnd": 571 }, "Level": { "NumPos": 571, "NumEnd": 573, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 582, "ColumnEnd": 623, "Name": { "Ident": { "Name": "f9", "QuoteType": 3, "NamePos": 582, "NameEnd": 584 }, "DotIdent": null }, "Type": { "LeftParenPos": 601, "RightParenPos": 607, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 586, "NameEnd": 600 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 601, "NameEnd": 607 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 609, "RightParenPos": 623, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 615, "NameEnd": 619 }, "Level": { "NumPos": 619, "NumEnd": 621, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 630, "ColumnEnd": 656, "Name": { "Ident": { "Name": "f10", "QuoteType": 3, "NamePos": 630, "NameEnd": 633 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 635, "NameEnd": 641 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 642, "RightParenPos": 656, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 648, "NameEnd": 652 }, "Level": { "NumPos": 652, "NumEnd": 654, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 663, "ColumnEnd": 705, "Name": { "Ident": { "Name": "f11", "QuoteType": 3, "NamePos": 663, "NameEnd": 666 }, "DotIdent": null }, "Type": { "LeftParenPos": 683, "RightParenPos": 689, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 668, "NameEnd": 682 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 683, "NameEnd": 689 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 691, "RightParenPos": 705, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 697, "NameEnd": 701 }, "Level": { "NumPos": 701, "NumEnd": 703, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 712, "ColumnEnd": 754, "Name": { "Ident": { "Name": "f12", "QuoteType": 3, "NamePos": 712, "NameEnd": 715 }, "DotIdent": null }, "Type": { "LeftParenPos": 732, "RightParenPos": 738, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 717, "NameEnd": 731 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 732, "NameEnd": 738 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 740, "RightParenPos": 754, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 746, "NameEnd": 750 }, "Level": { "NumPos": 750, "NumEnd": 752, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 761, "ColumnEnd": 787, "Name": { "Ident": { "Name": "f13", "QuoteType": 3, "NamePos": 761, "NameEnd": 764 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 766, "NameEnd": 772 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 773, "RightParenPos": 787, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 779, "NameEnd": 783 }, "Level": { "NumPos": 783, "NumEnd": 785, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 794, "ColumnEnd": 849, "Name": { "Ident": { "Name": "f14", "QuoteType": 3, "NamePos": 794, "NameEnd": 797 }, "DotIdent": null }, "Type": { "LeftParenPos": 803, "RightParenPos": 833, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 799, "NameEnd": 802 }, "Params": [ { "LeftParenPos": 818, "RightParenPos": 824, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 803, "NameEnd": 817 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 818, "NameEnd": 824 } } ] }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 827, "NameEnd": 833 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 835, "RightParenPos": 849, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 841, "NameEnd": 845 }, "Level": { "NumPos": 845, "NumEnd": 847, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 856, "ColumnEnd": 911, "Name": { "Ident": { "Name": "f15", "QuoteType": 3, "NamePos": 856, "NameEnd": 859 }, "DotIdent": null }, "Type": { "LeftParenPos": 865, "RightParenPos": 895, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 861, "NameEnd": 864 }, "Params": [ { "LeftParenPos": 880, "RightParenPos": 886, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 865, "NameEnd": 879 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 880, "NameEnd": 886 } } ] }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 889, "NameEnd": 895 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 897, "RightParenPos": 911, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 903, "NameEnd": 907 }, "Level": { "NumPos": 907, "NumEnd": 909, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 918, "ColumnEnd": 974, "Name": { "Ident": { "Name": "f16", "QuoteType": 3, "NamePos": 918, "NameEnd": 921 }, "DotIdent": null }, "Type": { "LeftParenPos": 927, "RightParenPos": 958, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 923, "NameEnd": 926 }, "Params": [ { "LeftParenPos": 942, "RightParenPos": 948, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 927, "NameEnd": 941 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 942, "NameEnd": 948 } } ] }, { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 951, "NameEnd": 958 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 960, "RightParenPos": 974, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 966, "NameEnd": 970 }, "Level": { "NumPos": 970, "NumEnd": 972, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 981, "ColumnEnd": 1034, "Name": { "Ident": { "Name": "f17", "QuoteType": 3, "NamePos": 981, "NameEnd": 984 }, "DotIdent": null }, "Type": { "LeftParenPos": 990, "RightParenPos": 1018, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 986, "NameEnd": 989 }, "Params": [ { "LeftParenPos": 1005, "RightParenPos": 1011, "Name": { "Name": "LowCardinality", "QuoteType": 1, "NamePos": 990, "NameEnd": 1004 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1005, "NameEnd": 1011 } } ] }, { "Name": { "Name": "BOOL", "QuoteType": 1, "NamePos": 1014, "NameEnd": 1018 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 1020, "RightParenPos": 1034, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 1026, "NameEnd": 1030 }, "Level": { "NumPos": 1030, "NumEnd": 1032, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1041, "ColumnEnd": 1188, "Name": { "Ident": { "Name": "f18", "QuoteType": 3, "NamePos": 1041, "NameEnd": 1044 }, "DotIdent": null }, "Type": { "LeftParenPos": 1052, "RightParenPos": 1172, "Name": { "Name": "Array", "QuoteType": 1, "NamePos": 1046, "NameEnd": 1051 }, "Params": [ { "LeftParenPos": 1067, "RightParenPos": 1171, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 1052, "NameEnd": 1057 }, "Columns": [ { "NamePos": 1067, "ColumnEnd": 1086, "Name": { "Ident": { "Name": "f180", "QuoteType": 1, "NamePos": 1067, "NameEnd": 1071 }, "DotIdent": null }, "Type": { "LeftParenPos": 1084, "RightParenPos": 1086, "Name": { "Name": "FixedString", "QuoteType": 1, "NamePos": 1072, "NameEnd": 1083 }, "Params": [ { "NumPos": 1084, "NumEnd": 1086, "Literal": "16", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1097, "ColumnEnd": 1115, "Name": { "Ident": { "Name": "f181", "QuoteType": 1, "NamePos": 1097, "NameEnd": 1101 }, "DotIdent": null }, "Type": { "LeftParenPos": 1114, "RightParenPos": 1115, "Name": { "Name": "FixedString", "QuoteType": 1, "NamePos": 1102, "NameEnd": 1113 }, "Params": [ { "NumPos": 1114, "NumEnd": 1115, "Literal": "8", "Base": 10 } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1126, "ColumnEnd": 1137, "Name": { "Ident": { "Name": "f182", "QuoteType": 1, "NamePos": 1126, "NameEnd": 1130 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1131, "NameEnd": 1137 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1147, "ColumnEnd": 1170, "Name": { "Ident": { "Name": "f183", "QuoteType": 1, "NamePos": 1147, "NameEnd": 1151 }, "DotIdent": null }, "Type": { "LeftParenPos": 1156, "RightParenPos": 1170, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 1152, "NameEnd": 1155 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1156, "NameEnd": 1162 } }, { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1164, "NameEnd": 1170 } } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] } ] }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 1174, "RightParenPos": 1188, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 1180, "NameEnd": 1184 }, "Level": { "NumPos": 1184, "NumEnd": 1186, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1199, "ColumnEnd": 1226, "Name": { "Ident": { "Name": "f184", "QuoteType": 3, "NamePos": 1199, "NameEnd": 1203 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1205, "NameEnd": 1211 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 1212, "RightParenPos": 1226, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 1218, "NameEnd": 1222 }, "Level": { "NumPos": 1222, "NumEnd": 1224, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1237, "ColumnEnd": 1264, "Name": { "Ident": { "Name": "f185", "QuoteType": 3, "NamePos": 1237, "NameEnd": 1241 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1243, "NameEnd": 1249 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 1250, "RightParenPos": 1264, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 1256, "NameEnd": 1260 }, "Level": { "NumPos": 1260, "NumEnd": 1262, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1275, "ColumnEnd": 1302, "Name": { "Ident": { "Name": "f186", "QuoteType": 3, "NamePos": 1275, "NameEnd": 1279 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 1281, "NameEnd": 1287 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 1288, "RightParenPos": 1302, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 1294, "NameEnd": 1298 }, "Level": { "NumPos": 1298, "NumEnd": 1300, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1313, "ColumnEnd": 1340, "Name": { "Ident": { "Name": "f187", "QuoteType": 3, "NamePos": 1313, "NameEnd": 1317 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 1319, "NameEnd": 1325 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": { "CodecPos": 1326, "RightParenPos": 1340, "Type": null, "TypeLevel": null, "Name": { "Name": "ZSTD", "QuoteType": 1, "NamePos": 1332, "NameEnd": 1336 }, "Level": { "NumPos": 1336, "NumEnd": 1338, "Literal": "1", "Base": 10 } }, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 1351, "ColumnEnd": 1378, "Name": { "Ident": { "Name": "f188", "QuoteType": 3, "NamePos": 1351, "NameEnd": 1355 }, "DotIdent": null }, "Type": { "Name": { "Name": "DATETIME", "QuoteType": 1, "NamePos": 1357, "NameEnd": 1365 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 1374, "NameEnd": 1377 }, "Params": { "LeftParenPos": 1377, "RightParenPos": 1378, "Items": { "ListPos": 1378, "ListEnd": 1378, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "IndexPos": 1389, "Name": { "Ident": { "Name": "idx_0", "QuoteType": 1, "NamePos": 1395, "NameEnd": 1400 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 1401, "NameEnd": 1403 }, "Alias": null }, "ColumnType": { "LeftParenPos": 1422, "RightParenPos": 1427, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 1409, "NameEnd": 1421 }, "Params": [ { "NumPos": 1422, "NumEnd": 1427, "Literal": "0.001", "Base": 10 } ] }, "Granularity": { "NumPos": 1441, "NumEnd": 1442, "Literal": "1", "Base": 10 } }, { "IndexPos": 1452, "Name": { "Ident": { "Name": "idx_f1", "QuoteType": 1, "NamePos": 1458, "NameEnd": 1464 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 1465, "NameEnd": 1467 }, "Alias": null }, "ColumnType": { "LeftParenPos": 1486, "RightParenPos": 1491, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 1473, "NameEnd": 1485 }, "Params": [ { "NumPos": 1486, "NumEnd": 1491, "Literal": "0.001", "Base": 10 } ] }, "Granularity": { "NumPos": 1505, "NumEnd": 1506, "Literal": "1", "Base": 10 } }, { "IndexPos": 1516, "Name": { "Ident": { "Name": "idx_f2", "QuoteType": 1, "NamePos": 1522, "NameEnd": 1528 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 1529, "NameEnd": 1531 }, "Alias": null }, "ColumnType": { "Name": { "Name": "minmax", "QuoteType": 1, "NamePos": 1537, "NameEnd": 1543 } }, "Granularity": { "NumPos": 1556, "NumEnd": 1557, "Literal": "1", "Base": 10 } }, { "IndexPos": 1567, "Name": { "Ident": { "Name": "idx_f3", "QuoteType": 1, "NamePos": 1573, "NameEnd": 1579 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 1580, "NameEnd": 1582 }, "Alias": null }, "ColumnType": { "LeftParenPos": 1592, "RightParenPos": 1593, "Name": { "Name": "set", "QuoteType": 1, "NamePos": 1588, "NameEnd": 1591 }, "Params": [ { "NumPos": 1592, "NumEnd": 1593, "Literal": "0", "Base": 10 } ] }, "Granularity": { "NumPos": 1607, "NumEnd": 1608, "Literal": "4", "Base": 10 } }, { "IndexPos": 1618, "Name": { "Ident": { "Name": "idx_f4", "QuoteType": 1, "NamePos": 1624, "NameEnd": 1630 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": { "Name": "mapValues", "QuoteType": 1, "NamePos": 1631, "NameEnd": 1640 }, "Params": { "LeftParenPos": 1640, "RightParenPos": 1643, "Items": { "ListPos": 1641, "ListEnd": 1643, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f4", "QuoteType": 1, "NamePos": 1641, "NameEnd": 1643 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null }, "ColumnType": { "LeftParenPos": 1663, "RightParenPos": 1667, "Name": { "Name": "bloom_filter", "QuoteType": 1, "NamePos": 1650, "NameEnd": 1662 }, "Params": [ { "NumPos": 1663, "NumEnd": 1667, "Literal": "0.01", "Base": 10 } ] }, "Granularity": { "NumPos": 1681, "NumEnd": 1682, "Literal": "1", "Base": 10 } }, { "IndexPos": 1692, "Name": { "Ident": { "Name": "idx_f5", "QuoteType": 1, "NamePos": 1698, "NameEnd": 1704 }, "DotIdent": null }, "ColumnExpr": { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 1705, "NameEnd": 1709 }, "Alias": null }, "ColumnType": { "LeftParenPos": 1726, "RightParenPos": 1736, "Name": { "Name": "tokenbf_v1", "QuoteType": 1, "NamePos": 1715, "NameEnd": 1725 }, "Params": [ { "NumPos": 1726, "NumEnd": 1730, "Literal": "4096", "Base": 10 }, { "NumPos": 1732, "NumEnd": 1733, "Literal": "3", "Base": 10 }, { "NumPos": 1735, "NumEnd": 1736, "Literal": "0", "Base": 10 } ] }, "Granularity": { "NumPos": 1750, "NumEnd": 1751, "Literal": "4", "Base": 10 } } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 1762, "EngineEnd": 2003, "Name": "MergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": { "PartitionPos": 1785, "Expr": { "ListPos": 1798, "ListEnd": 1814, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 1798, "NameEnd": 1804 }, "Params": { "LeftParenPos": 1804, "RightParenPos": 1814, "Items": { "ListPos": 1805, "ListEnd": 1814, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 1805, "NameEnd": 1814 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "SampleBy": null, "TTL": { "TTLPos": 1899, "ListEnd": 1939, "Items": [ { "TTLPos": 1899, "Expr": { "LeftExpr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 1903, "NameEnd": 1909 }, "Params": { "LeftParenPos": 1909, "RightParenPos": 1919, "Items": { "ListPos": 1910, "ListEnd": 1919, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 1910, "NameEnd": 1919 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "Name": { "Name": "toIntervalDay", "QuoteType": 1, "NamePos": 1923, "NameEnd": 1936 }, "Params": { "LeftParenPos": 1936, "RightParenPos": 1939, "Items": { "ListPos": 1937, "ListEnd": 1939, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 1937, "NumEnd": 1939, "Literal": "15", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Settings": { "SettingsPos": 1945, "ListEnd": 2003, "Items": [ { "SettingsPos": 1954, "Name": { "Name": "index_granularity", "QuoteType": 1, "NamePos": 1954, "NameEnd": 1971 }, "Expr": { "NumPos": 1974, "NumEnd": 1978, "Literal": "8192", "Base": 10 } }, { "SettingsPos": 1980, "Name": { "Name": "ttl_only_drop_parts", "QuoteType": 1, "NamePos": 1980, "NameEnd": 1999 }, "Expr": { "NumPos": 2002, "NumEnd": 2003, "Literal": "1", "Base": 10 } } ] }, "OrderBy": { "OrderPos": 1820, "ListEnd": 1893, "Items": [ { "OrderPos": 1820, "Expr": { "LeftParenPos": 1829, "RightParenPos": 1893, "Items": { "ListPos": 1830, "ListEnd": 1892, "HasDistinct": false, "Items": [ { "Expr": { "Name": "ts_bucket", "QuoteType": 1, "NamePos": 1830, "NameEnd": 1839 }, "Alias": null }, { "Expr": { "Name": "service_name", "QuoteType": 1, "NamePos": 1841, "NameEnd": 1853 }, "Alias": null }, { "Expr": { "Name": "name", "QuoteType": 1, "NamePos": 1855, "NameEnd": 1859 }, "Alias": null }, { "Expr": { "Name": { "Name": "toUnixTimestamp64Nano", "QuoteType": 1, "NamePos": 1861, "NameEnd": 1882 }, "Params": { "LeftParenPos": 1882, "RightParenPos": 1892, "Items": { "ListPos": 1883, "ListEnd": 1892, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 1883, "NameEnd": 1892 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/ddl/output/desc_table_with_table_keyword.sql.golden.json ================================================ [ { "DescribePos": 0, "StatementEnd": 18, "DescribeType": "TABLE", "Target": { "Database": null, "Table": { "Name": "mytable", "QuoteType": 1, "NamePos": 11, "NameEnd": 18 } } } ] ================================================ FILE: parser/testdata/ddl/output/desc_table_without_table_keyword.sql.golden.json ================================================ [ { "DescribePos": 0, "StatementEnd": 12, "DescribeType": "", "Target": { "Database": null, "Table": { "Name": "mytable", "QuoteType": 1, "NamePos": 5, "NameEnd": 12 } } } ] ================================================ FILE: parser/testdata/ddl/output/describe_table_with_table_keyword.sql.golden.json ================================================ [ { "DescribePos": 0, "StatementEnd": 22, "DescribeType": "TABLE", "Target": { "Database": null, "Table": { "Name": "mytable", "QuoteType": 1, "NamePos": 15, "NameEnd": 22 } } } ] ================================================ FILE: parser/testdata/ddl/output/describe_table_without_table_keyword.sql.golden.json ================================================ [ { "DescribePos": 0, "StatementEnd": 16, "DescribeType": "", "Target": { "Database": null, "Table": { "Name": "mytable", "QuoteType": 1, "NamePos": 9, "NameEnd": 16 } } } ] ================================================ FILE: parser/testdata/ddl/output/drop_database.sql.golden.json ================================================ [ { "DropPos": 0, "StatementEnd": 36, "Name": { "Name": "datbase_name", "QuoteType": 1, "NamePos": 24, "NameEnd": 36 }, "IfExists": true, "OnCluster": null } ] ================================================ FILE: parser/testdata/ddl/output/drop_role.sql.golden.json ================================================ [ { "DropPos": 0, "Target": "ROLE", "StatementEnd": 108, "Names": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 20, "NameEnd": 28 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r2_01293", "QuoteType": 1, "NamePos": 30, "NameEnd": 38 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r3_01293", "QuoteType": 1, "NamePos": 40, "NameEnd": 48 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r4_01293", "QuoteType": 1, "NamePos": 50, "NameEnd": 58 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r5_01293", "QuoteType": 1, "NamePos": 60, "NameEnd": 68 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r6_01293", "QuoteType": 1, "NamePos": 70, "NameEnd": 78 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r7_01293", "QuoteType": 1, "NamePos": 80, "NameEnd": 88 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r8_01293", "QuoteType": 1, "NamePos": 90, "NameEnd": 98 }, "Scope": null, "OnCluster": null }, { "Name": { "Name": "r9_01293", "QuoteType": 1, "NamePos": 100, "NameEnd": 108 }, "Scope": null, "OnCluster": null } ], "IfExists": true, "Modifier": "", "From": null }, { "DropPos": 110, "Target": "ROLE", "StatementEnd": 146, "Names": [ { "Name": { "Name": "r2_01293_renamed", "QuoteType": 1, "NamePos": 130, "NameEnd": 146 }, "Scope": null, "OnCluster": null } ], "IfExists": true, "Modifier": "", "From": null }, { "DropPos": 148, "Target": "ROLE", "StatementEnd": 204, "Names": [ { "Name": { "Name": "r1_01293", "QuoteType": 1, "NamePos": 168, "NameEnd": 176 }, "Scope": { "LiteralPos": 178, "LiteralEnd": 179, "Literal": "%" }, "OnCluster": null }, { "Name": { "LiteralPos": 183, "LiteralEnd": 204, "Literal": "r2_01293@%.myhost.com" }, "Scope": null, "OnCluster": null } ], "IfExists": true, "Modifier": "", "From": null } ] ================================================ FILE: parser/testdata/ddl/output/drop_table_basic.sql.golden.json ================================================ [ { "DropPos": 0, "StatementEnd": 36, "DropTarget": "TABLE", "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 21, "NameEnd": 25 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 26, "NameEnd": 36 } }, "IfExists": true, "OnCluster": null, "IsTemporary": false, "Modifier": "" } ] ================================================ FILE: parser/testdata/ddl/output/drop_table_with_no_delay.sql.golden.json ================================================ [ { "DropPos": 0, "StatementEnd": 74, "DropTarget": "TABLE", "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 21, "NameEnd": 25 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 26, "NameEnd": 36 } }, "IfExists": true, "OnCluster": { "OnPos": 37, "Expr": { "LiteralPos": 49, "LiteralEnd": 64, "Literal": "default_cluster" } }, "IsTemporary": false, "Modifier": "NO DELAY" } ] ================================================ FILE: parser/testdata/ddl/output/drop_table_with_on_clsuter.sql.golden.json ================================================ [ { "DropPos": 0, "StatementEnd": 65, "DropTarget": "TABLE", "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 21, "NameEnd": 25 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 26, "NameEnd": 36 } }, "IfExists": true, "OnCluster": { "OnPos": 37, "Expr": { "LiteralPos": 49, "LiteralEnd": 64, "Literal": "default_cluster" } }, "IsTemporary": false, "Modifier": "" } ] ================================================ FILE: parser/testdata/ddl/output/grant_privilege.sql.golden.json ================================================ [ { "GrantPos": 0, "StatementEnd": 37, "OnCluster": null, "Privileges": [ { "PrivilegePos": 6, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 12, "RightParenPos": 16, "Items": { "ListPos": 13, "ListEnd": 16, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 13, "NameEnd": 14 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 15, "NameEnd": 16 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 21, "NameEnd": 23 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 24, "NameEnd": 29 } }, "To": [ { "Name": "john", "QuoteType": 1, "NamePos": 33, "NameEnd": 37 } ], "WithOptions": [] }, { "GrantPos": 39, "StatementEnd": 113, "OnCluster": null, "Privileges": [ { "PrivilegePos": 45, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 51, "RightParenPos": 55, "Items": { "ListPos": 52, "ListEnd": 55, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 52, "NameEnd": 53 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 54, "NameEnd": 55 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 60, "NameEnd": 62 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 63, "NameEnd": 68 } }, "To": [ { "Name": "john", "QuoteType": 1, "NamePos": 72, "NameEnd": 76 } ], "WithOptions": [ "GRANT", "ADMIN" ] }, { "GrantPos": 114, "StatementEnd": 147, "OnCluster": null, "Privileges": [ { "PrivilegePos": 120, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 126, "RightParenPos": 130, "Items": { "ListPos": 127, "ListEnd": 130, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 127, "NameEnd": 128 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 129, "NameEnd": 130 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 135, "NameEnd": 137 }, "Table": { "Name": "*", "QuoteType": 0, "NamePos": 138, "NameEnd": 139 } }, "To": [ { "Name": "john", "QuoteType": 1, "NamePos": 143, "NameEnd": 147 } ], "WithOptions": [] }, { "GrantPos": 149, "StatementEnd": 185, "OnCluster": null, "Privileges": [ { "PrivilegePos": 155, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 161, "RightParenPos": 165, "Items": { "ListPos": 162, "ListEnd": 165, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 162, "NameEnd": 163 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 164, "NameEnd": 165 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 170, "NameEnd": 171 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 172, "NameEnd": 177 } }, "To": [ { "Name": "john", "QuoteType": 1, "NamePos": 181, "NameEnd": 185 } ], "WithOptions": [] }, { "GrantPos": 187, "StatementEnd": 219, "OnCluster": null, "Privileges": [ { "PrivilegePos": 193, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 199, "RightParenPos": 203, "Items": { "ListPos": 200, "ListEnd": 203, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 200, "NameEnd": 201 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 202, "NameEnd": 203 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 208, "NameEnd": 209 }, "Table": { "Name": "*", "QuoteType": 0, "NamePos": 210, "NameEnd": 211 } }, "To": [ { "Name": "john", "QuoteType": 1, "NamePos": 215, "NameEnd": 219 } ], "WithOptions": [] }, { "GrantPos": 221, "StatementEnd": 265, "OnCluster": null, "Privileges": [ { "PrivilegePos": 227, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 233, "RightParenPos": 237, "Items": { "ListPos": 234, "ListEnd": 237, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 234, "NameEnd": 235 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 236, "NameEnd": 237 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 242, "NameEnd": 243 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 244, "NameEnd": 249 } }, "To": [ { "Name": "CURRENT_USER", "QuoteType": 1, "NamePos": 253, "NameEnd": 265 } ], "WithOptions": [] }, { "GrantPos": 267, "StatementEnd": 321, "OnCluster": null, "Privileges": [ { "PrivilegePos": 273, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 279, "RightParenPos": 283, "Items": { "ListPos": 280, "ListEnd": 283, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 280, "NameEnd": 281 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 282, "NameEnd": 283 }, "Alias": null } ] }, "ColumnArgList": null } } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 288, "NameEnd": 289 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 290, "NameEnd": 295 } }, "To": [ { "Name": "CURRENT_USER", "QuoteType": 1, "NamePos": 299, "NameEnd": 311 }, { "Name": "john", "QuoteType": 1, "NamePos": 312, "NameEnd": 316 }, { "Name": "mary", "QuoteType": 1, "NamePos": 317, "NameEnd": 321 } ], "WithOptions": [] }, { "GrantPos": 323, "StatementEnd": 372, "OnCluster": null, "Privileges": [ { "PrivilegePos": 329, "PrivilegeEnd": 0, "Keywords": [ "ALL" ], "Params": null } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 336, "NameEnd": 337 }, "Table": { "Name": "*", "QuoteType": 0, "NamePos": 338, "NameEnd": 339 } }, "To": [ { "Name": "admin_role", "QuoteType": 1, "NamePos": 343, "NameEnd": 353 } ], "WithOptions": [ "GRANT" ] }, { "GrantPos": 373, "StatementEnd": 435, "OnCluster": null, "Privileges": [ { "PrivilegePos": 379, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": null }, { "PrivilegePos": 386, "PrivilegeEnd": 0, "Keywords": [ "INSERT" ], "Params": null } ], "On": { "Database": { "Name": "database", "QuoteType": 1, "NamePos": 396, "NameEnd": 404 }, "Table": { "Name": "table_1", "QuoteType": 1, "NamePos": 405, "NameEnd": 412 } }, "To": [ { "Name": "table_1_select_role", "QuoteType": 1, "NamePos": 416, "NameEnd": 435 } ], "WithOptions": [] }, { "GrantPos": 437, "StatementEnd": 508, "OnCluster": null, "Privileges": [ { "PrivilegePos": 443, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": { "LeftParenPos": 449, "RightParenPos": 457, "Items": { "ListPos": 450, "ListEnd": 457, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 450, "NameEnd": 451 }, "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 453, "NameEnd": 454 }, "Alias": null }, { "Expr": { "Name": "z", "QuoteType": 1, "NamePos": 456, "NameEnd": 457 }, "Alias": null } ] }, "ColumnArgList": null } }, { "PrivilegePos": 459, "PrivilegeEnd": 0, "Keywords": [ "INSERT" ], "Params": null } ], "On": { "Database": { "Name": "database", "QuoteType": 1, "NamePos": 469, "NameEnd": 477 }, "Table": { "Name": "table_1", "QuoteType": 1, "NamePos": 478, "NameEnd": 485 } }, "To": [ { "Name": "table_1_select_role", "QuoteType": 1, "NamePos": 489, "NameEnd": 508 } ], "WithOptions": [] }, { "GrantPos": 510, "StatementEnd": 558, "OnCluster": null, "Privileges": [ { "PrivilegePos": 516, "PrivilegeEnd": 0, "Keywords": [ "SELECT" ], "Params": null }, { "PrivilegePos": 524, "PrivilegeEnd": 0, "Keywords": [ "dictGet" ], "Params": null } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 535, "NameEnd": 536 }, "Table": { "Name": "*", "QuoteType": 0, "NamePos": 537, "NameEnd": 538 } }, "To": [ { "Name": "select_all_role", "QuoteType": 1, "NamePos": 543, "NameEnd": 558 } ], "WithOptions": [] }, { "GrantPos": 560, "StatementEnd": 605, "OnCluster": null, "Privileges": [ { "PrivilegePos": 566, "PrivilegeEnd": 0, "Keywords": [ "ADMIN", "OPTION" ], "Params": null } ], "On": { "Database": { "Name": "*", "QuoteType": 0, "NamePos": 582, "NameEnd": 583 }, "Table": { "Name": "*", "QuoteType": 0, "NamePos": 584, "NameEnd": 585 } }, "To": [ { "Name": "select_all_role", "QuoteType": 1, "NamePos": 590, "NameEnd": 605 } ], "WithOptions": [] } ] ================================================ FILE: parser/testdata/ddl/output/optimize.sql.golden.json ================================================ [ { "OptimizePos": 0, "StatementEnd": 32, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 15, "NameEnd": 20 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 21, "By": null, "Except": null } }, { "OptimizePos": 49, "StatementEnd": 85, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 64, "NameEnd": 69 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 70, "By": { "ListPos": 85, "ListEnd": 85, "HasDistinct": false, "Items": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 85, "NameEnd": 85 }, "Alias": null } ] }, "Except": null } }, { "OptimizePos": 131, "StatementEnd": 181, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 146, "NameEnd": 151 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 152, "By": { "ListPos": 167, "ListEnd": 181, "HasDistinct": false, "Items": [ { "Expr": { "Name": "colX", "QuoteType": 1, "NamePos": 167, "NameEnd": 171 }, "Alias": null }, { "Expr": { "Name": "colY", "QuoteType": 1, "NamePos": 172, "NameEnd": 176 }, "Alias": null }, { "Expr": { "Name": "colZ", "QuoteType": 1, "NamePos": 177, "NameEnd": 181 }, "Alias": null } ] }, "Except": null } }, { "OptimizePos": 183, "StatementEnd": 219, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 198, "NameEnd": 203 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 204, "By": { "ListPos": 219, "ListEnd": 219, "HasDistinct": false, "Items": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 219, "NameEnd": 219 }, "Alias": null } ] }, "Except": { "ListPos": 228, "ListEnd": 232, "HasDistinct": false, "Items": [ { "Expr": { "Name": "colX", "QuoteType": 1, "NamePos": 228, "NameEnd": 232 }, "Alias": null } ] } } }, { "OptimizePos": 234, "StatementEnd": 270, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 249, "NameEnd": 254 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 255, "By": { "ListPos": 270, "ListEnd": 270, "HasDistinct": false, "Items": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 270, "NameEnd": 270 }, "Alias": null } ] }, "Except": { "ListPos": 279, "ListEnd": 290, "HasDistinct": false, "Items": [ { "Expr": { "LeftParenPos": 279, "RightParenPos": 290, "Items": { "ListPos": 280, "ListEnd": 290, "HasDistinct": false, "Items": [ { "Expr": { "Name": "colX", "QuoteType": 1, "NamePos": 280, "NameEnd": 284 }, "Alias": null }, { "Expr": { "Name": "colY", "QuoteType": 1, "NamePos": 286, "NameEnd": 290 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null } ] } } }, { "OptimizePos": 293, "StatementEnd": 362, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 308, "NameEnd": 313 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 314, "By": { "ListPos": 329, "ListEnd": 362, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "COLUMNS", "QuoteType": 1, "NamePos": 329, "NameEnd": 336 }, "Params": { "LeftParenPos": 336, "RightParenPos": 362, "Items": { "ListPos": 338, "ListEnd": 361, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 338, "LiteralEnd": 361, "Literal": "column-matched-by-regex" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] }, "Except": null } }, { "OptimizePos": 365, "StatementEnd": 434, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 380, "NameEnd": 385 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 386, "By": { "ListPos": 401, "ListEnd": 434, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "COLUMNS", "QuoteType": 1, "NamePos": 401, "NameEnd": 408 }, "Params": { "LeftParenPos": 408, "RightParenPos": 434, "Items": { "ListPos": 410, "ListEnd": 433, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 410, "LiteralEnd": 433, "Literal": "column-matched-by-regex" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] }, "Except": { "ListPos": 443, "ListEnd": 447, "HasDistinct": false, "Items": [ { "Expr": { "Name": "colX", "QuoteType": 1, "NamePos": 443, "NameEnd": 447 }, "Alias": null } ] } } }, { "OptimizePos": 449, "StatementEnd": 518, "Table": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 464, "NameEnd": 469 } }, "OnCluster": null, "Partition": null, "HasFinal": false, "Deduplicate": { "DeduplicatePos": 470, "By": { "ListPos": 485, "ListEnd": 518, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "COLUMNS", "QuoteType": 1, "NamePos": 485, "NameEnd": 492 }, "Params": { "LeftParenPos": 492, "RightParenPos": 518, "Items": { "ListPos": 494, "ListEnd": 517, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 494, "LiteralEnd": 517, "Literal": "column-matched-by-regex" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] }, "Except": { "ListPos": 527, "ListEnd": 538, "HasDistinct": false, "Items": [ { "Expr": { "LeftParenPos": 527, "RightParenPos": 538, "Items": { "ListPos": 528, "ListEnd": 538, "HasDistinct": false, "Items": [ { "Expr": { "Name": "colX", "QuoteType": 1, "NamePos": 528, "NameEnd": 532 }, "Alias": null }, { "Expr": { "Name": "colY", "QuoteType": 1, "NamePos": 534, "NameEnd": 538 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null } ] } } } ] ================================================ FILE: parser/testdata/ddl/output/rename.sql.golden.json ================================================ [ { "RenamePos": 16, "StatementEnd": 38, "RenameTarget": "TABLE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 29, "NameEnd": 31 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 35, "NameEnd": 38 } } } ], "OnCluster": null }, { "RenamePos": 40, "StatementEnd": 90, "RenameTarget": "TABLE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 53, "NameEnd": 55 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 59, "NameEnd": 62 } } } ], "OnCluster": { "OnPos": 63, "Expr": { "LiteralPos": 75, "LiteralEnd": 90, "Literal": "default_cluster" } } }, { "RenamePos": 93, "StatementEnd": 126, "RenameTarget": "TABLE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 106, "NameEnd": 108 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 112, "NameEnd": 115 } } }, { "Old": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 117, "NameEnd": 119 } }, "New": { "Database": null, "Table": { "Name": "t22", "QuoteType": 1, "NamePos": 123, "NameEnd": 126 } } } ], "OnCluster": null }, { "RenamePos": 128, "StatementEnd": 189, "RenameTarget": "TABLE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 141, "NameEnd": 143 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 147, "NameEnd": 150 } } }, { "Old": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 152, "NameEnd": 154 } }, "New": { "Database": null, "Table": { "Name": "t22", "QuoteType": 1, "NamePos": 158, "NameEnd": 161 } } } ], "OnCluster": { "OnPos": 162, "Expr": { "LiteralPos": 174, "LiteralEnd": 189, "Literal": "default_cluster" } } }, { "RenamePos": 216, "StatementEnd": 243, "RenameTarget": "DICTIONARY", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 234, "NameEnd": 236 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 240, "NameEnd": 243 } } } ], "OnCluster": null }, { "RenamePos": 245, "StatementEnd": 300, "RenameTarget": "DICTIONARY", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 263, "NameEnd": 265 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 269, "NameEnd": 272 } } } ], "OnCluster": { "OnPos": 273, "Expr": { "LiteralPos": 285, "LiteralEnd": 300, "Literal": "default_cluster" } } }, { "RenamePos": 303, "StatementEnd": 341, "RenameTarget": "DICTIONARY", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 321, "NameEnd": 323 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 327, "NameEnd": 330 } } }, { "Old": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 332, "NameEnd": 334 } }, "New": { "Database": null, "Table": { "Name": "t22", "QuoteType": 1, "NamePos": 338, "NameEnd": 341 } } } ], "OnCluster": null }, { "RenamePos": 343, "StatementEnd": 409, "RenameTarget": "DICTIONARY", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 361, "NameEnd": 363 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 367, "NameEnd": 370 } } }, { "Old": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 372, "NameEnd": 374 } }, "New": { "Database": null, "Table": { "Name": "t22", "QuoteType": 1, "NamePos": 378, "NameEnd": 381 } } } ], "OnCluster": { "OnPos": 382, "Expr": { "LiteralPos": 394, "LiteralEnd": 409, "Literal": "default_cluster" } } }, { "RenamePos": 431, "StatementEnd": 456, "RenameTarget": "DATABASE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 447, "NameEnd": 449 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 453, "NameEnd": 456 } } } ], "OnCluster": null }, { "RenamePos": 458, "StatementEnd": 511, "RenameTarget": "DATABASE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 474, "NameEnd": 476 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 480, "NameEnd": 483 } } } ], "OnCluster": { "OnPos": 484, "Expr": { "LiteralPos": 496, "LiteralEnd": 511, "Literal": "default_cluster" } } }, { "RenamePos": 514, "StatementEnd": 550, "RenameTarget": "DATABASE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 530, "NameEnd": 532 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 536, "NameEnd": 539 } } }, { "Old": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 541, "NameEnd": 543 } }, "New": { "Database": null, "Table": { "Name": "t22", "QuoteType": 1, "NamePos": 547, "NameEnd": 550 } } } ], "OnCluster": null }, { "RenamePos": 552, "StatementEnd": 616, "RenameTarget": "DATABASE", "TargetPairList": [ { "Old": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 568, "NameEnd": 570 } }, "New": { "Database": null, "Table": { "Name": "t11", "QuoteType": 1, "NamePos": 574, "NameEnd": 577 } } }, { "Old": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 579, "NameEnd": 581 } }, "New": { "Database": null, "Table": { "Name": "t22", "QuoteType": 1, "NamePos": 585, "NameEnd": 588 } } } ], "OnCluster": { "OnPos": 589, "Expr": { "LiteralPos": 601, "LiteralEnd": 616, "Literal": "default_cluster" } } } ] ================================================ FILE: parser/testdata/ddl/output/show_create_table.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 26, "ShowType": "CREATE TABLE", "Target": { "Database": null, "Table": { "Name": "mytable", "QuoteType": 1, "NamePos": 18, "NameEnd": 25 } }, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 15, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_comprehensive.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 81, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "LIKE", "LikePattern": { "LiteralPos": 21, "LiteralEnd": 26, "Literal": "prod%" }, "Limit": { "NumPos": 34, "NumEnd": 35, "Literal": "5", "Base": 10 }, "OutFile": { "LiteralPos": 50, "LiteralEnd": 67, "Literal": "/tmp/prod_dbs.txt" }, "Format": { "LiteralPos": 76, "LiteralEnd": 80, "Literal": "JSON" } } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_format.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 27, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": null, "OutFile": null, "Format": { "LiteralPos": 22, "LiteralEnd": 26, "Literal": "JSON" } } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_format_string.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 37, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": null, "OutFile": null, "Format": { "LiteralPos": 23, "LiteralEnd": 35, "Literal": "TabSeparated" } } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_ilike.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 29, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "ILIKE", "LikePattern": { "LiteralPos": 22, "LiteralEnd": 27, "Literal": "Test%" }, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_like.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 28, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "LIKE", "LikePattern": { "LiteralPos": 21, "LiteralEnd": 26, "Literal": "test%" }, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_limit.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 24, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": { "NumPos": 21, "NumEnd": 23, "Literal": "10", "Base": 10 }, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_not_ilike.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 33, "ShowType": "DATABASES", "Target": null, "NotLike": true, "LikeType": "ILIKE", "LikePattern": { "LiteralPos": 26, "LiteralEnd": 31, "Literal": "Temp%" }, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_not_like.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 32, "ShowType": "DATABASES", "Target": null, "NotLike": true, "LikeType": "LIKE", "LikePattern": { "LiteralPos": 25, "LiteralEnd": 30, "Literal": "temp%" }, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_databases_outfile.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 49, "ShowType": "DATABASES", "Target": null, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": null, "OutFile": { "LiteralPos": 29, "LiteralEnd": 47, "Literal": "/tmp/databases.txt" }, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/show_tables.sql.golden.json ================================================ [ { "ShowPos": 0, "StatementEnd": 12, "ShowType": "TABLES", "Target": null, "NotLike": false, "LikeType": "", "LikePattern": null, "Limit": null, "OutFile": null, "Format": null } ] ================================================ FILE: parser/testdata/ddl/output/systems.sql.golden.json ================================================ [ { "SystemPos": 0, "Expr": { "FlushPos": 7, "StatementEnd": 17, "Logs": true, "Distributed": null } }, { "SystemPos": 19, "Expr": { "DropPos": 26, "StatementEnd": 49, "Type": "UNCOMPRESSED CACHE" } }, { "SystemPos": 51, "Expr": { "DropPos": 58, "StatementEnd": 79, "Type": "FILESYSTEM CACHE" } } ] ================================================ FILE: parser/testdata/ddl/output/truncate_table_basic.sql.golden.json ================================================ [ { "TruncatePos": 0, "StatementEnd": 40, "IsTemporary": false, "IfExists": true, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 25, "NameEnd": 29 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 30, "NameEnd": 40 } }, "OnCluster": null } ] ================================================ FILE: parser/testdata/ddl/output/truncate_temporary_table_on_clsuter.sql.golden.json ================================================ [ { "TruncatePos": 0, "StatementEnd": 78, "IsTemporary": true, "IfExists": true, "Name": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 35, "NameEnd": 39 }, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 40, "NameEnd": 50 } }, "OnCluster": { "OnPos": 51, "Expr": { "LiteralPos": 63, "LiteralEnd": 78, "Literal": "default_cluster" } } } ] ================================================ FILE: parser/testdata/ddl/rename.sql ================================================ -- rename table RENAME TABLE t1 TO t11; RENAME TABLE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME TABLE t1 TO t11, t2 TO t22; RENAME TABLE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- rename dictionary RENAME DICTIONARY t1 TO t11; RENAME DICTIONARY t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DICTIONARY t1 TO t11, t2 TO t22; RENAME DICTIONARY t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; -- rename database RENAME DATABASE t1 TO t11; RENAME DATABASE t1 TO t11 ON CLUSTER 'default_cluster'; RENAME DATABASE t1 TO t11, t2 TO t22; RENAME DATABASE t1 TO t11, t2 TO t22 ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/ddl/show_create_table.sql ================================================ SHOW CREATE TABLE mytable ================================================ FILE: parser/testdata/ddl/show_databases.sql ================================================ SHOW DATABASES ================================================ FILE: parser/testdata/ddl/show_databases_comprehensive.sql ================================================ SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON ================================================ FILE: parser/testdata/ddl/show_databases_format.sql ================================================ SHOW DATABASES FORMAT JSON ================================================ FILE: parser/testdata/ddl/show_databases_format_string.sql ================================================ SHOW DATABASES FORMAT 'TabSeparated' ================================================ FILE: parser/testdata/ddl/show_databases_ilike.sql ================================================ SHOW DATABASES ILIKE 'Test%' ================================================ FILE: parser/testdata/ddl/show_databases_like.sql ================================================ SHOW DATABASES LIKE 'test%' ================================================ FILE: parser/testdata/ddl/show_databases_limit.sql ================================================ SHOW DATABASES LIMIT 10 ================================================ FILE: parser/testdata/ddl/show_databases_not_ilike.sql ================================================ SHOW DATABASES NOT ILIKE 'Temp%' ================================================ FILE: parser/testdata/ddl/show_databases_not_like.sql ================================================ SHOW DATABASES NOT LIKE 'temp%' ================================================ FILE: parser/testdata/ddl/show_databases_outfile.sql ================================================ SHOW DATABASES INTO OUTFILE '/tmp/databases.txt' ================================================ FILE: parser/testdata/ddl/show_tables.sql ================================================ SHOW TABLES ================================================ FILE: parser/testdata/ddl/systems.sql ================================================ SYSTEM FLUSH LOGS; SYSTEM DROP UNCOMPRESSED CACHE; SYSTEM DROP FILESYSTEM CACHE; ================================================ FILE: parser/testdata/ddl/truncate_table_basic.sql ================================================ TRUNCATE TABLE IF EXISTS test.table_name; ================================================ FILE: parser/testdata/ddl/truncate_temporary_table_on_clsuter.sql ================================================ TRUNCATE TEMPORARY TABLE IF EXISTS test.table_name ON CLUSTER 'default_cluster'; ================================================ FILE: parser/testdata/dml/alter_table_modify_query.sql ================================================ ALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3; ================================================ FILE: parser/testdata/dml/alter_table_modify_ttl_multiple.sql ================================================ ALTER TABLE db.t0 ON CLUSTER default_cluster MODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY; ================================================ FILE: parser/testdata/dml/alter_table_with_comment.sql ================================================ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String default '' comment 'test' ; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String default ''; ================================================ FILE: parser/testdata/dml/alter_table_with_modify_remove_ttl.sql ================================================ ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; ================================================ FILE: parser/testdata/dml/alter_table_with_modify_ttl.sql ================================================ ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; ================================================ FILE: parser/testdata/dml/create_column_with_ttl.sql ================================================ CREATE TABLE example1 ( timestamp DateTime, x UInt32 TTL timestamp + INTERVAL 1 MONTH, y UInt32 TTL timestamp + INTERVAL 1 WEEK ) ENGINE = MergeTree ORDER BY tuple() ================================================ FILE: parser/testdata/dml/delete_from.sql ================================================ DELETE FROM hits WHERE Title LIKE '%hello%'; ================================================ FILE: parser/testdata/dml/format/alter_table_modify_query.sql ================================================ -- Origin SQL: ALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3; -- Format SQL: ALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3; ================================================ FILE: parser/testdata/dml/format/alter_table_modify_ttl_multiple.sql ================================================ -- Origin SQL: ALTER TABLE db.t0 ON CLUSTER default_cluster MODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY; -- Format SQL: ALTER TABLE db.t0 ON CLUSTER default_cluster MODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY; ================================================ FILE: parser/testdata/dml/format/alter_table_with_comment.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String default '' comment 'test' ; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String default ''; -- Format SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String DEFAULT '' COMMENT 'test'; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String DEFAULT ''; ================================================ FILE: parser/testdata/dml/format/alter_table_with_modify_remove_ttl.sql ================================================ -- Origin SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; -- Format SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; ================================================ FILE: parser/testdata/dml/format/alter_table_with_modify_ttl.sql ================================================ -- Origin SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; -- Format SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; ================================================ FILE: parser/testdata/dml/format/beautify/alter_table_modify_query.sql ================================================ -- Origin SQL: ALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3; -- Beautify SQL: ALTER TABLE test.some_mv ON CLUSTER cluster MODIFY QUERY SELECT field1, field2 FROM test.some_table WHERE count >= 3; ================================================ FILE: parser/testdata/dml/format/beautify/alter_table_modify_ttl_multiple.sql ================================================ -- Origin SQL: ALTER TABLE db.t0 ON CLUSTER default_cluster MODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY; -- Beautify SQL: ALTER TABLE db.t0 ON CLUSTER default_cluster MODIFY TTL toDateTime(timestamp / 1000000000) + INTERVAL 30 DAY TO DISK 'gcs', toDateTime(timestamp / 1000000000) + INTERVAL 60 DAY; ================================================ FILE: parser/testdata/dml/format/beautify/alter_table_with_comment.sql ================================================ -- Origin SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String default '' comment 'test' ; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String default ''; -- Beautify SQL: ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN a.f1 String DEFAULT '' COMMENT 'test'; ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD COLUMN hello String DEFAULT ''; ================================================ FILE: parser/testdata/dml/format/beautify/alter_table_with_modify_remove_ttl.sql ================================================ -- Origin SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; -- Beautify SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster REMOVE TTL; ================================================ FILE: parser/testdata/dml/format/beautify/alter_table_with_modify_ttl.sql ================================================ -- Origin SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; -- Beautify SQL: ALTER TABLE infra.flow_processed_emails_local ON CLUSTER default_cluster MODIFY TTL created_at + INTERVAL 3 YEAR; ================================================ FILE: parser/testdata/dml/format/beautify/create_column_with_ttl.sql ================================================ -- Origin SQL: CREATE TABLE example1 ( timestamp DateTime, x UInt32 TTL timestamp + INTERVAL 1 MONTH, y UInt32 TTL timestamp + INTERVAL 1 WEEK ) ENGINE = MergeTree ORDER BY tuple() -- Beautify SQL: CREATE TABLE example1 ( timestamp DateTime, x UInt32 TTL timestamp + INTERVAL 1 MONTH, y UInt32 TTL timestamp + INTERVAL 1 WEEK ) ENGINE = MergeTree ORDER BY tuple(); ================================================ FILE: parser/testdata/dml/format/beautify/delete_from.sql ================================================ -- Origin SQL: DELETE FROM hits WHERE Title LIKE '%hello%'; -- Beautify SQL: DELETE FROM hits WHERE Title LIKE '%hello%'; ================================================ FILE: parser/testdata/dml/format/beautify/insert_select_without_from.sql ================================================ -- Origin SQL: INSERT INTO t (c) SELECT 1 WHERE 1 = 1; -- Beautify SQL: INSERT INTO t (c) SELECT 1 WHERE 1 = 1; ================================================ FILE: parser/testdata/dml/format/beautify/insert_values.sql ================================================ -- Origin SQL: INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES (101, 'Hello, ClickHouse!', now(), -1.0 ), (102, 'Insert a lot of rows per batch', yesterday(), 1.41421 ), (102, 'Sort your data based on your commonly-used queries', today(), 2.718 ), (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159 ) -- Beautify SQL: INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES (101, 'Hello, ClickHouse!', now(), -1.0), (102, 'Insert a lot of rows per batch', yesterday(), 1.41421), (102, 'Sort your data based on your commonly-used queries', today(), 2.718), (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159); ================================================ FILE: parser/testdata/dml/format/beautify/insert_with_format.sql ================================================ -- Origin SQL: INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`; INSERT INTO "db"."table_name" (col1, col2) VALUES (1, 2); INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2); INSERT INTO table_name (col1, col2) VALUES (1, 2) FORMAT Native; -- Beautify SQL: INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`; INSERT INTO "db"."table_name" (col1, col2) VALUES (1, 2); INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2); INSERT INTO table_name (col1, col2) VALUES (1, 2); ================================================ FILE: parser/testdata/dml/format/beautify/insert_with_keyword_placeholder.sql ================================================ -- Origin SQL: INSERT INTO t (c) VALUES ({name :String}); -- Beautify SQL: INSERT INTO t (c) VALUES ({name:String}); ================================================ FILE: parser/testdata/dml/format/beautify/insert_with_placeholder.sql ================================================ -- Origin SQL: INSERT INTO t0(user_id, message, timestamp, metric) VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?) ; INSERT INTO test_with_typed_columns (id, created_at) VALUES ({id: Int32}, {created_at: DateTime64(6)}); -- Beautify SQL: INSERT INTO t0 (user_id, message, timestamp, metric) VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?); INSERT INTO test_with_typed_columns (id, created_at) VALUES ({id:Int32}, {created_at:DateTime64(6)}); ================================================ FILE: parser/testdata/dml/format/beautify/insert_with_select.sql ================================================ -- Origin SQL: INSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits; -- Beautify SQL: INSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits; ================================================ FILE: parser/testdata/dml/format/create_column_with_ttl.sql ================================================ -- Origin SQL: CREATE TABLE example1 ( timestamp DateTime, x UInt32 TTL timestamp + INTERVAL 1 MONTH, y UInt32 TTL timestamp + INTERVAL 1 WEEK ) ENGINE = MergeTree ORDER BY tuple() -- Format SQL: CREATE TABLE example1 (timestamp DateTime, x UInt32 TTL timestamp + INTERVAL 1 MONTH, y UInt32 TTL timestamp + INTERVAL 1 WEEK) ENGINE = MergeTree ORDER BY tuple(); ================================================ FILE: parser/testdata/dml/format/delete_from.sql ================================================ -- Origin SQL: DELETE FROM hits WHERE Title LIKE '%hello%'; -- Format SQL: DELETE FROM hits WHERE Title LIKE '%hello%'; ================================================ FILE: parser/testdata/dml/format/insert_select_without_from.sql ================================================ -- Origin SQL: INSERT INTO t (c) SELECT 1 WHERE 1 = 1; -- Format SQL: INSERT INTO t (c) SELECT 1 WHERE 1 = 1; ================================================ FILE: parser/testdata/dml/format/insert_values.sql ================================================ -- Origin SQL: INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES (101, 'Hello, ClickHouse!', now(), -1.0 ), (102, 'Insert a lot of rows per batch', yesterday(), 1.41421 ), (102, 'Sort your data based on your commonly-used queries', today(), 2.718 ), (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159 ) -- Format SQL: INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES (101, 'Hello, ClickHouse!', now(), -1.0), (102, 'Insert a lot of rows per batch', yesterday(), 1.41421), (102, 'Sort your data based on your commonly-used queries', today(), 2.718), (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159); ================================================ FILE: parser/testdata/dml/format/insert_with_format.sql ================================================ -- Origin SQL: INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`; INSERT INTO "db"."table_name" (col1, col2) VALUES (1, 2); INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2); INSERT INTO table_name (col1, col2) VALUES (1, 2) FORMAT Native; -- Format SQL: INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`; INSERT INTO "db"."table_name" (col1, col2) VALUES (1, 2); INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2); INSERT INTO table_name (col1, col2) VALUES (1, 2); ================================================ FILE: parser/testdata/dml/format/insert_with_keyword_placeholder.sql ================================================ -- Origin SQL: INSERT INTO t (c) VALUES ({name :String}); -- Format SQL: INSERT INTO t (c) VALUES ({name:String}); ================================================ FILE: parser/testdata/dml/format/insert_with_placeholder.sql ================================================ -- Origin SQL: INSERT INTO t0(user_id, message, timestamp, metric) VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?) ; INSERT INTO test_with_typed_columns (id, created_at) VALUES ({id: Int32}, {created_at: DateTime64(6)}); -- Format SQL: INSERT INTO t0 (user_id, message, timestamp, metric) VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?); INSERT INTO test_with_typed_columns (id, created_at) VALUES ({id:Int32}, {created_at:DateTime64(6)}); ================================================ FILE: parser/testdata/dml/format/insert_with_select.sql ================================================ -- Origin SQL: INSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits; -- Format SQL: INSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits; ================================================ FILE: parser/testdata/dml/insert_select_without_from.sql ================================================ INSERT INTO t (c) SELECT 1 WHERE 1 = 1; ================================================ FILE: parser/testdata/dml/insert_values.sql ================================================ INSERT INTO helloworld.my_first_table (user_id, message, timestamp, metric) VALUES (101, 'Hello, ClickHouse!', now(), -1.0 ), (102, 'Insert a lot of rows per batch', yesterday(), 1.41421 ), (102, 'Sort your data based on your commonly-used queries', today(), 2.718 ), (101, 'Granules are the smallest chunks of data read', now() + 5, 3.14159 ) ================================================ FILE: parser/testdata/dml/insert_with_format.sql ================================================ INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2`; INSERT INTO "db"."table_name" (col1, col2) VALUES (1, 2); INSERT INTO `_test_1345# $.ДБ`.`2. Таблица №2` (col1, col2); INSERT INTO table_name (col1, col2) VALUES (1, 2) FORMAT Native; ================================================ FILE: parser/testdata/dml/insert_with_keyword_placeholder.sql ================================================ INSERT INTO t (c) VALUES ({name :String}); ================================================ FILE: parser/testdata/dml/insert_with_placeholder.sql ================================================ INSERT INTO t0(user_id, message, timestamp, metric) VALUES (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?), (?, ?, ?, ?) ; INSERT INTO test_with_typed_columns (id, created_at) VALUES ({id: Int32}, {created_at: DateTime64(6)}); ================================================ FILE: parser/testdata/dml/insert_with_select.sql ================================================ INSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits; ================================================ FILE: parser/testdata/dml/output/alter_table_modify_query.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 116, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "some_mv", "QuoteType": 1, "NamePos": 17, "NameEnd": 24 } }, "OnCluster": { "OnPos": 25, "Expr": { "Name": "cluster", "QuoteType": 1, "NamePos": 36, "NameEnd": 43 } }, "AlterExprs": [ { "ModifyPos": 44, "StatementEnd": 116, "SelectExpr": { "SelectPos": 57, "StatementEnd": 116, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "field1", "QuoteType": 1, "NamePos": 64, "NameEnd": 70 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "field2", "QuoteType": 1, "NamePos": 72, "NameEnd": 78 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 79, "Expr": { "Table": { "TablePos": 84, "TableEnd": 99, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 84, "NameEnd": 88 }, "Table": { "Name": "some_table", "QuoteType": 1, "NamePos": 89, "NameEnd": 99 } }, "HasFinal": false }, "StatementEnd": 99, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 100, "Expr": { "LeftExpr": { "Name": "count", "QuoteType": 1, "NamePos": 106, "NameEnd": 111 }, "Operation": "\u003e=", "RightExpr": { "NumPos": 115, "NumEnd": 116, "Literal": "3", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] } ] ================================================ FILE: parser/testdata/dml/output/alter_table_modify_ttl_multiple.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 184, "TableIdentifier": { "Database": { "Name": "db", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 }, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 15, "NameEnd": 17 } }, "OnCluster": { "OnPos": 18, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 29, "NameEnd": 44 } }, "AlterExprs": [ { "ModifyPos": 45, "StatementEnd": 184, "TTL": { "TTLPos": 52, "ListEnd": 184, "Items": [ { "TTLPos": 52, "Expr": { "LeftExpr": { "Name": { "Name": "toDateTime", "QuoteType": 1, "NamePos": 60, "NameEnd": 70 }, "Params": { "LeftParenPos": 70, "RightParenPos": 93, "Items": { "ListPos": 71, "ListEnd": 93, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 71, "NameEnd": 80 }, "Operation": "/", "RightExpr": { "NumPos": 83, "NumEnd": 93, "Literal": "1000000000", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 97, "Expr": { "NumPos": 106, "NumEnd": 108, "Literal": "30", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 109, "NameEnd": 112 } }, "HasGlobal": false, "HasNot": false }, "Policy": { "Item": { "RulePos": 113, "ToVolume": null, "ToDisk": { "LiteralPos": 122, "LiteralEnd": 125, "Literal": "gcs" }, "Action": null }, "Where": null, "GroupBy": null } }, { "TTLPos": 52, "Expr": { "LeftExpr": { "Name": { "Name": "toDateTime", "QuoteType": 1, "NamePos": 132, "NameEnd": 142 }, "Params": { "LeftParenPos": 142, "RightParenPos": 165, "Items": { "ListPos": 143, "ListEnd": 165, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 143, "NameEnd": 152 }, "Operation": "/", "RightExpr": { "NumPos": 155, "NumEnd": 165, "Literal": "1000000000", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 169, "Expr": { "NumPos": 178, "NumEnd": 180, "Literal": "60", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 181, "NameEnd": 184 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] } } ] } ] ================================================ FILE: parser/testdata/dml/output/alter_table_with_comment.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 106, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 17, "NameEnd": 29 } }, "OnCluster": { "OnPos": 30, "Expr": { "LiteralPos": 42, "LiteralEnd": 57, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 59, "StatementEnd": 106, "Column": { "NamePos": 70, "ColumnEnd": 106, "Name": { "Ident": { "Name": "a", "QuoteType": 1, "NamePos": 70, "NameEnd": 71 }, "DotIdent": { "Name": "f1", "QuoteType": 1, "NamePos": 72, "NameEnd": 74 } }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 75, "NameEnd": 81 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "LiteralPos": 91, "LiteralEnd": 91, "Literal": "" }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": { "LiteralPos": 93, "LiteralEnd": 106, "Literal": "test" }, "CompressionCodec": null }, "IfNotExists": false, "After": null, "Settings": null } ] }, { "AlterPos": 110, "StatementEnd": 202, "TableIdentifier": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 122, "NameEnd": 126 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 127, "NameEnd": 139 } }, "OnCluster": { "OnPos": 140, "Expr": { "LiteralPos": 152, "LiteralEnd": 167, "Literal": "default_cluster" } }, "AlterExprs": [ { "AddPos": 169, "StatementEnd": 202, "Column": { "NamePos": 180, "ColumnEnd": 202, "Name": { "Ident": { "Name": "hello", "QuoteType": 1, "NamePos": 180, "NameEnd": 185 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 186, "NameEnd": 192 } }, "NotNull": null, "Nullable": null, "DefaultExpr": { "LiteralPos": 202, "LiteralEnd": 202, "Literal": "" }, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, "IfNotExists": false, "After": null, "Settings": null } ] } ] ================================================ FILE: parser/testdata/dml/output/alter_table_with_modify_remove_ttl.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 83, "TableIdentifier": { "Database": { "Name": "infra", "QuoteType": 1, "NamePos": 12, "NameEnd": 17 }, "Table": { "Name": "flow_processed_emails_local", "QuoteType": 1, "NamePos": 18, "NameEnd": 45 } }, "OnCluster": { "OnPos": 46, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 57, "NameEnd": 72 } }, "AlterExprs": [ { "RemovePos": 73, "StatementEnd": 83 } ] } ] ================================================ FILE: parser/testdata/dml/output/alter_table_with_modify_ttl.sql.golden.json ================================================ [ { "AlterPos": 0, "StatementEnd": 112, "TableIdentifier": { "Database": { "Name": "infra", "QuoteType": 1, "NamePos": 12, "NameEnd": 17 }, "Table": { "Name": "flow_processed_emails_local", "QuoteType": 1, "NamePos": 18, "NameEnd": 45 } }, "OnCluster": { "OnPos": 46, "Expr": { "Name": "default_cluster", "QuoteType": 1, "NamePos": 57, "NameEnd": 72 } }, "AlterExprs": [ { "ModifyPos": 73, "StatementEnd": 112, "TTL": { "TTLPos": 80, "ListEnd": 112, "Items": [ { "TTLPos": 80, "Expr": { "LeftExpr": { "Name": "created_at", "QuoteType": 1, "NamePos": 84, "NameEnd": 94 }, "Operation": "+", "RightExpr": { "IntervalPos": 97, "Expr": { "NumPos": 106, "NumEnd": 107, "Literal": "3", "Base": 10 }, "Unit": { "Name": "YEAR", "QuoteType": 1, "NamePos": 108, "NameEnd": 112 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] } } ] } ] ================================================ FILE: parser/testdata/dml/output/create_column_with_ttl.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 176, "OrReplace": false, "Name": { "Database": null, "Table": { "Name": "example1", "QuoteType": 1, "NamePos": 13, "NameEnd": 21 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": { "SchemaPos": 22, "SchemaEnd": 140, "Columns": [ { "NamePos": 28, "ColumnEnd": 46, "Name": { "Ident": { "Name": "timestamp", "QuoteType": 1, "NamePos": 28, "NameEnd": 37 }, "DotIdent": null }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 38, "NameEnd": 46 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 52, "ColumnEnd": 93, "Name": { "Ident": { "Name": "x", "QuoteType": 1, "NamePos": 52, "NameEnd": 53 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 54, "NameEnd": 60 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": { "TTLPos": 61, "ListEnd": 93, "Items": [ { "TTLPos": 61, "Expr": { "LeftExpr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 65, "NameEnd": 74 }, "Operation": "+", "RightExpr": { "IntervalPos": 77, "Expr": { "NumPos": 86, "NumEnd": 87, "Literal": "1", "Base": 10 }, "Unit": { "Name": "MONTH", "QuoteType": 1, "NamePos": 88, "NameEnd": 93 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Comment": null, "CompressionCodec": null }, { "NamePos": 99, "ColumnEnd": 139, "Name": { "Ident": { "Name": "y", "QuoteType": 1, "NamePos": 99, "NameEnd": 100 }, "DotIdent": null }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 101, "NameEnd": 107 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": { "TTLPos": 108, "ListEnd": 139, "Items": [ { "TTLPos": 108, "Expr": { "LeftExpr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 112, "NameEnd": 121 }, "Operation": "+", "RightExpr": { "IntervalPos": 124, "Expr": { "NumPos": 133, "NumEnd": 134, "Literal": "1", "Base": 10 }, "Unit": { "Name": "WEEK", "QuoteType": 1, "NamePos": 135, "NameEnd": 139 } }, "HasGlobal": false, "HasNot": false }, "Policy": null } ] }, "Comment": null, "CompressionCodec": null } ], "AliasTable": null, "TableFunction": null }, "Engine": { "EnginePos": 142, "EngineEnd": 176, "Name": "MergeTree", "Params": null, "PrimaryKey": null, "PartitionBy": null, "SampleBy": null, "TTL": null, "Settings": null, "OrderBy": { "OrderPos": 161, "ListEnd": 176, "Items": [ { "OrderPos": 161, "Expr": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 170, "NameEnd": 175 }, "Params": { "LeftParenPos": 175, "RightParenPos": 176, "Items": { "ListPos": 176, "ListEnd": 176, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null } }, "SubQuery": null, "TableFunction": null, "HasTemporary": false, "Comment": null } ] ================================================ FILE: parser/testdata/dml/output/delete_from.sql.golden.json ================================================ [ { "DeletePos": 0, "Table": { "Database": null, "Table": { "Name": "hits", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 } }, "OnCluster": null, "WhereExpr": { "LeftExpr": { "Name": "Title", "QuoteType": 1, "NamePos": 23, "NameEnd": 28 }, "Operation": "LIKE", "RightExpr": { "LiteralPos": 35, "LiteralEnd": 42, "Literal": "%hello%" }, "HasGlobal": false, "HasNot": false } } ] ================================================ FILE: parser/testdata/dml/output/insert_select_without_from.sql.golden.json ================================================ [ { "InsertPos": 0, "Format": null, "HasTableKeyword": false, "Table": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 12, "NameEnd": 13 } }, "ColumnNames": { "LeftParenPos": 14, "RightParenPos": 16, "ColumnNames": [ { "Ident": { "Name": "c", "QuoteType": 1, "NamePos": 15, "NameEnd": 16 }, "DotIdent": null } ] }, "Values": null, "SelectExpr": { "SelectPos": 18, "StatementEnd": 38, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 25, "NumEnd": 26, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": { "WherePos": 27, "Expr": { "LeftExpr": { "NumPos": 33, "NumEnd": 34, "Literal": "1", "Base": 10 }, "Operation": "=", "RightExpr": { "NumPos": 37, "NumEnd": 38, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] ================================================ FILE: parser/testdata/dml/output/insert_values.sql.golden.json ================================================ [ { "InsertPos": 0, "Format": null, "HasTableKeyword": false, "Table": { "Database": { "Name": "helloworld", "QuoteType": 1, "NamePos": 12, "NameEnd": 22 }, "Table": { "Name": "my_first_table", "QuoteType": 1, "NamePos": 23, "NameEnd": 37 } }, "ColumnNames": { "LeftParenPos": 38, "RightParenPos": 74, "ColumnNames": [ { "Ident": { "Name": "user_id", "QuoteType": 1, "NamePos": 39, "NameEnd": 46 }, "DotIdent": null }, { "Ident": { "Name": "message", "QuoteType": 1, "NamePos": 48, "NameEnd": 55 }, "DotIdent": null }, { "Ident": { "Name": "timestamp", "QuoteType": 1, "NamePos": 57, "NameEnd": 66 }, "DotIdent": null }, { "Ident": { "Name": "metric", "QuoteType": 1, "NamePos": 68, "NameEnd": 74 }, "DotIdent": null } ] }, "Values": [ { "LeftParenPos": 87, "RightParenPos": 168, "Values": [ { "NumPos": 88, "NumEnd": 91, "Literal": "101", "Base": 10 }, { "LiteralPos": 94, "LiteralEnd": 112, "Literal": "Hello, ClickHouse!" }, { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 147, "NameEnd": 150 }, "Params": { "LeftParenPos": 150, "RightParenPos": 151, "Items": { "ListPos": 151, "ListEnd": 151, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, { "NumPos": 160, "NumEnd": 164, "Literal": "-1.0", "Base": 10 } ] }, { "LeftParenPos": 175, "RightParenPos": 256, "Values": [ { "NumPos": 176, "NumEnd": 179, "Literal": "102", "Base": 10 }, { "LiteralPos": 182, "LiteralEnd": 212, "Literal": "Insert a lot of rows per batch" }, { "Name": { "Name": "yesterday", "QuoteType": 1, "NamePos": 235, "NameEnd": 244 }, "Params": { "LeftParenPos": 244, "RightParenPos": 245, "Items": { "ListPos": 245, "ListEnd": 245, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, { "NumPos": 248, "NumEnd": 255, "Literal": "1.41421", "Base": 10 } ] }, { "LeftParenPos": 263, "RightParenPos": 344, "Values": [ { "NumPos": 264, "NumEnd": 267, "Literal": "102", "Base": 10 }, { "LiteralPos": 270, "LiteralEnd": 320, "Literal": "Sort your data based on your commonly-used queries" }, { "Name": { "Name": "today", "QuoteType": 1, "NamePos": 323, "NameEnd": 328 }, "Params": { "LeftParenPos": 328, "RightParenPos": 329, "Items": { "ListPos": 329, "ListEnd": 329, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, { "NumPos": 336, "NumEnd": 341, "Literal": "2.718", "Base": 10 } ] }, { "LeftParenPos": 351, "RightParenPos": 432, "Values": [ { "NumPos": 352, "NumEnd": 355, "Literal": "101", "Base": 10 }, { "LiteralPos": 358, "LiteralEnd": 403, "Literal": "Granules are the smallest chunks of data read" }, { "LeftExpr": { "Name": { "Name": "now", "QuoteType": 1, "NamePos": 411, "NameEnd": 414 }, "Params": { "LeftParenPos": 414, "RightParenPos": 415, "Items": { "ListPos": 415, "ListEnd": 415, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "NumPos": 419, "NumEnd": 420, "Literal": "5", "Base": 10 }, "HasGlobal": false, "HasNot": false }, { "NumPos": 424, "NumEnd": 431, "Literal": "3.14159", "Base": 10 } ] } ], "SelectExpr": null } ] ================================================ FILE: parser/testdata/dml/output/insert_with_format.sql.golden.json ================================================ [ { "InsertPos": 0, "Format": null, "HasTableKeyword": false, "Table": { "Database": { "Name": "_test_1345# $.ДБ", "QuoteType": 3, "NamePos": 13, "NameEnd": 31 }, "Table": { "Name": "2. Таблица №2", "QuoteType": 3, "NamePos": 34, "NameEnd": 56 } }, "ColumnNames": null, "Values": null, "SelectExpr": null }, { "InsertPos": 59, "Format": null, "HasTableKeyword": false, "Table": { "Database": { "Name": "db", "QuoteType": 2, "NamePos": 72, "NameEnd": 74 }, "Table": { "Name": "table_name", "QuoteType": 2, "NamePos": 77, "NameEnd": 87 } }, "ColumnNames": { "LeftParenPos": 89, "RightParenPos": 100, "ColumnNames": [ { "Ident": { "Name": "col1", "QuoteType": 1, "NamePos": 90, "NameEnd": 94 }, "DotIdent": null }, { "Ident": { "Name": "col2", "QuoteType": 1, "NamePos": 96, "NameEnd": 100 }, "DotIdent": null } ] }, "Values": [ { "LeftParenPos": 109, "RightParenPos": 114, "Values": [ { "NumPos": 110, "NumEnd": 111, "Literal": "1", "Base": 10 }, { "NumPos": 113, "NumEnd": 114, "Literal": "2", "Base": 10 } ] } ], "SelectExpr": null }, { "InsertPos": 117, "Format": null, "HasTableKeyword": false, "Table": { "Database": { "Name": "_test_1345# $.ДБ", "QuoteType": 3, "NamePos": 130, "NameEnd": 148 }, "Table": { "Name": "2. Таблица №2", "QuoteType": 3, "NamePos": 151, "NameEnd": 173 } }, "ColumnNames": { "LeftParenPos": 175, "RightParenPos": 186, "ColumnNames": [ { "Ident": { "Name": "col1", "QuoteType": 1, "NamePos": 176, "NameEnd": 180 }, "DotIdent": null }, { "Ident": { "Name": "col2", "QuoteType": 1, "NamePos": 182, "NameEnd": 186 }, "DotIdent": null } ] }, "Values": null, "SelectExpr": null }, { "InsertPos": 189, "Format": null, "HasTableKeyword": false, "Table": { "Database": null, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 201, "NameEnd": 211 } }, "ColumnNames": { "LeftParenPos": 212, "RightParenPos": 223, "ColumnNames": [ { "Ident": { "Name": "col1", "QuoteType": 1, "NamePos": 213, "NameEnd": 217 }, "DotIdent": null }, { "Ident": { "Name": "col2", "QuoteType": 1, "NamePos": 219, "NameEnd": 223 }, "DotIdent": null } ] }, "Values": [ { "LeftParenPos": 232, "RightParenPos": 237, "Values": [ { "NumPos": 233, "NumEnd": 234, "Literal": "1", "Base": 10 }, { "NumPos": 236, "NumEnd": 237, "Literal": "2", "Base": 10 } ] } ], "SelectExpr": null } ] ================================================ FILE: parser/testdata/dml/output/insert_with_keyword_placeholder.sql.golden.json ================================================ [ { "InsertPos": 0, "Format": null, "HasTableKeyword": false, "Table": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 12, "NameEnd": 13 } }, "ColumnNames": { "LeftParenPos": 14, "RightParenPos": 16, "ColumnNames": [ { "Ident": { "Name": "c", "QuoteType": 1, "NamePos": 15, "NameEnd": 16 }, "DotIdent": null } ] }, "Values": [ { "LeftParenPos": 25, "RightParenPos": 40, "Values": [ { "LeftBracePos": 26, "RightBracePos": 40, "Name": { "Name": "name", "QuoteType": 1, "NamePos": 27, "NameEnd": 31 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 33, "NameEnd": 39 } } } ] } ], "SelectExpr": null } ] ================================================ FILE: parser/testdata/dml/output/insert_with_placeholder.sql.golden.json ================================================ [ { "InsertPos": 0, "Format": null, "HasTableKeyword": false, "Table": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 } }, "ColumnNames": { "LeftParenPos": 14, "RightParenPos": 50, "ColumnNames": [ { "Ident": { "Name": "user_id", "QuoteType": 1, "NamePos": 15, "NameEnd": 22 }, "DotIdent": null }, { "Ident": { "Name": "message", "QuoteType": 1, "NamePos": 24, "NameEnd": 31 }, "DotIdent": null }, { "Ident": { "Name": "timestamp", "QuoteType": 1, "NamePos": 33, "NameEnd": 42 }, "DotIdent": null }, { "Ident": { "Name": "metric", "QuoteType": 1, "NamePos": 44, "NameEnd": 50 }, "DotIdent": null } ] }, "Values": [ { "LeftParenPos": 63, "RightParenPos": 74, "Values": [ { "PlaceholderPos": 64, "PlaceHolderEnd": 64, "Type": "?" }, { "PlaceholderPos": 67, "PlaceHolderEnd": 67, "Type": "?" }, { "PlaceholderPos": 70, "PlaceHolderEnd": 70, "Type": "?" }, { "PlaceholderPos": 73, "PlaceHolderEnd": 73, "Type": "?" } ] }, { "LeftParenPos": 81, "RightParenPos": 92, "Values": [ { "PlaceholderPos": 82, "PlaceHolderEnd": 82, "Type": "?" }, { "PlaceholderPos": 85, "PlaceHolderEnd": 85, "Type": "?" }, { "PlaceholderPos": 88, "PlaceHolderEnd": 88, "Type": "?" }, { "PlaceholderPos": 91, "PlaceHolderEnd": 91, "Type": "?" } ] }, { "LeftParenPos": 99, "RightParenPos": 110, "Values": [ { "PlaceholderPos": 100, "PlaceHolderEnd": 100, "Type": "?" }, { "PlaceholderPos": 103, "PlaceHolderEnd": 103, "Type": "?" }, { "PlaceholderPos": 106, "PlaceHolderEnd": 106, "Type": "?" }, { "PlaceholderPos": 109, "PlaceHolderEnd": 109, "Type": "?" } ] }, { "LeftParenPos": 117, "RightParenPos": 128, "Values": [ { "PlaceholderPos": 118, "PlaceHolderEnd": 118, "Type": "?" }, { "PlaceholderPos": 121, "PlaceHolderEnd": 121, "Type": "?" }, { "PlaceholderPos": 124, "PlaceHolderEnd": 124, "Type": "?" }, { "PlaceholderPos": 127, "PlaceHolderEnd": 127, "Type": "?" } ] } ], "SelectExpr": null }, { "InsertPos": 133, "Format": null, "HasTableKeyword": false, "Table": { "Database": null, "Table": { "Name": "test_with_typed_columns", "QuoteType": 1, "NamePos": 145, "NameEnd": 168 } }, "ColumnNames": { "LeftParenPos": 169, "RightParenPos": 184, "ColumnNames": [ { "Ident": { "Name": "id", "QuoteType": 1, "NamePos": 170, "NameEnd": 172 }, "DotIdent": null }, { "Ident": { "Name": "created_at", "QuoteType": 1, "NamePos": 174, "NameEnd": 184 }, "DotIdent": null } ] }, "Values": [ { "LeftParenPos": 193, "RightParenPos": 234, "Values": [ { "LeftBracePos": 194, "RightBracePos": 205, "Name": { "Name": "id", "QuoteType": 1, "NamePos": 195, "NameEnd": 197 }, "Type": { "Name": { "Name": "Int32", "QuoteType": 1, "NamePos": 199, "NameEnd": 204 } } }, { "LeftBracePos": 207, "RightBracePos": 234, "Name": { "Name": "created_at", "QuoteType": 1, "NamePos": 208, "NameEnd": 218 }, "Type": { "LeftParenPos": 231, "RightParenPos": 232, "Name": { "Name": "DateTime64", "QuoteType": 1, "NamePos": 220, "NameEnd": 230 }, "Params": [ { "NumPos": 231, "NumEnd": 232, "Literal": "6", "Base": 10 } ] } } ] } ], "SelectExpr": null } ] ================================================ FILE: parser/testdata/dml/output/insert_with_select.sql.golden.json ================================================ [ { "InsertPos": 0, "Format": null, "HasTableKeyword": false, "Table": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 12, "NameEnd": 16 }, "Table": { "Name": "visits_null", "QuoteType": 1, "NamePos": 17, "NameEnd": 28 } }, "ColumnNames": null, "Values": null, "SelectExpr": { "SelectPos": 29, "StatementEnd": 103, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "CounterID", "QuoteType": 1, "NamePos": 40, "NameEnd": 49 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "StartDate", "QuoteType": 1, "NamePos": 55, "NameEnd": 64 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "Sign", "QuoteType": 1, "NamePos": 70, "NameEnd": 74 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "UserID", "QuoteType": 1, "NamePos": 80, "NameEnd": 86 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 87, "Expr": { "Table": { "TablePos": 92, "TableEnd": 103, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 92, "NameEnd": 96 }, "Table": { "Name": "visits", "QuoteType": 1, "NamePos": 97, "NameEnd": 103 } }, "HasFinal": false }, "StatementEnd": 103, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] ================================================ FILE: parser/testdata/query/access_tuple_with_dot.sql ================================================ SELECT tuple('a','b','c').3, .1234; SELECT toTypeName( tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)), (tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)).second, tuple('a','b','c').3, tupleElement(tuple('a','b','c'),1) ================================================ FILE: parser/testdata/query/compatible/1_stateful/00001_count_hits.sql ================================================ SELECT count() FROM test.hits ================================================ FILE: parser/testdata/query/compatible/1_stateful/00002_count_visits.sql ================================================ SELECT sum(Sign) FROM test.visits ================================================ FILE: parser/testdata/query/compatible/1_stateful/00004_top_counters.sql ================================================ SELECT CounterID, count() AS c FROM test.hits GROUP BY CounterID ORDER BY c DESC LIMIT 10; SELECT CounterID, count() AS c FROM test.hits GROUP BY CounterID ORDER BY c DESC LIMIT 10 SETTINGS optimize_aggregation_in_order = 1 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00005_filtering.sql ================================================ SELECT count() FROM test.hits WHERE AdvEngineID != 0 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00006_agregates.sql ================================================ SELECT sum(AdvEngineID), count(), avg(ResolutionWidth) FROM test.hits ================================================ FILE: parser/testdata/query/compatible/1_stateful/00007_uniq.sql ================================================ SELECT RegionID, uniq(UserID) AS u FROM test.hits WHERE CounterID = 800784 GROUP BY RegionID ORDER BY u DESC, RegionID LIMIT 10 -- nothing ================================================ FILE: parser/testdata/query/compatible/1_stateful/00008_uniq.sql ================================================ SELECT uniq(UserID), uniqIf(UserID, CounterID = 800784), uniqIf(FUniqID, RegionID = 213) FROM test.hits ================================================ FILE: parser/testdata/query/compatible/1_stateful/00009_uniq_distributed.sql ================================================ -- Tags: distributed SELECT uniq(UserID), uniqIf(UserID, CounterID = 800784), uniqIf(FUniqID, RegionID = 213) FROM remote('127.0.0.{1,2}', test, hits) ================================================ FILE: parser/testdata/query/compatible/1_stateful/00010_quantiles_segfault.sql ================================================ SELECT URL AS `ym:ah:URL`, sum((NOT DontCountHits AND NOT Refresh)), quantilesTimingIf(0.1, 0.5, 0.9)((DOMCompleteTiming + LoadEventEndTiming), DOMCompleteTiming != -1 AND LoadEventEndTiming != -1) as t FROM remote('127.0.0.{1,2}', test, hits) WHERE (CounterID = 800784) AND (((DontCountHits = 0) OR (IsNotBounce = 1)) AND (URL != '')) GROUP BY `ym:ah:URL` WITH TOTALS HAVING (sum((NOT DontCountHits AND NOT Refresh)) > 0) AND (count() > 0) ORDER BY sum((NOT DontCountHits AND NOT Refresh)) DESC, URL LIMIT 0, 1 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00011_sorting.sql ================================================ SELECT EventTime::DateTime('Asia/Dubai') FROM test.hits ORDER BY EventTime DESC LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00012_sorting_distributed.sql ================================================ -- Tags: distributed SELECT EventTime::DateTime('Asia/Dubai') FROM remote('127.0.0.{1,2}', test, hits) ORDER BY EventTime DESC LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00013_sorting_of_nested.sql ================================================ SELECT ParsedParams.Key1 FROM test.visits FINAL WHERE VisitID != 0 AND notEmpty(ParsedParams.Key1) ORDER BY VisitID LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00014_filtering_arrays.sql ================================================ SELECT GeneralInterests FROM test.hits WHERE AdvEngineID != 0 ORDER BY GeneralInterests DESC LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00015_totals_and_no_aggregate_functions.sql ================================================ SELECT AdvEngineID FROM test.hits GROUP BY AdvEngineID WITH TOTALS ORDER BY AdvEngineID ================================================ FILE: parser/testdata/query/compatible/1_stateful/00016_any_if_distributed_cond_always_false.sql ================================================ -- Tags: distributed SELECT anyIf(SearchPhrase, CounterID = -1) FROM remote('127.0.0.{1,2}:9000', test, hits) ================================================ FILE: parser/testdata/query/compatible/1_stateful/00017_aggregation_uninitialized_memory.sql ================================================ SELECT DISTINCT (URLHierarchy(URL)[1]) AS q, 'x' AS w FROM test.hits WHERE CounterID = 14917930 ORDER BY URL ================================================ FILE: parser/testdata/query/compatible/1_stateful/00020_distinct_order_by_distributed.sql ================================================ -- Tags: distributed SET max_rows_to_sort = 10000; SELECT count() FROM (SELECT DISTINCT PredLastVisit AS x FROM remote('127.0.0.{1,2}', test, visits) ORDER BY VisitID); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00021_1_select_with_in.sql ================================================ select sum(Sign) from test.visits where CounterID in (942285); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00021_2_select_with_in.sql ================================================ select sum(Sign) from test.visits where CounterID in (942285, 577322); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00021_3_select_with_in.sql ================================================ select 1 IN (1, 2, 3); SELECT count() FROM remote('localhost', test, hits) WHERE CounterID IN (598875); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00022_merge_prewhere.sql ================================================ DROP TABLE IF EXISTS test.merge_hits; CREATE TABLE IF NOT EXISTS test.merge_hits AS test.hits ENGINE = Merge(test, '^hits$'); SELECT count() FROM test.merge_hits WHERE AdvEngineID = 2; SELECT count() FROM test.merge_hits PREWHERE AdvEngineID = 2; DROP TABLE test.merge_hits; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00023_totals_limit.sql ================================================ SET output_format_write_statistics = 0; SELECT goals_alias.ID AS `ym:s:goalDimension`, uniqIf(UserID, (UserID != 0) AND (`_uniq_Goals` = 1)) FROM test.visits ARRAY JOIN Goals AS goals_alias, arrayEnumerateUniq(Goals.ID) AS `_uniq_Goals` WHERE (CounterID = 842440) GROUP BY `ym:s:goalDimension` WITH TOTALS ORDER BY `ym:s:goalDimension` LIMIT 0, 1 FORMAT JSONCompact; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00024_random_counters.sql ================================================ SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32152608; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9627212; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25152951; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22202319; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13848191; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27855803; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27944638; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16513894; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4314057; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11878090; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23005927; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17205778; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21296650; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12068702; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8446208; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8439835; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30344780; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2881921; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1828473; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27620040; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14960013; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 103918; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9626742; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18370244; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 813903; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22176733; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17175454; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31608140; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11802602; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12577104; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 153437; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32240558; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27444870; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 79306; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15222279; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11782937; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1677; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9527330; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23580782; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33027895; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 199609; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29139484; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1700065; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30212873; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6773723; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21842879; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9460479; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16451704; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 51267; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30489182; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11947625; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18776987; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25762358; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 74905; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 877422; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3465045; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2084559; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13828281; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30299683; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 132115; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10919775; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12329250; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11525543; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32395537; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24537202; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2270964; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8518291; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11897183; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23805647; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22652078; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19363661; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32339088; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11394550; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1988179; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2135273; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14500371; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10463153; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18838936; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24492652; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26848923; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12495799; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12028938; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8934725; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18602951; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32404741; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19171705; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9831187; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20047182; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26690858; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 126413; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31244775; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15690176; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28374997; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12717244; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9152092; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5397339; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12452068; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13626118; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 46783; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11484344; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21453219; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7692388; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30879805; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27784549; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 665663; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30535786; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11685143; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13652647; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9880318; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30148588; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32745436; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27390924; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17470663; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 196859; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22123478; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 87021; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25264218; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24125574; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26099981; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1141558; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 220829; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15651875; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 182483; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28430678; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31384642; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1008241; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10462834; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26829659; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29130002; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17891770; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26531140; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15014338; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15375411; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7952204; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 41859; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21651593; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9527676; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 107394; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23409492; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31407407; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29312961; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9705505; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29848510; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10187274; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 112606; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15639744; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4375349; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1423039; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13933371; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20430236; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30679961; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 37094; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23197674; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 994587; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 437496; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3904733; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19200606; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 84668; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28581029; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11074306; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2470089; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12251899; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16996077; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12426411; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1034934; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4721601; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22026000; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21031300; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 559124; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15492463; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21419604; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25632271; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14446476; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12684903; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23292922; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26976782; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20269131; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18309978; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5305320; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30926629; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14816057; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19523905; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18775058; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32507411; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25535479; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24858652; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32420158; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4805894; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8157258; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5759745; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12626987; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5342591; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10951832; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9729032; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27999107; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7302193; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30447727; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15764416; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15727130; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15116605; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 527313; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16687935; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28304381; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17699739; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17339596; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29348067; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20861945; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12922065; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27019489; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18299445; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 108465; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 233447; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13042904; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31481509; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2267268; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26140306; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19094364; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25000943; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6860549; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30714288; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16289139; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1419182; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33436573; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30062358; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18167743; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27846382; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30148240; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32332238; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25129158; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14066924; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19832770; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29018190; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 852275; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11328399; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28179212; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20155907; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30685297; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32783957; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1552720; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28110991; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4814424; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20171153; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14920591; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 65690; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14357916; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26533001; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17014738; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11977336; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30142464; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14082365; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18851419; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27638649; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8798932; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 717825; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6912378; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26898048; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5992218; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13422462; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21204372; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17845298; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6933004; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21627605; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3395439; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22315068; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24973444; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27751340; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6022884; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32417601; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18087198; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21940806; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23809389; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9510424; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30651933; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17818815; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9038457; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9153497; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29938964; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10471118; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12913162; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14933629; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7173707; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28680585; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1279785; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33276693; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 573557; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27753414; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22968595; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25211823; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32687774; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6062762; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18866703; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5164840; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6462629; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25039797; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10789598; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33076990; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28960547; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32723171; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17888313; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29810654; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21760643; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16678170; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 368520; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12506284; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9802670; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18488016; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 227003; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15254606; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32580177; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30313645; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20879524; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27222776; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11266528; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17018146; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19902143; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19469853; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22823497; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 56768; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 136798; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16554922; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20627728; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6551053; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 124145; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10881152; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17271030; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28213281; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15665842; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28264219; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29277533; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22926441; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31057728; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8027311; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14229492; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14782220; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29099258; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 99953; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9334015; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16156945; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 124031; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1670442; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21036594; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22954047; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16054043; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 121765; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1482385; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25977258; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24596247; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 550092; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1579438; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1205; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 126296; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 177248; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27523607; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15873699; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11971473; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18965085; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19035683; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29640643; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11929806; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9352219; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18492653; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7967264; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11391453; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4289; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3567; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13575826; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2566437; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21042675; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26498330; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23764459; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32664413; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10116935; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24572551; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26788657; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12830859; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 530033; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6764575; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25219472; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10721285; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26254035; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15486693; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10323514; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23578364; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25449880; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13428298; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17679279; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27610140; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15346859; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 535736; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 513828; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20411888; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13595045; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33221835; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 97601; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12819274; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18047205; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19900235; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27830172; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20839743; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29980468; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27417156; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17908689; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24471592; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32147490; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22966030; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21060870; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 238185; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10152551; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11255139; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 982334; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15199978; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15678357; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18206303; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10902608; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22494906; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22204221; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13097211; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30998656; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26656294; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 922545; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9428510; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15137339; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15578624; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31695129; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15791360; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29571338; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5371768; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15163979; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16312681; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6126176; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16061128; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8528634; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 136544; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3093873; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3994698; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8302978; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16115563; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21804036; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9785708; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10847072; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30692218; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15582824; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19802155; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20835290; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 204284; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25636491; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30446517; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16761451; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 456303; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17301839; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27472581; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24078399; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26345482; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 451381; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8576994; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19418898; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10068353; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3767138; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 758020; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13521375; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25968099; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26805240; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13051011; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 901894; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33097016; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12545080; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29944288; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8250825; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12499373; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22535728; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11929724; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3615273; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24172869; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 116132; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12002817; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23681158; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3938; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8468701; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1295067; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27469232; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32708119; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 122578; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12139400; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12219626; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9262336; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9269892; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 122701; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19589931; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29539889; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31115640; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6283044; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30642040; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18065262; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26714391; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15351586; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13090710; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16201652; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31960256; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2658509; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 467277; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1274110; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23640128; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16197014; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28228612; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11659509; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24981440; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 52285; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30583892; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31467341; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25512316; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2908472; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 422752; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32718035; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14213540; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14951444; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6819113; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9532880; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4102488; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19537427; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7078160; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29521616; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5045377; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23131467; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22383622; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22079706; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29466380; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12045654; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30178011; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20821588; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21966434; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29390311; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19370159; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24857158; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31982180; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11990254; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3841725; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13993951; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31252290; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26398773; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 891512; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27087947; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2097095; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26252354; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13928858; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4331960; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30552074; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27905732; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30049284; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2118697; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20849218; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11338538; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3348692; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17693905; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23502543; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8905975; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18343399; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15235863; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20356153; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10552704; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28875831; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1488561; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15012941; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25726446; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2601050; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27426912; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11269650; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14880200; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 362337; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23533327; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26381021; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17522450; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31868526; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18276314; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1841289; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22234319; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11463222; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15251006; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24841412; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28755796; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9087442; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13734462; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9285105; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13289061; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29890926; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30509694; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17698850; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 46229; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16541087; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11305551; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 429238; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7583796; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8604476; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29759280; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1388922; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10884907; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18220244; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 122157; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18069840; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6707469; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26818794; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14770800; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16652737; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25497243; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14747538; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21371935; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1681601; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5343898; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22040058; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 752596; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9377867; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1848946; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1449313; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31332002; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10829982; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22431161; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29172033; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7631750; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 898844; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21460344; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25387068; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30980374; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13021547; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27715925; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30292547; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18666245; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18954194; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29070192; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 914290; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14807517; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23062682; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5132969; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15094854; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 622095; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1244323; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14804701; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11656845; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17167258; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8959523; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23121135; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4339624; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22679035; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13127067; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18362622; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4189114; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18776826; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26792263; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13409810; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22183039; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16132723; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3925258; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14248840; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18135589; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11234961; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11179577; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 178965; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10138078; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21048048; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8001235; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32833016; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32275374; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1430786; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12969140; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25529912; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18395861; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27380554; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16653574; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16372034; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28050494; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6886254; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7472729; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12646802; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6589761; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19556032; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10261903; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4389; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2415202; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20007939; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17957094; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9920354; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24840314; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5077718; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11650674; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19766470; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7854638; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9169290; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22873394; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30838169; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 79894; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25792494; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25326672; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33123311; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33237554; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15130284; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18811870; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25418177; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17202302; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31836505; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28671820; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25643858; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16338596; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27288074; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9458517; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25163573; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15680967; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20413991; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19332304; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23159444; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24708786; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 250297; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29944728; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14582542; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 512441; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31273184; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30255145; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 89813; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14959234; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26621829; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 279206; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13041403; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33392742; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10895948; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20804625; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10129067; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13855355; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31007051; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4109301; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29492024; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28963180; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11530154; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31889101; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1713672; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16069992; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9075873; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14512529; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8632591; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33056094; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28349520; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26806792; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11496875; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11797321; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25795940; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33196708; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13243216; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25096876; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26974949; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27061789; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29686454; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5045092; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2893170; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21528033; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16980819; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30854698; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1041468; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 215125; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 91347; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22706469; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33038294; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1446406; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 183702; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10246325; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13754526; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6854006; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26686232; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29345198; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15956574; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8558022; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14066782; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31710428; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6750831; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14832055; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29613113; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15159107; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6309003; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4311581; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28180829; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15131841; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20458889; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26250664; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31737265; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 802571; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25064649; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21183784; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3218637; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3375471; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1690000; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18602620; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29918973; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8555235; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32152623; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19670163; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25856874; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6142197; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27822106; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8944163; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7596672; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 129436; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33541084; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5199217; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10337246; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12718765; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10729131; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28049397; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1410155; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24924437; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16706889; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 54647; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29407271; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1575071; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6861225; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30114382; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 129970; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21103497; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3433579; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14174715; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8450741; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30033987; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11474175; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9601520; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 7377941; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15646334; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18305797; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2057218; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17121933; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6870927; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19743903; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9019159; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21251610; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 239704; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16170940; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31857931; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25174672; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31546315; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 811438; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33135020; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28325470; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1196502; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 117339; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19198214; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28046111; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27663162; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3651; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8443242; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6773651; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28957858; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15586212; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 155469; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 731800; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13198917; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2080118; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17987407; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1832110; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32960999; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13858070; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2800568; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 381151; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26724412; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 238149; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20458616; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16847984; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14870120; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 4729620; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12886810; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 109350; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17512881; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5250020; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 184094; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3071553; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18940958; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16166873; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13648378; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32750584; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31167464; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21597707; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21992900; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16695153; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12272303; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18958518; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11827733; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12495926; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21022681; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32262727; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12082756; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15636497; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20081370; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26349655; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32832383; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18190567; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 61749; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28596915; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28835938; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32924951; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15835912; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22905942; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12295903; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12461093; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27568271; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33525856; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10351138; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16804486; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24506501; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1336365; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19178381; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17921720; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25396786; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22031463; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19624501; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 28665905; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14851585; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27554706; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14188052; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33301471; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32896955; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1134828; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27050219; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23641604; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22935857; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29805516; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25890338; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20710225; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3925036; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31404180; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25888177; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11074293; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30922753; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11403908; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25615656; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17652214; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 16155802; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5565120; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5508217; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33281735; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 11619273; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 67148; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22687534; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17887682; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18506413; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1443226; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13761576; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30941622; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17681363; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 187532; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 95405; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31073741; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 9706801; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12504322; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31779591; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18781661; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 18284607; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 10633383; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3249127; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17567300; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8789986; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 30073024; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26477401; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32222832; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 23098807; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 50708; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25067039; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29132588; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22947337; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27778601; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25325678; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12822401; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 8876685; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31096269; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17466070; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26058342; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 1468384; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 22665021; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24895973; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15423066; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26091197; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 12103346; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15917190; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 31527060; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 3944; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 24572480; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 229185; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 17038391; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 27368675; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 26899897; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 13257515; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19531252; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 21048946; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33104049; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20824535; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15014380; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 25235392; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29560548; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 2599836; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32842358; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 5795232; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29588193; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 19019850; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 29580949; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15335748; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 15094099; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 6308405; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 20762370; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 14121177; SYSTEM DROP UNCOMPRESSED CACHE; SET local_filesystem_read_method = 'pread_threadpool'; SET min_bytes_to_use_direct_io = 1; SET use_uncompressed_cache = 1; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 32745436; SELECT uniq(UserID), sum(Sign) FROM test.visits WHERE CounterID = 33436573; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00030_array_enumerate_uniq.sql ================================================ SELECT max(arrayJoin(arrayEnumerateUniq(arrayMap(x -> intDiv(x, 10), URLCategories)))) FROM test.hits ================================================ FILE: parser/testdata/query/compatible/1_stateful/00031_array_enumerate_uniq.sql ================================================ SELECT UserID, arrayEnumerateUniq(groupArray(SearchPhrase)) AS arr FROM ( SELECT UserID, SearchPhrase FROM test.hits WHERE CounterID = 1704509 AND UserID IN ( SELECT UserID FROM test.hits WHERE notEmpty(SearchPhrase) AND CounterID = 1704509 GROUP BY UserID HAVING count() > 1 ) ORDER BY UserID, WatchID ) WHERE notEmpty(SearchPhrase) GROUP BY UserID HAVING length(arr) > 1 ORDER BY UserID LIMIT 20 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00032_aggregate_key64.sql ================================================ SELECT SearchEngineID AS k1, count() AS c FROM test.hits GROUP BY k1 ORDER BY c DESC, k1 LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00033_aggregate_key_string.sql ================================================ SELECT SearchPhrase AS k1, count() AS c FROM test.hits GROUP BY k1 ORDER BY c DESC, k1 LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00034_aggregate_key_fixed_string.sql ================================================ SELECT toFixedString(substring(SearchPhrase, 1, 17), 17) AS k1, count() AS c FROM test.hits GROUP BY k1 ORDER BY c DESC, k1 LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00035_aggregate_keys128.sql ================================================ SELECT SearchEngineID AS k1, AdvEngineID AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC, k1, k2 LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00036_aggregate_hashed.sql ================================================ SELECT SearchEngineID AS k1, SearchPhrase AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC, k1, k2 LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00037_uniq_state_merge1.sql ================================================ SELECT k, any(u) AS u, uniqMerge(us) AS us FROM (SELECT domain(URL) AS k, uniq(UserID) AS u, uniqState(UserID) AS us FROM test.hits GROUP BY k) GROUP BY k ORDER BY u DESC, k ASC LIMIT 100 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00038_uniq_state_merge2.sql ================================================ SELECT topLevelDomain(concat('http://', k)) AS tld, sum(u) AS u, uniqMerge(us) AS us FROM (SELECT domain(URL) AS k, uniq(UserID) AS u, uniqState(UserID) AS us FROM test.hits GROUP BY k) GROUP BY tld ORDER BY u DESC, tld ASC LIMIT 100 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00039_primary_key.sql ================================================ SELECT count() FROM test.hits WHERE CounterID < 10000; SELECT count() FROM test.hits WHERE 10000 > CounterID; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00040_aggregating_materialized_view.sql ================================================ DROP TABLE IF EXISTS test.basic_00040; set allow_deprecated_syntax_for_merge_tree=1; CREATE MATERIALIZED VIEW test.basic_00040 ENGINE = AggregatingMergeTree(StartDate, (CounterID, StartDate), 8192) POPULATE AS SELECT CounterID, StartDate, sumState(Sign) AS Visits, uniqState(UserID) AS Users FROM test.visits GROUP BY CounterID, StartDate; SELECT StartDate, sumMerge(Visits) AS Visits, uniqMerge(Users) AS Users FROM test.basic_00040 GROUP BY StartDate ORDER BY StartDate; SELECT StartDate, sumMerge(Visits) AS Visits, uniqMerge(Users) AS Users FROM test.basic_00040 WHERE CounterID = 942285 GROUP BY StartDate ORDER BY StartDate; SELECT StartDate, sum(Sign) AS Visits, uniq(UserID) AS Users FROM test.visits WHERE CounterID = 942285 GROUP BY StartDate ORDER BY StartDate; DROP TABLE test.basic_00040; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00041_aggregating_materialized_view.sql ================================================ DROP TABLE IF EXISTS test.basic; DROP TABLE IF EXISTS test.visits_null; CREATE TABLE test.visits_null ( CounterID UInt32, StartDate Date, Sign Int8, UserID UInt64 ) ENGINE = Null; set allow_deprecated_syntax_for_merge_tree=1; CREATE MATERIALIZED VIEW test.basic ENGINE = AggregatingMergeTree(StartDate, (CounterID, StartDate), 8192) AS SELECT CounterID, StartDate, sumState(Sign) AS Visits, uniqState(UserID) AS Users FROM test.visits_null GROUP BY CounterID, StartDate; INSERT INTO test.visits_null SELECT CounterID, StartDate, Sign, UserID FROM test.visits; SELECT StartDate, sumMerge(Visits) AS Visits, uniqMerge(Users) AS Users FROM test.basic GROUP BY StartDate ORDER BY StartDate; SELECT StartDate, sumMerge(Visits) AS Visits, uniqMerge(Users) AS Users FROM test.basic WHERE CounterID = 942285 GROUP BY StartDate ORDER BY StartDate; SELECT StartDate, sum(Sign) AS Visits, uniq(UserID) AS Users FROM test.visits WHERE CounterID = 942285 GROUP BY StartDate ORDER BY StartDate; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; OPTIMIZE TABLE test.basic; DROP TABLE test.visits_null; DROP TABLE test.basic; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00042_any_left_join.sql ================================================ SELECT EventDate, hits, visits FROM ( SELECT EventDate, count() AS hits FROM test.hits GROUP BY EventDate ) ANY LEFT JOIN ( SELECT StartDate AS EventDate, sum(Sign) AS visits FROM test.visits GROUP BY EventDate ) USING EventDate ORDER BY hits DESC LIMIT 10 SETTINGS joined_subquery_requires_alias = 0; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00043_any_left_join.sql ================================================ SELECT EventDate, count() AS hits, any(visits) FROM test.hits ANY LEFT JOIN ( SELECT StartDate AS EventDate, sum(Sign) AS visits FROM test.visits GROUP BY EventDate ) USING EventDate GROUP BY EventDate ORDER BY hits DESC LIMIT 10 SETTINGS joined_subquery_requires_alias = 0; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00044_any_left_join_string.sql ================================================ SELECT domain, hits, visits FROM ( SELECT domain(URL) AS domain, count() AS hits FROM test.hits GROUP BY domain ) ANY LEFT JOIN ( SELECT domain(StartURL) AS domain, sum(Sign) AS visits FROM test.visits GROUP BY domain ) USING domain ORDER BY hits DESC LIMIT 10 SETTINGS joined_subquery_requires_alias = 0; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00045_uniq_upto.sql ================================================ SELECT RegionID, uniqExact(UserID) AS u1, uniqUpTo(10)(UserID) AS u2 FROM test.visits GROUP BY RegionID HAVING u1 <= 11 AND u1 != u2 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00046_uniq_upto_distributed.sql ================================================ -- Tags: distributed SELECT RegionID, uniqExact(UserID) AS u1, uniqUpTo(10)(UserID) AS u2 FROM remote('127.0.0.{1,2}', test, visits) GROUP BY RegionID HAVING u1 <= 11 AND u1 != u2 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00047_bar.sql ================================================ SELECT CounterID, count() AS c, bar(c, 0, 523264) FROM test.hits GROUP BY CounterID ORDER BY c DESC, CounterID ASC LIMIT 100; SELECT CounterID, count() AS c, bar(c, 0, 523264) FROM test.hits GROUP BY CounterID ORDER BY c DESC, CounterID ASC LIMIT 100 SETTINGS optimize_aggregation_in_order = 1 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00048_min_max.sql ================================================ SELECT min(EventDate), max(EventDate) FROM test.hits ================================================ FILE: parser/testdata/query/compatible/1_stateful/00049_max_string_if.sql ================================================ SELECT CounterID, count(), maxIf(SearchPhrase, notEmpty(SearchPhrase)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT CounterID, count(), maxIf(SearchPhrase, notEmpty(SearchPhrase)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SETTINGS optimize_aggregation_in_order = 1 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00050_min_max.sql ================================================ SELECT CounterID, min(WatchID), max(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT CounterID, min(WatchID), max(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SETTINGS optimize_aggregation_in_order = 1 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00051_min_max_array.sql ================================================ SELECT CounterID, count(), max(GoalsReached), min(GoalsReached), minIf(GoalsReached, notEmpty(GoalsReached)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT CounterID, count(), max(GoalsReached), min(GoalsReached), minIf(GoalsReached, notEmpty(GoalsReached)) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SETTINGS optimize_aggregation_in_order = 1 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00052_group_by_in.sql ================================================ select StartDate, TraficSourceID in (0) ? 'type_in' : 'other' as traf_type, sum(Sign) from test.visits where CounterID = 842440 group by StartDate, traf_type ORDER BY StartDate, traf_type ================================================ FILE: parser/testdata/query/compatible/1_stateful/00053_replicate_segfault.sql ================================================ -- Tags: replica SELECT count() > 0 FROM (SELECT ParsedParams.Key1 AS p FROM test.visits WHERE arrayAll(y -> arrayExists(x -> y != x, p), p)) ================================================ FILE: parser/testdata/query/compatible/1_stateful/00054_merge_tree_partitions.sql ================================================ DROP TABLE IF EXISTS test.partitions; set allow_deprecated_syntax_for_merge_tree=1; CREATE TABLE test.partitions (EventDate Date, CounterID UInt32) ENGINE = MergeTree(EventDate, CounterID, 8192); INSERT INTO test.partitions SELECT EventDate + UserID % 365 AS EventDate, CounterID FROM test.hits WHERE CounterID = 1704509; SELECT count() FROM test.partitions; SELECT count() FROM test.partitions WHERE EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01'); SELECT count() FROM test.partitions WHERE EventDate < toDate('2015-01-01') OR EventDate >= toDate('2015-02-01'); ALTER TABLE test.partitions DETACH PARTITION 201501; SELECT count() FROM test.partitions; SELECT count() FROM test.partitions WHERE EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01'); SELECT count() FROM test.partitions WHERE EventDate < toDate('2015-01-01') OR EventDate >= toDate('2015-02-01'); ALTER TABLE test.partitions ATTACH PARTITION 201501; SELECT count() FROM test.partitions; SELECT count() FROM test.partitions WHERE EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01'); SELECT count() FROM test.partitions WHERE EventDate < toDate('2015-01-01') OR EventDate >= toDate('2015-02-01'); ALTER TABLE test.partitions DETACH PARTITION 201403; SELECT count() FROM test.partitions; INSERT INTO test.partitions SELECT EventDate + UserID % 365 AS EventDate, CounterID FROM test.hits WHERE CounterID = 1704509 AND toStartOfMonth(EventDate) = toDate('2014-03-01'); SELECT count() FROM test.partitions; ALTER TABLE test.partitions ATTACH PARTITION 201403; SELECT count() FROM test.partitions; DROP TABLE test.partitions; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00055_index_and_not.sql ================================================ SELECT count() FROM test.hits WHERE NOT (EventDate >= toDate('2015-01-01') AND EventDate < toDate('2015-02-01')) ================================================ FILE: parser/testdata/query/compatible/1_stateful/00056_view.sql ================================================ DROP TABLE IF EXISTS test.view; CREATE VIEW test.view AS SELECT CounterID, count() AS c FROM test.hits GROUP BY CounterID; SELECT count() FROM test.view; SELECT c, count() FROM test.view GROUP BY c ORDER BY count() DESC LIMIT 10; SELECT * FROM test.view ORDER BY c DESC LIMIT 10; SELECT * FROM test.view SAMPLE 0.1 ORDER BY c DESC LIMIT 10; DROP TABLE test.view; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00059_merge_sorting_empty_array_joined.sql ================================================ SELECT CounterID FROM test.visits ARRAY JOIN Goals.ID WHERE CounterID = 942285 ORDER BY CounterID ================================================ FILE: parser/testdata/query/compatible/1_stateful/00060_move_to_prewhere_and_sets.sql ================================================ SET optimize_move_to_prewhere = 1; SELECT uniq(URL) FROM test.hits WHERE TraficSourceID IN (7); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00061_storage_buffer.sql ================================================ DROP TABLE IF EXISTS test.hits_dst; DROP TABLE IF EXISTS test.hits_buffer; CREATE TABLE test.hits_dst AS test.hits; CREATE TABLE test.hits_buffer AS test.hits_dst ENGINE = Buffer(test, hits_dst, 8, 1, 10, 10000, 100000, 10000000, 100000000); INSERT INTO test.hits_buffer SELECT * FROM test.hits WHERE CounterID = 800784; SELECT count() FROM test.hits_buffer; SELECT count() FROM test.hits_dst; OPTIMIZE TABLE test.hits_buffer; SELECT count() FROM test.hits_buffer; SELECT count() FROM test.hits_dst; DROP TABLE test.hits_dst; DROP TABLE test.hits_buffer; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00062_loyalty.sql ================================================ SELECT loyalty, count() AS c, bar(log(c + 1) * 1000, 0, log(6000) * 1000, 80) FROM (SELECT UserID, toInt8((yandex > google ? yandex / (yandex + google) : -google / (yandex + google)) * 10) AS loyalty FROM (SELECT UserID, sum(SearchEngineID = 2) AS yandex, sum(SearchEngineID = 3) AS google FROM test.hits WHERE SearchEngineID = 2 OR SearchEngineID = 3 GROUP BY UserID HAVING yandex + google > 10)) GROUP BY loyalty ORDER BY loyalty ================================================ FILE: parser/testdata/query/compatible/1_stateful/00063_loyalty_joins.sql ================================================ SET any_join_distinct_right_table_keys = 1; SET joined_subquery_requires_alias = 0; SELECT loyalty, count() FROM test.hits ANY LEFT JOIN ( SELECT UserID, sum(SearchEngineID = 2) AS yandex, sum(SearchEngineID = 3) AS google, toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty FROM test.hits WHERE (SearchEngineID = 2) OR (SearchEngineID = 3) GROUP BY UserID HAVING (yandex + google) > 10 ) USING UserID GROUP BY loyalty ORDER BY loyalty ASC; SELECT loyalty, count() FROM ( SELECT UserID FROM test.hits ) ANY LEFT JOIN ( SELECT UserID, sum(SearchEngineID = 2) AS yandex, sum(SearchEngineID = 3) AS google, toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty FROM test.hits WHERE (SearchEngineID = 2) OR (SearchEngineID = 3) GROUP BY UserID HAVING (yandex + google) > 10 ) USING UserID GROUP BY loyalty ORDER BY loyalty ASC; SELECT loyalty, count() FROM ( SELECT loyalty, UserID FROM ( SELECT UserID FROM test.hits ) ANY LEFT JOIN ( SELECT UserID, sum(SearchEngineID = 2) AS yandex, sum(SearchEngineID = 3) AS google, toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty FROM test.hits WHERE (SearchEngineID = 2) OR (SearchEngineID = 3) GROUP BY UserID HAVING (yandex + google) > 10 ) USING UserID ) GROUP BY loyalty ORDER BY loyalty ASC; SELECT loyalty, count() AS c, bar(log(c + 1) * 1000, 0, log(3000000) * 1000, 80) FROM test.hits ANY INNER JOIN ( SELECT UserID, toInt8(if(yandex > google, yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty FROM ( SELECT UserID, sum(SearchEngineID = 2) AS yandex, sum(SearchEngineID = 3) AS google FROM test.hits WHERE (SearchEngineID = 2) OR (SearchEngineID = 3) GROUP BY UserID HAVING (yandex + google) > 10 ) ) USING UserID GROUP BY loyalty ORDER BY loyalty ASC; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00065_loyalty_with_storage_join.sql ================================================ USE test; DROP TABLE IF EXISTS join; CREATE TABLE join (UserID UInt64, loyalty Int8) ENGINE = Join(SEMI, LEFT, UserID); INSERT INTO join SELECT UserID, toInt8(if((sum(SearchEngineID = 2) AS yandex) > (sum(SearchEngineID = 3) AS google), yandex / (yandex + google), -google / (yandex + google)) * 10) AS loyalty FROM hits WHERE (SearchEngineID = 2) OR (SearchEngineID = 3) GROUP BY UserID HAVING (yandex + google) > 10; SELECT loyalty, count() FROM hits SEMI LEFT JOIN join USING UserID GROUP BY loyalty ORDER BY loyalty ASC; DETACH TABLE join; ATTACH TABLE join; SELECT loyalty, count() FROM hits SEMI LEFT JOIN join USING UserID GROUP BY loyalty ORDER BY loyalty ASC; DROP TABLE join; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00066_sorting_distributed_many_replicas.sql ================================================ -- Tags: replica, distributed, no-random-settings SET max_parallel_replicas = 2; SELECT EventTime::DateTime('Asia/Dubai') FROM remote('127.0.0.{1|2}', test, hits) ORDER BY EventTime DESC LIMIT 10 ================================================ FILE: parser/testdata/query/compatible/1_stateful/00067_union_all.sql ================================================ SELECT * FROM ( SELECT UserID AS id, 1 AS event FROM remote('127.0.0.{1,2}', test, hits) ORDER BY id DESC LIMIT 10 UNION ALL SELECT FUniqID AS id, 2 AS event FROM remote('127.0.0.{1,2}', test, hits) ORDER BY id DESC LIMIT 10 ) ORDER BY id, event; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00068_subquery_in_prewhere.sql ================================================ SELECT count() FROM test.hits PREWHERE UserID IN (SELECT UserID FROM test.hits WHERE CounterID = 800784); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00069_duplicate_aggregation_keys.sql ================================================ SELECT URL, EventDate, max(URL) FROM test.hits WHERE CounterID = 1704509 AND UserID = 4322253409885123546 GROUP BY URL, EventDate, EventDate ORDER BY URL, EventDate; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00071_merge_tree_optimize_aio.sql ================================================ DROP TABLE IF EXISTS test.hits_snippet; set allow_deprecated_syntax_for_merge_tree=1; CREATE TABLE test.hits_snippet(EventTime DateTime('Asia/Dubai'), EventDate Date, CounterID UInt32, UserID UInt64, URL String, Referer String) ENGINE = MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID), EventTime), 8192); SET min_insert_block_size_rows = 0, min_insert_block_size_bytes = 0; SET max_block_size = 4096; INSERT INTO test.hits_snippet(EventTime, EventDate, CounterID, UserID, URL, Referer) SELECT EventTime, EventDate, CounterID, UserID, URL, Referer FROM test.hits WHERE EventDate = toDate('2014-03-18') ORDER BY EventTime, EventDate, CounterID, UserID, URL, Referer ASC LIMIT 50; INSERT INTO test.hits_snippet(EventTime, EventDate, CounterID, UserID, URL, Referer) SELECT EventTime, EventDate, CounterID, UserID, URL, Referer FROM test.hits WHERE EventDate = toDate('2014-03-19') ORDER BY EventTime, EventDate, CounterID, UserID, URL, Referer ASC LIMIT 50; SET min_bytes_to_use_direct_io = 8192; OPTIMIZE TABLE test.hits_snippet; SELECT EventTime, EventDate, CounterID, UserID, URL, Referer FROM test.hits_snippet ORDER BY EventTime, EventDate, CounterID, UserID, URL, Referer ASC; DROP TABLE test.hits_snippet; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00072_compare_date_and_string_index.sql ================================================ SELECT count() FROM test.hits WHERE EventDate = '2014-03-18'; SELECT count() FROM test.hits WHERE EventDate < '2014-03-18'; SELECT count() FROM test.hits WHERE EventDate > '2014-03-18'; SELECT count() FROM test.hits WHERE EventDate <= '2014-03-18'; SELECT count() FROM test.hits WHERE EventDate >= '2014-03-18'; SELECT count() FROM test.hits WHERE EventDate IN ('2014-03-18', '2014-03-19'); SELECT count() FROM test.hits WHERE EventDate = toDate('2014-03-18'); SELECT count() FROM test.hits WHERE EventDate < toDate('2014-03-18'); SELECT count() FROM test.hits WHERE EventDate > toDate('2014-03-18'); SELECT count() FROM test.hits WHERE EventDate <= toDate('2014-03-18'); SELECT count() FROM test.hits WHERE EventDate >= toDate('2014-03-18'); SELECT count() FROM test.hits WHERE EventDate IN (toDate('2014-03-18'), toDate('2014-03-19')); SELECT count() FROM test.hits WHERE EventDate = concat('2014-0', '3-18'); DROP TABLE IF EXISTS test.hits_indexed_by_time; CREATE TABLE test.hits_indexed_by_time (EventDate Date, EventTime DateTime('Asia/Dubai')) ENGINE = MergeTree ORDER BY (EventDate, EventTime); INSERT INTO test.hits_indexed_by_time SELECT EventDate, EventTime FROM test.hits; SELECT count() FROM test.hits_indexed_by_time WHERE EventTime = '2014-03-18 01:02:03'; SELECT count() FROM test.hits_indexed_by_time WHERE EventTime < '2014-03-18 01:02:03'; SELECT count() FROM test.hits_indexed_by_time WHERE EventTime > '2014-03-18 01:02:03'; SELECT count() FROM test.hits_indexed_by_time WHERE EventTime <= '2014-03-18 01:02:03'; SELECT count() FROM test.hits_indexed_by_time WHERE EventTime >= '2014-03-18 01:02:03'; SELECT count() FROM test.hits_indexed_by_time WHERE EventTime IN ('2014-03-18 01:02:03', '2014-03-19 04:05:06'); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime = toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime < toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime > toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime <= toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime >= toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime IN (toDateTime('2014-03-18 01:02:03', 'Asia/Dubai'), toDateTime('2014-03-19 04:05:06', 'Asia/Dubai')); SELECT count() FROM test.hits_indexed_by_time WHERE EventTime = concat('2014-03-18 ', '01:02:03'); DROP TABLE test.hits_indexed_by_time; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00073_uniq_array.sql ================================================ SELECT EventDate, uniqExact(UserID), length(groupUniqArray(UserID)), arrayUniq(groupArray(UserID)) FROM test.hits WHERE CounterID = 1704509 GROUP BY EventDate ORDER BY EventDate; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00074_full_join.sql ================================================ set any_join_distinct_right_table_keys = 1; set joined_subquery_requires_alias = 0; SELECT CounterID, hits, visits FROM ( SELECT (CounterID % 100000) AS CounterID, count() AS hits FROM test.hits GROUP BY CounterID ) ANY FULL OUTER JOIN ( SELECT (CounterID % 100000) AS CounterID, sum(Sign) AS visits FROM test.visits GROUP BY CounterID HAVING visits > 0 ) USING CounterID WHERE hits = 0 OR visits = 0 ORDER BY hits + visits * 10 DESC, CounterID ASC LIMIT 20; SELECT CounterID, hits, visits FROM ( SELECT (CounterID % 100000) AS CounterID, count() AS hits FROM test.hits GROUP BY CounterID ) ANY LEFT JOIN ( SELECT (CounterID % 100000) AS CounterID, sum(Sign) AS visits FROM test.visits GROUP BY CounterID HAVING visits > 0 ) USING CounterID WHERE hits = 0 OR visits = 0 ORDER BY hits + visits * 10 DESC, CounterID ASC LIMIT 20; SELECT CounterID, hits, visits FROM ( SELECT (CounterID % 100000) AS CounterID, count() AS hits FROM test.hits GROUP BY CounterID ) ANY RIGHT JOIN ( SELECT (CounterID % 100000) AS CounterID, sum(Sign) AS visits FROM test.visits GROUP BY CounterID HAVING visits > 0 ) USING CounterID WHERE hits = 0 OR visits = 0 ORDER BY hits + visits * 10 DESC, CounterID ASC LIMIT 20; SELECT CounterID, hits, visits FROM ( SELECT (CounterID % 100000) AS CounterID, count() AS hits FROM test.hits GROUP BY CounterID ) ANY INNER JOIN ( SELECT (CounterID % 100000) AS CounterID, sum(Sign) AS visits FROM test.visits GROUP BY CounterID HAVING visits > 0 ) USING CounterID WHERE hits = 0 OR visits = 0 ORDER BY hits + visits * 10 DESC, CounterID ASC LIMIT 20; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00075_left_array_join.sql ================================================ SELECT UserID, EventTime::DateTime('Asia/Dubai'), pp.Key1, pp.Key2, ParsedParams.Key1 FROM test.hits ARRAY JOIN ParsedParams AS pp WHERE CounterID = 1704509 ORDER BY UserID, EventTime, pp.Key1, pp.Key2 LIMIT 100; SELECT UserID, EventTime::DateTime('Asia/Dubai'), pp.Key1, pp.Key2, ParsedParams.Key1 FROM test.hits LEFT ARRAY JOIN ParsedParams AS pp WHERE CounterID = 1704509 ORDER BY UserID, EventTime, pp.Key1, pp.Key2 LIMIT 100; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00076_system_columns_bytes.sql ================================================ -- NOTE: database = currentDatabase() is not mandatory SELECT sum(data_compressed_bytes) > 0, sum(data_uncompressed_bytes) > 0, sum(marks_bytes) > 0 FROM system.columns; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00077_log_tinylog_stripelog.sql ================================================ SET check_query_single_value_result = 1; DROP TABLE IF EXISTS test.hits_log; DROP TABLE IF EXISTS test.hits_tinylog; DROP TABLE IF EXISTS test.hits_stripelog; CREATE TABLE test.hits_log (CounterID UInt32, AdvEngineID UInt8, RegionID UInt32, SearchPhrase String, UserID UInt64) ENGINE = Log; CREATE TABLE test.hits_tinylog (CounterID UInt32, AdvEngineID UInt8, RegionID UInt32, SearchPhrase String, UserID UInt64) ENGINE = TinyLog; CREATE TABLE test.hits_stripelog (CounterID UInt32, AdvEngineID UInt8, RegionID UInt32, SearchPhrase String, UserID UInt64) ENGINE = StripeLog; CHECK TABLE test.hits_log; CHECK TABLE test.hits_tinylog; CHECK TABLE test.hits_stripelog; INSERT INTO test.hits_log SELECT CounterID, AdvEngineID, RegionID, SearchPhrase, UserID FROM test.hits; INSERT INTO test.hits_tinylog SELECT CounterID, AdvEngineID, RegionID, SearchPhrase, UserID FROM test.hits; INSERT INTO test.hits_stripelog SELECT CounterID, AdvEngineID, RegionID, SearchPhrase, UserID FROM test.hits; SELECT count(), sum(cityHash64(CounterID, AdvEngineID, RegionID, SearchPhrase, UserID)) FROM test.hits; SELECT count(), sum(cityHash64(*)) FROM test.hits_log; SELECT count(), sum(cityHash64(*)) FROM test.hits_tinylog; SELECT count(), sum(cityHash64(*)) FROM test.hits_stripelog; CHECK TABLE test.hits_log; CHECK TABLE test.hits_tinylog; CHECK TABLE test.hits_stripelog; DROP TABLE test.hits_log; DROP TABLE test.hits_tinylog; DROP TABLE test.hits_stripelog; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00078_group_by_arrays.sql ================================================ SELECT GoalsReached AS k, count() AS c FROM test.hits GROUP BY k ORDER BY c DESC LIMIT 10; SELECT GeneralInterests AS k1, GoalsReached AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC LIMIT 10; SELECT ParsedParams.Key1 AS k1, GeneralInterests AS k2, count() AS c FROM test.hits GROUP BY k1, k2 ORDER BY c DESC LIMIT 10; SELECT ParsedParams.Key1 AS k1, GeneralInterests AS k2, count() AS c FROM test.hits WHERE notEmpty(k1) AND notEmpty(k2) GROUP BY k1, k2 ORDER BY c DESC LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00079_array_join_not_used_joined_column.sql ================================================ SELECT PP.Key1 AS `ym:s:paramsLevel1`, sum(arrayAll(`x_1` -> `x_1`= '', ParsedParams.Key2)) AS `ym:s:visits` FROM test.hits ARRAY JOIN ParsedParams AS `PP` WHERE CounterID = 1704509 GROUP BY `ym:s:paramsLevel1` ORDER BY PP.Key1, `ym:s:visits` LIMIT 0, 100; SELECT PP.Key1 AS x1, ParsedParams.Key2 AS x2 FROM test.hits ARRAY JOIN ParsedParams AS PP WHERE CounterID = 1704509 ORDER BY x1, x2 LIMIT 10; SELECT ParsedParams.Key2 AS x FROM test.hits ARRAY JOIN ParsedParams AS PP ORDER BY x DESC LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00080_array_join_and_union.sql ================================================ SELECT count() FROM (SELECT Goals.ID FROM test.visits ARRAY JOIN Goals WHERE CounterID = 842440 LIMIT 10 UNION ALL SELECT Goals.ID FROM test.visits ARRAY JOIN Goals WHERE CounterID = 842440 LIMIT 10); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00081_group_by_without_key_and_totals.sql ================================================ SET allow_experimental_analyzer = 1; SELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'before_having', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'after_having_inclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'after_having_exclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT count() AS c FROM test.hits WHERE CounterID = 1704509 WITH TOTALS SETTINGS totals_mode = 'after_having_auto', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'before_having', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'after_having_inclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'after_having_exclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT 1 AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS SETTINGS totals_mode = 'after_having_auto', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'before_having', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'after_having_inclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'after_having_exclusive', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; SELECT TraficSourceID AS k, count() AS c FROM test.hits WHERE CounterID = 1704509 GROUP BY k WITH TOTALS ORDER BY k SETTINGS totals_mode = 'after_having_auto', max_rows_to_group_by = 100000, group_by_overflow_mode = 'any'; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00082_quantiles.sql ================================================ SELECT CounterID AS k, quantileExact(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantilesExact(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantileTiming(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantilesTiming(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantileExact(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantilesExact(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantileTiming(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantilesTiming(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00083_array_filter.sql ================================================ SELECT sum(length(ParsedParams.Key1)) FROM test.hits WHERE notEmpty(ParsedParams.Key1); SELECT sum(length(ParsedParams.ValueDouble)) FROM test.hits WHERE notEmpty(ParsedParams.ValueDouble); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00084_external_aggregation.sql ================================================ SET max_bytes_before_external_group_by = 200000000; SET max_memory_usage = 1500000000; SET max_threads = 12; SELECT URL, uniq(SearchPhrase) AS u FROM test.hits GROUP BY URL ORDER BY u DESC, URL LIMIT 10; SET max_memory_usage = 300000000; SET max_threads = 2; SET aggregation_memory_efficient_merge_threads = 1; SELECT URL, uniq(SearchPhrase) AS u FROM test.hits GROUP BY URL ORDER BY u DESC, URL LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00085_monotonic_evaluation_segfault.sql ================================================ SELECT any(0) FROM test.visits WHERE (toInt32(toDateTime(StartDate))) > 1000000000; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00086_array_reduce.sql ================================================ SELECT arrayFilter(x -> x != 1, arrayMap((a, b) -> a = b, GeneralInterests, arrayReduce('groupArray', GeneralInterests))) AS res FROM test.hits WHERE length(res) != 0; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00087_where_0.sql ================================================ SET max_rows_to_read = 1000; SELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 != 0 GROUP BY CounterID; SELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 != 0 GROUP BY CounterID SETTINGS optimize_aggregation_in_order = 1; SELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 AND CounterID = 1704509 GROUP BY CounterID; SELECT CounterID, uniq(UserID) FROM test.hits WHERE 0 AND CounterID = 1704509 GROUP BY CounterID SETTINGS optimize_aggregation_in_order = 1; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00088_global_in_one_shard_and_rows_before_limit.sql ================================================ -- Tags: shard SET output_format_write_statistics = 0; SELECT EventDate, count() FROM remote('127.0.0.1', test.hits) WHERE UserID GLOBAL IN (SELECT UserID FROM test.hits) GROUP BY EventDate ORDER BY EventDate LIMIT 5 FORMAT JSONCompact; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00089_position_functions_with_non_constant_arg.sql ================================================ SET max_threads = 0; -- let's reset to automatic detection of the number of threads, otherwise test can be slow. SELECT count() FROM test.hits WHERE position(URL, 'metrika') != position(URL, materialize('metrika')); SELECT count() FROM test.hits WHERE positionCaseInsensitive(URL, 'metrika') != positionCaseInsensitive(URL, materialize('metrika')); SELECT count() FROM test.hits WHERE positionUTF8(Title, 'новости') != positionUTF8(Title, materialize('новости')); SELECT count() FROM test.hits WHERE positionCaseInsensitiveUTF8(Title, 'новости') != positionCaseInsensitiveUTF8(Title, materialize('новости')); SELECT position(URL, domain(URL)) AS x FROM test.hits WHERE x = 0 AND URL NOT LIKE '%yandex.ru%' LIMIT 100; SELECT URL FROM test.hits WHERE x > 10 ORDER BY position(URL, domain(URL)) AS x DESC, URL LIMIT 2; SELECT DISTINCT URL, URLDomain, position('http://yandex.ru/', domain(URL)) AS x FROM test.hits WHERE x > 8 ORDER BY position('http://yandex.ru/', domain(URL)) DESC, URL LIMIT 3; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00091_prewhere_two_conditions.sql ================================================ -- Tags: no-parallel-replicas -- Requires investigation (max_bytes_to_read is not respected) SET max_bytes_to_read = 600000000; SET optimize_move_to_prewhere = 1; SELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00'; SELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND URL != '' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00'; SELECT uniq(*) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00' AND EventDate = '2014-03-21'; WITH toTimeZone(EventTime, 'Asia/Dubai') AS xyz SELECT uniq(*) FROM test.hits WHERE xyz >= '2014-03-20 00:00:00' AND xyz < '2014-03-21 00:00:00' AND EventDate = '2014-03-21'; SET optimize_move_to_prewhere = 0; SELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00'; -- { serverError 307 } SELECT uniq(URL) FROM test.hits WHERE toTimeZone(EventTime, 'Asia/Dubai') >= '2014-03-20 00:00:00' AND URL != '' AND toTimeZone(EventTime, 'Asia/Dubai') < '2014-03-21 00:00:00'; -- { serverError 307 } ================================================ FILE: parser/testdata/query/compatible/1_stateful/00093_prewhere_array_join.sql ================================================ SELECT arrayJoin([SearchEngineID]) AS search_engine, URL FROM test.hits WHERE SearchEngineID != 0 AND search_engine != 0 FORMAT Null; SELECT arrayJoin([0]) AS browser, arrayJoin([SearchEngineID]) AS search_engine, URL FROM test.hits WHERE 1 AND (SearchEngineID != 0) AND (browser != 0) AND (search_engine != 0) FORMAT Null; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00094_order_by_array_join_limit.sql ================================================ SELECT `ParsedParams.Key2` AS x FROM test.hits ARRAY JOIN ParsedParams AS PP ORDER BY x ASC LIMIT 2; SELECT arrayJoin(`ParsedParams.Key2`) AS x FROM test.hits ORDER BY x ASC LIMIT 2; WITH arrayJoin(`ParsedParams.Key2`) AS pp SELECT ParsedParams.Key2 AS x FROM test.hits ORDER BY x ASC LIMIT 2; WITH arrayJoin(`ParsedParams.Key2`) AS pp SELECT ParsedParams.Key2 AS x FROM test.hits WHERE NOT ignore(pp) ORDER BY x ASC LIMIT 2; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00095_hyperscan_profiler.sql ================================================ -- Tags: no-debug, use-vectorscan -- Check that server does not get segfault due to bad stack unwinding from Hyperscan SET query_profiler_cpu_time_period_ns = 1000000; SET query_profiler_real_time_period_ns = 1000000; SELECT count() FROM test.hits WHERE multiFuzzyMatchAny(URL, 2, ['about/address', 'for_woman', '^https?://lm-company.ruy/$', 'ultimateguitar.com']); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00097_constexpr_in_index.sql ================================================ -- Even in presense of OR, we evaluate the "0 IN (1, 2, 3)" as a constant expression therefore it does not prevent the index analysis. SELECT count() FROM test.hits WHERE CounterID IN (14917930, 33034174) OR 0 IN (1, 2, 3) SETTINGS max_rows_to_read = 1000000, force_primary_key = 1; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00139_like.sql ================================================ /* Note that queries are written as the user doesn't really understand that the symbol _ has special meaning in LIKE pattern. */ SELECT count() FROM test.hits WHERE URL LIKE '%/avtomobili_s_probegom/_%__%__%__%'; SELECT count() FROM test.hits WHERE URL LIKE '/avtomobili_s_probegom/_%__%__%__%'; SELECT count() FROM test.hits WHERE URL LIKE '%_/avtomobili_s_probegom/_%__%__%__%'; SELECT count() FROM test.hits WHERE URL LIKE '%avtomobili%'; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00140_rename.sql ================================================ -- Tags: no-replicated-database, no-parallel -- Tag no-replicated-database: Does not support renaming of multiple tables in single query RENAME TABLE test.hits TO test.visits_tmp, test.visits TO test.hits, test.visits_tmp TO test.visits; SELECT sum(Sign) FROM test.hits WHERE CounterID = 912887; SELECT count() FROM test.visits WHERE CounterID = 732797; RENAME TABLE test.hits TO test.hits_tmp, test.hits_tmp TO test.hits; SELECT sum(Sign) FROM test.hits WHERE CounterID = 912887; SELECT count() FROM test.visits WHERE CounterID = 732797; RENAME TABLE test.hits TO test.visits_tmp, test.visits TO test.hits, test.visits_tmp TO test.visits; SELECT count() FROM test.hits WHERE CounterID = 732797; SELECT sum(Sign) FROM test.visits WHERE CounterID = 912887; RENAME TABLE test.hits TO test.hits2, test.hits2 TO test.hits3, test.hits3 TO test.hits4, test.hits4 TO test.hits5, test.hits5 TO test.hits6, test.hits6 TO test.hits7, test.hits7 TO test.hits8, test.hits8 TO test.hits9, test.hits9 TO test.hits10; SELECT count() FROM test.hits10 WHERE CounterID = 732797; RENAME TABLE test.hits10 TO test.hits; SELECT count() FROM test.hits WHERE CounterID = 732797; RENAME TABLE test.hits TO default.hits, test.visits TO test.hits; SELECT sum(Sign) FROM test.hits WHERE CounterID = 912887; SELECT count() FROM default.hits WHERE CounterID = 732797; RENAME TABLE test.hits TO test.visits, default.hits TO test.hits; SELECT count() FROM test.hits WHERE CounterID = 732797; SELECT sum(Sign) FROM test.visits WHERE CounterID = 912887; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00141_transform.sql ================================================ SELECT transform(SearchEngineID, [2, 3], ['Яндекс', 'Google'], 'Остальные') AS title, count() AS c FROM test.hits WHERE SearchEngineID != 0 GROUP BY title HAVING c > 0 ORDER BY c DESC LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00142_system_columns.sql ================================================ SELECT table, name, type, default_kind, default_expression FROM system.columns WHERE database = 'test' AND table = 'hits' ================================================ FILE: parser/testdata/query/compatible/1_stateful/00143_transform_non_const_default.sql ================================================ SELECT transform(SearchEngineID, [2, 3], ['Яндекс', 'Google'], PageCharset) AS title, count() AS c FROM test.hits WHERE SearchEngineID != 0 GROUP BY title HAVING c > 0 ORDER BY c DESC LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00144_functions_of_aggregation_states.sql ================================================ SELECT EventDate, finalizeAggregation(state), runningAccumulate(state) FROM (SELECT EventDate, uniqState(UserID) AS state FROM test.hits GROUP BY EventDate ORDER BY EventDate); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00145_aggregate_functions_statistics.sql ================================================ SELECT varSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0); SELECT varSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1); SELECT round(varSamp(ResolutionWidth), 6) FROM test.hits; SELECT stddevSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0); SELECT stddevSamp(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1); SELECT round(stddevSamp(ResolutionWidth), 6) FROM test.hits; SELECT varPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0); SELECT varPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1); SELECT round(varPop(ResolutionWidth), 6) FROM test.hits; SELECT stddevPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 0); SELECT stddevPop(ResolutionWidth) FROM (SELECT ResolutionWidth FROM test.hits LIMIT 1); SELECT round(stddevPop(ResolutionWidth), 6) FROM test.hits; SELECT covarSamp(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 0); SELECT covarSamp(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 1); SELECT round(covarSamp(ResolutionWidth, ResolutionHeight), 6) FROM test.hits; SELECT covarPop(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 0); SELECT covarPop(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 1); SELECT round(covarPop(ResolutionWidth, ResolutionHeight), 6) FROM test.hits; SELECT corr(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 0); SELECT corr(ResolutionWidth, ResolutionHeight) FROM (SELECT ResolutionWidth, ResolutionHeight FROM test.hits LIMIT 1); SELECT round(corr(ResolutionWidth, ResolutionHeight), 6) FROM test.hits; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00146_aggregate_function_uniq.sql ================================================ SELECT RegionID, uniqHLL12(WatchID) AS X FROM remote('127.0.0.{1,2}', test, hits) GROUP BY RegionID HAVING X > 100000 ORDER BY RegionID ASC; SELECT RegionID, uniqCombined(WatchID) AS X FROM remote('127.0.0.{1,2}', test, hits) GROUP BY RegionID HAVING X > 100000 ORDER BY RegionID ASC; SELECT abs(uniq(WatchID) - uniqExact(WatchID)) FROM test.hits; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00147_global_in_aggregate_function.sql ================================================ -- Tags: global SELECT sum(UserID GLOBAL IN (SELECT UserID FROM remote('127.0.0.{1,2}', test.hits))) FROM remote('127.0.0.{1,2}', test.hits); SELECT sum(UserID GLOBAL IN (SELECT UserID FROM test.hits)) FROM remote('127.0.0.{1,2}', test.hits); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00148_monotonic_functions_and_index.sql ================================================ SET max_rows_to_read = 60000; SELECT count() FROM test.hits WHERE -CounterID = -1731; SELECT count() FROM test.hits WHERE abs(-CounterID) = 1731; SELECT count() FROM test.hits WHERE -abs(CounterID) = -1731; SELECT count() FROM test.hits WHERE toUInt32(CounterID) = 1731; SELECT count() FROM test.hits WHERE toInt32(CounterID) = 1731; SELECT count() FROM test.hits WHERE toFloat32(CounterID) = 1731; SET max_rows_to_read = 0; SELECT count() FROM test.hits WHERE toInt16(CounterID) = 1731; SELECT count() FROM test.hits WHERE toInt8(CounterID) = toInt8(1731); SELECT count() FROM test.hits WHERE toDate(toUInt16(CounterID)) = toDate(1731); SELECT uniq(CounterID), uniqUpTo(5)(toInt8(CounterID)), count() FROM test.hits WHERE toInt8(CounterID + 1 - 1) = toInt8(1731); SELECT uniq(CounterID), uniqUpTo(5)(toInt8(CounterID)), count() FROM test.hits WHERE toInt8(CounterID) = toInt8(1731); SELECT uniq(CounterID), uniqUpTo(5)(toInt16(CounterID)), count() FROM test.hits WHERE toInt16(CounterID + 1 - 1) = 1731; SELECT uniq(CounterID), uniqUpTo(5)(toInt16(CounterID)), count() FROM test.hits WHERE toInt16(CounterID) = 1731; SET max_rows_to_read = 500000; SELECT uniq(CounterID), count() FROM test.hits WHERE toString(CounterID) = '1731'; SET max_rows_to_read = 2200000; SELECT count() FROM test.hits WHERE CounterID < 732797; SELECT count() FROM test.hits WHERE CounterID <= 732797; SELECT count() FROM test.hits WHERE CounterID < 732797 AND CounterID > 107931; SELECT count() FROM test.hits WHERE CounterID < 732797 AND CounterID >= 107931; SELECT count() FROM test.hits WHERE CounterID <= 732797 AND CounterID > 107931; SELECT count() FROM test.hits WHERE CounterID <= 732797 AND CounterID >= 107931; SELECT count() FROM test.hits WHERE -CounterID > -732797; SELECT count() FROM test.hits WHERE -CounterID >= -732797; SELECT count() FROM test.hits WHERE -CounterID > -732797 AND CounterID > 107931; SELECT count() FROM test.hits WHERE -CounterID > -732797 AND CounterID >= 107931; SELECT count() FROM test.hits WHERE -CounterID >= -732797 AND CounterID > 107931; SELECT count() FROM test.hits WHERE -CounterID >= -732797 AND CounterID >= 107931; SELECT count() FROM test.hits WHERE CounterID < 732797 AND -CounterID < -107931; SELECT count() FROM test.hits WHERE CounterID < 732797 AND -CounterID <= -107931; SELECT count() FROM test.hits WHERE CounterID <= 732797 AND -CounterID < -107931; SELECT count() FROM test.hits WHERE CounterID <= 732797 AND -CounterID <= -107931; SET max_rows_to_read = 0; SELECT count() FROM test.hits WHERE EventDate = '2014-03-20'; SELECT count() FROM test.hits WHERE toDayOfMonth(EventDate) = 20; SELECT count() FROM test.hits WHERE toDayOfWeek(EventDate) = 4; SELECT count() FROM test.hits WHERE toUInt16(EventDate) = toUInt16(toDate('2014-03-20')); SELECT count() FROM test.hits WHERE toInt64(EventDate) = toInt64(toDate('2014-03-20')); SELECT count() FROM test.hits WHERE toDateTime(EventDate) = '2014-03-20 00:00:00'; SET max_rows_to_read = 50000; SELECT count() FROM test.hits WHERE toMonth(EventDate) != 3; SELECT count() FROM test.hits WHERE toYear(EventDate) != 2014; SELECT count() FROM test.hits WHERE toDayOfMonth(EventDate) > 23 OR toDayOfMonth(EventDate) < 17; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00149_quantiles_timing_distributed.sql ================================================ -- Tags: distributed SELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID); SELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID) SETTINGS optimize_aggregation_in_order = 1; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00150_quantiles_timing_precision.sql ================================================ SELECT CounterID, quantileTiming(0.5)(SendTiming) AS qt, least(30000, quantileExact(0.5)(SendTiming)) AS qe, count() AS c, round(abs(qt - qe) / greatest(qt, qe) AS diff, 3) AS rounded_diff FROM test.hits WHERE SendTiming != -1 GROUP BY CounterID HAVING diff != 0 ORDER BY diff DESC; SELECT CounterID, quantileTiming(0.5)(SendTiming) AS qt, least(30000, quantileExact(0.5)(SendTiming)) AS qe, count() AS c, round(abs(qt - qe) / greatest(qt, qe) AS diff, 3) AS rounded_diff FROM test.hits WHERE SendTiming != -1 GROUP BY CounterID HAVING diff != 0 ORDER BY diff DESC SETTINGS optimize_aggregation_in_order = 1; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00151_order_by_read_in_order.sql ================================================ SET optimize_read_in_order = 1; SELECT CounterID FROM test.hits ORDER BY CounterID DESC LIMIT 50; SELECT CounterID FROM test.hits ORDER BY CounterID LIMIT 50; SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; SELECT EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; SELECT EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; SELECT CounterID FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; SELECT EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate LIMIT 50; SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00152_insert_different_granularity.sql ================================================ -- Tags: no-tsan, no-replicated-database, no-parallel -- Tag no-replicated-database: Fails due to additional replicas or shards DROP TABLE IF EXISTS fixed_granularity_table; CREATE TABLE fixed_granularity_table (`WatchID` UInt64, `JavaEnable` UInt8, `Title` String, `GoodEvent` Int16, `EventTime` DateTime, `EventDate` Date, `CounterID` UInt32, `ClientIP` UInt32, `ClientIP6` FixedString(16), `RegionID` UInt32, `UserID` UInt64, `CounterClass` Int8, `OS` UInt8, `UserAgent` UInt8, `URL` String, `Referer` String, `URLDomain` String, `RefererDomain` String, `Refresh` UInt8, `IsRobot` UInt8, `RefererCategories` Array(UInt16), `URLCategories` Array(UInt16), `URLRegions` Array(UInt32), `RefererRegions` Array(UInt32), `ResolutionWidth` UInt16, `ResolutionHeight` UInt16, `ResolutionDepth` UInt8, `FlashMajor` UInt8, `FlashMinor` UInt8, `FlashMinor2` String, `NetMajor` UInt8, `NetMinor` UInt8, `UserAgentMajor` UInt16, `UserAgentMinor` FixedString(2), `CookieEnable` UInt8, `JavascriptEnable` UInt8, `IsMobile` UInt8, `MobilePhone` UInt8, `MobilePhoneModel` String, `Params` String, `IPNetworkID` UInt32, `TraficSourceID` Int8, `SearchEngineID` UInt16, `SearchPhrase` String, `AdvEngineID` UInt8, `IsArtifical` UInt8, `WindowClientWidth` UInt16, `WindowClientHeight` UInt16, `ClientTimeZone` Int16, `ClientEventTime` DateTime, `SilverlightVersion1` UInt8, `SilverlightVersion2` UInt8, `SilverlightVersion3` UInt32, `SilverlightVersion4` UInt16, `PageCharset` String, `CodeVersion` UInt32, `IsLink` UInt8, `IsDownload` UInt8, `IsNotBounce` UInt8, `FUniqID` UInt64, `HID` UInt32, `IsOldCounter` UInt8, `IsEvent` UInt8, `IsParameter` UInt8, `DontCountHits` UInt8, `WithHash` UInt8, `HitColor` FixedString(1), `UTCEventTime` DateTime, `Age` UInt8, `Sex` UInt8, `Income` UInt8, `Interests` UInt16, `Robotness` UInt8, `GeneralInterests` Array(UInt16), `RemoteIP` UInt32, `RemoteIP6` FixedString(16), `WindowName` Int32, `OpenerName` Int32, `HistoryLength` Int16, `BrowserLanguage` FixedString(2), `BrowserCountry` FixedString(2), `SocialNetwork` String, `SocialAction` String, `HTTPError` UInt16, `SendTiming` Int32, `DNSTiming` Int32, `ConnectTiming` Int32, `ResponseStartTiming` Int32, `ResponseEndTiming` Int32, `FetchTiming` Int32, `RedirectTiming` Int32, `DOMInteractiveTiming` Int32, `DOMContentLoadedTiming` Int32, `DOMCompleteTiming` Int32, `LoadEventStartTiming` Int32, `LoadEventEndTiming` Int32, `NSToDOMContentLoadedTiming` Int32, `FirstPaintTiming` Int32, `RedirectCount` Int8, `SocialSourceNetworkID` UInt8, `SocialSourcePage` String, `ParamPrice` Int64, `ParamOrderID` String, `ParamCurrency` FixedString(3), `ParamCurrencyID` UInt16, `GoalsReached` Array(UInt32), `OpenstatServiceName` String, `OpenstatCampaignID` String, `OpenstatAdID` String, `OpenstatSourceID` String, `UTMSource` String, `UTMMedium` String, `UTMCampaign` String, `UTMContent` String, `UTMTerm` String, `FromTag` String, `HasGCLID` UInt8, `RefererHash` UInt64, `URLHash` UInt64, `CLID` UInt32, `YCLID` UInt64, `ShareService` String, `ShareURL` String, `ShareTitle` String, `ParsedParams.Key1` Array(String), `ParsedParams.Key2` Array(String), `ParsedParams.Key3` Array(String), `ParsedParams.Key4` Array(String), `ParsedParams.Key5` Array(String), `ParsedParams.ValueDouble` Array(Float64), `IslandID` FixedString(16), `RequestNum` UInt32, `RequestTry` UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192, index_granularity_bytes=0, min_bytes_for_wide_part = 0; -- looks like default table before update ALTER TABLE fixed_granularity_table REPLACE PARTITION 201403 FROM test.hits; INSERT INTO fixed_granularity_table SELECT * FROM test.hits LIMIT 10; -- should still have non adaptive granularity INSERT INTO fixed_granularity_table SELECT * FROM test.hits LIMIT 10; -- We have removed testing of OPTIMIZE because it's too heavy on very slow builds (debug + coverage + thread fuzzer with sleeps) -- OPTIMIZE TABLE fixed_granularity_table FINAL; -- and even after optimize DETACH TABLE fixed_granularity_table; ATTACH TABLE fixed_granularity_table; ALTER TABLE fixed_granularity_table DETACH PARTITION 201403; ALTER TABLE fixed_granularity_table ATTACH PARTITION 201403; SELECT count() from fixed_granularity_table; DROP TABLE IF EXISTS fixed_granularity_table; ALTER TABLE test.hits DETACH PARTITION 201403; ALTER TABLE test.hits ATTACH PARTITION 201403; DROP TABLE IF EXISTS hits_copy; CREATE TABLE hits_copy (`WatchID` UInt64, `JavaEnable` UInt8, `Title` String, `GoodEvent` Int16, `EventTime` DateTime, `EventDate` Date, `CounterID` UInt32, `ClientIP` UInt32, `ClientIP6` FixedString(16), `RegionID` UInt32, `UserID` UInt64, `CounterClass` Int8, `OS` UInt8, `UserAgent` UInt8, `URL` String, `Referer` String, `URLDomain` String, `RefererDomain` String, `Refresh` UInt8, `IsRobot` UInt8, `RefererCategories` Array(UInt16), `URLCategories` Array(UInt16), `URLRegions` Array(UInt32), `RefererRegions` Array(UInt32), `ResolutionWidth` UInt16, `ResolutionHeight` UInt16, `ResolutionDepth` UInt8, `FlashMajor` UInt8, `FlashMinor` UInt8, `FlashMinor2` String, `NetMajor` UInt8, `NetMinor` UInt8, `UserAgentMajor` UInt16, `UserAgentMinor` FixedString(2), `CookieEnable` UInt8, `JavascriptEnable` UInt8, `IsMobile` UInt8, `MobilePhone` UInt8, `MobilePhoneModel` String, `Params` String, `IPNetworkID` UInt32, `TraficSourceID` Int8, `SearchEngineID` UInt16, `SearchPhrase` String, `AdvEngineID` UInt8, `IsArtifical` UInt8, `WindowClientWidth` UInt16, `WindowClientHeight` UInt16, `ClientTimeZone` Int16, `ClientEventTime` DateTime, `SilverlightVersion1` UInt8, `SilverlightVersion2` UInt8, `SilverlightVersion3` UInt32, `SilverlightVersion4` UInt16, `PageCharset` String, `CodeVersion` UInt32, `IsLink` UInt8, `IsDownload` UInt8, `IsNotBounce` UInt8, `FUniqID` UInt64, `HID` UInt32, `IsOldCounter` UInt8, `IsEvent` UInt8, `IsParameter` UInt8, `DontCountHits` UInt8, `WithHash` UInt8, `HitColor` FixedString(1), `UTCEventTime` DateTime, `Age` UInt8, `Sex` UInt8, `Income` UInt8, `Interests` UInt16, `Robotness` UInt8, `GeneralInterests` Array(UInt16), `RemoteIP` UInt32, `RemoteIP6` FixedString(16), `WindowName` Int32, `OpenerName` Int32, `HistoryLength` Int16, `BrowserLanguage` FixedString(2), `BrowserCountry` FixedString(2), `SocialNetwork` String, `SocialAction` String, `HTTPError` UInt16, `SendTiming` Int32, `DNSTiming` Int32, `ConnectTiming` Int32, `ResponseStartTiming` Int32, `ResponseEndTiming` Int32, `FetchTiming` Int32, `RedirectTiming` Int32, `DOMInteractiveTiming` Int32, `DOMContentLoadedTiming` Int32, `DOMCompleteTiming` Int32, `LoadEventStartTiming` Int32, `LoadEventEndTiming` Int32, `NSToDOMContentLoadedTiming` Int32, `FirstPaintTiming` Int32, `RedirectCount` Int8, `SocialSourceNetworkID` UInt8, `SocialSourcePage` String, `ParamPrice` Int64, `ParamOrderID` String, `ParamCurrency` FixedString(3), `ParamCurrencyID` UInt16, `GoalsReached` Array(UInt32), `OpenstatServiceName` String, `OpenstatCampaignID` String, `OpenstatAdID` String, `OpenstatSourceID` String, `UTMSource` String, `UTMMedium` String, `UTMCampaign` String, `UTMContent` String, `UTMTerm` String, `FromTag` String, `HasGCLID` UInt8, `RefererHash` UInt64, `URLHash` UInt64, `CLID` UInt32, `YCLID` UInt64, `ShareService` String, `ShareURL` String, `ShareTitle` String, `ParsedParams.Key1` Array(String), `ParsedParams.Key2` Array(String), `ParsedParams.Key3` Array(String), `ParsedParams.Key4` Array(String), `ParsedParams.Key5` Array(String), `ParsedParams.ValueDouble` Array(Float64), `IslandID` FixedString(16), `RequestNum` UInt32, `RequestTry` UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192, min_bytes_for_wide_part = 0; ALTER TABLE hits_copy REPLACE PARTITION 201403 FROM test.hits; -- It's important to test table, which were created before server update INSERT INTO test.hits SELECT * FROM hits_copy LIMIT 100; ALTER TABLE test.hits DETACH PARTITION 201403; ALTER TABLE test.hits ATTACH PARTITION 201403; -- OPTIMIZE TABLE test.hits; SELECT count() FROM test.hits; -- restore hits ALTER TABLE test.hits REPLACE PARTITION 201403 FROM hits_copy; DROP TABLE IF EXISTS hits_copy; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00153_aggregate_arena_race.sql ================================================ -- Tags: race create temporary table dest00153 (`s` AggregateFunction(groupUniqArray, String)) engine Memory; insert into dest00153 select groupUniqArrayState(RefererDomain) from test.hits group by URLDomain; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00154_avro.sql ================================================ -- Tags: no-fasttest DROP TABLE IF EXISTS test.avro; SET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage CREATE TABLE test.avro AS test.hits ENGINE = File(Avro); INSERT INTO test.avro SELECT * FROM test.hits LIMIT 10000; SELECT sum(cityHash64(*)) FROM (SELECT * FROM test.hits LIMIT 10000); SELECT sum(cityHash64(*)) FROM test.avro; DROP TABLE test.avro; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00156_max_execution_speed_sample_merge.sql ================================================ SET max_execution_speed = 4000000, timeout_before_checking_execution_speed = 0; CREATE TEMPORARY TABLE times (t DateTime); INSERT INTO times SELECT now(); SELECT count() FROM test.hits SAMPLE 1 / 2; INSERT INTO times SELECT now(); SELECT max(t) - min(t) >= 1 FROM times; TRUNCATE TABLE times; INSERT INTO times SELECT now(); SELECT count() FROM merge(test, '^hits$') SAMPLE 1 / 2; INSERT INTO times SELECT now(); SELECT max(t) - min(t) >= 1 FROM times; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00157_cache_dictionary.sql ================================================ -- Tags: no-tsan, no-parallel DROP TABLE IF EXISTS test.hits_1m; CREATE TABLE test.hits_1m as test.hits; INSERT INTO test.hits_1m SELECT * FROM test.hits LIMIT 1000000; CREATE DATABASE IF NOT EXISTS db_dict; --DROP DICTIONARY IF EXISTS db_dict.cache_hits; /* CREATE DICTIONARY db_dict.cache_hits (WatchID UInt64, UserID UInt64, SearchPhrase String) PRIMARY KEY WatchID SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'hits_1m' PASSWORD '' DB 'test')) LIFETIME(MIN 1 MAX 10) LAYOUT(CACHE(SIZE_IN_CELLS 1 QUERY_WAIT_TIMEOUT_MILLISECONDS 60000)); */ SELECT count() FROM (SELECT WatchID, arrayDistinct(groupArray(dictGetUInt64( 'db_dict.cache_hits', 'UserID', toUInt64(WatchID)))) as arr FROM test.hits_1m PREWHERE WatchID % 5 == 0 GROUP BY WatchID order by length(arr) desc) WHERE arr = [0]; SELECT count() FROM (SELECT WatchID, arrayDistinct(groupArray(dictGetUInt64( 'db_dict.cache_hits', 'UserID', toUInt64(WatchID)))) as arr FROM test.hits_1m PREWHERE WatchID % 7 == 0 GROUP BY WatchID order by length(arr) desc) WHERE arr = [0]; SELECT count() FROM (SELECT WatchID, arrayDistinct(groupArray(dictGetUInt64( 'db_dict.cache_hits', 'UserID', toUInt64(WatchID)))) as arr FROM test.hits_1m PREWHERE WatchID % 13 == 0 GROUP BY WatchID order by length(arr) desc) WHERE arr = [0]; DROP DICTIONARY IF EXISTS db_dict.cache_hits; DROP DATABASE IF EXISTS db_dict; DROP TABLE IF EXISTS hits_1m; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00158_cache_dictionary_has.sql ================================================ -- Tags: no-parallel CREATE DATABASE IF NOT EXISTS db_dict; DROP DICTIONARY IF EXISTS db_dict.cache_hits; /* CREATE DICTIONARY db_dict.cache_hits (WatchID UInt64, UserID UInt64, SearchPhrase String) PRIMARY KEY WatchID SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() USER 'default' TABLE 'hits' PASSWORD '' DB 'test')) LIFETIME(MIN 300 MAX 600) LAYOUT(CACHE(SIZE_IN_CELLS 100 QUERY_WAIT_TIMEOUT_MILLISECONDS 600000)); */ SELECT sum(flag) FROM (SELECT dictHas('db_dict.cache_hits', toUInt64(WatchID)) as flag FROM test.hits PREWHERE WatchID % 1400 == 0 LIMIT 100); SELECT count() from test.hits PREWHERE WatchID % 1400 == 0; SELECT sum(flag) FROM (SELECT dictHas('db_dict.cache_hits', toUInt64(WatchID)) as flag FROM test.hits PREWHERE WatchID % 350 == 0 LIMIT 100); SELECT count() from test.hits PREWHERE WatchID % 350 == 0; SELECT sum(flag) FROM (SELECT dictHas('db_dict.cache_hits', toUInt64(WatchID)) as flag FROM test.hits PREWHERE WatchID % 5 == 0 LIMIT 100); SELECT count() from test.hits PREWHERE WatchID % 5 == 0; DROP DICTIONARY IF EXISTS db_dict.cache_hits; DROP DATABASE IF EXISTS db_dict; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00160_decode_xml_component.sql ================================================ SELECT sum(DISTINCT sipHash64(decodeXMLComponent(Title) AS decoded)) FROM test.hits WHERE Title != decoded; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00162_mmap_compression_none.sql ================================================ DROP TABLE IF EXISTS hits_none; CREATE TABLE hits_none (Title String CODEC(NONE)) ENGINE = MergeTree ORDER BY tuple(); INSERT INTO hits_none SELECT Title FROM test.hits; SET min_bytes_to_use_mmap_io = 1; SELECT sum(length(Title)) FROM hits_none; DROP TABLE hits_none; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00164_quantileBfloat16.sql ================================================ SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantilesBFloat16(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; SELECT CounterID AS k, quantilesBFloat16(0.1, 0.5, 0.9, 0.99, 0.999)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test.hits) GROUP BY k ORDER BY count() DESC, CounterID LIMIT 10; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00165_jit_aggregate_functions.sql ================================================ SET compile_aggregate_expressions = 1; SET min_count_to_compile_aggregate_expression = 0; SELECT 'Aggregation using JIT compilation'; SELECT 'Simple functions'; SELECT CounterID, min(WatchID), max(WatchID), sum(WatchID), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT 'Simple functions with non compilable function'; SELECT CounterID, min(WatchID), max(WatchID), sum(WatchID), sum(toUInt128(WatchID)), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT 'Simple functions if combinator'; WITH (WatchID % 2 == 0) AS predicate SELECT CounterID, minIf(WatchID,predicate), maxIf(WatchID, predicate), sumIf(WatchID, predicate), avgIf(WatchID, predicate), avgWeightedIf(WatchID, CounterID, predicate), countIf(WatchID, predicate), groupBitOrIf(WatchID, predicate), groupBitAndIf(WatchID, predicate), groupBitXorIf(WatchID, predicate) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT 'Simple functions without key'; SELECT min(WatchID) AS min_watch_id, max(WatchID), sum(WatchID), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits ORDER BY min_watch_id DESC LIMIT 20; SELECT 'Simple functions with non compilable function without key'; SELECT min(WatchID) AS min_watch_id, max(WatchID), sum(WatchID), sum(toUInt128(WatchID)), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits ORDER BY min_watch_id DESC LIMIT 20; SELECT 'Simple functions if combinator without key'; WITH (WatchID % 2 == 0) AS predicate SELECT minIf(WatchID, predicate) as min_watch_id, maxIf(WatchID, predicate), sumIf(WatchID, predicate), avgIf(WatchID, predicate), avgWeightedIf(WatchID, CounterID, predicate), countIf(WatchID, predicate), groupBitOrIf(WatchID, predicate), groupBitAndIf(WatchID, predicate), groupBitXorIf(WatchID, predicate) FROM test.hits ORDER BY min_watch_id DESC LIMIT 20; SET compile_aggregate_expressions = 0; SELECT 'Aggregation without JIT compilation'; SELECT 'Simple functions'; SELECT CounterID, min(WatchID), max(WatchID), sum(WatchID), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT 'Simple functions with non compilable function'; SELECT CounterID, min(WatchID), max(WatchID), sum(WatchID), sum(toUInt128(WatchID)), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT 'Simple functions if combinator'; WITH (WatchID % 2 == 0) AS predicate SELECT CounterID, minIf(WatchID,predicate), maxIf(WatchID, predicate), sumIf(WatchID, predicate), avgIf(WatchID, predicate), avgWeightedIf(WatchID, CounterID, predicate), countIf(WatchID, predicate), groupBitOrIf(WatchID, predicate), groupBitAndIf(WatchID, predicate), groupBitXorIf(WatchID, predicate) FROM test.hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20; SELECT 'Simple functions without key'; SELECT min(WatchID) AS min_watch_id, max(WatchID), sum(WatchID), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits ORDER BY min_watch_id DESC LIMIT 20; SELECT 'Simple functions with non compilable function without key'; SELECT min(WatchID) AS min_watch_id, max(WatchID), sum(WatchID), sum(toUInt128(WatchID)), avg(WatchID), avgWeighted(WatchID, CounterID), count(WatchID), groupBitOr(WatchID), groupBitAnd(WatchID), groupBitXor(WatchID) FROM test.hits ORDER BY min_watch_id DESC LIMIT 20; SELECT 'Simple functions if combinator without key'; WITH (WatchID % 2 == 0) AS predicate SELECT minIf(WatchID, predicate) as min_watch_id, maxIf(WatchID, predicate), sumIf(WatchID, predicate), avgIf(WatchID, predicate), avgWeightedIf(WatchID, CounterID, predicate), countIf(WatchID, predicate), groupBitOrIf(WatchID, predicate), groupBitAndIf(WatchID, predicate), groupBitXorIf(WatchID, predicate) FROM test.hits ORDER BY min_watch_id DESC LIMIT 20; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00166_explain_estimate.sql ================================================ -- Tags: no-replicated-database -- Tag no-replicated-database: Requires investigation EXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID = 29103473; EXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID != 29103473; EXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID > 29103473; EXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID < 29103473; EXPLAIN ESTIMATE SELECT count() FROM test.hits WHERE CounterID = 29103473 UNION ALL SELECT count() FROM test.hits WHERE CounterID = 1704509; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00167_read_bytes_from_fs.sql ================================================ -- Tags: no-random-settings SELECT sum(cityHash64(*)) FROM test.hits SETTINGS max_threads=40; -- We had a bug which lead to additional compressed data read. test.hits compressed size is about 1.2Gb, but we read more then 3Gb. -- Small additional reads still possible, so we compare with about 1.5Gb. SYSTEM FLUSH LOGS; SELECT ProfileEvents['ReadBufferFromFileDescriptorReadBytes'] < 1500000000 from system.query_log where query = 'SELECT sum(cityHash64(*)) FROM test.hits SETTINGS max_threads=40;' and current_database = currentDatabase() and type = 'QueryFinish'; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00169_contingency.sql ================================================ WITH URLDomain AS a, URLDomain AS b SELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits; WITH URLDomain AS a, RefererDomain AS b SELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits; WITH URLDomain AS a, CounterID AS b SELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits; WITH ClientIP AS a, RemoteIP AS b SELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits; WITH ResolutionWidth AS a, ResolutionHeight AS b SELECT round(cramersV(a, b), 2), round(cramersVBiasCorrected(a, b), 2), round(theilsU(a, b), 2), round(theilsU(b, a), 2), round(contingency(a, b), 2) FROM test.hits; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00170_s3_cache.sql ================================================ -- Tags: no-parallel, no-random-settings -- { echo } SET allow_prefetched_read_pool_for_remote_filesystem=0; SET enable_filesystem_cache_on_write_operations=0; SET max_memory_usage='20G'; SYSTEM DROP FILESYSTEM CACHE; SELECT count() FROM test.hits_s3; SELECT count() FROM test.hits_s3 WHERE AdvEngineID != 0; SELECT sum(AdvEngineID), count(), avg(ResolutionWidth) FROM test.hits_s3 ; SELECT sum(UserID) FROM test.hits_s3 ; SELECT uniq(UserID) FROM test.hits_s3 ; SELECT uniq(SearchPhrase) FROM test.hits_s3 ; SELECT min(EventDate), max(EventDate) FROM test.hits_s3 ; SELECT AdvEngineID, count() FROM test.hits_s3 WHERE AdvEngineID != 0 GROUP BY AdvEngineID ORDER BY AdvEngineID DESC; SELECT RegionID, uniq(UserID) AS u FROM test.hits_s3 GROUP BY RegionID ORDER BY u DESC LIMIT 10; SELECT RegionID, sum(AdvEngineID), count() AS c, avg(ResolutionWidth), uniq(UserID) FROM test.hits_s3 GROUP BY RegionID ORDER BY c DESC LIMIT 10; SELECT MobilePhoneModel, uniq(UserID) AS u FROM test.hits_s3 WHERE MobilePhoneModel != '' GROUP BY MobilePhoneModel ORDER BY u DESC LIMIT 10; SELECT MobilePhone, MobilePhoneModel, uniq(UserID) AS u FROM test.hits_s3 WHERE MobilePhoneModel != '' GROUP BY MobilePhone, MobilePhoneModel ORDER BY u DESC LIMIT 10; SELECT uniq(SearchPhrase), count() AS c FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10; SELECT uniq(SearchPhrase), uniq(UserID) AS u FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchPhrase ORDER BY u DESC LIMIT 10; SELECT SearchEngineID, uniq(SearchPhrase), count() AS c FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchEngineID, SearchPhrase ORDER BY c DESC LIMIT 10; SELECT UserID, count() FROM test.hits_s3 GROUP BY UserID ORDER BY count() DESC LIMIT 10; SELECT UserID, uniq(SearchPhrase) as m, count() as c FROM test.hits_s3 GROUP BY UserID, SearchPhrase ORDER BY UserID, m, c DESC LIMIT 10; SELECT UserID, uniq(SearchPhrase) as m, count() as c FROM test.hits_s3 GROUP BY UserID, SearchPhrase ORDER BY UserID, m, c LIMIT 10; SELECT UserID, toMinute(EventTime) AS m, uniq(SearchPhrase) as u, count() as c FROM test.hits_s3 GROUP BY UserID, m, SearchPhrase ORDER BY UserID DESC LIMIT 10 FORMAT Null; SELECT UserID FROM test.hits_s3 WHERE UserID = 12345678901234567890; SELECT count() FROM test.hits_s3 WHERE URL LIKE '%metrika%'; SELECT uniq(SearchPhrase) as u, max(URL) as m, count() AS c FROM test.hits_s3 WHERE URL LIKE '%metrika%' AND SearchPhrase != '' GROUP BY SearchPhrase ORDER BY u, m, c DESC LIMIT 10; SELECT uniq(SearchPhrase), max(URL), max(Title), count() AS c, uniq(UserID) FROM test.hits_s3 WHERE Title LIKE '%Яндекс%' AND URL NOT LIKE '%.yandex.%' AND SearchPhrase != '' GROUP BY SearchPhrase ORDER BY c DESC LIMIT 10; SELECT * FROM test.hits_s3 WHERE URL LIKE '%metrika%' ORDER BY EventTime LIMIT 10 format Null; SELECT SearchPhrase FROM test.hits_s3 WHERE SearchPhrase != '' ORDER BY EventTime LIMIT 10 FORMAT Null; SELECT SearchPhrase FROM test.hits_s3 WHERE SearchPhrase != '' ORDER BY SearchPhrase LIMIT 10 FORMAT Null; SELECT SearchPhrase FROM test.hits_s3 WHERE SearchPhrase != '' ORDER BY EventTime, SearchPhrase LIMIT 10 FORMAT Null; SELECT CounterID, avg(length(URL)) AS l, count() AS c FROM test.hits_s3 WHERE URL != '' GROUP BY CounterID HAVING c > 100000 ORDER BY l DESC LIMIT 25; SELECT domainWithoutWWW(Referer) AS key, avg(length(Referer)) AS l, count() AS c, max(Referer) FROM test.hits_s3 WHERE Referer != '' GROUP BY key HAVING c > 100000 ORDER BY l DESC LIMIT 25; SELECT sum(ResolutionWidth), sum(ResolutionWidth + 1), sum(ResolutionWidth + 2), sum(ResolutionWidth + 3), sum(ResolutionWidth + 4), sum(ResolutionWidth + 5), sum(ResolutionWidth + 6), sum(ResolutionWidth + 7), sum(ResolutionWidth + 8), sum(ResolutionWidth + 9), sum(ResolutionWidth + 10), sum(ResolutionWidth + 11), sum(ResolutionWidth + 12), sum(ResolutionWidth + 13), sum(ResolutionWidth + 14), sum(ResolutionWidth + 15), sum(ResolutionWidth + 16), sum(ResolutionWidth + 17), sum(ResolutionWidth + 18), sum(ResolutionWidth + 19), sum(ResolutionWidth + 20), sum(ResolutionWidth + 21), sum(ResolutionWidth + 22), sum(ResolutionWidth + 23), sum(ResolutionWidth + 24), sum(ResolutionWidth + 25), sum(ResolutionWidth + 26), sum(ResolutionWidth + 27), sum(ResolutionWidth + 28), sum(ResolutionWidth + 29), sum(ResolutionWidth + 30), sum(ResolutionWidth + 31), sum(ResolutionWidth + 32), sum(ResolutionWidth + 33), sum(ResolutionWidth + 34), sum(ResolutionWidth + 35), sum(ResolutionWidth + 36), sum(ResolutionWidth + 37), sum(ResolutionWidth + 38), sum(ResolutionWidth + 39), sum(ResolutionWidth + 40), sum(ResolutionWidth + 41), sum(ResolutionWidth + 42), sum(ResolutionWidth + 43), sum(ResolutionWidth + 44), sum(ResolutionWidth + 45), sum(ResolutionWidth + 46), sum(ResolutionWidth + 47), sum(ResolutionWidth + 48), sum(ResolutionWidth + 49), sum(ResolutionWidth + 50), sum(ResolutionWidth + 51), sum(ResolutionWidth + 52), sum(ResolutionWidth + 53), sum(ResolutionWidth + 54), sum(ResolutionWidth + 55), sum(ResolutionWidth + 56), sum(ResolutionWidth + 57), sum(ResolutionWidth + 58), sum(ResolutionWidth + 59), sum(ResolutionWidth + 60), sum(ResolutionWidth + 61), sum(ResolutionWidth + 62), sum(ResolutionWidth + 63), sum(ResolutionWidth + 64), sum(ResolutionWidth + 65), sum(ResolutionWidth + 66), sum(ResolutionWidth + 67), sum(ResolutionWidth + 68), sum(ResolutionWidth + 69), sum(ResolutionWidth + 70), sum(ResolutionWidth + 71), sum(ResolutionWidth + 72), sum(ResolutionWidth + 73), sum(ResolutionWidth + 74), sum(ResolutionWidth + 75), sum(ResolutionWidth + 76), sum(ResolutionWidth + 77), sum(ResolutionWidth + 78), sum(ResolutionWidth + 79), sum(ResolutionWidth + 80), sum(ResolutionWidth + 81), sum(ResolutionWidth + 82), sum(ResolutionWidth + 83), sum(ResolutionWidth + 84), sum(ResolutionWidth + 85), sum(ResolutionWidth + 86), sum(ResolutionWidth + 87), sum(ResolutionWidth + 88), sum(ResolutionWidth + 89) FROM test.hits_s3; SELECT SearchEngineID, ClientIP, count() AS c, sum(Refresh), avg(ResolutionWidth) FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY SearchEngineID, ClientIP ORDER BY c DESC LIMIT 10; SELECT WatchID, ClientIP, count() AS c, sum(Refresh), avg(ResolutionWidth) FROM test.hits_s3 WHERE SearchPhrase != '' GROUP BY WatchID, ClientIP ORDER BY c, WatchID DESC LIMIT 10; SELECT WatchID, ClientIP, count() AS c, sum(Refresh), avg(ResolutionWidth) FROM test.hits_s3 GROUP BY WatchID, ClientIP ORDER BY c, WatchID DESC LIMIT 10; SELECT URL, count() AS c FROM test.hits_s3 GROUP BY URL ORDER BY c DESC LIMIT 10; SELECT 1, URL, count() AS c FROM test.hits_s3 GROUP BY 1, URL ORDER BY c DESC LIMIT 10; SELECT ClientIP AS x, x - 1, x - 2, x - 3, count() AS c FROM test.hits_s3 GROUP BY x, x - 1, x - 2, x - 3 ORDER BY c DESC LIMIT 10; SELECT URL, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT DontCountHits AND NOT Refresh AND notEmpty(URL) GROUP BY URL ORDER BY PageViews DESC LIMIT 10; SELECT Title, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT DontCountHits AND NOT Refresh AND notEmpty(Title) GROUP BY Title ORDER BY PageViews, Title DESC LIMIT 10; SELECT URL, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh AND IsLink AND NOT IsDownload GROUP BY URL ORDER BY PageViews DESC LIMIT 1000; SELECT TraficSourceID, SearchEngineID, AdvEngineID, ((SearchEngineID = 0 AND AdvEngineID = 0) ? Referer : '') AS Src, URL AS Dst, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh GROUP BY TraficSourceID, SearchEngineID, AdvEngineID, Src, Dst ORDER BY PageViews, TraficSourceID DESC LIMIT 1000; SELECT URLHash, EventDate, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh AND TraficSourceID IN (-1, 6) AND RefererHash = halfMD5('http://example.ru/') GROUP BY URLHash, EventDate ORDER BY PageViews DESC LIMIT 100; SELECT WindowClientWidth, WindowClientHeight, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-31' AND NOT Refresh AND NOT DontCountHits AND URLHash = halfMD5('http://example.ru/') GROUP BY WindowClientWidth, WindowClientHeight ORDER BY PageViews DESC LIMIT 10000; SELECT toStartOfMinute(EventTime) AS Minute, count() AS PageViews FROM test.hits_s3 WHERE CounterID = 62 AND EventDate >= '2013-07-01' AND EventDate <= '2013-07-02' AND NOT Refresh AND NOT DontCountHits GROUP BY Minute ORDER BY Minute; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00171_grouping_aggregated_transform_bug.sql ================================================ -- Tags: distributed SELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID) SETTINGS max_block_size = 63169; SELECT sum(cityHash64(*)) FROM (SELECT CounterID, quantileTiming(0.5)(SendTiming), count() FROM remote('127.0.0.{1,2,3,4,5,6,7,8,9,10}', test.hits) WHERE SendTiming != -1 GROUP BY CounterID) SETTINGS optimize_aggregation_in_order = 1, max_block_size = 63169; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00172_early_constant_folding.sql ================================================ -- Tags: no-parallel-replicas set max_threads=10; EXPLAIN PIPELINE SELECT count(JavaEnable) FROM test.hits WHERE WatchID = 1 OR Title = 'next' OR URL = 'prev' OR URL = '???' OR 1; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00173_group_by_use_nulls.sql ================================================ SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test, hits) GROUP BY k ORDER BY count() DESC, CounterID ASC LIMIT 10 SETTINGS group_by_use_nulls = 1; SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM test.hits GROUP BY k ORDER BY count() DESC, CounterID ASC LIMIT 10 SETTINGS group_by_use_nulls = 1 FORMAT Null; -- { echoOn } set allow_experimental_analyzer = 1; SELECT CounterID AS k, quantileBFloat16(0.5)(ResolutionWidth) FROM remote('127.0.0.{1,2}', test, hits) GROUP BY k ORDER BY count() DESC, CounterID ASC LIMIT 10 SETTINGS group_by_use_nulls = 1; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00174_distinct_in_order.sql ================================================ select '-- check that distinct with and w/o optimization produce the same result'; drop table if exists distinct_in_order sync; drop table if exists ordinary_distinct sync; select '-- DISTINCT columns are the same as in ORDER BY'; create table distinct_in_order (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate); insert into distinct_in_order select distinct CounterID, EventDate from test.hits order by CounterID, EventDate settings optimize_distinct_in_order=1; create table ordinary_distinct (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate); insert into ordinary_distinct select distinct CounterID, EventDate from test.hits order by CounterID, EventDate settings optimize_distinct_in_order=0; select distinct * from distinct_in_order except select * from ordinary_distinct; drop table if exists distinct_in_order sync; drop table if exists ordinary_distinct sync; select '-- DISTINCT columns has prefix in ORDER BY columns'; create table distinct_in_order (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate); insert into distinct_in_order select distinct CounterID, EventDate from test.hits order by CounterID settings optimize_distinct_in_order=1; create table ordinary_distinct (CounterID UInt32, EventDate Date) engine=MergeTree() order by (CounterID, EventDate); insert into ordinary_distinct select distinct CounterID, EventDate from test.hits order by CounterID settings optimize_distinct_in_order=0; select distinct * from distinct_in_order except select * from ordinary_distinct; drop table if exists distinct_in_order sync; drop table if exists ordinary_distinct sync; ================================================ FILE: parser/testdata/query/compatible/1_stateful/00175_counting_resources_in_subqueries.sql ================================================ -- the work for scalar subquery is properly accounted: SET max_rows_to_read = 1000000; SELECT 1 = (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 } -- the work for subquery in IN is properly accounted: SET max_rows_to_read = 1000000; SELECT 1 IN (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 } -- this query reads from the table twice: SET max_rows_to_read = 15000000; SELECT count() IN (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)) FROM test.hits WHERE NOT ignore(AdvEngineID); -- { serverError 158 } -- the resources are properly accounted even if the subquery is evaluated in advance to facilitate the index analysis. -- this query is using index and filter out the second reading pass. SET max_rows_to_read = 1000000; SELECT count() FROM test.hits WHERE CounterID > (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 } -- this query is using index but have to read all the data twice. SET max_rows_to_read = 10000000; SELECT count() FROM test.hits WHERE CounterID < (SELECT count() FROM test.hits WHERE NOT ignore(AdvEngineID)); -- { serverError 158 } ================================================ FILE: parser/testdata/query/compatible/1_stateful/00176_distinct_limit_by_limit_bug_43377.sql ================================================ SELECT count() FROM ( SELECT DISTINCT Title, SearchPhrase FROM test.hits WHERE (SearchPhrase != '') AND (NOT match(Title, '[а-яА-ЯёЁ]')) AND (NOT match(SearchPhrase, '[а-яА-ЯёЁ]')) LIMIT 1 BY Title LIMIT 10 ); ================================================ FILE: parser/testdata/query/compatible/1_stateful/00177_select_from_gcs.sql ================================================ SELECT * FROM gcs(gcs_creds,url='https://storage.googleapis.com/some-bucket/some-path/'); ================================================ FILE: parser/testdata/query/create_window_view.sql ================================================ CREATE OR REPLACE VIEW asdf AS SELECT id, price * 1.5 AS computed_value, row_number() OVER ( PARTITION BY category ORDER BY created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW ) AS rn FROM source_table WHERE date >= '2023-01-01'; ================================================ FILE: parser/testdata/query/format/access_tuple_with_dot.sql ================================================ -- Origin SQL: SELECT tuple('a','b','c').3, .1234; SELECT toTypeName( tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)), (tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)).second, tuple('a','b','c').3, tupleElement(tuple('a','b','c'),1) -- Format SQL: SELECT tuple('a', 'b', 'c').3, .1234; SELECT toTypeName(tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)), (tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)).second, tuple('a', 'b', 'c').3, tupleElement(tuple('a', 'b', 'c'), 1); ================================================ FILE: parser/testdata/query/format/beautify/access_tuple_with_dot.sql ================================================ -- Origin SQL: SELECT tuple('a','b','c').3, .1234; SELECT toTypeName( tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)), (tuple('a' as first,'b' as second ,'c' as third)::Tuple(first String,second String,third String)).second, tuple('a','b','c').3, tupleElement(tuple('a','b','c'),1) -- Beautify SQL: SELECT tuple('a', 'b', 'c').3, .1234; SELECT toTypeName(tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)), (tuple('a' AS first, 'b' AS second, 'c' AS third)::Tuple(first String, second String, third String)).second, tuple('a', 'b', 'c').3, tupleElement(tuple('a', 'b', 'c'), 1); ================================================ FILE: parser/testdata/query/format/beautify/create_window_view.sql ================================================ -- Origin SQL: CREATE OR REPLACE VIEW asdf AS SELECT id, price * 1.5 AS computed_value, row_number() OVER ( PARTITION BY category ORDER BY created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW ) AS rn FROM source_table WHERE date >= '2023-01-01'; -- Beautify SQL: CREATE OR REPLACE VIEW asdf AS SELECT id, price * 1.5 AS computed_value, row_number() OVER (PARTITION BY category ORDER BY created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW) AS rn FROM source_table WHERE date >= '2023-01-01'; ================================================ FILE: parser/testdata/query/format/beautify/query_with_expr_compare.sql ================================================ -- Origin SQL: SELECT date, path, splitByChar('/', path)[2] AS path_b FROM( SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date ) WHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30' AND splitByChar('/', path)[1] = 'pathA' -- Beautify SQL: SELECT date, path, splitByChar('/', path)[2] AS path_b FROM (SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date) WHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30' AND splitByChar('/', path)[1] = 'pathA'; ================================================ FILE: parser/testdata/query/format/beautify/select_case_multiple_when.sql ================================================ -- Origin SQL: SELECT *, CASE WHEN col2 = 'value1' THEN 'when1' WHEN col3 = 'value2' THEN 'when2' ELSE 'else' END as check_result FROM table_name WHERE col1 = '123456789' -- Beautify SQL: SELECT *, CASE WHEN col2 = 'value1' THEN 'when1' WHEN col3 = 'value2' THEN 'when2' ELSE 'else' END AS check_result FROM table_name WHERE col1 = '123456789'; ================================================ FILE: parser/testdata/query/format/beautify/select_case_when_exists.sql ================================================ -- Origin SQL: SELECT *, CASE WHEN EXISTS(SELECT 1 FROM table_name WHERE col1 = '999999999') THEN 'then' ELSE 'else' END as check_result FROM table_name WHERE col1 = '123456789' -- Beautify SQL: SELECT *, CASE WHEN EXISTS(SELECT 1 FROM table_name WHERE col1 = '999999999') THEN 'then' ELSE 'else' END AS check_result FROM table_name WHERE col1 = '123456789'; ================================================ FILE: parser/testdata/query/format/beautify/select_cast.sql ================================================ -- Origin SQL: select cast(1 as Float64) as value; select cast(1, 'Float64') as value; select (1 as Float64) as value; select 1::Float64 as value; -- Beautify SQL: SELECT CAST(1 AS Float64) AS value; SELECT CAST(1, 'Float64') AS value; SELECT (1 AS Float64) AS value; SELECT 1::Float64 AS value; ================================================ FILE: parser/testdata/query/format/beautify/select_column_alias_string.sql ================================================ -- Origin SQL: SELECT 'abc' as "value2"; SELECT $abc, a$$bc, abc$$; -- Beautify SQL: SELECT 'abc' AS "value2"; SELECT $abc, a$$bc, abc$$; ================================================ FILE: parser/testdata/query/format/beautify/select_concat_expr.sql ================================================ -- Origin SQL: SELECT 'a' || 'b'; SELECT 'a' || 'b' || 'c'; SELECT 'a' || 'b' || 'c' + 5; -- Beautify SQL: SELECT 'a' || 'b'; SELECT 'a' || 'b' || 'c'; SELECT 'a' || 'b' || 'c' + 5; ================================================ FILE: parser/testdata/query/format/beautify/select_expr.sql ================================================ -- Origin SQL: SELECT 1+1 -- Beautify SQL: SELECT 1 + 1; ================================================ FILE: parser/testdata/query/format/beautify/select_extract_with_regex.sql ================================================ -- Origin SQL: SELECT COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT FROM test.table WHERE app_id = 999118646 AND toUnixTimestamp(timestamp) >= 1740366695 AND toUnixTimestamp(timestamp) <= 1740377495 GROUP BY CASE WHEN length(extract(instance, '((\\d+\\.){3}\\d+)')) > 0 THEN instance ELSE '空' END, CASE WHEN length(extract(client_ip, '((\\d+\\.){3}\\d+)')) > 0 THEN client_ip ELSE '空' END, src_type, node_class, port, client_port LIMIT 10000 -- Beautify SQL: SELECT COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT FROM test.table WHERE app_id = 999118646 AND toUnixTimestamp(timestamp) >= 1740366695 AND toUnixTimestamp(timestamp) <= 1740377495 GROUP BY CASE WHEN length(EXTRACT(instance, '((\\d+\\.){3}\\d+)')) > 0 THEN instance ELSE '空' END, CASE WHEN length(EXTRACT(client_ip, '((\\d+\\.){3}\\d+)')) > 0 THEN client_ip ELSE '空' END, src_type, node_class, port, client_port LIMIT 10000; ================================================ FILE: parser/testdata/query/format/beautify/select_item_with_modifiers.sql ================================================ -- Origin SQL: SELECT c0 REPLACE(c0 AS c1) FROM t0; SELECT * REPLACE(i + 1 AS i) FROM t1; SELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from t2; -- Beautify SQL: SELECT c0 REPLACE(c0 AS c1) FROM t0; SELECT * REPLACE(i + 1 AS i) FROM t1; SELECT * REPLACE(i + 1 AS i) EXCEPT(j) APPLY(sum) FROM t2; ================================================ FILE: parser/testdata/query/format/beautify/select_json_type.sql ================================================ -- Origin SQL: SELECT a, a.b, a.b.c.d.e; SELECT JSON_TYPE('{"a": 1, "b": {"c": 2}}', '$.b'); SELECT CAST(some, 'String') AS value; SELECT CAST(some.long, 'String') AS value; SELECT CAST(some.long.json, 'String') AS value; SELECT CAST(some.long.json.path, 'String') AS value; -- Beautify SQL: SELECT a, a.b, a.b.c.d.e; SELECT JSON_TYPE('{"a": 1, "b": {"c": 2}}', '$.b'); SELECT CAST(some, 'String') AS value; SELECT CAST(some.long, 'String') AS value; SELECT CAST(some.long.json, 'String') AS value; SELECT CAST(some.long.json.path, 'String') AS value; ================================================ FILE: parser/testdata/query/format/beautify/select_keyword_alias_no_as.sql ================================================ -- Origin SQL: SELECT 'Joe' name FROM users -- Beautify SQL: SELECT 'Joe' AS name FROM users; ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_timestamp.sql ================================================ -- Origin SQL: SELECT Timestamp FROM events ORDER BY Timestamp; -- Beautify SQL: SELECT Timestamp FROM events ORDER BY Timestamp; ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_with_fill_basic.sql ================================================ -- Origin SQL: SELECT n, source FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL; -- Beautify SQL: SELECT n, source FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL; ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_with_fill_from_to.sql ================================================ -- Origin SQL: SELECT n, source FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5; -- Beautify SQL: SELECT n, source FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5; ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_with_fill_interpolate.sql ================================================ -- Origin SQL: SELECT n, source, inter FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1); -- Beautify SQL: SELECT n, source, inter FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1); ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_with_fill_interpolate_no_columns.sql ================================================ -- Origin SQL: SELECT n, value FROM ( SELECT toFloat32(number % 10) AS n, number AS value FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1 INTERPOLATE; -- Beautify SQL: SELECT n, value FROM (SELECT toFloat32(number % 10) AS n, number AS value FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1 INTERPOLATE; ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_with_fill_staleness.sql ================================================ -- Origin SQL: SELECT number as key, 5 * number value, 'original' AS source FROM numbers(16) WHERE (number % 5) == 0 ORDER BY key WITH FILL STALENESS 11; -- Beautify SQL: SELECT number AS key, 5 * number AS value, 'original' AS source FROM numbers(16) WHERE (number % 5) == 0 ORDER BY key WITH FILL STALENESS 11; ================================================ FILE: parser/testdata/query/format/beautify/select_order_by_with_fill_step.sql ================================================ -- Origin SQL: SELECT date, value FROM ( SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value FROM numbers(5) ) ORDER BY date WITH FILL STEP INTERVAL 1 DAY; -- Beautify SQL: SELECT date, value FROM (SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value FROM numbers(5)) ORDER BY date WITH FILL STEP INTERVAL 1 DAY; ================================================ FILE: parser/testdata/query/format/beautify/select_simple.sql ================================================ -- Origin SQL: SELECT f0, coalesce(f1, f2) AS f3, row_number() OVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c') GROUP BY f0, f1 Limit 100, 10 By f0; -- Beautify SQL: SELECT f0, coalesce(f1, f2) AS f3, row_number() OVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c') GROUP BY f0, f1 LIMIT 10 OFFSET 100 BY f0; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_field_alias.sql ================================================ -- Origin SQL: SELECT field0, field1 as x, field2 y from events; -- Beautify SQL: SELECT field0, field1 AS x, field2 AS y FROM events; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_bracket.sql ================================================ -- Origin SQL: SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1["abc"] as f2 -- Beautify SQL: SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1["abc"] AS f2; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_cte_with_column_aliases.sql ================================================ -- Origin SQL: WITH test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales) SELECT f1 AS new_f1, f2 AS new_f2, f3 AS new_f3 FROM test; -- Beautify SQL: WITH test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales) SELECT f1 AS new_f1, f2 AS new_f2, f3 AS new_f3 FROM test; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_group_by_with_cube_totals.sql ================================================ -- Origin SQL: SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a; -- Beautify SQL: SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_is_not_null.sql ================================================ -- Origin SQL: SELECT f0,f1,f2,f3 as a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL AND f3 IS NOT NULL -- Beautify SQL: SELECT f0, f1, f2, f3 AS a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL AND f3 IS NOT NULL; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_is_null.sql ================================================ -- Origin SQL: SELECT f0,f1,f2,f3 as a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL -- Beautify SQL: SELECT f0, f1, f2, f3 AS a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_limit.sql ================================================ -- Origin SQL: SELECT 1 LIMIT 1; SELECT 1 LIMIT 1 OFFSET 0; SELECT 1 OFFSET 0; -- Beautify SQL: SELECT 1 LIMIT 1; SELECT 1 LIMIT 1 OFFSET 0; SELECT 1 OFFSET 0; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_top_clause.sql ================================================ -- Origin SQL: SELECT TOP 10 my_column FROM tableName; -- Beautify SQL: SELECT TOP 10 my_column FROM tableName; ================================================ FILE: parser/testdata/query/format/beautify/select_simple_with_with_clause.sql ================================================ -- Origin SQL: WITH cte1 AS (SELECT f1 FROM t1), cte2 AS (SELECT f2 FROM t2) SELECT cte1.f1, cte2.f2, t3.f3 FROM t3,cte1,cte2 -- Beautify SQL: WITH cte1 AS (SELECT f1 FROM t1), cte2 AS (SELECT f2 FROM t2) SELECT cte1.f1, cte2.f2, t3.f3 FROM t3,cte1,cte2; ================================================ FILE: parser/testdata/query/format/beautify/select_table_alias_without_keyword.sql ================================================ -- Origin SQL: SELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b -- Beautify SQL: SELECT t1.Timestamp FROM my_table AS t1 INNER JOIN my_other_table AS t2 ON t1.a = t2.b; ================================================ FILE: parser/testdata/query/format/beautify/select_table_function_with_query.sql ================================================ -- Origin SQL: SELECT 1, (SELECT 70) AS `power`, number FROM numbers( plus( ifNull((SELECT 1 AS bin_count, 1), 1) ) ) -- Beautify SQL: SELECT 1, (SELECT 70) AS `power`, number FROM numbers(plus(ifNull((SELECT 1 AS bin_count, 1), 1))); ================================================ FILE: parser/testdata/query/format/beautify/select_when_condition.sql ================================================ -- Origin SQL: select case when false then 'hello' else 'world' end; -- Beautify SQL: SELECT CASE WHEN false THEN 'hello' ELSE 'world' END; ================================================ FILE: parser/testdata/query/format/beautify/select_window_comprehensive.sql ================================================ -- Origin SQL: -- Comprehensive window spec coverage: ad-hoc specs, named windows, ROWS/RANGE frames -- multiple functions, multi-column PARTITION/ORDER, and expression-based specs. SELECT -- Ad-hoc windows sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total, avg(x) OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1, -- Named window reuse (OVER w1) row_number() OVER w1 AS rn_w1, rank() OVER w1 AS rank_w1, sum(x) OVER w1 AS sum_w1, -- Frame variants (incl. shorthand & RANGE) sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following, sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f, sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur, sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur, -- Ranking & navigation row_number() OVER (PARTITION BY y ORDER BY x) AS row_num, rank() OVER (PARTITION BY y ORDER BY x) AS rank_val, dense_rank() OVER (PARTITION BY y ORDER BY x) AS dense_rank_val, first_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val, last_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val, lag(x, 1) OVER (PARTITION BY y ORDER BY x) AS prev_x, lead(x, 1) OVER (PARTITION BY y ORDER BY x) AS next_x, percent_rank() OVER (PARTITION BY y ORDER BY x) AS pct_rank, -- Named window reference via OVER w (no parentheses) sum(x) OVER w AS sum_over_w, avg(x) OVER w AS avg_over_w, row_number() OVER w AS rn_over_w, -- Multiple columns in PARTITION BY / ORDER BY count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC) AS cnt_multi, sum(val) OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi, -- Expressions in PARTITION/ORDER sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total, avg(amount) OVER (ORDER BY extract(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg FROM t WINDOW w AS (ORDER BY y), w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); -- Beautify SQL: SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total, avg(x) OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1, row_number() OVER w1 AS rn_w1, rank() OVER w1 AS rank_w1, sum(x) OVER w1 AS sum_w1, sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following, sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f, sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur, sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur, row_number() OVER (PARTITION BY y ORDER BY x) AS row_num, rank() OVER (PARTITION BY y ORDER BY x) AS rank_val, dense_rank() OVER (PARTITION BY y ORDER BY x) AS dense_rank_val, first_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val, last_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val, lag(x, 1) OVER (PARTITION BY y ORDER BY x) AS prev_x, lead(x, 1) OVER (PARTITION BY y ORDER BY x) AS next_x, percent_rank() OVER (PARTITION BY y ORDER BY x) AS pct_rank, sum(x) OVER w AS sum_over_w, avg(x) OVER w AS avg_over_w, row_number() OVER w AS rn_over_w, count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC) AS cnt_multi, sum(val) OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi, sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total, avg(amount) OVER (ORDER BY EXTRACT(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg FROM t WINDOW w AS (ORDER BY y), w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); ================================================ FILE: parser/testdata/query/format/beautify/select_window_cte.sql ================================================ -- Origin SQL: WITH monthly AS ( SELECT toStartOfMonth(date) AS month, department, avg(salary) AS avg_salary FROM salary_table WHERE year = 2023 GROUP BY month, department ), ranked AS ( SELECT month, department, avg_salary, row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank FROM monthly ) SELECT month, department, avg_salary, lag(avg_salary, 1, 0) OVER ( PARTITION BY department ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) AS prev_month_avg FROM ranked WHERE dept_rank <= 5 ORDER BY month, department; -- Beautify SQL: WITH monthly AS (SELECT toStartOfMonth(date) AS month, department, avg(salary) AS avg_salary FROM salary_table WHERE year = 2023 GROUP BY month, department), ranked AS (SELECT month, department, avg_salary, row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank FROM monthly) SELECT month, department, avg_salary, lag(avg_salary, 1, 0) OVER (PARTITION BY department ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_month_avg FROM ranked WHERE dept_rank <= 5 ORDER BY month, department; ================================================ FILE: parser/testdata/query/format/beautify/select_window_keyword_name_in_parens.sql ================================================ -- Origin SQL: SELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts); -- Beautify SQL: SELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts); ================================================ FILE: parser/testdata/query/format/beautify/select_window_named_in_parens.sql ================================================ -- Origin SQL: SELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x); -- Beautify SQL: SELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x); ================================================ FILE: parser/testdata/query/format/beautify/select_window_named_reference_extensions.sql ================================================ -- Origin SQL: SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); -- Beautify SQL: SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); ================================================ FILE: parser/testdata/query/format/beautify/select_window_params.sql ================================================ -- Origin SQL: -- Parameters in WHERE and in window frames (UInt32 & String; both spacing styles; shorthand frame) SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start:UInt32} PRECEDING AND CURRENT ROW) AS total1, avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end:UInt32} FOLLOWING) AS avg1, count(*) OVER (ORDER BY y RANGE BETWEEN {range_start:UInt32} PRECEDING AND {range_end:UInt32} FOLLOWING) AS cnt1, sum(x) OVER (ROWS {window_size :UInt32} PRECEDING) AS rows_shorthand FROM t WHERE category = {category :String} AND type = {type:String}; -- Beautify SQL: SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start: UInt32} PRECEDING AND CURRENT ROW) AS total1, avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end: UInt32} FOLLOWING) AS avg1, count(*) OVER (ORDER BY y RANGE BETWEEN {range_start: UInt32} PRECEDING AND {range_end: UInt32} FOLLOWING) AS cnt1, sum(x) OVER (ROWS {window_size: UInt32} PRECEDING) AS rows_shorthand FROM t WHERE category = {category: String} AND type = {type: String}; ================================================ FILE: parser/testdata/query/format/beautify/select_with_distinct.sql ================================================ -- Origin SQL: SELECT count(DISTINCT(RECORD_ID)) FROM RECORD_TABLE -- Beautify SQL: SELECT count(DISTINCT (RECORD_ID)) FROM RECORD_TABLE; ================================================ FILE: parser/testdata/query/format/beautify/select_with_distinct_keyword.sql ================================================ -- Origin SQL: SELECT DISTINCT record_id FROM records -- Beautify SQL: SELECT DISTINCT record_id FROM records; ================================================ FILE: parser/testdata/query/format/beautify/select_with_distinct_on_dotted_columns.sql ================================================ -- Origin SQL: SELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table t -- Beautify SQL: SELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table AS t; ================================================ FILE: parser/testdata/query/format/beautify/select_with_distinct_on_keyword.sql ================================================ -- Origin SQL: SELECT DISTINCT ON(album,artist) record_id FROM records -- Beautify SQL: SELECT DISTINCT ON (album, artist) record_id FROM records; ================================================ FILE: parser/testdata/query/format/beautify/select_with_group_by.sql ================================================ -- Origin SQL: SELECT datacenter, distro, SUM (quantity) AS qty FROM servers GROUP BY GROUPING SETS( (datacenter,distro), (datacenter), (distro), () ); SELECT datacenter, distro, SUM (quantity) AS qty FROM servers GROUP BY ALL; -- Beautify SQL: SELECT datacenter, distro, SUM(quantity) AS qty FROM servers GROUP BY GROUPING SETS((datacenter, distro), (datacenter), (distro), ()); SELECT datacenter, distro, SUM(quantity) AS qty FROM servers GROUP BY ALL; ================================================ FILE: parser/testdata/query/format/beautify/select_with_join_only.sql ================================================ -- Origin SQL: SELECT * FROM "t1" JOIN "t2" ON true -- Beautify SQL: SELECT * FROM "t1" JOIN "t2" ON true; ================================================ FILE: parser/testdata/query/format/beautify/select_with_keyword_in_group_by.sql ================================================ -- Origin SQL: SELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC -- Beautify SQL: SELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC; ================================================ FILE: parser/testdata/query/format/beautify/select_with_keyword_placeholder.sql ================================================ -- Origin SQL: SELECT {name :String}; SELECT toString({name :String}); -- Beautify SQL: SELECT {name: String}; SELECT toString({name: String}); ================================================ FILE: parser/testdata/query/format/beautify/select_with_left_join.sql ================================================ -- Origin SQL: WITH t1 AS ( SELECT 1 AS value ), t2 AS ( SELECT 2 AS value ) SELECT * FROM t1 LEFT JOIN t2 ON true -- Beautify SQL: WITH t1 AS (SELECT 1 AS value), t2 AS (SELECT 2 AS value) SELECT * FROM t1 LEFT JOIN t2 ON true; ================================================ FILE: parser/testdata/query/format/beautify/select_with_literal_table_name.sql ================================================ -- Origin SQL: select table_name from "information_schema"."tables" limit 1; -- Beautify SQL: SELECT table_name FROM "information_schema"."tables" LIMIT 1; ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_array_and_inner_join.sql ================================================ -- Origin SQL: SELECT JSONExtractString(t3.props, 'value') AS value FROM t1 ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1 INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id') ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2 INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id') WHERE value != ''; -- Beautify SQL: SELECT JSONExtractString(t3.props, 'value') AS value FROM t1 ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1 INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id') ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2 INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id') WHERE value != ''; ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_array_join.sql ================================================ -- Origin SQL: SELECT v, j FROM t1 ARRAY JOIN JSONExtractArrayRaw(a) AS j ARRAY JOIN array( JSONExtractString(j, 'x'), JSONExtractString(j, 'y') ) AS v; -- Beautify SQL: SELECT v, j FROM t1 ARRAY JOIN JSONExtractArrayRaw(a) AS j ARRAY JOIN array(JSONExtractString(j, 'x'), JSONExtractString(j, 'y')) AS v; ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_except.sql ================================================ -- Origin SQL: SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9) -- Beautify SQL: SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9); ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_join.sql ================================================ -- Origin SQL: with t1 as ( select 'value1' as value ), t2 as ( select 'value2' as value ), t3 as ( select 'value3' as value ) select t1.value as value1, t2.value as value2, t3.value as value3 from t1 join t2 on true join t3 join t4 on true join t5 -- Beautify SQL: WITH t1 AS (SELECT 'value1' AS value), t2 AS (SELECT 'value2' AS value), t3 AS (SELECT 'value3' AS value) SELECT t1.value AS value1, t2.value AS value2, t3.value AS value3 FROM t1 JOIN t2 ON true JOIN t3 JOIN t4 ON true JOIN t5; ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_line_comment.sql ================================================ -- Origin SQL: select -- first line -- second line * from t0 -- Beautify SQL: SELECT * FROM t0; ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_union.sql ================================================ -- Origin SQL: SELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3 -- Beautify SQL: SELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3; ================================================ FILE: parser/testdata/query/format/beautify/select_with_multi_union_distinct.sql ================================================ -- Origin SQL: SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3 -- Beautify SQL: SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3; ================================================ FILE: parser/testdata/query/format/beautify/select_with_number_field.sql ================================================ -- Origin SQL: SELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m as bar -- Beautify SQL: SELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m AS bar; ================================================ FILE: parser/testdata/query/format/beautify/select_with_placeholder.sql ================================================ -- Origin SQL: SELECT * FROM t0 WHERE id = ?; -- Beautify SQL: SELECT * FROM t0 WHERE id = ?; ================================================ FILE: parser/testdata/query/format/beautify/select_with_query_parameter.sql ================================================ -- Origin SQL: SET param_a = 13; SET param_b = 'str'; SET param_c = '2022-08-04 18:30:53'; SET param_d = {'10': [11, 12], '13': [14, 15]}; SELECT {a: UInt32}, {b: String}, {c: DateTime}, {d: Map(String, Array(UInt8))}; SELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String}; -- Beautify SQL: SET param_a=13; SET param_b='str'; SET param_c='2022-08-04 18:30:53'; SET param_d={'10': [11, 12], '13': [14, 15]}; SELECT {a: UInt32}, {b: String}, {c: DateTime}, {d: Map(String, Array(UInt8))}; SELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String}; ================================================ FILE: parser/testdata/query/format/beautify/select_with_settings_additional_table_filters.sql ================================================ -- Origin SQL: SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \'test\''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'id IN (\'a\', \'b\') AND status = \'active\''} FORMAT JSON; SELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) f ANY LEFT JOIN (SELECT x, y FROM table_1) s ON f.number = s.x SETTINGS additional_table_filters={'system.numbers':'number != 3', 'table_1':'x != 2'}; -- Beautify SQL: SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \'test\''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'id IN (\'a\', \'b\') AND status = \'active\''} FORMAT JSON; SELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) AS f ANY LEFT JOIN (SELECT x, y FROM table_1) AS s ON f.number = s.x SETTINGS additional_table_filters={'system.numbers': 'number != 3', 'table_1': 'x != 2'}; ================================================ FILE: parser/testdata/query/format/beautify/select_with_single_quote_table.sql ================================================ -- Origin SQL: SELECT * FROM 'test_table' -- Beautify SQL: SELECT * FROM 'test_table'; ================================================ FILE: parser/testdata/query/format/beautify/select_with_string_expr.sql ================================================ -- Origin SQL: WITH "abc" AS (SELECT 1 AS a) SELECT * FROM "abc" -- Beautify SQL: WITH "abc" AS (SELECT 1 AS a) SELECT * FROM "abc"; ================================================ FILE: parser/testdata/query/format/beautify/select_with_union_distinct.sql ================================================ -- Origin SQL: SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON -- Beautify SQL: SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas FORMAT JSON; ================================================ FILE: parser/testdata/query/format/beautify/select_with_variable.sql ================================================ -- Origin SQL: WITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc -- Beautify SQL: WITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc; ================================================ FILE: parser/testdata/query/format/beautify/select_with_window_function.sql ================================================ -- Origin SQL: SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2, min(latest_1) OVER w AS latest_1 FROM t0 WINDOW w AS (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING); -- Beautify SQL: SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2, min(latest_1) OVER w AS latest_1 FROM t0 WINDOW w AS (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING); ================================================ FILE: parser/testdata/query/format/beautify/select_without_from_where.sql ================================================ -- Origin SQL: SELECT 1 WHERE 1 = 1; SELECT {p :UInt8} WHERE {p :UInt8} = 1; -- Beautify SQL: SELECT 1 WHERE 1 = 1; SELECT {p: UInt8} WHERE {p: UInt8} = 1; ================================================ FILE: parser/testdata/query/format/beautify/set_simple.sql ================================================ -- Origin SQL: SET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage -- Beautify SQL: SET max_threads=1, max_insert_threads=0, max_block_size=8192, min_insert_block_size_rows=8192, min_insert_block_size_bytes=1048576; ================================================ FILE: parser/testdata/query/format/create_window_view.sql ================================================ -- Origin SQL: CREATE OR REPLACE VIEW asdf AS SELECT id, price * 1.5 AS computed_value, row_number() OVER ( PARTITION BY category ORDER BY created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW ) AS rn FROM source_table WHERE date >= '2023-01-01'; -- Format SQL: CREATE OR REPLACE VIEW asdf AS SELECT id, price * 1.5 AS computed_value, row_number() OVER (PARTITION BY category ORDER BY created_at RANGE BETWEEN 3600 PRECEDING AND CURRENT ROW) AS rn FROM source_table WHERE date >= '2023-01-01'; ================================================ FILE: parser/testdata/query/format/query_with_expr_compare.sql ================================================ -- Origin SQL: SELECT date, path, splitByChar('/', path)[2] AS path_b FROM( SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date ) WHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30' AND splitByChar('/', path)[1] = 'pathA' -- Format SQL: SELECT date, path, splitByChar('/', path)[2] AS path_b FROM (SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date) WHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30' AND splitByChar('/', path)[1] = 'pathA'; ================================================ FILE: parser/testdata/query/format/select_case_multiple_when.sql ================================================ -- Origin SQL: SELECT *, CASE WHEN col2 = 'value1' THEN 'when1' WHEN col3 = 'value2' THEN 'when2' ELSE 'else' END as check_result FROM table_name WHERE col1 = '123456789' -- Format SQL: SELECT *, CASE WHEN col2 = 'value1' THEN 'when1' WHEN col3 = 'value2' THEN 'when2' ELSE 'else' END AS check_result FROM table_name WHERE col1 = '123456789'; ================================================ FILE: parser/testdata/query/format/select_case_when_exists.sql ================================================ -- Origin SQL: SELECT *, CASE WHEN EXISTS(SELECT 1 FROM table_name WHERE col1 = '999999999') THEN 'then' ELSE 'else' END as check_result FROM table_name WHERE col1 = '123456789' -- Format SQL: SELECT *, CASE WHEN EXISTS(SELECT 1 FROM table_name WHERE col1 = '999999999') THEN 'then' ELSE 'else' END AS check_result FROM table_name WHERE col1 = '123456789'; ================================================ FILE: parser/testdata/query/format/select_cast.sql ================================================ -- Origin SQL: select cast(1 as Float64) as value; select cast(1, 'Float64') as value; select (1 as Float64) as value; select 1::Float64 as value; -- Format SQL: SELECT CAST(1 AS Float64) AS value; SELECT CAST(1, 'Float64') AS value; SELECT (1 AS Float64) AS value; SELECT 1::Float64 AS value; ================================================ FILE: parser/testdata/query/format/select_column_alias_string.sql ================================================ -- Origin SQL: SELECT 'abc' as "value2"; SELECT $abc, a$$bc, abc$$; -- Format SQL: SELECT 'abc' AS "value2"; SELECT $abc, a$$bc, abc$$; ================================================ FILE: parser/testdata/query/format/select_concat_expr.sql ================================================ -- Origin SQL: SELECT 'a' || 'b'; SELECT 'a' || 'b' || 'c'; SELECT 'a' || 'b' || 'c' + 5; -- Format SQL: SELECT 'a' || 'b'; SELECT 'a' || 'b' || 'c'; SELECT 'a' || 'b' || 'c' + 5; ================================================ FILE: parser/testdata/query/format/select_expr.sql ================================================ -- Origin SQL: SELECT 1+1 -- Format SQL: SELECT 1 + 1; ================================================ FILE: parser/testdata/query/format/select_extract_with_regex.sql ================================================ -- Origin SQL: SELECT COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT FROM test.table WHERE app_id = 999118646 AND toUnixTimestamp(timestamp) >= 1740366695 AND toUnixTimestamp(timestamp) <= 1740377495 GROUP BY CASE WHEN length(extract(instance, '((\\d+\\.){3}\\d+)')) > 0 THEN instance ELSE '空' END, CASE WHEN length(extract(client_ip, '((\\d+\\.){3}\\d+)')) > 0 THEN client_ip ELSE '空' END, src_type, node_class, port, client_port LIMIT 10000 -- Format SQL: SELECT COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT FROM test.table WHERE app_id = 999118646 AND toUnixTimestamp(timestamp) >= 1740366695 AND toUnixTimestamp(timestamp) <= 1740377495 GROUP BY CASE WHEN length(EXTRACT(instance, '((\\d+\\.){3}\\d+)')) > 0 THEN instance ELSE '空' END, CASE WHEN length(EXTRACT(client_ip, '((\\d+\\.){3}\\d+)')) > 0 THEN client_ip ELSE '空' END, src_type, node_class, port, client_port LIMIT 10000; ================================================ FILE: parser/testdata/query/format/select_item_with_modifiers.sql ================================================ -- Origin SQL: SELECT c0 REPLACE(c0 AS c1) FROM t0; SELECT * REPLACE(i + 1 AS i) FROM t1; SELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from t2; -- Format SQL: SELECT c0 REPLACE(c0 AS c1) FROM t0; SELECT * REPLACE(i + 1 AS i) FROM t1; SELECT * REPLACE(i + 1 AS i) EXCEPT(j) APPLY(sum) FROM t2; ================================================ FILE: parser/testdata/query/format/select_json_type.sql ================================================ -- Origin SQL: SELECT a, a.b, a.b.c.d.e; SELECT JSON_TYPE('{"a": 1, "b": {"c": 2}}', '$.b'); SELECT CAST(some, 'String') AS value; SELECT CAST(some.long, 'String') AS value; SELECT CAST(some.long.json, 'String') AS value; SELECT CAST(some.long.json.path, 'String') AS value; -- Format SQL: SELECT a, a.b, a.b.c.d.e; SELECT JSON_TYPE('{"a": 1, "b": {"c": 2}}', '$.b'); SELECT CAST(some, 'String') AS value; SELECT CAST(some.long, 'String') AS value; SELECT CAST(some.long.json, 'String') AS value; SELECT CAST(some.long.json.path, 'String') AS value; ================================================ FILE: parser/testdata/query/format/select_keyword_alias_no_as.sql ================================================ -- Origin SQL: SELECT 'Joe' name FROM users -- Format SQL: SELECT 'Joe' AS name FROM users; ================================================ FILE: parser/testdata/query/format/select_order_by_timestamp.sql ================================================ -- Origin SQL: SELECT Timestamp FROM events ORDER BY Timestamp; -- Format SQL: SELECT Timestamp FROM events ORDER BY Timestamp; ================================================ FILE: parser/testdata/query/format/select_order_by_with_fill_basic.sql ================================================ -- Origin SQL: SELECT n, source FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL; -- Format SQL: SELECT n, source FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL; ================================================ FILE: parser/testdata/query/format/select_order_by_with_fill_from_to.sql ================================================ -- Origin SQL: SELECT n, source FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5; -- Format SQL: SELECT n, source FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5; ================================================ FILE: parser/testdata/query/format/select_order_by_with_fill_interpolate.sql ================================================ -- Origin SQL: SELECT n, source, inter FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1); -- Format SQL: SELECT n, source, inter FROM (SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1); ================================================ FILE: parser/testdata/query/format/select_order_by_with_fill_interpolate_no_columns.sql ================================================ -- Origin SQL: SELECT n, value FROM ( SELECT toFloat32(number % 10) AS n, number AS value FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1 INTERPOLATE; -- Format SQL: SELECT n, value FROM (SELECT toFloat32(number % 10) AS n, number AS value FROM numbers(10) WHERE number % 3 = 1) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1 INTERPOLATE; ================================================ FILE: parser/testdata/query/format/select_order_by_with_fill_staleness.sql ================================================ -- Origin SQL: SELECT number as key, 5 * number value, 'original' AS source FROM numbers(16) WHERE (number % 5) == 0 ORDER BY key WITH FILL STALENESS 11; -- Format SQL: SELECT number AS key, 5 * number AS value, 'original' AS source FROM numbers(16) WHERE (number % 5) == 0 ORDER BY key WITH FILL STALENESS 11; ================================================ FILE: parser/testdata/query/format/select_order_by_with_fill_step.sql ================================================ -- Origin SQL: SELECT date, value FROM ( SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value FROM numbers(5) ) ORDER BY date WITH FILL STEP INTERVAL 1 DAY; -- Format SQL: SELECT date, value FROM (SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value FROM numbers(5)) ORDER BY date WITH FILL STEP INTERVAL 1 DAY; ================================================ FILE: parser/testdata/query/format/select_simple.sql ================================================ -- Origin SQL: SELECT f0, coalesce(f1, f2) AS f3, row_number() OVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c') GROUP BY f0, f1 Limit 100, 10 By f0; -- Format SQL: SELECT f0, coalesce(f1, f2) AS f3, row_number() OVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c') GROUP BY f0, f1 LIMIT 10 OFFSET 100 BY f0; ================================================ FILE: parser/testdata/query/format/select_simple_field_alias.sql ================================================ -- Origin SQL: SELECT field0, field1 as x, field2 y from events; -- Format SQL: SELECT field0, field1 AS x, field2 AS y FROM events; ================================================ FILE: parser/testdata/query/format/select_simple_with_bracket.sql ================================================ -- Origin SQL: SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1["abc"] as f2 -- Format SQL: SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1["abc"] AS f2; ================================================ FILE: parser/testdata/query/format/select_simple_with_cte_with_column_aliases.sql ================================================ -- Origin SQL: WITH test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales) SELECT f1 AS new_f1, f2 AS new_f2, f3 AS new_f3 FROM test; -- Format SQL: WITH test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales) SELECT f1 AS new_f1, f2 AS new_f2, f3 AS new_f3 FROM test; ================================================ FILE: parser/testdata/query/format/select_simple_with_group_by_with_cube_totals.sql ================================================ -- Origin SQL: SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a; -- Format SQL: SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a; ================================================ FILE: parser/testdata/query/format/select_simple_with_is_not_null.sql ================================================ -- Origin SQL: SELECT f0,f1,f2,f3 as a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL AND f3 IS NOT NULL -- Format SQL: SELECT f0, f1, f2, f3 AS a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL AND f3 IS NOT NULL; ================================================ FILE: parser/testdata/query/format/select_simple_with_is_null.sql ================================================ -- Origin SQL: SELECT f0,f1,f2,f3 as a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL -- Format SQL: SELECT f0, f1, f2, f3 AS a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL; ================================================ FILE: parser/testdata/query/format/select_simple_with_limit.sql ================================================ -- Origin SQL: SELECT 1 LIMIT 1; SELECT 1 LIMIT 1 OFFSET 0; SELECT 1 OFFSET 0; -- Format SQL: SELECT 1 LIMIT 1; SELECT 1 LIMIT 1 OFFSET 0; SELECT 1 OFFSET 0; ================================================ FILE: parser/testdata/query/format/select_simple_with_top_clause.sql ================================================ -- Origin SQL: SELECT TOP 10 my_column FROM tableName; -- Format SQL: SELECT TOP 10 my_column FROM tableName; ================================================ FILE: parser/testdata/query/format/select_simple_with_with_clause.sql ================================================ -- Origin SQL: WITH cte1 AS (SELECT f1 FROM t1), cte2 AS (SELECT f2 FROM t2) SELECT cte1.f1, cte2.f2, t3.f3 FROM t3,cte1,cte2 -- Format SQL: WITH cte1 AS (SELECT f1 FROM t1), cte2 AS (SELECT f2 FROM t2) SELECT cte1.f1, cte2.f2, t3.f3 FROM t3,cte1,cte2; ================================================ FILE: parser/testdata/query/format/select_table_alias_without_keyword.sql ================================================ -- Origin SQL: SELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b -- Format SQL: SELECT t1.Timestamp FROM my_table AS t1 INNER JOIN my_other_table AS t2 ON t1.a = t2.b; ================================================ FILE: parser/testdata/query/format/select_table_function_with_query.sql ================================================ -- Origin SQL: SELECT 1, (SELECT 70) AS `power`, number FROM numbers( plus( ifNull((SELECT 1 AS bin_count, 1), 1) ) ) -- Format SQL: SELECT 1, (SELECT 70) AS `power`, number FROM numbers(plus(ifNull((SELECT 1 AS bin_count, 1), 1))); ================================================ FILE: parser/testdata/query/format/select_when_condition.sql ================================================ -- Origin SQL: select case when false then 'hello' else 'world' end; -- Format SQL: SELECT CASE WHEN false THEN 'hello' ELSE 'world' END; ================================================ FILE: parser/testdata/query/format/select_window_comprehensive.sql ================================================ -- Origin SQL: -- Comprehensive window spec coverage: ad-hoc specs, named windows, ROWS/RANGE frames -- multiple functions, multi-column PARTITION/ORDER, and expression-based specs. SELECT -- Ad-hoc windows sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total, avg(x) OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1, -- Named window reuse (OVER w1) row_number() OVER w1 AS rn_w1, rank() OVER w1 AS rank_w1, sum(x) OVER w1 AS sum_w1, -- Frame variants (incl. shorthand & RANGE) sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following, sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f, sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur, sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur, -- Ranking & navigation row_number() OVER (PARTITION BY y ORDER BY x) AS row_num, rank() OVER (PARTITION BY y ORDER BY x) AS rank_val, dense_rank() OVER (PARTITION BY y ORDER BY x) AS dense_rank_val, first_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val, last_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val, lag(x, 1) OVER (PARTITION BY y ORDER BY x) AS prev_x, lead(x, 1) OVER (PARTITION BY y ORDER BY x) AS next_x, percent_rank() OVER (PARTITION BY y ORDER BY x) AS pct_rank, -- Named window reference via OVER w (no parentheses) sum(x) OVER w AS sum_over_w, avg(x) OVER w AS avg_over_w, row_number() OVER w AS rn_over_w, -- Multiple columns in PARTITION BY / ORDER BY count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC) AS cnt_multi, sum(val) OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi, -- Expressions in PARTITION/ORDER sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total, avg(amount) OVER (ORDER BY extract(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg FROM t WINDOW w AS (ORDER BY y), w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); -- Format SQL: SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total, avg(x) OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1, row_number() OVER w1 AS rn_w1, rank() OVER w1 AS rank_w1, sum(x) OVER w1 AS sum_w1, sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following, sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f, sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur, sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur, row_number() OVER (PARTITION BY y ORDER BY x) AS row_num, rank() OVER (PARTITION BY y ORDER BY x) AS rank_val, dense_rank() OVER (PARTITION BY y ORDER BY x) AS dense_rank_val, first_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val, last_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val, lag(x, 1) OVER (PARTITION BY y ORDER BY x) AS prev_x, lead(x, 1) OVER (PARTITION BY y ORDER BY x) AS next_x, percent_rank() OVER (PARTITION BY y ORDER BY x) AS pct_rank, sum(x) OVER w AS sum_over_w, avg(x) OVER w AS avg_over_w, row_number() OVER w AS rn_over_w, count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC) AS cnt_multi, sum(val) OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi, sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total, avg(amount) OVER (ORDER BY EXTRACT(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg FROM t WINDOW w AS (ORDER BY y), w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); ================================================ FILE: parser/testdata/query/format/select_window_cte.sql ================================================ -- Origin SQL: WITH monthly AS ( SELECT toStartOfMonth(date) AS month, department, avg(salary) AS avg_salary FROM salary_table WHERE year = 2023 GROUP BY month, department ), ranked AS ( SELECT month, department, avg_salary, row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank FROM monthly ) SELECT month, department, avg_salary, lag(avg_salary, 1, 0) OVER ( PARTITION BY department ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) AS prev_month_avg FROM ranked WHERE dept_rank <= 5 ORDER BY month, department; -- Format SQL: WITH monthly AS (SELECT toStartOfMonth(date) AS month, department, avg(salary) AS avg_salary FROM salary_table WHERE year = 2023 GROUP BY month, department), ranked AS (SELECT month, department, avg_salary, row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank FROM monthly) SELECT month, department, avg_salary, lag(avg_salary, 1, 0) OVER (PARTITION BY department ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_month_avg FROM ranked WHERE dept_rank <= 5 ORDER BY month, department; ================================================ FILE: parser/testdata/query/format/select_window_keyword_name_in_parens.sql ================================================ -- Origin SQL: SELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts); -- Format SQL: SELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts); ================================================ FILE: parser/testdata/query/format/select_window_named_in_parens.sql ================================================ -- Origin SQL: SELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x); -- Format SQL: SELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x); ================================================ FILE: parser/testdata/query/format/select_window_named_reference_extensions.sql ================================================ -- Origin SQL: SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); -- Format SQL: SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); ================================================ FILE: parser/testdata/query/format/select_window_params.sql ================================================ -- Origin SQL: -- Parameters in WHERE and in window frames (UInt32 & String; both spacing styles; shorthand frame) SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start:UInt32} PRECEDING AND CURRENT ROW) AS total1, avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end:UInt32} FOLLOWING) AS avg1, count(*) OVER (ORDER BY y RANGE BETWEEN {range_start:UInt32} PRECEDING AND {range_end:UInt32} FOLLOWING) AS cnt1, sum(x) OVER (ROWS {window_size :UInt32} PRECEDING) AS rows_shorthand FROM t WHERE category = {category :String} AND type = {type:String}; -- Format SQL: SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start: UInt32} PRECEDING AND CURRENT ROW) AS total1, avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end: UInt32} FOLLOWING) AS avg1, count(*) OVER (ORDER BY y RANGE BETWEEN {range_start: UInt32} PRECEDING AND {range_end: UInt32} FOLLOWING) AS cnt1, sum(x) OVER (ROWS {window_size: UInt32} PRECEDING) AS rows_shorthand FROM t WHERE category = {category: String} AND type = {type: String}; ================================================ FILE: parser/testdata/query/format/select_with_distinct.sql ================================================ -- Origin SQL: SELECT count(DISTINCT(RECORD_ID)) FROM RECORD_TABLE -- Format SQL: SELECT count(DISTINCT (RECORD_ID)) FROM RECORD_TABLE; ================================================ FILE: parser/testdata/query/format/select_with_distinct_keyword.sql ================================================ -- Origin SQL: SELECT DISTINCT record_id FROM records -- Format SQL: SELECT DISTINCT record_id FROM records; ================================================ FILE: parser/testdata/query/format/select_with_distinct_on_dotted_columns.sql ================================================ -- Origin SQL: SELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table t -- Format SQL: SELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table AS t; ================================================ FILE: parser/testdata/query/format/select_with_distinct_on_keyword.sql ================================================ -- Origin SQL: SELECT DISTINCT ON(album,artist) record_id FROM records -- Format SQL: SELECT DISTINCT ON (album, artist) record_id FROM records; ================================================ FILE: parser/testdata/query/format/select_with_group_by.sql ================================================ -- Origin SQL: SELECT datacenter, distro, SUM (quantity) AS qty FROM servers GROUP BY GROUPING SETS( (datacenter,distro), (datacenter), (distro), () ); SELECT datacenter, distro, SUM (quantity) AS qty FROM servers GROUP BY ALL; -- Format SQL: SELECT datacenter, distro, SUM(quantity) AS qty FROM servers GROUP BY GROUPING SETS((datacenter, distro), (datacenter), (distro), ()); SELECT datacenter, distro, SUM(quantity) AS qty FROM servers GROUP BY ALL; ================================================ FILE: parser/testdata/query/format/select_with_join_only.sql ================================================ -- Origin SQL: SELECT * FROM "t1" JOIN "t2" ON true -- Format SQL: SELECT * FROM "t1" JOIN "t2" ON true; ================================================ FILE: parser/testdata/query/format/select_with_keyword_in_group_by.sql ================================================ -- Origin SQL: SELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC -- Format SQL: SELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC; ================================================ FILE: parser/testdata/query/format/select_with_keyword_placeholder.sql ================================================ -- Origin SQL: SELECT {name :String}; SELECT toString({name :String}); -- Format SQL: SELECT {name: String}; SELECT toString({name: String}); ================================================ FILE: parser/testdata/query/format/select_with_left_join.sql ================================================ -- Origin SQL: WITH t1 AS ( SELECT 1 AS value ), t2 AS ( SELECT 2 AS value ) SELECT * FROM t1 LEFT JOIN t2 ON true -- Format SQL: WITH t1 AS (SELECT 1 AS value), t2 AS (SELECT 2 AS value) SELECT * FROM t1 LEFT JOIN t2 ON true; ================================================ FILE: parser/testdata/query/format/select_with_literal_table_name.sql ================================================ -- Origin SQL: select table_name from "information_schema"."tables" limit 1; -- Format SQL: SELECT table_name FROM "information_schema"."tables" LIMIT 1; ================================================ FILE: parser/testdata/query/format/select_with_multi_array_and_inner_join.sql ================================================ -- Origin SQL: SELECT JSONExtractString(t3.props, 'value') AS value FROM t1 ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1 INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id') ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2 INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id') WHERE value != ''; -- Format SQL: SELECT JSONExtractString(t3.props, 'value') AS value FROM t1 ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1 INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id') ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2 INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id') WHERE value != ''; ================================================ FILE: parser/testdata/query/format/select_with_multi_array_join.sql ================================================ -- Origin SQL: SELECT v, j FROM t1 ARRAY JOIN JSONExtractArrayRaw(a) AS j ARRAY JOIN array( JSONExtractString(j, 'x'), JSONExtractString(j, 'y') ) AS v; -- Format SQL: SELECT v, j FROM t1 ARRAY JOIN JSONExtractArrayRaw(a) AS j ARRAY JOIN array(JSONExtractString(j, 'x'), JSONExtractString(j, 'y')) AS v; ================================================ FILE: parser/testdata/query/format/select_with_multi_except.sql ================================================ -- Origin SQL: SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9) -- Format SQL: SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9); ================================================ FILE: parser/testdata/query/format/select_with_multi_join.sql ================================================ -- Origin SQL: with t1 as ( select 'value1' as value ), t2 as ( select 'value2' as value ), t3 as ( select 'value3' as value ) select t1.value as value1, t2.value as value2, t3.value as value3 from t1 join t2 on true join t3 join t4 on true join t5 -- Format SQL: WITH t1 AS (SELECT 'value1' AS value), t2 AS (SELECT 'value2' AS value), t3 AS (SELECT 'value3' AS value) SELECT t1.value AS value1, t2.value AS value2, t3.value AS value3 FROM t1 JOIN t2 ON true JOIN t3 JOIN t4 ON true JOIN t5; ================================================ FILE: parser/testdata/query/format/select_with_multi_line_comment.sql ================================================ -- Origin SQL: select -- first line -- second line * from t0 -- Format SQL: SELECT * FROM t0; ================================================ FILE: parser/testdata/query/format/select_with_multi_union.sql ================================================ -- Origin SQL: SELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3 -- Format SQL: SELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3; ================================================ FILE: parser/testdata/query/format/select_with_multi_union_distinct.sql ================================================ -- Origin SQL: SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3 -- Format SQL: SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3; ================================================ FILE: parser/testdata/query/format/select_with_number_field.sql ================================================ -- Origin SQL: SELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m as bar -- Format SQL: SELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m AS bar; ================================================ FILE: parser/testdata/query/format/select_with_placeholder.sql ================================================ -- Origin SQL: SELECT * FROM t0 WHERE id = ?; -- Format SQL: SELECT * FROM t0 WHERE id = ?; ================================================ FILE: parser/testdata/query/format/select_with_query_parameter.sql ================================================ -- Origin SQL: SET param_a = 13; SET param_b = 'str'; SET param_c = '2022-08-04 18:30:53'; SET param_d = {'10': [11, 12], '13': [14, 15]}; SELECT {a: UInt32}, {b: String}, {c: DateTime}, {d: Map(String, Array(UInt8))}; SELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String}; -- Format SQL: SET param_a=13; SET param_b='str'; SET param_c='2022-08-04 18:30:53'; SET param_d={'10': [11, 12], '13': [14, 15]}; SELECT {a: UInt32}, {b: String}, {c: DateTime}, {d: Map(String, Array(UInt8))}; SELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String}; ================================================ FILE: parser/testdata/query/format/select_with_settings_additional_table_filters.sql ================================================ -- Origin SQL: SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \'test\''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'id IN (\'a\', \'b\') AND status = \'active\''} FORMAT JSON; SELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) f ANY LEFT JOIN (SELECT x, y FROM table_1) s ON f.number = s.x SETTINGS additional_table_filters={'system.numbers':'number != 3', 'table_1':'x != 2'}; -- Format SQL: SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \'test\''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'id IN (\'a\', \'b\') AND status = \'active\''} FORMAT JSON; SELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) AS f ANY LEFT JOIN (SELECT x, y FROM table_1) AS s ON f.number = s.x SETTINGS additional_table_filters={'system.numbers': 'number != 3', 'table_1': 'x != 2'}; ================================================ FILE: parser/testdata/query/format/select_with_single_quote_table.sql ================================================ -- Origin SQL: SELECT * FROM 'test_table' -- Format SQL: SELECT * FROM 'test_table'; ================================================ FILE: parser/testdata/query/format/select_with_string_expr.sql ================================================ -- Origin SQL: WITH "abc" AS (SELECT 1 AS a) SELECT * FROM "abc" -- Format SQL: WITH "abc" AS (SELECT 1 AS a) SELECT * FROM "abc"; ================================================ FILE: parser/testdata/query/format/select_with_union_distinct.sql ================================================ -- Origin SQL: SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON -- Format SQL: SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas FORMAT JSON; ================================================ FILE: parser/testdata/query/format/select_with_variable.sql ================================================ -- Origin SQL: WITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc -- Format SQL: WITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc; ================================================ FILE: parser/testdata/query/format/select_with_window_function.sql ================================================ -- Origin SQL: SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2, min(latest_1) OVER w AS latest_1 FROM t0 WINDOW w AS (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING); -- Format SQL: SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2, min(latest_1) OVER w AS latest_1 FROM t0 WINDOW w AS (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING); ================================================ FILE: parser/testdata/query/format/select_without_from_where.sql ================================================ -- Origin SQL: SELECT 1 WHERE 1 = 1; SELECT {p :UInt8} WHERE {p :UInt8} = 1; -- Format SQL: SELECT 1 WHERE 1 = 1; SELECT {p: UInt8} WHERE {p: UInt8} = 1; ================================================ FILE: parser/testdata/query/format/set_simple.sql ================================================ -- Origin SQL: SET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage -- Format SQL: SET max_threads=1, max_insert_threads=0, max_block_size=8192, min_insert_block_size_rows=8192, min_insert_block_size_bytes=1048576; ================================================ FILE: parser/testdata/query/output/access_tuple_with_dot.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 34, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Object": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 7, "NameEnd": 12 }, "Params": { "LeftParenPos": 12, "RightParenPos": 24, "Items": { "ListPos": 14, "ListEnd": 23, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 14, "LiteralEnd": 15, "Literal": "a" }, "Alias": null }, { "Expr": { "LiteralPos": 18, "LiteralEnd": 19, "Literal": "b" }, "Alias": null }, { "Expr": { "LiteralPos": 22, "LiteralEnd": 23, "Literal": "c" }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": ".", "Index": { "NumPos": 26, "NumEnd": 27, "Literal": "3", "Base": 10 } }, "Modifiers": [], "Alias": null }, { "Expr": { "NumPos": 29, "NumEnd": 34, "Literal": ".1234", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 37, "StatementEnd": 336, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toTypeName", "QuoteType": 1, "NamePos": 44, "NameEnd": 54 }, "Params": { "LeftParenPos": 54, "RightParenPos": 151, "Items": { "ListPos": 56, "ListEnd": 150, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 56, "NameEnd": 61 }, "Params": { "LeftParenPos": 61, "RightParenPos": 102, "Items": { "ListPos": 63, "ListEnd": 102, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 63, "LiteralEnd": 64, "Literal": "a" }, "Alias": { "Name": "first", "QuoteType": 1, "NamePos": 69, "NameEnd": 74 } }, { "Expr": { "LiteralPos": 76, "LiteralEnd": 77, "Literal": "b" }, "Alias": { "Name": "second", "QuoteType": 1, "NamePos": 82, "NameEnd": 88 } }, { "Expr": { "LiteralPos": 91, "LiteralEnd": 92, "Literal": "c" }, "Alias": { "Name": "third", "QuoteType": 1, "NamePos": 97, "NameEnd": 102 } } ] }, "ColumnArgList": null } }, "Operation": "::", "RightExpr": { "LeftParenPos": 111, "RightParenPos": 150, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 105, "NameEnd": 110 }, "Columns": [ { "NamePos": 111, "ColumnEnd": 123, "Name": { "Ident": { "Name": "first", "QuoteType": 1, "NamePos": 111, "NameEnd": 116 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 117, "NameEnd": 123 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 124, "ColumnEnd": 137, "Name": { "Ident": { "Name": "second", "QuoteType": 1, "NamePos": 124, "NameEnd": 130 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 131, "NameEnd": 137 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 138, "ColumnEnd": 150, "Name": { "Ident": { "Name": "third", "QuoteType": 1, "NamePos": 138, "NameEnd": 143 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 144, "NameEnd": 150 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null }, { "Expr": { "Object": { "LeftParenPos": 161, "RightParenPos": 257, "Items": { "ListPos": 162, "ListEnd": 256, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 162, "NameEnd": 167 }, "Params": { "LeftParenPos": 167, "RightParenPos": 208, "Items": { "ListPos": 169, "ListEnd": 208, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 169, "LiteralEnd": 170, "Literal": "a" }, "Alias": { "Name": "first", "QuoteType": 1, "NamePos": 175, "NameEnd": 180 } }, { "Expr": { "LiteralPos": 182, "LiteralEnd": 183, "Literal": "b" }, "Alias": { "Name": "second", "QuoteType": 1, "NamePos": 188, "NameEnd": 194 } }, { "Expr": { "LiteralPos": 197, "LiteralEnd": 198, "Literal": "c" }, "Alias": { "Name": "third", "QuoteType": 1, "NamePos": 203, "NameEnd": 208 } } ] }, "ColumnArgList": null } }, "Operation": "::", "RightExpr": { "LeftParenPos": 217, "RightParenPos": 256, "Name": { "Name": "Tuple", "QuoteType": 1, "NamePos": 211, "NameEnd": 216 }, "Columns": [ { "NamePos": 217, "ColumnEnd": 229, "Name": { "Ident": { "Name": "first", "QuoteType": 1, "NamePos": 217, "NameEnd": 222 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 223, "NameEnd": 229 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 230, "ColumnEnd": 243, "Name": { "Ident": { "Name": "second", "QuoteType": 1, "NamePos": 230, "NameEnd": 236 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 237, "NameEnd": 243 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null }, { "NamePos": 244, "ColumnEnd": 256, "Name": { "Ident": { "Name": "third", "QuoteType": 1, "NamePos": 244, "NameEnd": 249 }, "DotIdent": null }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 250, "NameEnd": 256 } }, "NotNull": null, "Nullable": null, "DefaultExpr": null, "MaterializedExpr": null, "AliasExpr": null, "Codec": null, "TTL": null, "Comment": null, "CompressionCodec": null } ] }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "Operation": ".", "Index": { "Name": "second", "QuoteType": 1, "NamePos": 259, "NameEnd": 265 } }, "Modifiers": [], "Alias": null }, { "Expr": { "Object": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 274, "NameEnd": 279 }, "Params": { "LeftParenPos": 279, "RightParenPos": 291, "Items": { "ListPos": 281, "ListEnd": 290, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 281, "LiteralEnd": 282, "Literal": "a" }, "Alias": null }, { "Expr": { "LiteralPos": 285, "LiteralEnd": 286, "Literal": "b" }, "Alias": null }, { "Expr": { "LiteralPos": 289, "LiteralEnd": 290, "Literal": "c" }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": ".", "Index": { "NumPos": 293, "NumEnd": 294, "Literal": "3", "Base": 10 } }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "tupleElement", "QuoteType": 1, "NamePos": 303, "NameEnd": 315 }, "Params": { "LeftParenPos": 315, "RightParenPos": 336, "Items": { "ListPos": 316, "ListEnd": 336, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "tuple", "QuoteType": 1, "NamePos": 316, "NameEnd": 321 }, "Params": { "LeftParenPos": 321, "RightParenPos": 333, "Items": { "ListPos": 323, "ListEnd": 332, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 323, "LiteralEnd": 324, "Literal": "a" }, "Alias": null }, { "Expr": { "LiteralPos": 327, "LiteralEnd": 328, "Literal": "b" }, "Alias": null }, { "Expr": { "LiteralPos": 331, "LiteralEnd": 332, "Literal": "c" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null }, { "Expr": { "NumPos": 335, "NumEnd": 336, "Literal": "1", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/create_window_view.sql.golden.json ================================================ [ { "CreatePos": 0, "StatementEnd": 295, "OrReplace": true, "Name": { "Database": null, "Table": { "Name": "asdf", "QuoteType": 1, "NamePos": 23, "NameEnd": 27 } }, "IfNotExists": false, "UUID": null, "OnCluster": null, "TableSchema": null, "Comment": null, "SubQuery": { "HasParen": false, "Select": { "SelectPos": 31, "StatementEnd": 295, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "id", "QuoteType": 1, "NamePos": 38, "NameEnd": 40 }, "Modifiers": [], "Alias": null }, { "Expr": { "LeftExpr": { "Name": "price", "QuoteType": 1, "NamePos": 49, "NameEnd": 54 }, "Operation": "*", "RightExpr": { "NumPos": 57, "NumEnd": 60, "Literal": "1.5", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": { "Name": "computed_value", "QuoteType": 1, "NamePos": 64, "NameEnd": 78 } }, { "Expr": { "Function": { "Name": { "Name": "row_number", "QuoteType": 1, "NamePos": 87, "NameEnd": 97 }, "Params": { "LeftParenPos": 97, "RightParenPos": 98, "Items": { "ListPos": 98, "ListEnd": 98, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 100, "OverExpr": { "LeftParenPos": 105, "RightParenPos": 238, "WindowName": null, "PartitionBy": { "PartitionPos": 105, "Expr": { "ListPos": 131, "ListEnd": 139, "HasDistinct": false, "Items": [ { "Expr": { "Name": "category", "QuoteType": 1, "NamePos": 131, "NameEnd": 139 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 151, "ListEnd": 170, "Items": [ { "OrderPos": 151, "Expr": { "Name": "created_at", "QuoteType": 1, "NamePos": 160, "NameEnd": 170 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 182, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 196, "NumEnd": 200, "Literal": "3600", "Base": 10 }, "EndPos": 210, "Direction": "PRECEDING" }, "AndPos": 211, "And": { "CurrentPos": 215, "RowEnd": 239 } } } } }, "Modifiers": [], "Alias": { "Name": "rn", "QuoteType": 1, "NamePos": 249, "NameEnd": 251 } } ], "From": { "FromPos": 252, "Expr": { "Table": { "TablePos": 257, "TableEnd": 269, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "source_table", "QuoteType": 1, "NamePos": 257, "NameEnd": 269 } }, "HasFinal": false }, "StatementEnd": 269, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 270, "Expr": { "LeftExpr": { "Name": "date", "QuoteType": 1, "NamePos": 276, "NameEnd": 280 }, "Operation": "\u003e=", "RightExpr": { "LiteralPos": 285, "LiteralEnd": 295, "Literal": "2023-01-01" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } } ] ================================================ FILE: parser/testdata/query/output/query_with_expr_compare.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 225, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "date", "QuoteType": 1, "NamePos": 7, "NameEnd": 11 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "path", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 }, "Modifiers": [], "Alias": null }, { "Expr": { "Object": { "Name": { "Name": "splitByChar", "QuoteType": 1, "NamePos": 19, "NameEnd": 30 }, "Params": { "LeftParenPos": 30, "RightParenPos": 40, "Items": { "ListPos": 32, "ListEnd": 40, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 32, "LiteralEnd": 33, "Literal": "/" }, "Alias": null }, { "Expr": { "Name": "path", "QuoteType": 1, "NamePos": 36, "NameEnd": 40 }, "Alias": null } ] }, "ColumnArgList": null } }, "Params": { "LeftBracketPos": 41, "RightBracketPos": 43, "Items": { "ListPos": 42, "ListEnd": 43, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 42, "NumEnd": 43, "Literal": "2", "Base": 10 }, "Alias": null } ] } } }, "Modifiers": [], "Alias": { "Name": "path_b", "QuoteType": 1, "NamePos": 48, "NameEnd": 54 } } ], "From": { "FromPos": 55, "Expr": { "Table": { "TablePos": 59, "TableEnd": 121, "Alias": null, "Expr": { "HasParen": true, "Select": { "SelectPos": 65, "StatementEnd": 121, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LiteralPos": 73, "LiteralEnd": 90, "Literal": "pathA/pathB/pathC" }, "Modifiers": [], "Alias": { "Name": "path", "QuoteType": 1, "NamePos": 95, "NameEnd": 99 } }, { "Expr": { "LiteralPos": 102, "LiteralEnd": 112, "Literal": "2024-09-10" }, "Modifiers": [], "Alias": { "Name": "date", "QuoteType": 1, "NamePos": 117, "NameEnd": 121 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "HasFinal": false }, "StatementEnd": 121, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 128, "Expr": { "LeftExpr": { "Expr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 134, "NameEnd": 140 }, "Params": { "LeftParenPos": 140, "RightParenPos": 145, "Items": { "ListPos": 141, "ListEnd": 145, "HasDistinct": false, "Items": [ { "Expr": { "Name": "date", "QuoteType": 1, "NamePos": 141, "NameEnd": 145 }, "Alias": null } ] }, "ColumnArgList": null } }, "Between": { "LiteralPos": 156, "LiteralEnd": 166, "Literal": "2024-09-01" }, "AndPos": 168, "And": { "LiteralPos": 173, "LiteralEnd": 183, "Literal": "2024-09-30" } }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Object": { "Name": { "Name": "splitByChar", "QuoteType": 1, "NamePos": 191, "NameEnd": 202 }, "Params": { "LeftParenPos": 202, "RightParenPos": 212, "Items": { "ListPos": 204, "ListEnd": 212, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 204, "LiteralEnd": 205, "Literal": "/" }, "Alias": null }, { "Expr": { "Name": "path", "QuoteType": 1, "NamePos": 208, "NameEnd": 212 }, "Alias": null } ] }, "ColumnArgList": null } }, "Params": { "LeftBracketPos": 213, "RightBracketPos": 215, "Items": { "ListPos": 214, "ListEnd": 215, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 214, "NumEnd": 215, "Literal": "1", "Base": 10 }, "Alias": null } ] } } }, "Operation": "=", "RightExpr": { "LiteralPos": 220, "LiteralEnd": 225, "Literal": "pathA" }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_case_multiple_when.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 190, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 11, "NameEnd": 11 }, "Modifiers": [], "Alias": null }, { "Expr": { "CasePos": 18, "EndPos": 0, "Expr": null, "Whens": [ { "WhenPos": 31, "ThenPos": 52, "When": { "LeftExpr": { "Name": "col2", "QuoteType": 1, "NamePos": 36, "NameEnd": 40 }, "Operation": "=", "RightExpr": { "LiteralPos": 44, "LiteralEnd": 50, "Literal": "value1" }, "HasGlobal": false, "HasNot": false }, "Then": { "LiteralPos": 58, "LiteralEnd": 63, "Literal": "when1" }, "ElsePos": 0, "Else": null }, { "WhenPos": 73, "ThenPos": 94, "When": { "LeftExpr": { "Name": "col3", "QuoteType": 1, "NamePos": 78, "NameEnd": 82 }, "Operation": "=", "RightExpr": { "LiteralPos": 86, "LiteralEnd": 92, "Literal": "value2" }, "HasGlobal": false, "HasNot": false }, "Then": { "LiteralPos": 100, "LiteralEnd": 105, "Literal": "when2" }, "ElsePos": 0, "Else": null } ], "ElsePos": 115, "Else": { "LiteralPos": 121, "LiteralEnd": 125, "Literal": "else" } }, "Modifiers": [], "Alias": { "Name": "check_result", "QuoteType": 1, "NamePos": 138, "NameEnd": 150 } } ], "From": { "FromPos": 151, "Expr": { "Table": { "TablePos": 156, "TableEnd": 166, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 156, "NameEnd": 166 } }, "HasFinal": false }, "StatementEnd": 166, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 167, "Expr": { "LeftExpr": { "Name": "col1", "QuoteType": 1, "NamePos": 173, "NameEnd": 177 }, "Operation": "=", "RightExpr": { "LiteralPos": 181, "LiteralEnd": 190, "Literal": "123456789" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_case_when_exists.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 205, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 11, "NameEnd": 11 }, "Modifiers": [], "Alias": null }, { "Expr": { "CasePos": 18, "EndPos": 0, "Expr": null, "Whens": [ { "WhenPos": 31, "ThenPos": 110, "When": { "Name": { "Name": "EXISTS", "QuoteType": 1, "NamePos": 36, "NameEnd": 42 }, "Params": { "LeftParenPos": 42, "RightParenPos": 100, "Items": { "ListPos": 43, "ListEnd": 99, "HasDistinct": false, "Items": [ { "Expr": { "SelectPos": 43, "StatementEnd": 99, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 50, "NumEnd": 51, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 56, "Expr": { "Table": { "TablePos": 61, "TableEnd": 71, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 61, "NameEnd": 71 } }, "HasFinal": false }, "StatementEnd": 71, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 76, "Expr": { "LeftExpr": { "Name": "col1", "QuoteType": 1, "NamePos": 82, "NameEnd": 86 }, "Operation": "=", "RightExpr": { "LiteralPos": 90, "LiteralEnd": 99, "Literal": "999999999" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, "Alias": null } ] }, "ColumnArgList": null } }, "Then": { "LiteralPos": 116, "LiteralEnd": 120, "Literal": "then" }, "ElsePos": 0, "Else": null } ], "ElsePos": 130, "Else": { "LiteralPos": 136, "LiteralEnd": 140, "Literal": "else" } }, "Modifiers": [], "Alias": { "Name": "check_result", "QuoteType": 1, "NamePos": 153, "NameEnd": 165 } } ], "From": { "FromPos": 166, "Expr": { "Table": { "TablePos": 171, "TableEnd": 181, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "table_name", "QuoteType": 1, "NamePos": 171, "NameEnd": 181 } }, "HasFinal": false }, "StatementEnd": 181, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 182, "Expr": { "LeftExpr": { "Name": "col1", "QuoteType": 1, "NamePos": 188, "NameEnd": 192 }, "Operation": "=", "RightExpr": { "LiteralPos": 196, "LiteralEnd": 205, "Literal": "123456789" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_cast.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 34, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CastPos": 7, "Expr": { "NumPos": 12, "NumEnd": 13, "Literal": "1", "Base": 10 }, "Separator": "as", "AsPos": 14, "AsType": { "Name": { "Name": "Float64", "QuoteType": 1, "NamePos": 17, "NameEnd": 24 } } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 29, "NameEnd": 34 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 36, "StatementEnd": 70, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CastPos": 43, "Expr": { "NumPos": 48, "NumEnd": 49, "Literal": "1", "Base": 10 }, "Separator": ",", "AsPos": 49, "AsType": { "LiteralPos": 52, "LiteralEnd": 59, "Literal": "Float64" } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 65, "NameEnd": 70 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 72, "StatementEnd": 102, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftParenPos": 79, "RightParenPos": 92, "Items": { "ListPos": 80, "ListEnd": 92, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 80, "NumEnd": 81, "Literal": "1", "Base": 10 }, "Alias": { "Name": "Float64", "QuoteType": 1, "NamePos": 85, "NameEnd": 92 } } ] }, "ColumnArgList": null }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 97, "NameEnd": 102 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 104, "StatementEnd": 130, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftExpr": { "NumPos": 111, "NumEnd": 112, "Literal": "1", "Base": 10 }, "Operation": "::", "RightExpr": { "Name": "Float64", "QuoteType": 1, "NamePos": 114, "NameEnd": 121 }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 125, "NameEnd": 130 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_column_alias_string.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 23, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LiteralPos": 8, "LiteralEnd": 11, "Literal": "abc" }, "Modifiers": [], "Alias": { "Name": "value2", "QuoteType": 2, "NamePos": 17, "NameEnd": 23 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 27, "StatementEnd": 52, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "$abc", "QuoteType": 1, "NamePos": 34, "NameEnd": 38 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "a$$bc", "QuoteType": 1, "NamePos": 40, "NameEnd": 45 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "abc$$", "QuoteType": 1, "NamePos": 47, "NameEnd": 52 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_concat_expr.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 16, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftExpr": { "LiteralPos": 8, "LiteralEnd": 9, "Literal": "a" }, "Operation": "||", "RightExpr": { "LiteralPos": 15, "LiteralEnd": 16, "Literal": "b" }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 19, "StatementEnd": 42, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftExpr": { "LeftExpr": { "LiteralPos": 27, "LiteralEnd": 28, "Literal": "a" }, "Operation": "||", "RightExpr": { "LiteralPos": 34, "LiteralEnd": 35, "Literal": "b" }, "HasGlobal": false, "HasNot": false }, "Operation": "||", "RightExpr": { "LiteralPos": 41, "LiteralEnd": 42, "Literal": "c" }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 45, "StatementEnd": 73, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftExpr": { "LeftExpr": { "LiteralPos": 53, "LiteralEnd": 54, "Literal": "a" }, "Operation": "||", "RightExpr": { "LiteralPos": 60, "LiteralEnd": 61, "Literal": "b" }, "HasGlobal": false, "HasNot": false }, "Operation": "||", "RightExpr": { "LeftExpr": { "LiteralPos": 67, "LiteralEnd": 68, "Literal": "c" }, "Operation": "+", "RightExpr": { "NumPos": 72, "NumEnd": 73, "Literal": "5", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_expr.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 10, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftExpr": { "NumPos": 7, "NumEnd": 8, "Literal": "1", "Base": 10 }, "Operation": "+", "RightExpr": { "NumPos": 9, "NumEnd": 10, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_extract_with_regex.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 476, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "COUNT", "QuoteType": 1, "NamePos": 9, "NameEnd": 14 }, "Params": { "LeftParenPos": 14, "RightParenPos": 16, "Items": { "ListPos": 15, "ListEnd": 16, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 15, "NumEnd": 16, "Literal": "1", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "SRC_TYPE", "QuoteType": 1, "NamePos": 19, "NameEnd": 27 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "NODE_CLASS", "QuoteType": 1, "NamePos": 29, "NameEnd": 39 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "PORT", "QuoteType": 1, "NamePos": 41, "NameEnd": 45 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "CLIENT_PORT", "QuoteType": 1, "NamePos": 47, "NameEnd": 58 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 59, "Expr": { "Table": { "TablePos": 66, "TableEnd": 76, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 66, "NameEnd": 70 }, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 71, "NameEnd": 76 } }, "HasFinal": false }, "StatementEnd": 76, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 77, "Expr": { "LeftExpr": { "LeftExpr": { "LeftExpr": { "Name": "app_id", "QuoteType": 1, "NamePos": 85, "NameEnd": 91 }, "Operation": "=", "RightExpr": { "NumPos": 94, "NumEnd": 103, "Literal": "999118646", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Name": { "Name": "toUnixTimestamp", "QuoteType": 1, "NamePos": 110, "NameEnd": 125 }, "Params": { "LeftParenPos": 125, "RightParenPos": 135, "Items": { "ListPos": 126, "ListEnd": 135, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 126, "NameEnd": 135 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "\u003e=", "RightExpr": { "NumPos": 140, "NumEnd": 150, "Literal": "1740366695", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Name": { "Name": "toUnixTimestamp", "QuoteType": 1, "NamePos": 157, "NameEnd": 172 }, "Params": { "LeftParenPos": 172, "RightParenPos": 182, "Items": { "ListPos": 173, "ListEnd": 182, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 173, "NameEnd": 182 }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "\u003c=", "RightExpr": { "NumPos": 187, "NumEnd": 197, "Literal": "1740377495", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } }, "GroupBy": { "GroupByPos": 198, "GroupByEnd": 465, "AggregateType": "", "Expr": { "ListPos": 209, "ListEnd": 464, "HasDistinct": false, "Items": [ { "Expr": { "CasePos": 209, "EndPos": 0, "Expr": null, "Whens": [ { "WhenPos": 218, "ThenPos": 275, "When": { "LeftExpr": { "Name": { "Name": "length", "QuoteType": 1, "NamePos": 223, "NameEnd": 229 }, "Params": { "LeftParenPos": 229, "RightParenPos": 269, "Items": { "ListPos": 230, "ListEnd": 268, "HasDistinct": false, "Items": [ { "Expr": { "ExtractPos": 230, "ExtractEnd": 268, "Parameters": [ { "Name": "instance", "QuoteType": 1, "NamePos": 238, "NameEnd": 246 }, { "LiteralPos": 249, "LiteralEnd": 267, "Literal": "((\\\\d+\\\\.){3}\\\\d+)" } ] }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "\u003e", "RightExpr": { "NumPos": 273, "NumEnd": 274, "Literal": "0", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Then": { "Name": "instance", "QuoteType": 1, "NamePos": 280, "NameEnd": 288 }, "ElsePos": 0, "Else": null } ], "ElsePos": 293, "Else": { "LiteralPos": 299, "LiteralEnd": 302, "Literal": "空" } }, "Alias": null }, { "Expr": { "CasePos": 313, "EndPos": 0, "Expr": null, "Whens": [ { "WhenPos": 322, "ThenPos": 380, "When": { "LeftExpr": { "Name": { "Name": "length", "QuoteType": 1, "NamePos": 327, "NameEnd": 333 }, "Params": { "LeftParenPos": 333, "RightParenPos": 374, "Items": { "ListPos": 334, "ListEnd": 373, "HasDistinct": false, "Items": [ { "Expr": { "ExtractPos": 334, "ExtractEnd": 373, "Parameters": [ { "Name": "client_ip", "QuoteType": 1, "NamePos": 342, "NameEnd": 351 }, { "LiteralPos": 354, "LiteralEnd": 372, "Literal": "((\\\\d+\\\\.){3}\\\\d+)" } ] }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "\u003e", "RightExpr": { "NumPos": 378, "NumEnd": 379, "Literal": "0", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Then": { "Name": "client_ip", "QuoteType": 1, "NamePos": 385, "NameEnd": 394 }, "ElsePos": 0, "Else": null } ], "ElsePos": 399, "Else": { "LiteralPos": 405, "LiteralEnd": 408, "Literal": "空" } }, "Alias": null }, { "Expr": { "Name": "src_type", "QuoteType": 1, "NamePos": 419, "NameEnd": 427 }, "Alias": null }, { "Expr": { "Name": "node_class", "QuoteType": 1, "NamePos": 431, "NameEnd": 441 }, "Alias": null }, { "Expr": { "Name": "port", "QuoteType": 1, "NamePos": 445, "NameEnd": 449 }, "Alias": null }, { "Expr": { "Name": "client_port", "QuoteType": 1, "NamePos": 453, "NameEnd": 464 }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": { "LimitPos": 465, "Limit": { "NumPos": 471, "NumEnd": 476, "Literal": "10000", "Base": 10 }, "Offset": null }, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_item_with_modifiers.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 35, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "c0", "QuoteType": 1, "NamePos": 7, "NameEnd": 9 }, "Modifiers": [ { "Name": { "Name": "REPLACE", "QuoteType": 1, "NamePos": 10, "NameEnd": 17 }, "Params": { "LeftParenPos": 17, "RightParenPos": 26, "Items": { "ListPos": 18, "ListEnd": 26, "HasDistinct": false, "Items": [ { "Expr": { "Name": "c0", "QuoteType": 1, "NamePos": 18, "NameEnd": 20 }, "Alias": { "Name": "c1", "QuoteType": 1, "NamePos": 24, "NameEnd": 26 } } ] }, "ColumnArgList": null } } ], "Alias": null } ], "From": { "FromPos": 28, "Expr": { "Table": { "TablePos": 33, "TableEnd": 35, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 33, "NameEnd": 35 } }, "HasFinal": false }, "StatementEnd": 35, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 37, "StatementEnd": 73, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 44, "NameEnd": 44 }, "Modifiers": [ { "Name": { "Name": "REPLACE", "QuoteType": 1, "NamePos": 46, "NameEnd": 53 }, "Params": { "LeftParenPos": 53, "RightParenPos": 64, "Items": { "ListPos": 54, "ListEnd": 64, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "i", "QuoteType": 1, "NamePos": 54, "NameEnd": 55 }, "Operation": "+", "RightExpr": { "NumPos": 58, "NumEnd": 59, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": { "Name": "i", "QuoteType": 1, "NamePos": 63, "NameEnd": 64 } } ] }, "ColumnArgList": null } } ], "Alias": null } ], "From": { "FromPos": 66, "Expr": { "Table": { "TablePos": 71, "TableEnd": 73, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 71, "NameEnd": 73 } }, "HasFinal": false }, "StatementEnd": 73, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 75, "StatementEnd": 133, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 82, "NameEnd": 82 }, "Modifiers": [ { "Name": { "Name": "REPLACE", "QuoteType": 1, "NamePos": 84, "NameEnd": 91 }, "Params": { "LeftParenPos": 91, "RightParenPos": 102, "Items": { "ListPos": 92, "ListEnd": 102, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "i", "QuoteType": 1, "NamePos": 92, "NameEnd": 93 }, "Operation": "+", "RightExpr": { "NumPos": 96, "NumEnd": 97, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": { "Name": "i", "QuoteType": 1, "NamePos": 101, "NameEnd": 102 } } ] }, "ColumnArgList": null } }, { "Name": { "Name": "EXCEPT", "QuoteType": 1, "NamePos": 104, "NameEnd": 110 }, "Params": { "LeftParenPos": 111, "RightParenPos": 113, "Items": { "ListPos": 112, "ListEnd": 113, "HasDistinct": false, "Items": [ { "Expr": { "Name": "j", "QuoteType": 1, "NamePos": 112, "NameEnd": 113 }, "Alias": null } ] }, "ColumnArgList": null } }, { "Name": { "Name": "APPLY", "QuoteType": 1, "NamePos": 115, "NameEnd": 120 }, "Params": { "LeftParenPos": 120, "RightParenPos": 124, "Items": { "ListPos": 121, "ListEnd": 124, "HasDistinct": false, "Items": [ { "Expr": { "Name": "sum", "QuoteType": 1, "NamePos": 121, "NameEnd": 124 }, "Alias": null } ] }, "ColumnArgList": null } } ], "Alias": null } ], "From": { "FromPos": 126, "Expr": { "Table": { "TablePos": 131, "TableEnd": 133, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 131, "NameEnd": 133 } }, "HasFinal": false }, "StatementEnd": 133, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_json_type.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 24, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "a", "QuoteType": 1, "NamePos": 7, "NameEnd": 8 }, "Modifiers": [], "Alias": null }, { "Expr": { "Fields": [ { "Name": "a", "QuoteType": 1, "NamePos": 10, "NameEnd": 11 }, { "Name": "b", "QuoteType": 1, "NamePos": 12, "NameEnd": 13 } ] }, "Modifiers": [], "Alias": null }, { "Expr": { "Fields": [ { "Name": "a", "QuoteType": 1, "NamePos": 15, "NameEnd": 16 }, { "Name": "b", "QuoteType": 1, "NamePos": 17, "NameEnd": 18 }, { "Name": "c", "QuoteType": 1, "NamePos": 19, "NameEnd": 20 }, { "Name": "d", "QuoteType": 1, "NamePos": 21, "NameEnd": 22 }, { "Name": "e", "QuoteType": 1, "NamePos": 23, "NameEnd": 24 } ] }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 26, "StatementEnd": 75, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "JSON_TYPE", "QuoteType": 1, "NamePos": 33, "NameEnd": 42 }, "Params": { "LeftParenPos": 42, "RightParenPos": 75, "Items": { "ListPos": 44, "ListEnd": 74, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 44, "LiteralEnd": 67, "Literal": "{\"a\": 1, \"b\": {\"c\": 2}}" }, "Alias": null }, { "Expr": { "LiteralPos": 71, "LiteralEnd": 74, "Literal": "$.b" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 78, "StatementEnd": 114, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CastPos": 85, "Expr": { "Name": "some", "QuoteType": 1, "NamePos": 90, "NameEnd": 94 }, "Separator": ",", "AsPos": 94, "AsType": { "LiteralPos": 97, "LiteralEnd": 103, "Literal": "String" } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 109, "NameEnd": 114 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 116, "StatementEnd": 157, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CastPos": 123, "Expr": { "Fields": [ { "Name": "some", "QuoteType": 1, "NamePos": 128, "NameEnd": 132 }, { "Name": "long", "QuoteType": 1, "NamePos": 133, "NameEnd": 137 } ] }, "Separator": ",", "AsPos": 137, "AsType": { "LiteralPos": 140, "LiteralEnd": 146, "Literal": "String" } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 152, "NameEnd": 157 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 159, "StatementEnd": 205, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CastPos": 166, "Expr": { "Fields": [ { "Name": "some", "QuoteType": 1, "NamePos": 171, "NameEnd": 175 }, { "Name": "long", "QuoteType": 1, "NamePos": 176, "NameEnd": 180 }, { "Name": "json", "QuoteType": 1, "NamePos": 181, "NameEnd": 185 } ] }, "Separator": ",", "AsPos": 185, "AsType": { "LiteralPos": 188, "LiteralEnd": 194, "Literal": "String" } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 200, "NameEnd": 205 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 207, "StatementEnd": 258, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CastPos": 214, "Expr": { "Fields": [ { "Name": "some", "QuoteType": 1, "NamePos": 219, "NameEnd": 223 }, { "Name": "long", "QuoteType": 1, "NamePos": 224, "NameEnd": 228 }, { "Name": "json", "QuoteType": 1, "NamePos": 229, "NameEnd": 233 }, { "Name": "path", "QuoteType": 1, "NamePos": 234, "NameEnd": 238 } ] }, "Separator": ",", "AsPos": 238, "AsType": { "LiteralPos": 241, "LiteralEnd": 247, "Literal": "String" } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 253, "NameEnd": 258 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_keyword_alias_no_as.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 28, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LiteralPos": 8, "LiteralEnd": 11, "Literal": "Joe" }, "Modifiers": [], "Alias": { "Name": "name", "QuoteType": 1, "NamePos": 13, "NameEnd": 17 } } ], "From": { "FromPos": 18, "Expr": { "Table": { "TablePos": 23, "TableEnd": 28, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "users", "QuoteType": 1, "NamePos": 23, "NameEnd": 28 } }, "HasFinal": false }, "StatementEnd": 28, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_timestamp.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 47, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "Timestamp", "QuoteType": 1, "NamePos": 7, "NameEnd": 16 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 17, "Expr": { "Table": { "TablePos": 22, "TableEnd": 28, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 22, "NameEnd": 28 } }, "HasFinal": false }, "StatementEnd": 28, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 29, "ListEnd": 47, "Items": [ { "OrderPos": 29, "Expr": { "Name": "Timestamp", "QuoteType": 1, "NamePos": 38, "NameEnd": 47 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_with_fill_basic.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 151, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 7, "NameEnd": 8 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "source", "QuoteType": 1, "NamePos": 10, "NameEnd": 16 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 17, "Expr": { "Table": { "TablePos": 22, "TableEnd": 124, "Alias": null, "Expr": { "HasParen": true, "Select": { "SelectPos": 27, "StatementEnd": 124, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toFloat32", "QuoteType": 1, "NamePos": 34, "NameEnd": 43 }, "Params": { "LeftParenPos": 43, "RightParenPos": 55, "Items": { "ListPos": 44, "ListEnd": 55, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 44, "NameEnd": 50 }, "Operation": "%", "RightExpr": { "NumPos": 53, "NumEnd": 55, "Literal": "10", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "n", "QuoteType": 1, "NamePos": 60, "NameEnd": 61 } }, { "Expr": { "LiteralPos": 64, "LiteralEnd": 72, "Literal": "original" }, "Modifiers": [], "Alias": { "Name": "source", "QuoteType": 1, "NamePos": 77, "NameEnd": 83 } } ], "From": { "FromPos": 87, "Expr": { "Table": { "TablePos": 92, "TableEnd": 102, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 92, "NameEnd": 99 }, "Args": { "LeftParenPos": 99, "RightParenPos": 102, "Args": [ { "NumPos": 100, "NumEnd": 102, "Literal": "10", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 102, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 104, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 110, "NameEnd": 116 }, "Operation": "%", "RightExpr": { "NumPos": 119, "NumEnd": 120, "Literal": "3", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "=", "RightExpr": { "NumPos": 123, "NumEnd": 124, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "HasFinal": false }, "StatementEnd": 124, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 127, "ListEnd": 151, "Items": [ { "OrderPos": 127, "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 136, "NameEnd": 137 }, "Alias": null, "Direction": "", "Fill": { "FillPos": 147, "From": null, "To": null, "Step": null, "Staleness": null } } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_with_fill_from_to.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 171, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 7, "NameEnd": 8 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "source", "QuoteType": 1, "NamePos": 10, "NameEnd": 16 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 17, "Expr": { "Table": { "TablePos": 22, "TableEnd": 124, "Alias": null, "Expr": { "HasParen": true, "Select": { "SelectPos": 27, "StatementEnd": 124, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toFloat32", "QuoteType": 1, "NamePos": 34, "NameEnd": 43 }, "Params": { "LeftParenPos": 43, "RightParenPos": 55, "Items": { "ListPos": 44, "ListEnd": 55, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 44, "NameEnd": 50 }, "Operation": "%", "RightExpr": { "NumPos": 53, "NumEnd": 55, "Literal": "10", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "n", "QuoteType": 1, "NamePos": 60, "NameEnd": 61 } }, { "Expr": { "LiteralPos": 64, "LiteralEnd": 72, "Literal": "original" }, "Modifiers": [], "Alias": { "Name": "source", "QuoteType": 1, "NamePos": 77, "NameEnd": 83 } } ], "From": { "FromPos": 87, "Expr": { "Table": { "TablePos": 92, "TableEnd": 102, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 92, "NameEnd": 99 }, "Args": { "LeftParenPos": 99, "RightParenPos": 102, "Args": [ { "NumPos": 100, "NumEnd": 102, "Literal": "10", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 102, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 104, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 110, "NameEnd": 116 }, "Operation": "%", "RightExpr": { "NumPos": 119, "NumEnd": 120, "Literal": "3", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "=", "RightExpr": { "NumPos": 123, "NumEnd": 124, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "HasFinal": false }, "StatementEnd": 124, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 127, "ListEnd": 171, "Items": [ { "OrderPos": 127, "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 136, "NameEnd": 137 }, "Alias": null, "Direction": "", "Fill": { "FillPos": 148, "From": { "NumPos": 148, "NumEnd": 154, "Literal": "0", "Base": 10 }, "To": { "NumPos": 148, "NumEnd": 162, "Literal": "5.51", "Base": 10 }, "Step": { "NumPos": 148, "NumEnd": 171, "Literal": "0.5", "Base": 10 }, "Staleness": null } } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_with_fill_interpolate.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 228, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 7, "NameEnd": 8 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "source", "QuoteType": 1, "NamePos": 10, "NameEnd": 16 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "inter", "QuoteType": 1, "NamePos": 18, "NameEnd": 23 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 24, "Expr": { "Table": { "TablePos": 29, "TableEnd": 148, "Alias": null, "Expr": { "HasParen": true, "Select": { "SelectPos": 34, "StatementEnd": 148, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toFloat32", "QuoteType": 1, "NamePos": 41, "NameEnd": 50 }, "Params": { "LeftParenPos": 50, "RightParenPos": 62, "Items": { "ListPos": 51, "ListEnd": 62, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 51, "NameEnd": 57 }, "Operation": "%", "RightExpr": { "NumPos": 60, "NumEnd": 62, "Literal": "10", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "n", "QuoteType": 1, "NamePos": 67, "NameEnd": 68 } }, { "Expr": { "LiteralPos": 71, "LiteralEnd": 79, "Literal": "original" }, "Modifiers": [], "Alias": { "Name": "source", "QuoteType": 1, "NamePos": 84, "NameEnd": 90 } }, { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 92, "NameEnd": 98 }, "Modifiers": [], "Alias": { "Name": "inter", "QuoteType": 1, "NamePos": 102, "NameEnd": 107 } } ], "From": { "FromPos": 111, "Expr": { "Table": { "TablePos": 116, "TableEnd": 126, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 116, "NameEnd": 123 }, "Args": { "LeftParenPos": 123, "RightParenPos": 126, "Args": [ { "NumPos": 124, "NumEnd": 126, "Literal": "10", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 126, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 128, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 134, "NameEnd": 140 }, "Operation": "%", "RightExpr": { "NumPos": 143, "NumEnd": 144, "Literal": "3", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "=", "RightExpr": { "NumPos": 147, "NumEnd": 148, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "HasFinal": false }, "StatementEnd": 148, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 151, "ListEnd": 228, "Items": [ { "OrderPos": 151, "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 160, "NameEnd": 161 }, "Alias": null, "Direction": "", "Fill": { "FillPos": 172, "From": { "NumPos": 172, "NumEnd": 178, "Literal": "0", "Base": 10 }, "To": { "NumPos": 172, "NumEnd": 186, "Literal": "5.51", "Base": 10 }, "Step": { "NumPos": 172, "NumEnd": 195, "Literal": "0.5", "Base": 10 }, "Staleness": null } } ], "Interpolate": { "InterpolatePos": 196, "ListEnd": 228, "Items": [ { "Column": { "Name": "inter", "QuoteType": 1, "NamePos": 209, "NameEnd": 214 }, "Expr": { "LeftExpr": { "Name": "inter", "QuoteType": 1, "NamePos": 218, "NameEnd": 223 }, "Operation": "+", "RightExpr": { "NumPos": 226, "NumEnd": 227, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } } ] } }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_with_fill_interpolate_no_columns.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 173, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 7, "NameEnd": 8 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "value", "QuoteType": 1, "NamePos": 10, "NameEnd": 15 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 16, "Expr": { "Table": { "TablePos": 21, "TableEnd": 118, "Alias": null, "Expr": { "HasParen": true, "Select": { "SelectPos": 26, "StatementEnd": 118, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toFloat32", "QuoteType": 1, "NamePos": 33, "NameEnd": 42 }, "Params": { "LeftParenPos": 42, "RightParenPos": 54, "Items": { "ListPos": 43, "ListEnd": 54, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 43, "NameEnd": 49 }, "Operation": "%", "RightExpr": { "NumPos": 52, "NumEnd": 54, "Literal": "10", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "n", "QuoteType": 1, "NamePos": 59, "NameEnd": 60 } }, { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 62, "NameEnd": 68 }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 72, "NameEnd": 77 } } ], "From": { "FromPos": 81, "Expr": { "Table": { "TablePos": 86, "TableEnd": 96, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 86, "NameEnd": 93 }, "Args": { "LeftParenPos": 93, "RightParenPos": 96, "Args": [ { "NumPos": 94, "NumEnd": 96, "Literal": "10", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 96, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 98, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 104, "NameEnd": 110 }, "Operation": "%", "RightExpr": { "NumPos": 113, "NumEnd": 114, "Literal": "3", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Operation": "=", "RightExpr": { "NumPos": 117, "NumEnd": 118, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "HasFinal": false }, "StatementEnd": 118, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 121, "ListEnd": 173, "Items": [ { "OrderPos": 121, "Expr": { "Name": "n", "QuoteType": 1, "NamePos": 130, "NameEnd": 131 }, "Alias": null, "Direction": "", "Fill": { "FillPos": 142, "From": { "NumPos": 142, "NumEnd": 148, "Literal": "0", "Base": 10 }, "To": { "NumPos": 142, "NumEnd": 154, "Literal": "10", "Base": 10 }, "Step": { "NumPos": 142, "NumEnd": 161, "Literal": "1", "Base": 10 }, "Staleness": null } } ], "Interpolate": { "InterpolatePos": 162, "ListEnd": 173, "Items": null } }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_with_fill_staleness.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 137, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 7, "NameEnd": 13 }, "Modifiers": [], "Alias": { "Name": "key", "QuoteType": 1, "NamePos": 17, "NameEnd": 20 } }, { "Expr": { "LeftExpr": { "NumPos": 22, "NumEnd": 23, "Literal": "5", "Base": 10 }, "Operation": "*", "RightExpr": { "Name": "number", "QuoteType": 1, "NamePos": 26, "NameEnd": 32 }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 33, "NameEnd": 38 } }, { "Expr": { "LiteralPos": 41, "LiteralEnd": 49, "Literal": "original" }, "Modifiers": [], "Alias": { "Name": "source", "QuoteType": 1, "NamePos": 54, "NameEnd": 60 } } ], "From": { "FromPos": 61, "Expr": { "Table": { "TablePos": 66, "TableEnd": 76, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 66, "NameEnd": 73 }, "Args": { "LeftParenPos": 73, "RightParenPos": 76, "Args": [ { "NumPos": 74, "NumEnd": 76, "Literal": "16", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 76, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 78, "Expr": { "LeftExpr": { "LeftParenPos": 84, "RightParenPos": 95, "Items": { "ListPos": 85, "ListEnd": 95, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "number", "QuoteType": 1, "NamePos": 85, "NameEnd": 91 }, "Operation": "%", "RightExpr": { "NumPos": 94, "NumEnd": 95, "Literal": "5", "Base": 10 }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "Operation": "==", "RightExpr": { "NumPos": 100, "NumEnd": 101, "Literal": "0", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 102, "ListEnd": 137, "Items": [ { "OrderPos": 102, "Expr": { "Name": "key", "QuoteType": 1, "NamePos": 111, "NameEnd": 114 }, "Alias": null, "Direction": "", "Fill": { "FillPos": 125, "From": null, "To": null, "Step": null, "Staleness": { "NumPos": 125, "NumEnd": 137, "Literal": "11", "Base": 10 } } } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_order_by_with_fill_step.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 170, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "date", "QuoteType": 1, "NamePos": 7, "NameEnd": 11 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "value", "QuoteType": 1, "NamePos": 13, "NameEnd": 18 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 19, "Expr": { "Table": { "TablePos": 24, "TableEnd": 123, "Alias": null, "Expr": { "HasParen": true, "Select": { "SelectPos": 30, "StatementEnd": 123, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LeftExpr": { "Name": { "Name": "toDate", "QuoteType": 1, "NamePos": 37, "NameEnd": 43 }, "Params": { "LeftParenPos": 43, "RightParenPos": 56, "Items": { "ListPos": 45, "ListEnd": 55, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 45, "LiteralEnd": 55, "Literal": "2020-01-01" }, "Alias": null } ] }, "ColumnArgList": null } }, "Operation": "+", "RightExpr": { "IntervalPos": 60, "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 69, "NameEnd": 75 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 76, "NameEnd": 79 } }, "HasGlobal": false, "HasNot": false }, "Modifiers": [], "Alias": { "Name": "date", "QuoteType": 1, "NamePos": 83, "NameEnd": 87 } }, { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 89, "NameEnd": 95 }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 99, "NameEnd": 104 } } ], "From": { "FromPos": 109, "Expr": { "Table": { "TablePos": 114, "TableEnd": 123, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 114, "NameEnd": 121 }, "Args": { "LeftParenPos": 121, "RightParenPos": 123, "Args": [ { "NumPos": 122, "NumEnd": 123, "Literal": "5", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 123, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "HasFinal": false }, "StatementEnd": 123, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 127, "ListEnd": 170, "Items": [ { "OrderPos": 127, "Expr": { "Name": "date", "QuoteType": 1, "NamePos": 136, "NameEnd": 140 }, "Alias": null, "Direction": "", "Fill": { "FillPos": 151, "From": null, "To": null, "Step": { "IntervalPos": 156, "Expr": { "NumPos": 165, "NumEnd": 166, "Literal": "1", "Base": 10 }, "Unit": { "Name": "DAY", "QuoteType": 1, "NamePos": 167, "NameEnd": 170 } }, "Staleness": null } } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 277, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 11, "NameEnd": 13 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "coalesce", "QuoteType": 1, "NamePos": 15, "NameEnd": 23 }, "Params": { "LeftParenPos": 23, "RightParenPos": 30, "Items": { "ListPos": 24, "ListEnd": 30, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 24, "NameEnd": 26 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 28, "NameEnd": 30 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "f3", "QuoteType": 1, "NamePos": 35, "NameEnd": 37 } }, { "Expr": { "Function": { "Name": { "Name": "row_number", "QuoteType": 1, "NamePos": 39, "NameEnd": 49 }, "Params": { "LeftParenPos": 49, "RightParenPos": 50, "Items": { "ListPos": 50, "ListEnd": 50, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 52, "OverExpr": { "LeftParenPos": 57, "RightParenPos": 89, "WindowName": null, "PartitionBy": { "PartitionPos": 57, "Expr": { "ListPos": 71, "ListEnd": 73, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 71, "NameEnd": 73 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 74, "ListEnd": 85, "Items": [ { "OrderPos": 74, "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 83, "NameEnd": 85 }, "Alias": null, "Direction": "ASC", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "rn", "QuoteType": 1, "NamePos": 94, "NameEnd": 96 } } ], "From": { "FromPos": 97, "Expr": { "Table": { "TablePos": 102, "TableEnd": 119, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 102, "NameEnd": 106 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 107, "NameEnd": 119 } }, "HasFinal": false }, "StatementEnd": 119, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 120, "Expr": { "LeftExpr": { "LeftExpr": { "LeftExpr": { "LeftParenPos": 126, "RightParenPos": 155, "Items": { "ListPos": 127, "ListEnd": 154, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f0", "QuoteType": 1, "NamePos": 127, "NameEnd": 129 }, "Operation": "IN", "RightExpr": { "LeftParenPos": 133, "RightParenPos": 154, "Items": { "ListPos": 135, "ListEnd": 153, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 135, "LiteralEnd": 138, "Literal": "foo" }, "Alias": null }, { "Expr": { "LiteralPos": 142, "LiteralEnd": 145, "Literal": "bar" }, "Alias": null }, { "Expr": { "LiteralPos": 149, "LiteralEnd": 153, "Literal": "test" }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "Operation": "AND", "RightExpr": { "LeftParenPos": 161, "RightParenPos": 176, "Items": { "ListPos": 162, "ListEnd": 175, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f1", "QuoteType": 1, "NamePos": 162, "NameEnd": 164 }, "Operation": "=", "RightExpr": { "LiteralPos": 168, "LiteralEnd": 175, "Literal": "testing" }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftParenPos": 182, "RightParenPos": 205, "Items": { "ListPos": 183, "ListEnd": 204, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f2", "QuoteType": 1, "NamePos": 183, "NameEnd": 185 }, "Operation": "NOT LIKE", "RightExpr": { "LiteralPos": 196, "LiteralEnd": 204, "Literal": "testing2" }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Name": "f3", "QuoteType": 1, "NamePos": 211, "NameEnd": 213 }, "Operation": "NOT IN", "RightExpr": { "LeftParenPos": 221, "RightParenPos": 235, "Items": { "ListPos": 223, "ListEnd": 234, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 223, "LiteralEnd": 224, "Literal": "a" }, "Alias": null }, { "Expr": { "LiteralPos": 228, "LiteralEnd": 229, "Literal": "b" }, "Alias": null }, { "Expr": { "LiteralPos": 233, "LiteralEnd": 234, "Literal": "c" }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } }, "GroupBy": { "GroupByPos": 239, "GroupByEnd": 258, "AggregateType": "", "Expr": { "ListPos": 248, "ListEnd": 256, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 248, "NameEnd": 250 }, "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 254, "NameEnd": 256 }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": { "Limit": { "LimitPos": 258, "Limit": { "NumPos": 269, "NumEnd": 271, "Literal": "10", "Base": 10 }, "Offset": { "NumPos": 264, "NumEnd": 267, "Literal": "100", "Base": 10 } }, "ByExpr": { "ListPos": 275, "ListEnd": 277, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 275, "NameEnd": 277 }, "Alias": null } ] } }, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_field_alias.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 48, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "field0", "QuoteType": 1, "NamePos": 7, "NameEnd": 13 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "field1", "QuoteType": 1, "NamePos": 15, "NameEnd": 21 }, "Modifiers": [], "Alias": { "Name": "x", "QuoteType": 1, "NamePos": 25, "NameEnd": 26 } }, { "Expr": { "Name": "field2", "QuoteType": 1, "NamePos": 28, "NameEnd": 34 }, "Modifiers": [], "Alias": { "Name": "y", "QuoteType": 1, "NamePos": 35, "NameEnd": 36 } } ], "From": { "FromPos": 37, "Expr": { "Table": { "TablePos": 42, "TableEnd": 48, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "events", "QuoteType": 1, "NamePos": 42, "NameEnd": 48 } }, "HasFinal": false }, "StatementEnd": 48, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_bracket.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 66, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "arrayConcat", "QuoteType": 1, "NamePos": 7, "NameEnd": 18 }, "Params": { "LeftParenPos": 18, "RightParenPos": 41, "Items": { "ListPos": 19, "ListEnd": 40, "HasDistinct": false, "Items": [ { "Expr": { "LeftBracketPos": 19, "RightBracketPos": 24, "Items": { "ListPos": 20, "ListEnd": 24, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 20, "NumEnd": 21, "Literal": "1", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 23, "NumEnd": 24, "Literal": "2", "Base": 10 }, "Alias": null } ] } }, "Alias": null }, { "Expr": { "LeftBracketPos": 27, "RightBracketPos": 32, "Items": { "ListPos": 28, "ListEnd": 32, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 28, "NumEnd": 29, "Literal": "3", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 31, "NumEnd": 32, "Literal": "4", "Base": 10 }, "Alias": null } ] } }, "Alias": null }, { "Expr": { "LeftBracketPos": 35, "RightBracketPos": 40, "Items": { "ListPos": 36, "ListEnd": 40, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 36, "NumEnd": 37, "Literal": "5", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 39, "NumEnd": 40, "Literal": "6", "Base": 10 }, "Alias": null } ] } }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "res", "QuoteType": 1, "NamePos": 46, "NameEnd": 49 } }, { "Expr": { "Object": { "Name": "f1", "QuoteType": 1, "NamePos": 51, "NameEnd": 53 }, "Params": { "LeftBracketPos": 53, "RightBracketPos": 59, "Items": { "ListPos": 55, "ListEnd": 58, "HasDistinct": false, "Items": [ { "Expr": { "Name": "abc", "QuoteType": 2, "NamePos": 55, "NameEnd": 58 }, "Alias": null } ] } } }, "Modifiers": [], "Alias": { "Name": "f2", "QuoteType": 1, "NamePos": 64, "NameEnd": 66 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_cte_with_column_aliases.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 133, "With": { "WithPos": 0, "EndPos": 24, "CTEs": [ { "CTEPos": 9, "Expr": { "Name": { "Name": "test", "QuoteType": 1, "NamePos": 9, "NameEnd": 13 }, "Params": { "LeftParenPos": 13, "RightParenPos": 24, "Items": { "ListPos": 14, "ListEnd": 24, "HasDistinct": false, "Items": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 14, "NameEnd": 16 }, "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 18, "NameEnd": 20 }, "Alias": null }, { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 22, "NameEnd": 24 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "SelectPos": 30, "StatementEnd": 58, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f4", "QuoteType": 1, "NamePos": 37, "NameEnd": 39 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f5", "QuoteType": 1, "NamePos": 41, "NameEnd": 43 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f6", "QuoteType": 1, "NamePos": 45, "NameEnd": 47 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 48, "Expr": { "Table": { "TablePos": 53, "TableEnd": 58, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "sales", "QuoteType": 1, "NamePos": 53, "NameEnd": 58 } }, "HasFinal": false }, "StatementEnd": 58, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 71, "NameEnd": 73 }, "Modifiers": [], "Alias": { "Name": "new_f1", "QuoteType": 1, "NamePos": 77, "NameEnd": 83 } }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 89, "NameEnd": 91 }, "Modifiers": [], "Alias": { "Name": "new_f2", "QuoteType": 1, "NamePos": 95, "NameEnd": 101 } }, { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 107, "NameEnd": 109 }, "Modifiers": [], "Alias": { "Name": "new_f3", "QuoteType": 1, "NamePos": 113, "NameEnd": 119 } } ], "From": { "FromPos": 120, "Expr": { "Table": { "TablePos": 129, "TableEnd": 133, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test", "QuoteType": 1, "NamePos": 129, "NameEnd": 133 } }, "HasFinal": false }, "StatementEnd": 133, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_group_by_with_cube_totals.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 86, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "a", "QuoteType": 1, "NamePos": 7, "NameEnd": 8 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "COUNT", "QuoteType": 1, "NamePos": 10, "NameEnd": 15 }, "Params": { "LeftParenPos": 15, "RightParenPos": 17, "Items": { "ListPos": 16, "ListEnd": 17, "HasDistinct": false, "Items": [ { "Expr": { "Name": "b", "QuoteType": 1, "NamePos": 16, "NameEnd": 17 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 19, "Expr": { "Table": { "TablePos": 24, "TableEnd": 36, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "group_by_all", "QuoteType": 1, "NamePos": 24, "NameEnd": 36 } }, "HasFinal": false }, "StatementEnd": 36, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": { "GroupByPos": 37, "GroupByEnd": 76, "AggregateType": "CUBE", "Expr": { "LeftParenPos": 50, "RightParenPos": 52, "Items": { "ListPos": 51, "ListEnd": 52, "HasDistinct": false, "Items": [ { "Expr": { "Name": "a", "QuoteType": 1, "NamePos": 51, "NameEnd": 52 }, "Alias": null } ] }, "ColumnArgList": null }, "WithCube": true, "WithRollup": false, "WithTotals": true }, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 76, "ListEnd": 86, "Items": [ { "OrderPos": 76, "Expr": { "Name": "a", "QuoteType": 1, "NamePos": 85, "NameEnd": 86 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_is_not_null.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 133, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 7, "NameEnd": 9 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 10, "NameEnd": 12 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 13, "NameEnd": 15 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 16, "NameEnd": 18 }, "Modifiers": [], "Alias": { "Name": "a0", "QuoteType": 1, "NamePos": 22, "NameEnd": 24 } } ], "From": { "FromPos": 25, "Expr": { "Table": { "TablePos": 30, "TableEnd": 47, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 30, "NameEnd": 34 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 35, "NameEnd": 47 } }, "HasFinal": false }, "StatementEnd": 47, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 48, "Expr": { "LeftExpr": { "LeftExpr": { "LeftExpr": { "LeftParenPos": 54, "RightParenPos": 83, "Items": { "ListPos": 55, "ListEnd": 82, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f0", "QuoteType": 1, "NamePos": 55, "NameEnd": 57 }, "Operation": "IN", "RightExpr": { "LeftParenPos": 61, "RightParenPos": 82, "Items": { "ListPos": 63, "ListEnd": 81, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 63, "LiteralEnd": 66, "Literal": "foo" }, "Alias": null }, { "Expr": { "LiteralPos": 70, "LiteralEnd": 73, "Literal": "bar" }, "Alias": null }, { "Expr": { "LiteralPos": 77, "LiteralEnd": 81, "Literal": "test" }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "Operation": "AND", "RightExpr": { "LeftParenPos": 91, "RightParenPos": 106, "Items": { "ListPos": 92, "ListEnd": 105, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f1", "QuoteType": 1, "NamePos": 92, "NameEnd": 94 }, "Operation": "=", "RightExpr": { "LiteralPos": 98, "LiteralEnd": 105, "Literal": "testing" }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "IsPos": 127, "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 114, "NameEnd": 116 } }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "IsPos": 145, "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 131, "NameEnd": 133 } }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_is_null.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 112, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f0", "QuoteType": 1, "NamePos": 7, "NameEnd": 9 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 10, "NameEnd": 12 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 13, "NameEnd": 15 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "f3", "QuoteType": 1, "NamePos": 16, "NameEnd": 18 }, "Modifiers": [], "Alias": { "Name": "a0", "QuoteType": 1, "NamePos": 22, "NameEnd": 24 } } ], "From": { "FromPos": 25, "Expr": { "Table": { "TablePos": 30, "TableEnd": 47, "Alias": null, "Expr": { "Database": { "Name": "test", "QuoteType": 1, "NamePos": 30, "NameEnd": 34 }, "Table": { "Name": "events_local", "QuoteType": 1, "NamePos": 35, "NameEnd": 47 } }, "HasFinal": false }, "StatementEnd": 47, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 48, "Expr": { "LeftExpr": { "LeftExpr": { "LeftParenPos": 54, "RightParenPos": 83, "Items": { "ListPos": 55, "ListEnd": 82, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f0", "QuoteType": 1, "NamePos": 55, "NameEnd": 57 }, "Operation": "IN", "RightExpr": { "LeftParenPos": 61, "RightParenPos": 82, "Items": { "ListPos": 63, "ListEnd": 81, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 63, "LiteralEnd": 66, "Literal": "foo" }, "Alias": null }, { "Expr": { "LiteralPos": 70, "LiteralEnd": 73, "Literal": "bar" }, "Alias": null }, { "Expr": { "LiteralPos": 77, "LiteralEnd": 81, "Literal": "test" }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "Operation": "AND", "RightExpr": { "LeftParenPos": 89, "RightParenPos": 104, "Items": { "ListPos": 90, "ListEnd": 103, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Name": "f1", "QuoteType": 1, "NamePos": 90, "NameEnd": 92 }, "Operation": "=", "RightExpr": { "LiteralPos": 96, "LiteralEnd": 103, "Literal": "testing" }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] }, "ColumnArgList": null }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "IsPos": 120, "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 110, "NameEnd": 112 } }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_limit.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 16, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 7, "NumEnd": 8, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": { "LimitPos": 9, "Limit": { "NumPos": 15, "NumEnd": 16, "Literal": "1", "Base": 10 }, "Offset": null }, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 18, "StatementEnd": 43, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 25, "NumEnd": 26, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": { "LimitPos": 27, "Limit": { "NumPos": 33, "NumEnd": 34, "Literal": "1", "Base": 10 }, "Offset": { "NumPos": 42, "NumEnd": 43, "Literal": "0", "Base": 10 } }, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 45, "StatementEnd": 62, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 52, "NumEnd": 53, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": { "LimitPos": 54, "Limit": null, "Offset": { "NumPos": 61, "NumEnd": 62, "Literal": "0", "Base": 10 } }, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_top_clause.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 38, "With": null, "Top": { "TopPos": 7, "TopEnd": 13, "Number": { "NumPos": 11, "NumEnd": 13, "Literal": "10", "Base": 10 }, "WithTies": false }, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "my_column", "QuoteType": 1, "NamePos": 14, "NameEnd": 23 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 24, "Expr": { "Table": { "TablePos": 29, "TableEnd": 38, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "tableName", "QuoteType": 1, "NamePos": 29, "NameEnd": 38 } }, "HasFinal": false }, "StatementEnd": 38, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_simple_with_with_clause.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 134, "With": { "WithPos": 0, "EndPos": 46, "CTEs": [ { "CTEPos": 9, "Expr": { "Name": "cte1", "QuoteType": 1, "NamePos": 9, "NameEnd": 13 }, "Alias": { "SelectPos": 18, "StatementEnd": 35, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f1", "QuoteType": 1, "NamePos": 25, "NameEnd": 27 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 28, "Expr": { "Table": { "TablePos": 33, "TableEnd": 35, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 33, "NameEnd": 35 } }, "HasFinal": false }, "StatementEnd": 35, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, { "CTEPos": 42, "Expr": { "Name": "cte2", "QuoteType": 1, "NamePos": 42, "NameEnd": 46 }, "Alias": { "SelectPos": 51, "StatementEnd": 68, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "f2", "QuoteType": 1, "NamePos": 58, "NameEnd": 60 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 61, "Expr": { "Table": { "TablePos": 66, "TableEnd": 68, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 66, "NameEnd": 68 } }, "HasFinal": false }, "StatementEnd": 68, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Fields": [ { "Name": "cte1", "QuoteType": 1, "NamePos": 81, "NameEnd": 85 }, { "Name": "f1", "QuoteType": 1, "NamePos": 86, "NameEnd": 88 } ] }, "Modifiers": [], "Alias": null }, { "Expr": { "Fields": [ { "Name": "cte2", "QuoteType": 1, "NamePos": 94, "NameEnd": 98 }, { "Name": "f2", "QuoteType": 1, "NamePos": 99, "NameEnd": 101 } ] }, "Modifiers": [], "Alias": null }, { "Expr": { "Fields": [ { "Name": "t3", "QuoteType": 1, "NamePos": 107, "NameEnd": 109 }, { "Name": "f3", "QuoteType": 1, "NamePos": 110, "NameEnd": 112 } ] }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 113, "Expr": { "JoinPos": 122, "Left": { "Table": { "TablePos": 122, "TableEnd": 124, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t3", "QuoteType": 1, "NamePos": 122, "NameEnd": 124 } }, "HasFinal": false }, "StatementEnd": 124, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 125, "Left": { "Table": { "TablePos": 125, "TableEnd": 129, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "cte1", "QuoteType": 1, "NamePos": 125, "NameEnd": 129 } }, "HasFinal": false }, "StatementEnd": 129, "SampleRatio": null, "HasFinal": false }, "Right": { "Table": { "TablePos": 130, "TableEnd": 134, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "cte2", "QuoteType": 1, "NamePos": 130, "NameEnd": 134 } }, "HasFinal": false }, "StatementEnd": 134, "SampleRatio": null, "HasFinal": false }, "Modifiers": null, "Constraints": null }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_table_alias_without_keyword.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 78, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Fields": [ { "Name": "t1", "QuoteType": 1, "NamePos": 7, "NameEnd": 9 }, { "Name": "Timestamp", "QuoteType": 1, "NamePos": 10, "NameEnd": 19 } ] }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 20, "Expr": { "JoinPos": 25, "Left": { "Table": { "TablePos": 25, "TableEnd": 36, "Alias": null, "Expr": { "Expr": { "Database": null, "Table": { "Name": "my_table", "QuoteType": 1, "NamePos": 25, "NameEnd": 33 } }, "AliasPos": 34, "Alias": { "Name": "t1", "QuoteType": 1, "NamePos": 34, "NameEnd": 36 } }, "HasFinal": false }, "StatementEnd": 36, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 37, "Left": { "Table": { "TablePos": 48, "TableEnd": 65, "Alias": null, "Expr": { "Expr": { "Database": null, "Table": { "Name": "my_other_table", "QuoteType": 1, "NamePos": 48, "NameEnd": 62 } }, "AliasPos": 63, "Alias": { "Name": "t2", "QuoteType": 1, "NamePos": 63, "NameEnd": 65 } }, "HasFinal": false }, "StatementEnd": 65, "SampleRatio": null, "HasFinal": false }, "Right": null, "Modifiers": [ "INNER", "JOIN" ], "Constraints": { "OnPos": 66, "On": { "ListPos": 69, "ListEnd": 78, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Fields": [ { "Name": "t1", "QuoteType": 1, "NamePos": 69, "NameEnd": 71 }, { "Name": "a", "QuoteType": 1, "NamePos": 72, "NameEnd": 73 } ] }, "Operation": "=", "RightExpr": { "Fields": [ { "Name": "t2", "QuoteType": 1, "NamePos": 74, "NameEnd": 76 }, { "Name": "b", "QuoteType": 1, "NamePos": 77, "NameEnd": 78 } ] }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] } } }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_table_function_with_query.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 125, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 7, "NumEnd": 8, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null }, { "Expr": { "HasParen": true, "Select": { "SelectPos": 11, "StatementEnd": 20, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 18, "NumEnd": 20, "Literal": "70", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "Modifiers": [], "Alias": { "Name": "power", "QuoteType": 3, "NamePos": 26, "NameEnd": 31 } }, { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 34, "NameEnd": 40 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 41, "Expr": { "Table": { "TablePos": 46, "TableEnd": 125, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 46, "NameEnd": 53 }, "Args": { "LeftParenPos": 53, "RightParenPos": 125, "Args": [ { "Name": { "Name": "plus", "QuoteType": 1, "NamePos": 59, "NameEnd": 63 }, "Args": { "LeftParenPos": 59, "RightParenPos": 123, "Args": [ { "Name": { "Name": "ifNull", "QuoteType": 1, "NamePos": 73, "NameEnd": 79 }, "Args": { "LeftParenPos": 73, "RightParenPos": 117, "Args": [ { "HasParen": true, "Select": { "SelectPos": 81, "StatementEnd": 105, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 88, "NumEnd": 89, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "bin_count", "QuoteType": 1, "NamePos": 93, "NameEnd": 102 } }, { "Expr": { "NumPos": 104, "NumEnd": 105, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, { "NumPos": 116, "NumEnd": 117, "Literal": "1", "Base": 10 } ] } } ] } } ] } }, "HasFinal": false }, "StatementEnd": 125, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_when_condition.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 0, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "CasePos": 7, "EndPos": 0, "Expr": null, "Whens": [ { "WhenPos": 12, "ThenPos": 23, "When": { "Name": "false", "QuoteType": 1, "NamePos": 17, "NameEnd": 22 }, "Then": { "LiteralPos": 29, "LiteralEnd": 34, "Literal": "hello" }, "ElsePos": 0, "Else": null } ], "ElsePos": 36, "Else": { "LiteralPos": 42, "LiteralEnd": 47, "Literal": "world" } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_window_comprehensive.sql.golden.json ================================================ [ { "SelectPos": 167, "StatementEnd": 4194, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 200, "NameEnd": 203 }, "Params": { "LeftParenPos": 203, "RightParenPos": 205, "Items": { "ListPos": 204, "ListEnd": 205, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 204, "NameEnd": 205 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 207, "OverExpr": { "LeftParenPos": 212, "RightParenPos": 272, "WindowName": null, "PartitionBy": null, "OrderBy": { "OrderPos": 213, "ListEnd": 223, "Items": [ { "OrderPos": 213, "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 222, "NameEnd": 223 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 224, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 237, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 257, "And": { "CurrentPos": 261, "RowEnd": 273 } } } } }, "Modifiers": [], "Alias": { "Name": "running_total", "QuoteType": 1, "NamePos": 317, "NameEnd": 330 } }, { "Expr": { "Function": { "Name": { "Name": "avg", "QuoteType": 1, "NamePos": 336, "NameEnd": 339 }, "Params": { "LeftParenPos": 339, "RightParenPos": 341, "Items": { "ListPos": 340, "ListEnd": 341, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 340, "NameEnd": 341 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 351, "OverExpr": { "LeftParenPos": 356, "RightParenPos": 424, "WindowName": null, "PartitionBy": { "PartitionPos": 356, "Expr": { "ListPos": 370, "ListEnd": 371, "HasDistinct": false, "Items": [ { "Expr": { "Name": "z", "QuoteType": 1, "NamePos": 370, "NameEnd": 371 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 372, "ListEnd": 382, "Items": [ { "OrderPos": 372, "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 381, "NameEnd": 382 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 383, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 397, "NumEnd": 398, "Literal": "1", "Base": 10 }, "EndPos": 408, "Direction": "PRECEDING" }, "AndPos": 409, "And": { "Number": { "NumPos": 413, "NumEnd": 414, "Literal": "1", "Base": 10 }, "EndPos": 424, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "avg_range1", "QuoteType": 1, "NamePos": 464, "NameEnd": 474 } }, { "Expr": { "Function": { "Name": { "Name": "row_number", "QuoteType": 1, "NamePos": 517, "NameEnd": 527 }, "Params": { "LeftParenPos": 527, "RightParenPos": 528, "Items": { "ListPos": 528, "ListEnd": 528, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 530, "OverExpr": { "Name": "w1", "QuoteType": 1, "NamePos": 535, "NameEnd": 537 } }, "Modifiers": [], "Alias": { "Name": "rn_w1", "QuoteType": 1, "NamePos": 634, "NameEnd": 639 } }, { "Expr": { "Function": { "Name": { "Name": "rank", "QuoteType": 1, "NamePos": 645, "NameEnd": 649 }, "Params": { "LeftParenPos": 649, "RightParenPos": 650, "Items": { "ListPos": 650, "ListEnd": 650, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 652, "OverExpr": { "Name": "w1", "QuoteType": 1, "NamePos": 657, "NameEnd": 659 } }, "Modifiers": [], "Alias": { "Name": "rank_w1", "QuoteType": 1, "NamePos": 762, "NameEnd": 769 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 775, "NameEnd": 778 }, "Params": { "LeftParenPos": 778, "RightParenPos": 780, "Items": { "ListPos": 779, "ListEnd": 780, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 779, "NameEnd": 780 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 782, "OverExpr": { "Name": "w1", "QuoteType": 1, "NamePos": 787, "NameEnd": 789 } }, "Modifiers": [], "Alias": { "Name": "sum_w1", "QuoteType": 1, "NamePos": 892, "NameEnd": 898 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 953, "NameEnd": 956 }, "Params": { "LeftParenPos": 956, "RightParenPos": 958, "Items": { "ListPos": 957, "ListEnd": 958, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 957, "NameEnd": 958 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 960, "OverExpr": { "LeftParenPos": 965, "RightParenPos": 983, "WindowName": null, "PartitionBy": null, "OrderBy": null, "Frame": { "FramePos": 966, "Type": "ROWS", "Extend": { "Number": { "NumPos": 971, "NumEnd": 973, "Literal": "10", "Base": 10 }, "EndPos": 983, "Direction": "PRECEDING" } } } }, "Modifiers": [], "Alias": { "Name": "rows_10_preceding", "QuoteType": 1, "NamePos": 1070, "NameEnd": 1087 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 1093, "NameEnd": 1096 }, "Params": { "LeftParenPos": 1096, "RightParenPos": 1098, "Items": { "ListPos": 1097, "ListEnd": 1098, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1097, "NameEnd": 1098 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 1100, "OverExpr": { "LeftParenPos": 1105, "RightParenPos": 1154, "WindowName": null, "PartitionBy": null, "OrderBy": null, "Frame": { "FramePos": 1106, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "CurrentPos": 1119, "RowEnd": 1134 }, "AndPos": 1131, "And": { "UnboundedPos": 1135, "UnboundedEnd": 0, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "rows_cur_to_unbounded_following", "QuoteType": 1, "NamePos": 1210, "NameEnd": 1241 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 1247, "NameEnd": 1250 }, "Params": { "LeftParenPos": 1250, "RightParenPos": 1252, "Items": { "ListPos": 1251, "ListEnd": 1252, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1251, "NameEnd": 1252 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 1254, "OverExpr": { "LeftParenPos": 1259, "RightParenPos": 1300, "WindowName": null, "PartitionBy": null, "OrderBy": null, "Frame": { "FramePos": 1260, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 1273, "NumEnd": 1274, "Literal": "5", "Base": 10 }, "EndPos": 1284, "Direction": "PRECEDING" }, "AndPos": 1285, "And": { "Number": { "NumPos": 1289, "NumEnd": 1290, "Literal": "3", "Base": 10 }, "EndPos": 1300, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "rows_5p_3f", "QuoteType": 1, "NamePos": 1364, "NameEnd": 1374 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 1380, "NameEnd": 1383 }, "Params": { "LeftParenPos": 1383, "RightParenPos": 1385, "Items": { "ListPos": 1384, "ListEnd": 1385, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1384, "NameEnd": 1385 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 1387, "OverExpr": { "LeftParenPos": 1392, "RightParenPos": 1435, "WindowName": null, "PartitionBy": null, "OrderBy": null, "Frame": { "FramePos": 1393, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 1407, "NumEnd": 1409, "Literal": "10", "Base": 10 }, "EndPos": 1419, "Direction": "PRECEDING" }, "AndPos": 1420, "And": { "CurrentPos": 1424, "RowEnd": 1436 } } } } }, "Modifiers": [], "Alias": { "Name": "range_10p_cur", "QuoteType": 1, "NamePos": 1497, "NameEnd": 1510 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 1516, "NameEnd": 1519 }, "Params": { "LeftParenPos": 1519, "RightParenPos": 1521, "Items": { "ListPos": 1520, "ListEnd": 1521, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1520, "NameEnd": 1521 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 1523, "OverExpr": { "LeftParenPos": 1528, "RightParenPos": 1578, "WindowName": null, "PartitionBy": null, "OrderBy": null, "Frame": { "FramePos": 1529, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "UnboundedPos": 1543, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 1563, "And": { "CurrentPos": 1567, "RowEnd": 1579 } } } } }, "Modifiers": [], "Alias": { "Name": "range_unbounded_to_cur", "QuoteType": 1, "NamePos": 1633, "NameEnd": 1655 } }, { "Expr": { "Function": { "Name": { "Name": "row_number", "QuoteType": 1, "NamePos": 1690, "NameEnd": 1700 }, "Params": { "LeftParenPos": 1700, "RightParenPos": 1701, "Items": { "ListPos": 1701, "ListEnd": 1701, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 1703, "OverExpr": { "LeftParenPos": 1708, "RightParenPos": 1734, "WindowName": null, "PartitionBy": { "PartitionPos": 1708, "Expr": { "ListPos": 1722, "ListEnd": 1723, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 1722, "NameEnd": 1723 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 1724, "ListEnd": 1734, "Items": [ { "OrderPos": 1724, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1733, "NameEnd": 1734 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "row_num", "QuoteType": 1, "NamePos": 1807, "NameEnd": 1814 } }, { "Expr": { "Function": { "Name": { "Name": "rank", "QuoteType": 1, "NamePos": 1820, "NameEnd": 1824 }, "Params": { "LeftParenPos": 1824, "RightParenPos": 1825, "Items": { "ListPos": 1825, "ListEnd": 1825, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 1827, "OverExpr": { "LeftParenPos": 1832, "RightParenPos": 1858, "WindowName": null, "PartitionBy": { "PartitionPos": 1832, "Expr": { "ListPos": 1846, "ListEnd": 1847, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 1846, "NameEnd": 1847 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 1848, "ListEnd": 1858, "Items": [ { "OrderPos": 1848, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1857, "NameEnd": 1858 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "rank_val", "QuoteType": 1, "NamePos": 1937, "NameEnd": 1945 } }, { "Expr": { "Function": { "Name": { "Name": "dense_rank", "QuoteType": 1, "NamePos": 1951, "NameEnd": 1961 }, "Params": { "LeftParenPos": 1961, "RightParenPos": 1962, "Items": { "ListPos": 1962, "ListEnd": 1962, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 1964, "OverExpr": { "LeftParenPos": 1969, "RightParenPos": 1995, "WindowName": null, "PartitionBy": { "PartitionPos": 1969, "Expr": { "ListPos": 1983, "ListEnd": 1984, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 1983, "NameEnd": 1984 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 1985, "ListEnd": 1995, "Items": [ { "OrderPos": 1985, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 1994, "NameEnd": 1995 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "dense_rank_val", "QuoteType": 1, "NamePos": 2068, "NameEnd": 2082 } }, { "Expr": { "Function": { "Name": { "Name": "first_value", "QuoteType": 1, "NamePos": 2088, "NameEnd": 2099 }, "Params": { "LeftParenPos": 2099, "RightParenPos": 2101, "Items": { "ListPos": 2100, "ListEnd": 2101, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2100, "NameEnd": 2101 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 2119, "OverExpr": { "LeftParenPos": 2124, "RightParenPos": 2207, "WindowName": null, "PartitionBy": { "PartitionPos": 2124, "Expr": { "ListPos": 2138, "ListEnd": 2139, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 2138, "NameEnd": 2139 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 2140, "ListEnd": 2150, "Items": [ { "OrderPos": 2140, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2149, "NameEnd": 2150 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 2151, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 2164, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 2184, "And": { "UnboundedPos": 2188, "UnboundedEnd": 0, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "first_val", "QuoteType": 1, "NamePos": 2224, "NameEnd": 2233 } }, { "Expr": { "Function": { "Name": { "Name": "last_value", "QuoteType": 1, "NamePos": 2239, "NameEnd": 2249 }, "Params": { "LeftParenPos": 2249, "RightParenPos": 2251, "Items": { "ListPos": 2250, "ListEnd": 2251, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2250, "NameEnd": 2251 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 2268, "OverExpr": { "LeftParenPos": 2273, "RightParenPos": 2356, "WindowName": null, "PartitionBy": { "PartitionPos": 2273, "Expr": { "ListPos": 2287, "ListEnd": 2288, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 2287, "NameEnd": 2288 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 2289, "ListEnd": 2299, "Items": [ { "OrderPos": 2289, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2298, "NameEnd": 2299 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 2300, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 2313, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 2333, "And": { "UnboundedPos": 2337, "UnboundedEnd": 0, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "last_val", "QuoteType": 1, "NamePos": 2374, "NameEnd": 2382 } }, { "Expr": { "Function": { "Name": { "Name": "lag", "QuoteType": 1, "NamePos": 2388, "NameEnd": 2391 }, "Params": { "LeftParenPos": 2391, "RightParenPos": 2396, "Items": { "ListPos": 2392, "ListEnd": 2396, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2392, "NameEnd": 2393 }, "Alias": null }, { "Expr": { "NumPos": 2395, "NumEnd": 2396, "Literal": "1", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 2398, "OverExpr": { "LeftParenPos": 2403, "RightParenPos": 2429, "WindowName": null, "PartitionBy": { "PartitionPos": 2403, "Expr": { "ListPos": 2417, "ListEnd": 2418, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 2417, "NameEnd": 2418 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 2419, "ListEnd": 2429, "Items": [ { "OrderPos": 2419, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2428, "NameEnd": 2429 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "prev_x", "QuoteType": 1, "NamePos": 2505, "NameEnd": 2511 } }, { "Expr": { "Function": { "Name": { "Name": "lead", "QuoteType": 1, "NamePos": 2517, "NameEnd": 2521 }, "Params": { "LeftParenPos": 2521, "RightParenPos": 2526, "Items": { "ListPos": 2522, "ListEnd": 2526, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2522, "NameEnd": 2523 }, "Alias": null }, { "Expr": { "NumPos": 2525, "NumEnd": 2526, "Literal": "1", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 2528, "OverExpr": { "LeftParenPos": 2533, "RightParenPos": 2559, "WindowName": null, "PartitionBy": { "PartitionPos": 2533, "Expr": { "ListPos": 2547, "ListEnd": 2548, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 2547, "NameEnd": 2548 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 2549, "ListEnd": 2559, "Items": [ { "OrderPos": 2549, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2558, "NameEnd": 2559 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "next_x", "QuoteType": 1, "NamePos": 2634, "NameEnd": 2640 } }, { "Expr": { "Function": { "Name": { "Name": "percent_rank", "QuoteType": 1, "NamePos": 2646, "NameEnd": 2658 }, "Params": { "LeftParenPos": 2658, "RightParenPos": 2659, "Items": { "ListPos": 2659, "ListEnd": 2659, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 2661, "OverExpr": { "LeftParenPos": 2666, "RightParenPos": 2692, "WindowName": null, "PartitionBy": { "PartitionPos": 2666, "Expr": { "ListPos": 2680, "ListEnd": 2681, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 2680, "NameEnd": 2681 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 2682, "ListEnd": 2692, "Items": [ { "OrderPos": 2682, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2691, "NameEnd": 2692 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "pct_rank", "QuoteType": 1, "NamePos": 2763, "NameEnd": 2771 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 2836, "NameEnd": 2839 }, "Params": { "LeftParenPos": 2839, "RightParenPos": 2841, "Items": { "ListPos": 2840, "ListEnd": 2841, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2840, "NameEnd": 2841 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 2843, "OverExpr": { "Name": "w", "QuoteType": 1, "NamePos": 2848, "NameEnd": 2849 } }, "Modifiers": [], "Alias": { "Name": "sum_over_w", "QuoteType": 1, "NamePos": 2953, "NameEnd": 2963 } }, { "Expr": { "Function": { "Name": { "Name": "avg", "QuoteType": 1, "NamePos": 2969, "NameEnd": 2972 }, "Params": { "LeftParenPos": 2972, "RightParenPos": 2974, "Items": { "ListPos": 2973, "ListEnd": 2974, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 2973, "NameEnd": 2974 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 2976, "OverExpr": { "Name": "w", "QuoteType": 1, "NamePos": 2981, "NameEnd": 2982 } }, "Modifiers": [], "Alias": { "Name": "avg_over_w", "QuoteType": 1, "NamePos": 3086, "NameEnd": 3096 } }, { "Expr": { "Function": { "Name": { "Name": "row_number", "QuoteType": 1, "NamePos": 3102, "NameEnd": 3112 }, "Params": { "LeftParenPos": 3112, "RightParenPos": 3113, "Items": { "ListPos": 3113, "ListEnd": 3113, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 3115, "OverExpr": { "Name": "w", "QuoteType": 1, "NamePos": 3120, "NameEnd": 3121 } }, "Modifiers": [], "Alias": { "Name": "rn_over_w", "QuoteType": 1, "NamePos": 3219, "NameEnd": 3228 } }, { "Expr": { "Function": { "Name": { "Name": "count", "QuoteType": 1, "NamePos": 3286, "NameEnd": 3291 }, "Params": { "LeftParenPos": 3291, "RightParenPos": 3293, "Items": { "ListPos": 3292, "ListEnd": 3292, "HasDistinct": false, "Items": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 3292, "NameEnd": 3292 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 3295, "OverExpr": { "LeftParenPos": 3300, "RightParenPos": 3355, "WindowName": null, "PartitionBy": { "PartitionPos": 3300, "Expr": { "ListPos": 3314, "ListEnd": 3330, "HasDistinct": false, "Items": [ { "Expr": { "Name": "col1", "QuoteType": 1, "NamePos": 3314, "NameEnd": 3318 }, "Alias": null }, { "Expr": { "Name": "col2", "QuoteType": 1, "NamePos": 3320, "NameEnd": 3324 }, "Alias": null }, { "Expr": { "Name": "col3", "QuoteType": 1, "NamePos": 3326, "NameEnd": 3330 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 3331, "ListEnd": 3350, "Items": [ { "OrderPos": 3331, "Expr": { "Name": "col4", "QuoteType": 1, "NamePos": 3340, "NameEnd": 3344 }, "Alias": null, "Direction": "", "Fill": null }, { "OrderPos": 3331, "Expr": { "Name": "col5", "QuoteType": 1, "NamePos": 3346, "NameEnd": 3350 }, "Alias": null, "Direction": "DESC", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "cnt_multi", "QuoteType": 1, "NamePos": 3403, "NameEnd": 3412 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 3418, "NameEnd": 3421 }, "Params": { "LeftParenPos": 3421, "RightParenPos": 3425, "Items": { "ListPos": 3422, "ListEnd": 3425, "HasDistinct": false, "Items": [ { "Expr": { "Name": "val", "QuoteType": 1, "NamePos": 3422, "NameEnd": 3425 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 3435, "OverExpr": { "LeftParenPos": 3440, "RightParenPos": 3533, "WindowName": null, "PartitionBy": { "PartitionPos": 3440, "Expr": { "ListPos": 3454, "ListEnd": 3464, "HasDistinct": false, "Items": [ { "Expr": { "Name": "col1", "QuoteType": 1, "NamePos": 3454, "NameEnd": 3458 }, "Alias": null }, { "Expr": { "Name": "col2", "QuoteType": 1, "NamePos": 3460, "NameEnd": 3464 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 3465, "ListEnd": 3484, "Items": [ { "OrderPos": 3465, "Expr": { "Name": "col4", "QuoteType": 1, "NamePos": 3474, "NameEnd": 3478 }, "Alias": null, "Direction": "", "Fill": null }, { "OrderPos": 3465, "Expr": { "Name": "col5", "QuoteType": 1, "NamePos": 3480, "NameEnd": 3484 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 3485, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 3498, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 3518, "And": { "CurrentPos": 3522, "RowEnd": 3534 } } } } }, "Modifiers": [], "Alias": { "Name": "total_multi", "QuoteType": 1, "NamePos": 3548, "NameEnd": 3559 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 3604, "NameEnd": 3607 }, "Params": { "LeftParenPos": 3607, "RightParenPos": 3614, "Items": { "ListPos": 3608, "ListEnd": 3614, "HasDistinct": false, "Items": [ { "Expr": { "Name": "amount", "QuoteType": 1, "NamePos": 3608, "NameEnd": 3614 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 3624, "OverExpr": { "LeftParenPos": 3629, "RightParenPos": 3732, "WindowName": null, "PartitionBy": { "PartitionPos": 3629, "Expr": { "ListPos": 3643, "ListEnd": 3670, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "date_trunc", "QuoteType": 1, "NamePos": 3643, "NameEnd": 3653 }, "Params": { "LeftParenPos": 3653, "RightParenPos": 3670, "Items": { "ListPos": 3655, "ListEnd": 3670, "HasDistinct": false, "Items": [ { "Expr": { "LiteralPos": 3655, "LiteralEnd": 3658, "Literal": "day" }, "Alias": null }, { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 3661, "NameEnd": 3670 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 3672, "ListEnd": 3690, "Items": [ { "OrderPos": 3672, "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 3681, "NameEnd": 3690 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 3691, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 3704, "NumEnd": 3706, "Literal": "10", "Base": 10 }, "EndPos": 3716, "Direction": "PRECEDING" }, "AndPos": 3717, "And": { "CurrentPos": 3721, "RowEnd": 3733 } } } } }, "Modifiers": [], "Alias": { "Name": "daily_total", "QuoteType": 1, "NamePos": 3737, "NameEnd": 3748 } }, { "Expr": { "Function": { "Name": { "Name": "avg", "QuoteType": 1, "NamePos": 3754, "NameEnd": 3757 }, "Params": { "LeftParenPos": 3757, "RightParenPos": 3764, "Items": { "ListPos": 3758, "ListEnd": 3764, "HasDistinct": false, "Items": [ { "Expr": { "Name": "amount", "QuoteType": 1, "NamePos": 3758, "NameEnd": 3764 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 3774, "OverExpr": { "LeftParenPos": 3779, "RightParenPos": 3859, "WindowName": null, "PartitionBy": null, "OrderBy": { "OrderPos": 3780, "ListEnd": 3816, "Items": [ { "OrderPos": 3780, "Expr": { "ExtractPos": 3780, "ExtractEnd": 3816, "Parameters": [ { "Interval": { "Name": "HOUR", "QuoteType": 1, "NamePos": 3797, "NameEnd": 3801 }, "FromPos": 3802, "FromExpr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 3807, "NameEnd": 3816 } } ] }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 3818, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 3832, "NumEnd": 3833, "Literal": "1", "Base": 10 }, "EndPos": 3843, "Direction": "PRECEDING" }, "AndPos": 3844, "And": { "Number": { "NumPos": 3848, "NumEnd": 3849, "Literal": "1", "Base": 10 }, "EndPos": 3859, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "hourly_avg", "QuoteType": 1, "NamePos": 3887, "NameEnd": 3897 } } ], "From": { "FromPos": 3898, "Expr": { "Table": { "TablePos": 3903, "TableEnd": 3904, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 3903, "NameEnd": 3904 } }, "HasFinal": false }, "StatementEnd": 3904, "SampleRatio": null, "HasFinal": false } }, "Window": { "WindowPos": 3905, "EndPos": 4194, "Windows": [ { "Name": { "Name": "w", "QuoteType": 1, "NamePos": 3912, "NameEnd": 3913 }, "AsPos": 3914, "Expr": { "LeftParenPos": 3917, "RightParenPos": 3928, "WindowName": null, "PartitionBy": null, "OrderBy": { "OrderPos": 3918, "ListEnd": 3928, "Items": [ { "OrderPos": 3918, "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 3927, "NameEnd": 3928 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } }, { "Name": { "Name": "w1", "QuoteType": 1, "NamePos": 3938, "NameEnd": 3940 }, "AsPos": 3941, "Expr": { "LeftParenPos": 3944, "RightParenPos": 4019, "WindowName": null, "PartitionBy": { "PartitionPos": 3944, "Expr": { "ListPos": 3958, "ListEnd": 3959, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 3958, "NameEnd": 3959 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 3960, "ListEnd": 3970, "Items": [ { "OrderPos": 3960, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 3969, "NameEnd": 3970 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 3971, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 3984, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 4004, "And": { "CurrentPos": 4008, "RowEnd": 4020 } } } } }, { "Name": { "Name": "w4", "QuoteType": 1, "NamePos": 4029, "NameEnd": 4031 }, "AsPos": 4032, "Expr": { "LeftParenPos": 4035, "RightParenPos": 4102, "WindowName": null, "PartitionBy": { "PartitionPos": 4035, "Expr": { "ListPos": 4049, "ListEnd": 4050, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 4049, "NameEnd": 4050 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 4051, "ListEnd": 4061, "Items": [ { "OrderPos": 4051, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 4060, "NameEnd": 4061 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 4062, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 4075, "NumEnd": 4076, "Literal": "3", "Base": 10 }, "EndPos": 4086, "Direction": "PRECEDING" }, "AndPos": 4087, "And": { "CurrentPos": 4091, "RowEnd": 4103 } } } } }, { "Name": { "Name": "w5", "QuoteType": 1, "NamePos": 4112, "NameEnd": 4114 }, "AsPos": 4115, "Expr": { "LeftParenPos": 4118, "RightParenPos": 4194, "WindowName": null, "PartitionBy": { "PartitionPos": 4118, "Expr": { "ListPos": 4132, "ListEnd": 4133, "HasDistinct": false, "Items": [ { "Expr": { "Name": "z", "QuoteType": 1, "NamePos": 4132, "NameEnd": 4133 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 4134, "ListEnd": 4144, "Items": [ { "OrderPos": 4134, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 4143, "NameEnd": 4144 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 4145, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "UnboundedPos": 4159, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 4179, "And": { "CurrentPos": 4183, "RowEnd": 4195 } } } } } ] }, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_window_cte.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 746, "With": { "WithPos": 0, "EndPos": 249, "CTEs": [ { "CTEPos": 9, "Expr": { "Name": "monthly", "QuoteType": 1, "NamePos": 9, "NameEnd": 16 }, "Alias": { "SelectPos": 30, "StatementEnd": 236, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toStartOfMonth", "QuoteType": 1, "NamePos": 37, "NameEnd": 51 }, "Params": { "LeftParenPos": 51, "RightParenPos": 56, "Items": { "ListPos": 52, "ListEnd": 56, "HasDistinct": false, "Items": [ { "Expr": { "Name": "date", "QuoteType": 1, "NamePos": 52, "NameEnd": 56 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "month", "QuoteType": 1, "NamePos": 61, "NameEnd": 66 } }, { "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 83, "NameEnd": 93 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "avg", "QuoteType": 1, "NamePos": 110, "NameEnd": 113 }, "Params": { "LeftParenPos": 113, "RightParenPos": 120, "Items": { "ListPos": 114, "ListEnd": 120, "HasDistinct": false, "Items": [ { "Expr": { "Name": "salary", "QuoteType": 1, "NamePos": 114, "NameEnd": 120 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "avg_salary", "QuoteType": 1, "NamePos": 134, "NameEnd": 144 } } ], "From": { "FromPos": 153, "Expr": { "Table": { "TablePos": 158, "TableEnd": 170, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "salary_table", "QuoteType": 1, "NamePos": 158, "NameEnd": 170 } }, "HasFinal": false }, "StatementEnd": 170, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 179, "Expr": { "LeftExpr": { "Name": "year", "QuoteType": 1, "NamePos": 185, "NameEnd": 189 }, "Operation": "=", "RightExpr": { "NumPos": 192, "NumEnd": 196, "Literal": "2023", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": { "GroupByPos": 205, "GroupByEnd": 236, "AggregateType": "", "Expr": { "ListPos": 214, "ListEnd": 231, "HasDistinct": false, "Items": [ { "Expr": { "Name": "month", "QuoteType": 1, "NamePos": 214, "NameEnd": 219 }, "Alias": null }, { "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 221, "NameEnd": 231 }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, { "CTEPos": 243, "Expr": { "Name": "ranked", "QuoteType": 1, "NamePos": 243, "NameEnd": 249 }, "Alias": { "SelectPos": 263, "StatementEnd": 448, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "month", "QuoteType": 1, "NamePos": 270, "NameEnd": 275 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 292, "NameEnd": 302 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "avg_salary", "QuoteType": 1, "NamePos": 319, "NameEnd": 329 }, "Modifiers": [], "Alias": null }, { "Expr": { "Function": { "Name": { "Name": "row_number", "QuoteType": 1, "NamePos": 346, "NameEnd": 356 }, "Params": { "LeftParenPos": 356, "RightParenPos": 357, "Items": { "ListPos": 357, "ListEnd": 357, "HasDistinct": false, "Items": [] }, "ColumnArgList": null } }, "OverPos": 359, "OverExpr": { "LeftParenPos": 364, "RightParenPos": 413, "WindowName": null, "PartitionBy": { "PartitionPos": 364, "Expr": { "ListPos": 378, "ListEnd": 388, "HasDistinct": false, "Items": [ { "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 378, "NameEnd": 388 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 389, "ListEnd": 408, "Items": [ { "OrderPos": 389, "Expr": { "Name": "avg_salary", "QuoteType": 1, "NamePos": 398, "NameEnd": 408 }, "Alias": null, "Direction": "DESC", "Fill": null } ], "Interpolate": null }, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "dept_rank", "QuoteType": 1, "NamePos": 418, "NameEnd": 427 } } ], "From": { "FromPos": 436, "Expr": { "Table": { "TablePos": 441, "TableEnd": 448, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "monthly", "QuoteType": 1, "NamePos": 441, "NameEnd": 448 } }, "HasFinal": false }, "StatementEnd": 448, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "month", "QuoteType": 1, "NamePos": 462, "NameEnd": 467 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 476, "NameEnd": 486 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "avg_salary", "QuoteType": 1, "NamePos": 495, "NameEnd": 505 }, "Modifiers": [], "Alias": null }, { "Expr": { "Function": { "Name": { "Name": "lag", "QuoteType": 1, "NamePos": 514, "NameEnd": 517 }, "Params": { "LeftParenPos": 517, "RightParenPos": 534, "Items": { "ListPos": 518, "ListEnd": 534, "HasDistinct": false, "Items": [ { "Expr": { "Name": "avg_salary", "QuoteType": 1, "NamePos": 518, "NameEnd": 528 }, "Alias": null }, { "Expr": { "NumPos": 530, "NumEnd": 531, "Literal": "1", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 533, "NumEnd": 534, "Literal": "0", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 536, "OverExpr": { "LeftParenPos": 541, "RightParenPos": 667, "WindowName": null, "PartitionBy": { "PartitionPos": 541, "Expr": { "ListPos": 567, "ListEnd": 577, "HasDistinct": false, "Items": [ { "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 567, "NameEnd": 577 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 589, "ListEnd": 603, "Items": [ { "OrderPos": 589, "Expr": { "Name": "month", "QuoteType": 1, "NamePos": 598, "NameEnd": 603 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 615, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 628, "NumEnd": 629, "Literal": "1", "Base": 10 }, "EndPos": 639, "Direction": "PRECEDING" }, "AndPos": 640, "And": { "CurrentPos": 644, "RowEnd": 668 } } } } }, "Modifiers": [], "Alias": { "Name": "prev_month_avg", "QuoteType": 1, "NamePos": 672, "NameEnd": 686 } } ], "From": { "FromPos": 687, "Expr": { "Table": { "TablePos": 692, "TableEnd": 698, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "ranked", "QuoteType": 1, "NamePos": 692, "NameEnd": 698 } }, "HasFinal": false }, "StatementEnd": 698, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 699, "Expr": { "LeftExpr": { "Name": "dept_rank", "QuoteType": 1, "NamePos": 705, "NameEnd": 714 }, "Operation": "\u003c=", "RightExpr": { "NumPos": 718, "NumEnd": 719, "Literal": "5", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 720, "ListEnd": 746, "Items": [ { "OrderPos": 720, "Expr": { "Name": "month", "QuoteType": 1, "NamePos": 729, "NameEnd": 734 }, "Alias": null, "Direction": "", "Fill": null }, { "OrderPos": 720, "Expr": { "Name": "department", "QuoteType": 1, "NamePos": 736, "NameEnd": 746 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_window_keyword_name_in_parens.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 98, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 7, "NameEnd": 10 }, "Params": { "LeftParenPos": 10, "RightParenPos": 12, "Items": { "ListPos": 11, "ListEnd": 12, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 11, "NameEnd": 12 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 14, "OverExpr": { "LeftParenPos": 19, "RightParenPos": 25, "WindowName": { "Name": "order", "QuoteType": 1, "NamePos": 20, "NameEnd": 25 }, "PartitionBy": null, "OrderBy": null, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "sum_over_order", "QuoteType": 1, "NamePos": 30, "NameEnd": 44 } } ], "From": { "FromPos": 45, "Expr": { "Table": { "TablePos": 50, "TableEnd": 51, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 50, "NameEnd": 51 } }, "HasFinal": false }, "StatementEnd": 51, "SampleRatio": null, "HasFinal": false } }, "Window": { "WindowPos": 52, "EndPos": 98, "Windows": [ { "Name": { "Name": "order", "QuoteType": 1, "NamePos": 59, "NameEnd": 64 }, "AsPos": 65, "Expr": { "LeftParenPos": 68, "RightParenPos": 98, "WindowName": null, "PartitionBy": { "PartitionPos": 68, "Expr": { "ListPos": 82, "ListEnd": 86, "HasDistinct": false, "Items": [ { "Expr": { "Name": "team", "QuoteType": 1, "NamePos": 82, "NameEnd": 86 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 87, "ListEnd": 98, "Items": [ { "OrderPos": 87, "Expr": { "Name": "ts", "QuoteType": 1, "NamePos": 96, "NameEnd": 98 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } } ] }, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_window_named_in_parens.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 82, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 7, "NameEnd": 10 }, "Params": { "LeftParenPos": 10, "RightParenPos": 12, "Items": { "ListPos": 11, "ListEnd": 12, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 11, "NameEnd": 12 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 14, "OverExpr": { "LeftParenPos": 19, "RightParenPos": 21, "WindowName": { "Name": "w", "QuoteType": 1, "NamePos": 20, "NameEnd": 21 }, "PartitionBy": null, "OrderBy": null, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "sum_over_w", "QuoteType": 1, "NamePos": 26, "NameEnd": 36 } } ], "From": { "FromPos": 37, "Expr": { "Table": { "TablePos": 42, "TableEnd": 43, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 42, "NameEnd": 43 } }, "HasFinal": false }, "StatementEnd": 43, "SampleRatio": null, "HasFinal": false } }, "Window": { "WindowPos": 44, "EndPos": 82, "Windows": [ { "Name": { "Name": "w", "QuoteType": 1, "NamePos": 51, "NameEnd": 52 }, "AsPos": 53, "Expr": { "LeftParenPos": 56, "RightParenPos": 82, "WindowName": null, "PartitionBy": { "PartitionPos": 56, "Expr": { "ListPos": 70, "ListEnd": 71, "HasDistinct": false, "Items": [ { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 70, "NameEnd": 71 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 72, "ListEnd": 82, "Items": [ { "OrderPos": 72, "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 81, "NameEnd": 82 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": null } } ] }, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_window_named_reference_extensions.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 303, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 7, "NameEnd": 10 }, "Params": { "LeftParenPos": 10, "RightParenPos": 12, "Items": { "ListPos": 11, "ListEnd": 12, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 11, "NameEnd": 12 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 14, "OverExpr": { "LeftParenPos": 19, "RightParenPos": 75, "WindowName": { "Name": "w1", "QuoteType": 1, "NamePos": 20, "NameEnd": 22 }, "PartitionBy": null, "OrderBy": { "OrderPos": 23, "ListEnd": 34, "Items": [ { "OrderPos": 23, "Expr": { "Name": "ts", "QuoteType": 1, "NamePos": 32, "NameEnd": 34 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 35, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "Number": { "NumPos": 48, "NumEnd": 49, "Literal": "1", "Base": 10 }, "EndPos": 59, "Direction": "PRECEDING" }, "AndPos": 60, "And": { "CurrentPos": 64, "RowEnd": 76 } } } } }, "Modifiers": [], "Alias": { "Name": "rolling_sum", "QuoteType": 1, "NamePos": 80, "NameEnd": 91 } }, { "Expr": { "Function": { "Name": { "Name": "avg", "QuoteType": 1, "NamePos": 100, "NameEnd": 103 }, "Params": { "LeftParenPos": 103, "RightParenPos": 105, "Items": { "ListPos": 104, "ListEnd": 105, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 104, "NameEnd": 105 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 107, "OverExpr": { "LeftParenPos": 112, "RightParenPos": 115, "WindowName": { "Name": "w2", "QuoteType": 1, "NamePos": 113, "NameEnd": 115 }, "PartitionBy": null, "OrderBy": null, "Frame": null } }, "Modifiers": [], "Alias": { "Name": "avg_over_w2", "QuoteType": 1, "NamePos": 173, "NameEnd": 184 } } ], "From": { "FromPos": 185, "Expr": { "Table": { "TablePos": 190, "TableEnd": 191, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 190, "NameEnd": 191 } }, "HasFinal": false }, "StatementEnd": 191, "SampleRatio": null, "HasFinal": false } }, "Window": { "WindowPos": 192, "EndPos": 303, "Windows": [ { "Name": { "Name": "w1", "QuoteType": 1, "NamePos": 199, "NameEnd": 201 }, "AsPos": 202, "Expr": { "LeftParenPos": 205, "RightParenPos": 223, "WindowName": null, "PartitionBy": { "PartitionPos": 205, "Expr": { "ListPos": 219, "ListEnd": 223, "HasDistinct": false, "Items": [ { "Expr": { "Name": "team", "QuoteType": 1, "NamePos": 219, "NameEnd": 223 }, "Alias": null } ] } }, "OrderBy": null, "Frame": null } }, { "Name": { "Name": "w2", "QuoteType": 1, "NamePos": 233, "NameEnd": 235 }, "AsPos": 236, "Expr": { "LeftParenPos": 239, "RightParenPos": 303, "WindowName": { "Name": "w1", "QuoteType": 1, "NamePos": 240, "NameEnd": 242 }, "PartitionBy": null, "OrderBy": { "OrderPos": 243, "ListEnd": 254, "Items": [ { "OrderPos": 243, "Expr": { "Name": "ts", "QuoteType": 1, "NamePos": 252, "NameEnd": 254 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 255, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 268, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 288, "And": { "CurrentPos": 292, "RowEnd": 304 } } } } } ] }, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_window_params.sql.golden.json ================================================ [ { "SelectPos": 100, "StatementEnd": 663, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 107, "NameEnd": 110 }, "Params": { "LeftParenPos": 110, "RightParenPos": 112, "Items": { "ListPos": 111, "ListEnd": 112, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 111, "NameEnd": 112 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 114, "OverExpr": { "LeftParenPos": 119, "RightParenPos": 184, "WindowName": null, "PartitionBy": null, "OrderBy": { "OrderPos": 120, "ListEnd": 130, "Items": [ { "OrderPos": 120, "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 129, "NameEnd": 130 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 131, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "Param": { "LBracePos": 144, "RBracePos": 157, "Name": { "Name": "start", "QuoteType": 1, "NamePos": 145, "NameEnd": 150 }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 151, "NameEnd": 157 } } }, "EndPos": 168, "Direction": "PRECEDING" }, "AndPos": 169, "And": { "CurrentPos": 173, "RowEnd": 185 } } } } }, "Modifiers": [], "Alias": { "Name": "total1", "QuoteType": 1, "NamePos": 215, "NameEnd": 221 } }, { "Expr": { "Function": { "Name": { "Name": "avg", "QuoteType": 1, "NamePos": 230, "NameEnd": 233 }, "Params": { "LeftParenPos": 233, "RightParenPos": 235, "Items": { "ListPos": 234, "ListEnd": 235, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 234, "NameEnd": 235 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 237, "OverExpr": { "LeftParenPos": 242, "RightParenPos": 305, "WindowName": null, "PartitionBy": null, "OrderBy": { "OrderPos": 243, "ListEnd": 253, "Items": [ { "OrderPos": 243, "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 252, "NameEnd": 253 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 254, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "CurrentPos": 267, "RowEnd": 282 }, "AndPos": 279, "And": { "Param": { "LBracePos": 283, "RBracePos": 294, "Name": { "Name": "end", "QuoteType": 1, "NamePos": 284, "NameEnd": 287 }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 288, "NameEnd": 294 } } }, "EndPos": 305, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "avg1", "QuoteType": 1, "NamePos": 338, "NameEnd": 342 } }, { "Expr": { "Function": { "Name": { "Name": "count", "QuoteType": 1, "NamePos": 351, "NameEnd": 356 }, "Params": { "LeftParenPos": 356, "RightParenPos": 358, "Items": { "ListPos": 357, "ListEnd": 357, "HasDistinct": false, "Items": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 357, "NameEnd": 357 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 360, "OverExpr": { "LeftParenPos": 365, "RightParenPos": 454, "WindowName": null, "PartitionBy": null, "OrderBy": { "OrderPos": 366, "ListEnd": 376, "Items": [ { "OrderPos": 366, "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 375, "NameEnd": 376 }, "Alias": null, "Direction": "", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 377, "Type": "RANGE", "Extend": { "Expr": null, "Between": { "Param": { "LBracePos": 391, "RBracePos": 410, "Name": { "Name": "range_start", "QuoteType": 1, "NamePos": 392, "NameEnd": 403 }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 404, "NameEnd": 410 } } }, "EndPos": 421, "Direction": "PRECEDING" }, "AndPos": 422, "And": { "Param": { "LBracePos": 426, "RBracePos": 443, "Name": { "Name": "range_end", "QuoteType": 1, "NamePos": 427, "NameEnd": 436 }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 437, "NameEnd": 443 } } }, "EndPos": 454, "Direction": "FOLLOWING" } } } } }, "Modifiers": [], "Alias": { "Name": "cnt1", "QuoteType": 1, "NamePos": 459, "NameEnd": 463 } }, { "Expr": { "Function": { "Name": { "Name": "sum", "QuoteType": 1, "NamePos": 472, "NameEnd": 475 }, "Params": { "LeftParenPos": 475, "RightParenPos": 477, "Items": { "ListPos": 476, "ListEnd": 477, "HasDistinct": false, "Items": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 476, "NameEnd": 477 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 479, "OverExpr": { "LeftParenPos": 484, "RightParenPos": 521, "WindowName": null, "PartitionBy": null, "OrderBy": null, "Frame": { "FramePos": 485, "Type": "ROWS", "Extend": { "Param": { "LBracePos": 490, "RBracePos": 510, "Name": { "Name": "window_size", "QuoteType": 1, "NamePos": 491, "NameEnd": 502 }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 504, "NameEnd": 510 } } }, "EndPos": 521, "Direction": "PRECEDING" } } } }, "Modifiers": [], "Alias": { "Name": "rows_shorthand", "QuoteType": 1, "NamePos": 580, "NameEnd": 594 } } ], "From": { "FromPos": 595, "Expr": { "Table": { "TablePos": 600, "TableEnd": 601, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t", "QuoteType": 1, "NamePos": 600, "NameEnd": 601 } }, "HasFinal": false }, "StatementEnd": 601, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 602, "Expr": { "LeftExpr": { "LeftExpr": { "Name": "category", "QuoteType": 1, "NamePos": 608, "NameEnd": 616 }, "Operation": "=", "RightExpr": { "LBracePos": 619, "RBracePos": 636, "Name": { "Name": "category", "QuoteType": 1, "NamePos": 620, "NameEnd": 628 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 630, "NameEnd": 636 } } }, "HasGlobal": false, "HasNot": false }, "Operation": "AND", "RightExpr": { "LeftExpr": { "Name": "type", "QuoteType": 1, "NamePos": 644, "NameEnd": 648 }, "Operation": "=", "RightExpr": { "LBracePos": 651, "RBracePos": 663, "Name": { "Name": "type", "QuoteType": 1, "NamePos": 652, "NameEnd": 656 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 657, "NameEnd": 663 } } }, "HasGlobal": false, "HasNot": false }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_distinct.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 51, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "count", "QuoteType": 1, "NamePos": 7, "NameEnd": 12 }, "Params": { "LeftParenPos": 12, "RightParenPos": 32, "Items": { "ListPos": 13, "ListEnd": 31, "HasDistinct": true, "Items": [ { "Expr": { "LeftParenPos": 21, "RightParenPos": 31, "Items": { "ListPos": 22, "ListEnd": 31, "HasDistinct": false, "Items": [ { "Expr": { "Name": "RECORD_ID", "QuoteType": 1, "NamePos": 22, "NameEnd": 31 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 34, "Expr": { "Table": { "TablePos": 39, "TableEnd": 51, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "RECORD_TABLE", "QuoteType": 1, "NamePos": 39, "NameEnd": 51 } }, "HasFinal": false }, "StatementEnd": 51, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_distinct_keyword.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 38, "With": null, "Top": null, "HasDistinct": true, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "record_id", "QuoteType": 1, "NamePos": 16, "NameEnd": 25 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 26, "Expr": { "Table": { "TablePos": 31, "TableEnd": 38, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "records", "QuoteType": 1, "NamePos": 31, "NameEnd": 38 } }, "HasFinal": false }, "StatementEnd": 38, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_distinct_on_dotted_columns.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 73, "With": null, "Top": null, "HasDistinct": true, "DistinctOn": { "Idents": [ { "Ident": { "Name": "t", "QuoteType": 1, "NamePos": 20, "NameEnd": 21 }, "DotIdent": { "Name": "id", "QuoteType": 1, "NamePos": 22, "NameEnd": 24 } }, { "Ident": { "Name": "t", "QuoteType": 1, "NamePos": 26, "NameEnd": 27 }, "DotIdent": { "Name": "name", "QuoteType": 1, "NamePos": 28, "NameEnd": 32 } } ], "DistinctOnPos": 16, "DistinctOnEnd": 34 }, "SelectItems": [ { "Expr": { "Fields": [ { "Name": "t", "QuoteType": 1, "NamePos": 34, "NameEnd": 35 }, { "Name": "id", "QuoteType": 1, "NamePos": 36, "NameEnd": 38 } ] }, "Modifiers": [], "Alias": null }, { "Expr": { "Fields": [ { "Name": "t", "QuoteType": 1, "NamePos": 40, "NameEnd": 41 }, { "Name": "name", "QuoteType": 1, "NamePos": 42, "NameEnd": 46 } ] }, "Modifiers": [], "Alias": null }, { "Expr": { "Fields": [ { "Name": "t", "QuoteType": 1, "NamePos": 48, "NameEnd": 49 }, { "Name": "value", "QuoteType": 1, "NamePos": 50, "NameEnd": 55 } ] }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 56, "Expr": { "Table": { "TablePos": 61, "TableEnd": 73, "Alias": null, "Expr": { "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 61, "NameEnd": 71 } }, "AliasPos": 72, "Alias": { "Name": "t", "QuoteType": 1, "NamePos": 72, "NameEnd": 73 } }, "HasFinal": false }, "StatementEnd": 73, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_distinct_on_keyword.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 55, "With": null, "Top": null, "HasDistinct": true, "DistinctOn": { "Idents": [ { "Ident": { "Name": "album", "QuoteType": 1, "NamePos": 19, "NameEnd": 24 }, "DotIdent": null }, { "Ident": { "Name": "artist", "QuoteType": 1, "NamePos": 25, "NameEnd": 31 }, "DotIdent": null } ], "DistinctOnPos": 16, "DistinctOnEnd": 33 }, "SelectItems": [ { "Expr": { "Name": "record_id", "QuoteType": 1, "NamePos": 33, "NameEnd": 42 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 43, "Expr": { "Table": { "TablePos": 48, "TableEnd": 55, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "records", "QuoteType": 1, "NamePos": 48, "NameEnd": 55 } }, "HasFinal": false }, "StatementEnd": 55, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_group_by.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 171, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "datacenter", "QuoteType": 1, "NamePos": 11, "NameEnd": 21 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "distro", "QuoteType": 1, "NamePos": 27, "NameEnd": 33 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "SUM", "QuoteType": 1, "NamePos": 39, "NameEnd": 42 }, "Params": { "LeftParenPos": 43, "RightParenPos": 52, "Items": { "ListPos": 44, "ListEnd": 52, "HasDistinct": false, "Items": [ { "Expr": { "Name": "quantity", "QuoteType": 1, "NamePos": 44, "NameEnd": 52 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "qty", "QuoteType": 1, "NamePos": 57, "NameEnd": 60 } } ], "From": { "FromPos": 61, "Expr": { "Table": { "TablePos": 70, "TableEnd": 77, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "servers", "QuoteType": 1, "NamePos": 70, "NameEnd": 77 } }, "HasFinal": false }, "StatementEnd": 77, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": { "GroupByPos": 78, "GroupByEnd": 171, "AggregateType": "GROUPING SETS", "Expr": { "LeftParenPos": 104, "RightParenPos": 170, "Items": { "ListPos": 110, "ListEnd": 168, "HasDistinct": false, "Items": [ { "Expr": { "LeftParenPos": 110, "RightParenPos": 128, "Items": { "ListPos": 111, "ListEnd": 128, "HasDistinct": false, "Items": [ { "Expr": { "Name": "datacenter", "QuoteType": 1, "NamePos": 111, "NameEnd": 121 }, "Alias": null }, { "Expr": { "Name": "distro", "QuoteType": 1, "NamePos": 122, "NameEnd": 128 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null }, { "Expr": { "LeftParenPos": 135, "RightParenPos": 146, "Items": { "ListPos": 136, "ListEnd": 146, "HasDistinct": false, "Items": [ { "Expr": { "Name": "datacenter", "QuoteType": 1, "NamePos": 136, "NameEnd": 146 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null }, { "Expr": { "LeftParenPos": 153, "RightParenPos": 160, "Items": { "ListPos": 154, "ListEnd": 160, "HasDistinct": false, "Items": [ { "Expr": { "Name": "distro", "QuoteType": 1, "NamePos": 154, "NameEnd": 160 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null }, { "Expr": { "LeftParenPos": 167, "RightParenPos": 168, "Items": { "ListPos": 168, "ListEnd": 168, "HasDistinct": false, "Items": [] }, "ColumnArgList": null }, "Alias": null } ] }, "ColumnArgList": null }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 174, "StatementEnd": 264, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "datacenter", "QuoteType": 1, "NamePos": 185, "NameEnd": 195 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "distro", "QuoteType": 1, "NamePos": 201, "NameEnd": 207 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": { "Name": "SUM", "QuoteType": 1, "NamePos": 213, "NameEnd": 216 }, "Params": { "LeftParenPos": 217, "RightParenPos": 226, "Items": { "ListPos": 218, "ListEnd": 226, "HasDistinct": false, "Items": [ { "Expr": { "Name": "quantity", "QuoteType": 1, "NamePos": 218, "NameEnd": 226 }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "qty", "QuoteType": 1, "NamePos": 231, "NameEnd": 234 } } ], "From": { "FromPos": 235, "Expr": { "Table": { "TablePos": 244, "TableEnd": 251, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "servers", "QuoteType": 1, "NamePos": 244, "NameEnd": 251 } }, "HasFinal": false }, "StatementEnd": 251, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": { "GroupByPos": 252, "GroupByEnd": 264, "AggregateType": "ALL", "Expr": null, "WithCube": false, "WithRollup": false, "WithTotals": false }, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_join_only.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 36, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 7, "NameEnd": 7 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 9, "Expr": { "JoinPos": 15, "Left": { "Table": { "TablePos": 15, "TableEnd": 17, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 2, "NamePos": 15, "NameEnd": 17 } }, "HasFinal": false }, "StatementEnd": 17, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 19, "Left": { "Table": { "TablePos": 25, "TableEnd": 27, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t2", "QuoteType": 2, "NamePos": 25, "NameEnd": 27 } }, "HasFinal": false }, "StatementEnd": 27, "SampleRatio": null, "HasFinal": false }, "Right": null, "Modifiers": [ "JOIN" ], "Constraints": { "OnPos": 29, "On": { "ListPos": 32, "ListEnd": 36, "HasDistinct": false, "Items": [ { "Expr": { "Name": "true", "QuoteType": 1, "NamePos": 32, "NameEnd": 36 }, "Alias": null } ] } } }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_keyword_in_group_by.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 181, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toStartOfInterval", "QuoteType": 1, "NamePos": 11, "NameEnd": 28 }, "Params": { "LeftParenPos": 28, "RightParenPos": 59, "Items": { "ListPos": 29, "ListEnd": 58, "HasDistinct": false, "Items": [ { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 29, "NameEnd": 38 }, "Alias": null }, { "Expr": { "Name": { "Name": "toIntervalMinute", "QuoteType": 1, "NamePos": 40, "NameEnd": 56 }, "Params": { "LeftParenPos": 56, "RightParenPos": 58, "Items": { "ListPos": 57, "ListEnd": 58, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 57, "NumEnd": 58, "Literal": "1", "Base": 10 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "interval", "QuoteType": 1, "NamePos": 64, "NameEnd": 72 } }, { "Expr": { "Name": "column_name", "QuoteType": 1, "NamePos": 78, "NameEnd": 89 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 90, "Expr": { "Table": { "TablePos": 95, "TableEnd": 100, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "table", "QuoteType": 1, "NamePos": 95, "NameEnd": 100 } }, "HasFinal": false }, "StatementEnd": 100, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 101, "Expr": { "Name": "true", "QuoteType": 1, "NamePos": 107, "NameEnd": 111 } }, "GroupBy": { "GroupByPos": 112, "GroupByEnd": 145, "AggregateType": "", "Expr": { "ListPos": 121, "ListEnd": 143, "HasDistinct": false, "Items": [ { "Expr": { "LeftParenPos": 121, "RightParenPos": 143, "Items": { "ListPos": 122, "ListEnd": 143, "HasDistinct": false, "Items": [ { "Expr": { "Name": "interval", "QuoteType": 1, "NamePos": 122, "NameEnd": 130 }, "Alias": null }, { "Expr": { "Name": "column_name", "QuoteType": 1, "NamePos": 132, "NameEnd": 143 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null } ] }, "WithCube": false, "WithRollup": false, "WithTotals": false }, "WithTotal": false, "Having": null, "OrderBy": { "OrderPos": 145, "ListEnd": 181, "Items": [ { "OrderPos": 145, "Expr": { "LeftParenPos": 154, "RightParenPos": 181, "Items": { "ListPos": 155, "ListEnd": 181, "HasDistinct": false, "Items": [ { "Expr": { "Name": "interval", "QuoteType": 1, "NamePos": 155, "NameEnd": 163 }, "Alias": { "Name": "i", "QuoteType": 1, "NamePos": 167, "NameEnd": 168 } }, { "Expr": { "Name": "column_name", "QuoteType": 1, "NamePos": 170, "NameEnd": 181 }, "Alias": null } ] }, "ColumnArgList": null }, "Alias": null, "Direction": "ASC", "Fill": null } ], "Interpolate": null }, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_keyword_placeholder.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 20, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LBracePos": 7, "RBracePos": 20, "Name": { "Name": "name", "QuoteType": 1, "NamePos": 8, "NameEnd": 12 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 14, "NameEnd": 20 } } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 23, "StatementEnd": 53, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "toString", "QuoteType": 1, "NamePos": 30, "NameEnd": 38 }, "Params": { "LeftParenPos": 38, "RightParenPos": 53, "Items": { "ListPos": 39, "ListEnd": 52, "HasDistinct": false, "Items": [ { "Expr": { "LBracePos": 39, "RBracePos": 52, "Name": { "Name": "name", "QuoteType": 1, "NamePos": 40, "NameEnd": 44 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 46, "NameEnd": 52 } } }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_left_join.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 151, "With": { "WithPos": 0, "EndPos": 68, "CTEs": [ { "CTEPos": 9, "Expr": { "Name": "t1", "QuoteType": 1, "NamePos": 9, "NameEnd": 11 }, "Alias": { "SelectPos": 37, "StatementEnd": 54, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 44, "NumEnd": 45, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 49, "NameEnd": 54 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, { "CTEPos": 66, "Expr": { "Name": "t2", "QuoteType": 1, "NamePos": 66, "NameEnd": 68 }, "Alias": { "SelectPos": 81, "StatementEnd": 98, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 88, "NumEnd": 89, "Literal": "2", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 93, "NameEnd": 98 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 112, "NameEnd": 112 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 114, "Expr": { "JoinPos": 119, "Left": { "Table": { "TablePos": 119, "TableEnd": 121, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 119, "NameEnd": 121 } }, "HasFinal": false }, "StatementEnd": 121, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 131, "Left": { "Table": { "TablePos": 141, "TableEnd": 143, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 141, "NameEnd": 143 } }, "HasFinal": false }, "StatementEnd": 143, "SampleRatio": null, "HasFinal": false }, "Right": null, "Modifiers": [ "LEFT", "JOIN" ], "Constraints": { "OnPos": 144, "On": { "ListPos": 147, "ListEnd": 151, "HasDistinct": false, "Items": [ { "Expr": { "Name": "true", "QuoteType": 1, "NamePos": 147, "NameEnd": 151 }, "Alias": null } ] } } }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_literal_table_name.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 60, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "table_name", "QuoteType": 1, "NamePos": 7, "NameEnd": 17 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 18, "Expr": { "Table": { "TablePos": 24, "TableEnd": 51, "Alias": null, "Expr": { "Database": { "Name": "information_schema", "QuoteType": 2, "NamePos": 24, "NameEnd": 42 }, "Table": { "Name": "tables", "QuoteType": 2, "NamePos": 45, "NameEnd": 51 } }, "HasFinal": false }, "StatementEnd": 51, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": { "LimitPos": 53, "Limit": { "NumPos": 59, "NumEnd": 60, "Literal": "1", "Base": 10 }, "Offset": null }, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_array_and_inner_join.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 313, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": { "Name": "JSONExtractString", "QuoteType": 1, "NamePos": 11, "NameEnd": 28 }, "Params": { "LeftParenPos": 28, "RightParenPos": 46, "Items": { "ListPos": 29, "ListEnd": 45, "HasDistinct": false, "Items": [ { "Expr": { "Fields": [ { "Name": "t3", "QuoteType": 1, "NamePos": 29, "NameEnd": 31 }, { "Name": "props", "QuoteType": 1, "NamePos": 32, "NameEnd": 37 } ] }, "Alias": null }, { "Expr": { "LiteralPos": 40, "LiteralEnd": 45, "Literal": "value" }, "Alias": null } ] }, "ColumnArgList": null } }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 51, "NameEnd": 56 } } ], "From": { "FromPos": 57, "Expr": { "JoinPos": 62, "Left": { "Table": { "TablePos": 62, "TableEnd": 64, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 62, "NameEnd": 64 } }, "HasFinal": false }, "StatementEnd": 64, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 69, "Left": { "ListPos": 80, "ListEnd": 123, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "JSONExtractArrayRaw", "QuoteType": 1, "NamePos": 80, "NameEnd": 99 }, "Params": { "LeftParenPos": 99, "RightParenPos": 116, "Items": { "ListPos": 100, "ListEnd": 115, "HasDistinct": false, "Items": [ { "Expr": { "Fields": [ { "Name": "t1", "QuoteType": 1, "NamePos": 100, "NameEnd": 102 }, { "Name": "props", "QuoteType": 1, "NamePos": 103, "NameEnd": 108 } ] }, "Alias": null }, { "Expr": { "LiteralPos": 111, "LiteralEnd": 115, "Literal": "arr1" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "a1", "QuoteType": 1, "NamePos": 121, "NameEnd": 123 } } ] }, "Right": { "JoinPos": 128, "Left": { "Table": { "TablePos": 139, "TableEnd": 141, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 139, "NameEnd": 141 } }, "HasFinal": false }, "StatementEnd": 141, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 185, "Left": { "ListPos": 196, "ListEnd": 239, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "JSONExtractArrayRaw", "QuoteType": 1, "NamePos": 196, "NameEnd": 215 }, "Params": { "LeftParenPos": 215, "RightParenPos": 232, "Items": { "ListPos": 216, "ListEnd": 231, "HasDistinct": false, "Items": [ { "Expr": { "Fields": [ { "Name": "t2", "QuoteType": 1, "NamePos": 216, "NameEnd": 218 }, { "Name": "props", "QuoteType": 1, "NamePos": 219, "NameEnd": 224 } ] }, "Alias": null }, { "Expr": { "LiteralPos": 227, "LiteralEnd": 231, "Literal": "arr2" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "a2", "QuoteType": 1, "NamePos": 237, "NameEnd": 239 } } ] }, "Right": { "JoinPos": 244, "Left": { "Table": { "TablePos": 255, "TableEnd": 257, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t3", "QuoteType": 1, "NamePos": 255, "NameEnd": 257 } }, "HasFinal": false }, "StatementEnd": 257, "SampleRatio": null, "HasFinal": false }, "Right": null, "Modifiers": [ "INNER", "JOIN" ], "Constraints": { "OnPos": 258, "On": { "ListPos": 261, "ListEnd": 295, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Fields": [ { "Name": "t3", "QuoteType": 1, "NamePos": 261, "NameEnd": 263 }, { "Name": "id", "QuoteType": 1, "NamePos": 264, "NameEnd": 266 } ] }, "Operation": "=", "RightExpr": { "Name": { "Name": "JSONExtractString", "QuoteType": 1, "NamePos": 269, "NameEnd": 286 }, "Params": { "LeftParenPos": 286, "RightParenPos": 295, "Items": { "ListPos": 287, "ListEnd": 294, "HasDistinct": false, "Items": [ { "Expr": { "Name": "a2", "QuoteType": 1, "NamePos": 287, "NameEnd": 289 }, "Alias": null }, { "Expr": { "LiteralPos": 292, "LiteralEnd": 294, "Literal": "id" }, "Alias": null } ] }, "ColumnArgList": null } }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] } } }, "Modifiers": [ "ARRAY", "JOIN" ], "Constraints": null }, "Modifiers": [ "INNER", "JOIN" ], "Constraints": { "OnPos": 142, "On": { "ListPos": 145, "ListEnd": 179, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Fields": [ { "Name": "t2", "QuoteType": 1, "NamePos": 145, "NameEnd": 147 }, { "Name": "id", "QuoteType": 1, "NamePos": 148, "NameEnd": 150 } ] }, "Operation": "=", "RightExpr": { "Name": { "Name": "JSONExtractString", "QuoteType": 1, "NamePos": 153, "NameEnd": 170 }, "Params": { "LeftParenPos": 170, "RightParenPos": 179, "Items": { "ListPos": 171, "ListEnd": 178, "HasDistinct": false, "Items": [ { "Expr": { "Name": "a1", "QuoteType": 1, "NamePos": 171, "NameEnd": 173 }, "Alias": null }, { "Expr": { "LiteralPos": 176, "LiteralEnd": 178, "Literal": "id" }, "Alias": null } ] }, "ColumnArgList": null } }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] } } }, "Modifiers": [ "ARRAY", "JOIN" ], "Constraints": null }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 297, "Expr": { "LeftExpr": { "Name": "value", "QuoteType": 1, "NamePos": 303, "NameEnd": 308 }, "Operation": "!=", "RightExpr": { "LiteralPos": 313, "LiteralEnd": 313, "Literal": "" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_array_join.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 160, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "v", "QuoteType": 1, "NamePos": 11, "NameEnd": 12 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "j", "QuoteType": 1, "NamePos": 18, "NameEnd": 19 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 20, "Expr": { "JoinPos": 25, "Left": { "Table": { "TablePos": 25, "TableEnd": 27, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 25, "NameEnd": 27 } }, "HasFinal": false }, "StatementEnd": 27, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 32, "Left": { "ListPos": 43, "ListEnd": 70, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "JSONExtractArrayRaw", "QuoteType": 1, "NamePos": 43, "NameEnd": 62 }, "Params": { "LeftParenPos": 62, "RightParenPos": 64, "Items": { "ListPos": 63, "ListEnd": 64, "HasDistinct": false, "Items": [ { "Expr": { "Name": "a", "QuoteType": 1, "NamePos": 63, "NameEnd": 64 }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "j", "QuoteType": 1, "NamePos": 69, "NameEnd": 70 } } ] }, "Right": { "JoinPos": 75, "Left": { "ListPos": 86, "ListEnd": 160, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "array", "QuoteType": 1, "NamePos": 86, "NameEnd": 91 }, "Params": { "LeftParenPos": 91, "RightParenPos": 154, "Items": { "ListPos": 97, "ListEnd": 152, "HasDistinct": false, "Items": [ { "Expr": { "Name": { "Name": "JSONExtractString", "QuoteType": 1, "NamePos": 97, "NameEnd": 114 }, "Params": { "LeftParenPos": 114, "RightParenPos": 121, "Items": { "ListPos": 115, "ListEnd": 120, "HasDistinct": false, "Items": [ { "Expr": { "Name": "j", "QuoteType": 1, "NamePos": 115, "NameEnd": 116 }, "Alias": null }, { "Expr": { "LiteralPos": 119, "LiteralEnd": 120, "Literal": "x" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null }, { "Expr": { "Name": { "Name": "JSONExtractString", "QuoteType": 1, "NamePos": 128, "NameEnd": 145 }, "Params": { "LeftParenPos": 145, "RightParenPos": 152, "Items": { "ListPos": 146, "ListEnd": 151, "HasDistinct": false, "Items": [ { "Expr": { "Name": "j", "QuoteType": 1, "NamePos": 146, "NameEnd": 147 }, "Alias": null }, { "Expr": { "LiteralPos": 150, "LiteralEnd": 151, "Literal": "y" }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": null } ] }, "ColumnArgList": null } }, "Alias": { "Name": "v", "QuoteType": 1, "NamePos": 159, "NameEnd": 160 } } ] }, "Right": null, "Modifiers": [ "ARRAY", "JOIN" ], "Constraints": null }, "Modifiers": [ "ARRAY", "JOIN" ], "Constraints": null }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_except.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 32, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 7, "NameEnd": 13 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 14, "Expr": { "Table": { "TablePos": 19, "TableEnd": 32, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 19, "NameEnd": 26 }, "Args": { "LeftParenPos": 26, "RightParenPos": 32, "Args": [ { "NumPos": 27, "NumEnd": 28, "Literal": "1", "Base": 10 }, { "NumPos": 30, "NumEnd": 32, "Literal": "10", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 32, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": { "SelectPos": 41, "StatementEnd": 72, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 48, "NameEnd": 54 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 55, "Expr": { "Table": { "TablePos": 60, "TableEnd": 72, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 60, "NameEnd": 67 }, "Args": { "LeftParenPos": 67, "RightParenPos": 72, "Args": [ { "NumPos": 68, "NumEnd": 69, "Literal": "3", "Base": 10 }, { "NumPos": 71, "NumEnd": 72, "Literal": "6", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 72, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": { "SelectPos": 81, "StatementEnd": 112, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 88, "NameEnd": 94 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 95, "Expr": { "Table": { "TablePos": 100, "TableEnd": 112, "Alias": null, "Expr": { "Name": { "Name": "numbers", "QuoteType": 1, "NamePos": 100, "NameEnd": 107 }, "Args": { "LeftParenPos": 107, "RightParenPos": 112, "Args": [ { "NumPos": 108, "NumEnd": 109, "Literal": "8", "Base": 10 }, { "NumPos": 111, "NumEnd": 112, "Literal": "9", "Base": 10 } ] } }, "HasFinal": false }, "StatementEnd": 112, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_join.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 297, "With": { "WithPos": 0, "EndPos": 91, "CTEs": [ { "CTEPos": 5, "Expr": { "Name": "t1", "QuoteType": 1, "NamePos": 5, "NameEnd": 7 }, "Alias": { "SelectPos": 17, "StatementEnd": 41, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LiteralPos": 25, "LiteralEnd": 31, "Literal": "value1" }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 36, "NameEnd": 41 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, { "CTEPos": 49, "Expr": { "Name": "t2", "QuoteType": 1, "NamePos": 49, "NameEnd": 51 }, "Alias": { "SelectPos": 57, "StatementEnd": 81, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LiteralPos": 65, "LiteralEnd": 71, "Literal": "value2" }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 76, "NameEnd": 81 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, { "CTEPos": 89, "Expr": { "Name": "t3", "QuoteType": 1, "NamePos": 89, "NameEnd": 91 }, "Alias": { "SelectPos": 97, "StatementEnd": 121, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LiteralPos": 105, "LiteralEnd": 111, "Literal": "value3" }, "Modifiers": [], "Alias": { "Name": "value", "QuoteType": 1, "NamePos": 116, "NameEnd": 121 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Fields": [ { "Name": "t1", "QuoteType": 1, "NamePos": 139, "NameEnd": 141 }, { "Name": "value", "QuoteType": 1, "NamePos": 142, "NameEnd": 147 } ] }, "Modifiers": [], "Alias": { "Name": "value1", "QuoteType": 1, "NamePos": 151, "NameEnd": 157 } }, { "Expr": { "Fields": [ { "Name": "t2", "QuoteType": 1, "NamePos": 163, "NameEnd": 165 }, { "Name": "value", "QuoteType": 1, "NamePos": 166, "NameEnd": 171 } ] }, "Modifiers": [], "Alias": { "Name": "value2", "QuoteType": 1, "NamePos": 175, "NameEnd": 181 } }, { "Expr": { "Fields": [ { "Name": "t3", "QuoteType": 1, "NamePos": 187, "NameEnd": 189 }, { "Name": "value", "QuoteType": 1, "NamePos": 190, "NameEnd": 195 } ] }, "Modifiers": [], "Alias": { "Name": "value3", "QuoteType": 1, "NamePos": 199, "NameEnd": 205 } } ], "From": { "FromPos": 206, "Expr": { "JoinPos": 215, "Left": { "Table": { "TablePos": 215, "TableEnd": 217, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t1", "QuoteType": 1, "NamePos": 215, "NameEnd": 217 } }, "HasFinal": false }, "StatementEnd": 217, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 226, "Left": { "Table": { "TablePos": 231, "TableEnd": 233, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t2", "QuoteType": 1, "NamePos": 231, "NameEnd": 233 } }, "HasFinal": false }, "StatementEnd": 233, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 250, "Left": { "Table": { "TablePos": 255, "TableEnd": 257, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t3", "QuoteType": 1, "NamePos": 255, "NameEnd": 257 } }, "HasFinal": false }, "StatementEnd": 257, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 266, "Left": { "Table": { "TablePos": 271, "TableEnd": 273, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t4", "QuoteType": 1, "NamePos": 271, "NameEnd": 273 } }, "HasFinal": false }, "StatementEnd": 273, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 290, "Left": { "Table": { "TablePos": 295, "TableEnd": 297, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t5", "QuoteType": 1, "NamePos": 295, "NameEnd": 297 } }, "HasFinal": false }, "StatementEnd": 297, "SampleRatio": null, "HasFinal": false }, "Right": null, "Modifiers": [ "JOIN" ], "Constraints": null }, "Modifiers": [ "JOIN" ], "Constraints": { "OnPos": 274, "On": { "ListPos": 277, "ListEnd": 281, "HasDistinct": false, "Items": [ { "Expr": { "Name": "true", "QuoteType": 1, "NamePos": 277, "NameEnd": 281 }, "Alias": null } ] } } }, "Modifiers": [ "JOIN" ], "Constraints": null }, "Modifiers": [ "JOIN" ], "Constraints": { "OnPos": 234, "On": { "ListPos": 237, "ListEnd": 241, "HasDistinct": false, "Items": [ { "Expr": { "Name": "true", "QuoteType": 1, "NamePos": 237, "NameEnd": 241 }, "Alias": null } ] } } }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_line_comment.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 61, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 48, "NameEnd": 48 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 50, "Expr": { "Table": { "TablePos": 59, "TableEnd": 61, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 59, "NameEnd": 61 } }, "HasFinal": false }, "StatementEnd": 61, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_union.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 14, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 7, "NumEnd": 8, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "v1", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": { "SelectPos": 25, "StatementEnd": 39, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 32, "NumEnd": 33, "Literal": "2", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "v2", "QuoteType": 1, "NamePos": 37, "NameEnd": 39 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": { "SelectPos": 50, "StatementEnd": 64, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 57, "NumEnd": 58, "Literal": "3", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "v3", "QuoteType": 1, "NamePos": 62, "NameEnd": 64 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, "UnionDistinct": null, "Except": null }, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_multi_union_distinct.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 14, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 7, "NumEnd": 8, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "v1", "QuoteType": 1, "NamePos": 12, "NameEnd": 14 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": { "SelectPos": 30, "StatementEnd": 44, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 37, "NumEnd": 38, "Literal": "2", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "v2", "QuoteType": 1, "NamePos": 42, "NameEnd": 44 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": { "SelectPos": 60, "StatementEnd": 74, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 67, "NumEnd": 68, "Literal": "3", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "v3", "QuoteType": 1, "NamePos": 72, "NameEnd": 74 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, "Except": null }, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_number_field.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 53, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "foo", "QuoteType": 1, "NamePos": 7, "NameEnd": 10 }, "Modifiers": [], "Alias": null }, { "Expr": { "Object": { "Name": "bar", "QuoteType": 1, "NamePos": 12, "NameEnd": 15 }, "Operation": ".", "Index": { "NumPos": 16, "NumEnd": 17, "Literal": "1", "Base": 10 } }, "Modifiers": [], "Alias": null }, { "Expr": { "Object": { "Name": "foo", "QuoteType": 1, "NamePos": 19, "NameEnd": 22 }, "Operation": ".", "Index": { "NumPos": 23, "NumEnd": 24, "Literal": "2", "Base": 10 } }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 25, "Expr": { "JoinPos": 30, "Left": { "Table": { "TablePos": 30, "TableEnd": 33, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "foo", "QuoteType": 1, "NamePos": 30, "NameEnd": 33 } }, "HasFinal": false }, "StatementEnd": 33, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 34, "Left": { "ListPos": 45, "ListEnd": 53, "HasDistinct": false, "Items": [ { "Expr": { "Name": "m", "QuoteType": 1, "NamePos": 45, "NameEnd": 46 }, "Alias": { "Name": "bar", "QuoteType": 1, "NamePos": 50, "NameEnd": 53 } } ] }, "Right": null, "Modifiers": [ "ARRAY", "JOIN" ], "Constraints": null }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_placeholder.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 28, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 7, "NameEnd": 7 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 9, "Expr": { "Table": { "TablePos": 14, "TableEnd": 16, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 14, "NameEnd": 16 } }, "HasFinal": false }, "StatementEnd": 16, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 17, "Expr": { "LeftExpr": { "Name": "id", "QuoteType": 1, "NamePos": 23, "NameEnd": 25 }, "Operation": "=", "RightExpr": { "PlaceholderPos": 28, "PlaceHolderEnd": 28, "Type": "?" }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_query_parameter.sql.golden.json ================================================ [ { "SetPos": 0, "Settings": { "SettingsPos": 4, "ListEnd": 16, "Items": [ { "SettingsPos": 4, "Name": { "Name": "param_a", "QuoteType": 1, "NamePos": 4, "NameEnd": 11 }, "Expr": { "NumPos": 14, "NumEnd": 16, "Literal": "13", "Base": 10 } } ] } }, { "SetPos": 18, "Settings": { "SettingsPos": 22, "ListEnd": 36, "Items": [ { "SettingsPos": 22, "Name": { "Name": "param_b", "QuoteType": 1, "NamePos": 22, "NameEnd": 29 }, "Expr": { "LiteralPos": 33, "LiteralEnd": 36, "Literal": "str" } } ] } }, { "SetPos": 39, "Settings": { "SettingsPos": 43, "ListEnd": 73, "Items": [ { "SettingsPos": 43, "Name": { "Name": "param_c", "QuoteType": 1, "NamePos": 43, "NameEnd": 50 }, "Expr": { "LiteralPos": 54, "LiteralEnd": 73, "Literal": "2022-08-04 18:30:53" } } ] } }, { "SetPos": 76, "Settings": { "SettingsPos": 80, "ListEnd": 121, "Items": [ { "SettingsPos": 80, "Name": { "Name": "param_d", "QuoteType": 1, "NamePos": 80, "NameEnd": 87 }, "Expr": { "LBracePos": 90, "RBracePos": 121, "KeyValues": [ { "Key": { "LiteralPos": 92, "LiteralEnd": 94, "Literal": "10" }, "Value": { "LeftBracketPos": 97, "RightBracketPos": 104, "Items": { "ListPos": 98, "ListEnd": 104, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 98, "NumEnd": 100, "Literal": "11", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 102, "NumEnd": 104, "Literal": "12", "Base": 10 }, "Alias": null } ] } } }, { "Key": { "LiteralPos": 108, "LiteralEnd": 110, "Literal": "13" }, "Value": { "LeftBracketPos": 113, "RightBracketPos": 120, "Items": { "ListPos": 114, "ListEnd": 120, "HasDistinct": false, "Items": [ { "Expr": { "NumPos": 114, "NumEnd": 116, "Literal": "14", "Base": 10 }, "Alias": null }, { "Expr": { "NumPos": 118, "NumEnd": 120, "Literal": "15", "Base": 10 }, "Alias": null } ] } } } ] } } ] } }, { "SelectPos": 125, "StatementEnd": 218, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LBracePos": 136, "RBracePos": 146, "Name": { "Name": "a", "QuoteType": 1, "NamePos": 137, "NameEnd": 138 }, "Type": { "Name": { "Name": "UInt32", "QuoteType": 1, "NamePos": 140, "NameEnd": 146 } } }, "Modifiers": [], "Alias": null }, { "Expr": { "LBracePos": 153, "RBracePos": 163, "Name": { "Name": "b", "QuoteType": 1, "NamePos": 154, "NameEnd": 155 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 157, "NameEnd": 163 } } }, "Modifiers": [], "Alias": null }, { "Expr": { "LBracePos": 170, "RBracePos": 182, "Name": { "Name": "c", "QuoteType": 1, "NamePos": 171, "NameEnd": 172 }, "Type": { "Name": { "Name": "DateTime", "QuoteType": 1, "NamePos": 174, "NameEnd": 182 } } }, "Modifiers": [], "Alias": null }, { "Expr": { "LBracePos": 189, "RBracePos": 218, "Name": { "Name": "d", "QuoteType": 1, "NamePos": 190, "NameEnd": 191 }, "Type": { "LeftParenPos": 197, "RightParenPos": 217, "Name": { "Name": "Map", "QuoteType": 1, "NamePos": 193, "NameEnd": 196 }, "Params": [ { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 197, "NameEnd": 203 } }, { "LeftParenPos": 211, "RightParenPos": 216, "Name": { "Name": "Array", "QuoteType": 1, "NamePos": 205, "NameEnd": 210 }, "Params": [ { "Name": { "Name": "UInt8", "QuoteType": 1, "NamePos": 211, "NameEnd": 216 } } ] } ] } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 222, "StatementEnd": 283, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 229, "NameEnd": 229 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 231, "Expr": { "Table": { "TablePos": 236, "TableEnd": 246, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "clickhouse", "QuoteType": 1, "NamePos": 236, "NameEnd": 246 } }, "HasFinal": false }, "StatementEnd": 246, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": { "WherePos": 247, "Expr": { "LeftExpr": { "Name": "tenant_id", "QuoteType": 1, "NamePos": 253, "NameEnd": 262 }, "Operation": "=", "RightExpr": { "LBracePos": 265, "RBracePos": 283, "Name": { "Name": "tenant_id", "QuoteType": 1, "NamePos": 266, "NameEnd": 275 }, "Type": { "Name": { "Name": "String", "QuoteType": 1, "NamePos": 277, "NameEnd": 283 } } }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_settings_additional_table_filters.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 86, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 7, "NameEnd": 7 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 9, "Expr": { "Table": { "TablePos": 14, "TableEnd": 24, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 14, "NameEnd": 24 } }, "HasFinal": false }, "StatementEnd": 24, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": { "SettingsPos": 25, "ListEnd": 86, "Items": [ { "SettingsPos": 34, "Name": { "Name": "additional_table_filters", "QuoteType": 1, "NamePos": 34, "NameEnd": 58 }, "Expr": { "LBracePos": 59, "RBracePos": 86, "KeyValues": [ { "Key": { "LiteralPos": 61, "LiteralEnd": 71, "Literal": "test_table" }, "Value": { "LiteralPos": 75, "LiteralEnd": 85, "Literal": "status = 1" } } ] } } ] }, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 90, "StatementEnd": 182, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 97, "NameEnd": 97 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 99, "Expr": { "Table": { "TablePos": 104, "TableEnd": 114, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 104, "NameEnd": 114 } }, "HasFinal": false }, "StatementEnd": 114, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": { "SettingsPos": 115, "ListEnd": 182, "Items": [ { "SettingsPos": 124, "Name": { "Name": "additional_table_filters", "QuoteType": 1, "NamePos": 124, "NameEnd": 148 }, "Expr": { "LBracePos": 149, "RBracePos": 182, "KeyValues": [ { "Key": { "LiteralPos": 151, "LiteralEnd": 161, "Literal": "test_table" }, "Value": { "LiteralPos": 165, "LiteralEnd": 181, "Literal": "value = \\'test\\'" } } ] } } ] }, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 186, "StatementEnd": 278, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 193, "NameEnd": 193 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 195, "Expr": { "Table": { "TablePos": 200, "TableEnd": 210, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 200, "NameEnd": 210 } }, "HasFinal": false }, "StatementEnd": 210, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": { "SettingsPos": 211, "ListEnd": 278, "Items": [ { "SettingsPos": 220, "Name": { "Name": "additional_table_filters", "QuoteType": 1, "NamePos": 220, "NameEnd": 244 }, "Expr": { "LBracePos": 245, "RBracePos": 278, "KeyValues": [ { "Key": { "LiteralPos": 247, "LiteralEnd": 257, "Literal": "test_table" }, "Value": { "LiteralPos": 261, "LiteralEnd": 277, "Literal": "value = ''test''" } } ] } } ] }, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 282, "StatementEnd": 415, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 289, "NameEnd": 289 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 291, "Expr": { "Table": { "TablePos": 296, "TableEnd": 306, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 1, "NamePos": 296, "NameEnd": 306 } }, "HasFinal": false }, "StatementEnd": 306, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": { "SettingsPos": 307, "ListEnd": 402, "Items": [ { "SettingsPos": 316, "Name": { "Name": "additional_table_filters", "QuoteType": 1, "NamePos": 316, "NameEnd": 340 }, "Expr": { "LBracePos": 341, "RBracePos": 402, "KeyValues": [ { "Key": { "LiteralPos": 343, "LiteralEnd": 353, "Literal": "test_table" }, "Value": { "LiteralPos": 357, "LiteralEnd": 401, "Literal": "id IN (\\'a\\', \\'b\\') AND status = \\'active\\'" } } ] } } ] }, "Format": { "FormatPos": 404, "Format": { "Name": "JSON", "QuoteType": 1, "NamePos": 411, "NameEnd": 415 } }, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 418, "StatementEnd": 635, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 425, "NameEnd": 431 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 433, "NameEnd": 434 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 436, "NameEnd": 437 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 438, "Expr": { "JoinPos": 443, "Left": { "Table": { "TablePos": 443, "TableEnd": 488, "Alias": null, "Expr": { "Expr": { "HasParen": true, "Select": { "SelectPos": 444, "StatementEnd": 485, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "number", "QuoteType": 1, "NamePos": 451, "NameEnd": 457 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 458, "Expr": { "Table": { "TablePos": 463, "TableEnd": 477, "Alias": null, "Expr": { "Database": { "Name": "system", "QuoteType": 1, "NamePos": 463, "NameEnd": 469 }, "Table": { "Name": "numbers", "QuoteType": 1, "NamePos": 470, "NameEnd": 477 } }, "HasFinal": false }, "StatementEnd": 477, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": { "LimitPos": 478, "Limit": { "NumPos": 484, "NumEnd": 485, "Literal": "5", "Base": 10 }, "Offset": null }, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "AliasPos": 487, "Alias": { "Name": "f", "QuoteType": 1, "NamePos": 487, "NameEnd": 488 } }, "HasFinal": false }, "StatementEnd": 488, "SampleRatio": null, "HasFinal": false }, "Right": { "JoinPos": 489, "Left": { "Table": { "TablePos": 503, "TableEnd": 531, "Alias": null, "Expr": { "Expr": { "HasParen": true, "Select": { "SelectPos": 504, "StatementEnd": 528, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "x", "QuoteType": 1, "NamePos": 511, "NameEnd": 512 }, "Modifiers": [], "Alias": null }, { "Expr": { "Name": "y", "QuoteType": 1, "NamePos": 514, "NameEnd": 515 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 516, "Expr": { "Table": { "TablePos": 521, "TableEnd": 528, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "table_1", "QuoteType": 1, "NamePos": 521, "NameEnd": 528 } }, "HasFinal": false }, "StatementEnd": 528, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } }, "AliasPos": 530, "Alias": { "Name": "s", "QuoteType": 1, "NamePos": 530, "NameEnd": 531 } }, "HasFinal": false }, "StatementEnd": 531, "SampleRatio": null, "HasFinal": false }, "Right": null, "Modifiers": [ "ANY", "LEFT", "JOIN" ], "Constraints": { "OnPos": 532, "On": { "ListPos": 535, "ListEnd": 549, "HasDistinct": false, "Items": [ { "Expr": { "LeftExpr": { "Fields": [ { "Name": "f", "QuoteType": 1, "NamePos": 535, "NameEnd": 536 }, { "Name": "number", "QuoteType": 1, "NamePos": 537, "NameEnd": 543 } ] }, "Operation": "=", "RightExpr": { "Fields": [ { "Name": "s", "QuoteType": 1, "NamePos": 546, "NameEnd": 547 }, { "Name": "x", "QuoteType": 1, "NamePos": 548, "NameEnd": 549 } ] }, "HasGlobal": false, "HasNot": false }, "Alias": null } ] } } }, "Modifiers": null, "Constraints": null } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": { "SettingsPos": 550, "ListEnd": 635, "Items": [ { "SettingsPos": 559, "Name": { "Name": "additional_table_filters", "QuoteType": 1, "NamePos": 559, "NameEnd": 583 }, "Expr": { "LBracePos": 584, "RBracePos": 635, "KeyValues": [ { "Key": { "LiteralPos": 586, "LiteralEnd": 600, "Literal": "system.numbers" }, "Value": { "LiteralPos": 603, "LiteralEnd": 614, "Literal": "number != 3" } }, { "Key": { "LiteralPos": 618, "LiteralEnd": 625, "Literal": "table_1" }, "Value": { "LiteralPos": 628, "LiteralEnd": 634, "Literal": "x != 2" } } ] } } ] }, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_single_quote_table.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 25, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 7, "NameEnd": 7 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 9, "Expr": { "Table": { "TablePos": 15, "TableEnd": 25, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "test_table", "QuoteType": 4, "NamePos": 15, "NameEnd": 25 } }, "HasFinal": false }, "StatementEnd": 25, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_string_expr.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 48, "With": { "WithPos": 0, "EndPos": 9, "CTEs": [ { "CTEPos": 6, "Expr": { "Name": "abc", "QuoteType": 2, "NamePos": 6, "NameEnd": 9 }, "Alias": { "SelectPos": 15, "StatementEnd": 28, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 22, "NumEnd": 23, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "a", "QuoteType": 1, "NamePos": 27, "NameEnd": 28 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 37, "NameEnd": 37 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 39, "Expr": { "Table": { "TablePos": 45, "TableEnd": 48, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "abc", "QuoteType": 2, "NamePos": 45, "NameEnd": 48 } }, "HasFinal": false }, "StatementEnd": 48, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_union_distinct.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 43, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "replica_name", "QuoteType": 1, "NamePos": 7, "NameEnd": 19 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 20, "Expr": { "Table": { "TablePos": 25, "TableEnd": 43, "Alias": null, "Expr": { "Database": { "Name": "system", "QuoteType": 1, "NamePos": 25, "NameEnd": 31 }, "Table": { "Name": "ha_replicas", "QuoteType": 1, "NamePos": 32, "NameEnd": 43 } }, "HasFinal": false }, "StatementEnd": 43, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": { "SelectPos": 59, "StatementEnd": 121, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "replica_name", "QuoteType": 1, "NamePos": 66, "NameEnd": 78 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 79, "Expr": { "Table": { "TablePos": 84, "TableEnd": 109, "Alias": null, "Expr": { "Database": { "Name": "system", "QuoteType": 1, "NamePos": 84, "NameEnd": 90 }, "Table": { "Name": "ha_unique_replicas", "QuoteType": 1, "NamePos": 91, "NameEnd": 109 } }, "HasFinal": false }, "StatementEnd": 109, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": { "FormatPos": 110, "Format": { "Name": "JSON", "QuoteType": 1, "NamePos": 117, "NameEnd": 121 } }, "UnionAll": null, "UnionDistinct": null, "Except": null }, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_variable.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 47, "With": { "WithPos": 0, "EndPos": 9, "CTEs": [ { "CTEPos": 5, "Expr": { "Name": "$abc", "QuoteType": 1, "NamePos": 5, "NameEnd": 9 }, "Alias": { "SelectPos": 14, "StatementEnd": 27, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 21, "NumEnd": 22, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": { "Name": "a", "QuoteType": 1, "NamePos": 26, "NameEnd": 27 } } ], "From": null, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } } ] }, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "*", "QuoteType": 0, "NamePos": 36, "NameEnd": 36 }, "Modifiers": [], "Alias": null } ], "From": { "FromPos": 38, "Expr": { "Table": { "TablePos": 43, "TableEnd": 47, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "$abc", "QuoteType": 1, "NamePos": 43, "NameEnd": 47 } }, "HasFinal": false }, "StatementEnd": 47, "SampleRatio": null, "HasFinal": false } }, "Window": null, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_with_window_function.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 508, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "Name": "aggregation_target", "QuoteType": 1, "NamePos": 7, "NameEnd": 25 }, "Modifiers": [], "Alias": { "Name": "aggregation_target", "QuoteType": 1, "NamePos": 29, "NameEnd": 47 } }, { "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 53, "NameEnd": 62 }, "Modifiers": [], "Alias": { "Name": "timestamp", "QuoteType": 1, "NamePos": 66, "NameEnd": 75 } }, { "Expr": { "Name": "step_0", "QuoteType": 1, "NamePos": 81, "NameEnd": 87 }, "Modifiers": [], "Alias": { "Name": "step_0", "QuoteType": 1, "NamePos": 91, "NameEnd": 97 } }, { "Expr": { "Name": "latest_0", "QuoteType": 1, "NamePos": 103, "NameEnd": 111 }, "Modifiers": [], "Alias": { "Name": "latest_0", "QuoteType": 1, "NamePos": 115, "NameEnd": 123 } }, { "Expr": { "Name": "step_1", "QuoteType": 1, "NamePos": 129, "NameEnd": 135 }, "Modifiers": [], "Alias": { "Name": "step_1", "QuoteType": 1, "NamePos": 139, "NameEnd": 145 } }, { "Expr": { "Name": "latest_1", "QuoteType": 1, "NamePos": 151, "NameEnd": 159 }, "Modifiers": [], "Alias": { "Name": "latest_1", "QuoteType": 1, "NamePos": 163, "NameEnd": 171 } }, { "Expr": { "Name": "step_2", "QuoteType": 1, "NamePos": 177, "NameEnd": 183 }, "Modifiers": [], "Alias": { "Name": "step_2", "QuoteType": 1, "NamePos": 187, "NameEnd": 193 } }, { "Expr": { "Function": { "Name": { "Name": "min", "QuoteType": 1, "NamePos": 199, "NameEnd": 202 }, "Params": { "LeftParenPos": 202, "RightParenPos": 211, "Items": { "ListPos": 203, "ListEnd": 211, "HasDistinct": false, "Items": [ { "Expr": { "Name": "latest_2", "QuoteType": 1, "NamePos": 203, "NameEnd": 211 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 213, "OverExpr": { "LeftParenPos": 218, "RightParenPos": 327, "WindowName": null, "PartitionBy": { "PartitionPos": 218, "Expr": { "ListPos": 232, "ListEnd": 250, "HasDistinct": false, "Items": [ { "Expr": { "Name": "aggregation_target", "QuoteType": 1, "NamePos": 232, "NameEnd": 250 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 255, "ListEnd": 273, "Items": [ { "OrderPos": 255, "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 264, "NameEnd": 273 }, "Alias": null, "Direction": "DESC", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 279, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 292, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 312, "And": { "Number": { "NumPos": 316, "NumEnd": 317, "Literal": "0", "Base": 10 }, "EndPos": 327, "Direction": "PRECEDING" } } } } }, "Modifiers": [], "Alias": { "Name": "latest_2", "QuoteType": 1, "NamePos": 332, "NameEnd": 340 } }, { "Expr": { "Function": { "Name": { "Name": "min", "QuoteType": 1, "NamePos": 346, "NameEnd": 349 }, "Params": { "LeftParenPos": 349, "RightParenPos": 358, "Items": { "ListPos": 350, "ListEnd": 358, "HasDistinct": false, "Items": [ { "Expr": { "Name": "latest_1", "QuoteType": 1, "NamePos": 350, "NameEnd": 358 }, "Alias": null } ] }, "ColumnArgList": null } }, "OverPos": 360, "OverExpr": { "Name": "w", "QuoteType": 1, "NamePos": 365, "NameEnd": 366 } }, "Modifiers": [], "Alias": { "Name": "latest_1", "QuoteType": 1, "NamePos": 370, "NameEnd": 378 } } ], "From": { "FromPos": 379, "Expr": { "Table": { "TablePos": 384, "TableEnd": 386, "Alias": null, "Expr": { "Database": null, "Table": { "Name": "t0", "QuoteType": 1, "NamePos": 384, "NameEnd": 386 } }, "HasFinal": false }, "StatementEnd": 386, "SampleRatio": null, "HasFinal": false } }, "Window": { "WindowPos": 387, "EndPos": 508, "Windows": [ { "Name": { "Name": "w", "QuoteType": 1, "NamePos": 394, "NameEnd": 395 }, "AsPos": 396, "Expr": { "LeftParenPos": 399, "RightParenPos": 508, "WindowName": null, "PartitionBy": { "PartitionPos": 399, "Expr": { "ListPos": 413, "ListEnd": 431, "HasDistinct": false, "Items": [ { "Expr": { "Name": "aggregation_target", "QuoteType": 1, "NamePos": 413, "NameEnd": 431 }, "Alias": null } ] } }, "OrderBy": { "OrderPos": 436, "ListEnd": 454, "Items": [ { "OrderPos": 436, "Expr": { "Name": "timestamp", "QuoteType": 1, "NamePos": 445, "NameEnd": 454 }, "Alias": null, "Direction": "DESC", "Fill": null } ], "Interpolate": null }, "Frame": { "FramePos": 460, "Type": "ROWS", "Extend": { "Expr": null, "Between": { "UnboundedPos": 473, "UnboundedEnd": 0, "Direction": "PRECEDING" }, "AndPos": 493, "And": { "Number": { "NumPos": 497, "NumEnd": 498, "Literal": "0", "Base": 10 }, "EndPos": 508, "Direction": "PRECEDING" } } } } } ] }, "Prewhere": null, "Where": null, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/select_without_from_where.sql.golden.json ================================================ [ { "SelectPos": 0, "StatementEnd": 20, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "NumPos": 7, "NumEnd": 8, "Literal": "1", "Base": 10 }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": { "WherePos": 9, "Expr": { "LeftExpr": { "NumPos": 15, "NumEnd": 16, "Literal": "1", "Base": 10 }, "Operation": "=", "RightExpr": { "NumPos": 19, "NumEnd": 20, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null }, { "SelectPos": 22, "StatementEnd": 60, "With": null, "Top": null, "HasDistinct": false, "DistinctOn": null, "SelectItems": [ { "Expr": { "LBracePos": 29, "RBracePos": 38, "Name": { "Name": "p", "QuoteType": 1, "NamePos": 30, "NameEnd": 31 }, "Type": { "Name": { "Name": "UInt8", "QuoteType": 1, "NamePos": 33, "NameEnd": 38 } } }, "Modifiers": [], "Alias": null } ], "From": null, "Window": null, "Prewhere": null, "Where": { "WherePos": 40, "Expr": { "LeftExpr": { "LBracePos": 46, "RBracePos": 55, "Name": { "Name": "p", "QuoteType": 1, "NamePos": 47, "NameEnd": 48 }, "Type": { "Name": { "Name": "UInt8", "QuoteType": 1, "NamePos": 50, "NameEnd": 55 } } }, "Operation": "=", "RightExpr": { "NumPos": 59, "NumEnd": 60, "Literal": "1", "Base": 10 }, "HasGlobal": false, "HasNot": false } }, "GroupBy": null, "WithTotal": false, "Having": null, "OrderBy": null, "LimitBy": null, "Limit": null, "Settings": null, "Format": null, "UnionAll": null, "UnionDistinct": null, "Except": null } ] ================================================ FILE: parser/testdata/query/output/set_simple.sql.golden.json ================================================ [ { "SetPos": 0, "Settings": { "SettingsPos": 4, "ListEnd": 140, "Items": [ { "SettingsPos": 4, "Name": { "Name": "max_threads", "QuoteType": 1, "NamePos": 4, "NameEnd": 15 }, "Expr": { "NumPos": 18, "NumEnd": 19, "Literal": "1", "Base": 10 } }, { "SettingsPos": 21, "Name": { "Name": "max_insert_threads", "QuoteType": 1, "NamePos": 21, "NameEnd": 39 }, "Expr": { "NumPos": 42, "NumEnd": 43, "Literal": "0", "Base": 10 } }, { "SettingsPos": 45, "Name": { "Name": "max_block_size", "QuoteType": 1, "NamePos": 45, "NameEnd": 59 }, "Expr": { "NumPos": 62, "NumEnd": 66, "Literal": "8192", "Base": 10 } }, { "SettingsPos": 68, "Name": { "Name": "min_insert_block_size_rows", "QuoteType": 1, "NamePos": 68, "NameEnd": 94 }, "Expr": { "NumPos": 97, "NumEnd": 101, "Literal": "8192", "Base": 10 } }, { "SettingsPos": 103, "Name": { "Name": "min_insert_block_size_bytes", "QuoteType": 1, "NamePos": 103, "NameEnd": 130 }, "Expr": { "NumPos": 133, "NumEnd": 140, "Literal": "1048576", "Base": 10 } } ] } } ] ================================================ FILE: parser/testdata/query/query_with_expr_compare.sql ================================================ SELECT date, path, splitByChar('/', path)[2] AS path_b FROM( SELECT 'pathA/pathB/pathC' AS path, '2024-09-10' AS date ) WHERE toDate(date) BETWEEN '2024-09-01' AND '2024-09-30' AND splitByChar('/', path)[1] = 'pathA' ================================================ FILE: parser/testdata/query/select_case_multiple_when.sql ================================================ SELECT *, CASE WHEN col2 = 'value1' THEN 'when1' WHEN col3 = 'value2' THEN 'when2' ELSE 'else' END as check_result FROM table_name WHERE col1 = '123456789' ================================================ FILE: parser/testdata/query/select_case_when_exists.sql ================================================ SELECT *, CASE WHEN EXISTS(SELECT 1 FROM table_name WHERE col1 = '999999999') THEN 'then' ELSE 'else' END as check_result FROM table_name WHERE col1 = '123456789' ================================================ FILE: parser/testdata/query/select_cast.sql ================================================ select cast(1 as Float64) as value; select cast(1, 'Float64') as value; select (1 as Float64) as value; select 1::Float64 as value; ================================================ FILE: parser/testdata/query/select_column_alias_string.sql ================================================ SELECT 'abc' as "value2"; SELECT $abc, a$$bc, abc$$; ================================================ FILE: parser/testdata/query/select_concat_expr.sql ================================================ SELECT 'a' || 'b'; SELECT 'a' || 'b' || 'c'; SELECT 'a' || 'b' || 'c' + 5; ================================================ FILE: parser/testdata/query/select_expr.sql ================================================ SELECT 1+1 ================================================ FILE: parser/testdata/query/select_extract_with_regex.sql ================================================ SELECT COUNT(1), SRC_TYPE, NODE_CLASS, PORT, CLIENT_PORT FROM test.table WHERE app_id = 999118646 AND toUnixTimestamp(timestamp) >= 1740366695 AND toUnixTimestamp(timestamp) <= 1740377495 GROUP BY CASE WHEN length(extract(instance, '((\\d+\\.){3}\\d+)')) > 0 THEN instance ELSE '空' END, CASE WHEN length(extract(client_ip, '((\\d+\\.){3}\\d+)')) > 0 THEN client_ip ELSE '空' END, src_type, node_class, port, client_port LIMIT 10000 ================================================ FILE: parser/testdata/query/select_item_with_modifiers.sql ================================================ SELECT c0 REPLACE(c0 AS c1) FROM t0; SELECT * REPLACE(i + 1 AS i) FROM t1; SELECT * REPLACE(i + 1 AS i) EXCEPT (j) APPLY(sum) from t2; ================================================ FILE: parser/testdata/query/select_json_type.sql ================================================ SELECT a, a.b, a.b.c.d.e; SELECT JSON_TYPE('{"a": 1, "b": {"c": 2}}', '$.b'); SELECT CAST(some, 'String') AS value; SELECT CAST(some.long, 'String') AS value; SELECT CAST(some.long.json, 'String') AS value; SELECT CAST(some.long.json.path, 'String') AS value; ================================================ FILE: parser/testdata/query/select_keyword_alias_no_as.sql ================================================ SELECT 'Joe' name FROM users ================================================ FILE: parser/testdata/query/select_order_by_timestamp.sql ================================================ SELECT Timestamp FROM events ORDER BY Timestamp; ================================================ FILE: parser/testdata/query/select_order_by_with_fill_basic.sql ================================================ SELECT n, source FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL; ================================================ FILE: parser/testdata/query/select_order_by_with_fill_from_to.sql ================================================ SELECT n, source FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5; ================================================ FILE: parser/testdata/query/select_order_by_with_fill_interpolate.sql ================================================ SELECT n, source, inter FROM ( SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1); ================================================ FILE: parser/testdata/query/select_order_by_with_fill_interpolate_no_columns.sql ================================================ SELECT n, value FROM ( SELECT toFloat32(number % 10) AS n, number AS value FROM numbers(10) WHERE number % 3 = 1 ) ORDER BY n WITH FILL FROM 0 TO 10 STEP 1 INTERPOLATE; ================================================ FILE: parser/testdata/query/select_order_by_with_fill_staleness.sql ================================================ SELECT number as key, 5 * number value, 'original' AS source FROM numbers(16) WHERE (number % 5) == 0 ORDER BY key WITH FILL STALENESS 11; ================================================ FILE: parser/testdata/query/select_order_by_with_fill_step.sql ================================================ SELECT date, value FROM ( SELECT toDate('2020-01-01') + INTERVAL number DAY AS date, number AS value FROM numbers(5) ) ORDER BY date WITH FILL STEP INTERVAL 1 DAY; ================================================ FILE: parser/testdata/query/select_simple.sql ================================================ SELECT f0, coalesce(f1, f2) AS f3, row_number() OVER (PARTITION BY f0 ORDER BY f1 ASC) AS rn FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND (f2 NOT LIKE 'testing2') AND f3 NOT IN ('a', 'b', 'c') GROUP BY f0, f1 Limit 100, 10 By f0; ================================================ FILE: parser/testdata/query/select_simple_field_alias.sql ================================================ SELECT field0, field1 as x, field2 y from events; ================================================ FILE: parser/testdata/query/select_simple_with_bracket.sql ================================================ SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res, f1["abc"] as f2 ================================================ FILE: parser/testdata/query/select_simple_with_cte_with_column_aliases.sql ================================================ WITH test(f1, f2, f3) AS (SELECT f4, f5, f6 FROM sales) SELECT f1 AS new_f1, f2 AS new_f2, f3 AS new_f3 FROM test; ================================================ FILE: parser/testdata/query/select_simple_with_group_by_with_cube_totals.sql ================================================ SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a; ================================================ FILE: parser/testdata/query/select_simple_with_is_not_null.sql ================================================ SELECT f0,f1,f2,f3 as a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL AND f3 IS NOT NULL ================================================ FILE: parser/testdata/query/select_simple_with_is_null.sql ================================================ SELECT f0,f1,f2,f3 as a0 FROM test.events_local WHERE (f0 IN ('foo', 'bar', 'test')) AND (f1 = 'testing') AND f2 IS NULL ================================================ FILE: parser/testdata/query/select_simple_with_limit.sql ================================================ SELECT 1 LIMIT 1; SELECT 1 LIMIT 1 OFFSET 0; SELECT 1 OFFSET 0; ================================================ FILE: parser/testdata/query/select_simple_with_top_clause.sql ================================================ SELECT TOP 10 my_column FROM tableName; ================================================ FILE: parser/testdata/query/select_simple_with_with_clause.sql ================================================ WITH cte1 AS (SELECT f1 FROM t1), cte2 AS (SELECT f2 FROM t2) SELECT cte1.f1, cte2.f2, t3.f3 FROM t3,cte1,cte2 ================================================ FILE: parser/testdata/query/select_table_alias_without_keyword.sql ================================================ SELECT t1.Timestamp FROM my_table t1 INNER JOIN my_other_table t2 ON t1.a=t2.b ================================================ FILE: parser/testdata/query/select_table_function_with_query.sql ================================================ SELECT 1, (SELECT 70) AS `power`, number FROM numbers( plus( ifNull((SELECT 1 AS bin_count, 1), 1) ) ) ================================================ FILE: parser/testdata/query/select_when_condition.sql ================================================ select case when false then 'hello' else 'world' end; ================================================ FILE: parser/testdata/query/select_window_comprehensive.sql ================================================ -- Comprehensive window spec coverage: ad-hoc specs, named windows, ROWS/RANGE frames -- multiple functions, multi-column PARTITION/ORDER, and expression-based specs. SELECT -- Ad-hoc windows sum(x) OVER (ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total, avg(x) OVER (PARTITION BY z ORDER BY y RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS avg_range1, -- Named window reuse (OVER w1) row_number() OVER w1 AS rn_w1, rank() OVER w1 AS rank_w1, sum(x) OVER w1 AS sum_w1, -- Frame variants (incl. shorthand & RANGE) sum(x) OVER (ROWS 10 PRECEDING) AS rows_10_preceding, sum(x) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS rows_cur_to_unbounded_following, sum(x) OVER (ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING) AS rows_5p_3f, sum(x) OVER (RANGE BETWEEN 10 PRECEDING AND CURRENT ROW) AS range_10p_cur, sum(x) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS range_unbounded_to_cur, -- Ranking & navigation row_number() OVER (PARTITION BY y ORDER BY x) AS row_num, rank() OVER (PARTITION BY y ORDER BY x) AS rank_val, dense_rank() OVER (PARTITION BY y ORDER BY x) AS dense_rank_val, first_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_val, last_value(x) OVER (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_val, lag(x, 1) OVER (PARTITION BY y ORDER BY x) AS prev_x, lead(x, 1) OVER (PARTITION BY y ORDER BY x) AS next_x, percent_rank() OVER (PARTITION BY y ORDER BY x) AS pct_rank, -- Named window reference via OVER w (no parentheses) sum(x) OVER w AS sum_over_w, avg(x) OVER w AS avg_over_w, row_number() OVER w AS rn_over_w, -- Multiple columns in PARTITION BY / ORDER BY count(*) OVER (PARTITION BY col1, col2, col3 ORDER BY col4, col5 DESC) AS cnt_multi, sum(val) OVER (PARTITION BY col1, col2 ORDER BY col4, col5 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_multi, -- Expressions in PARTITION/ORDER sum(amount) OVER (PARTITION BY date_trunc('day', timestamp) ORDER BY timestamp ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) AS daily_total, avg(amount) OVER (ORDER BY extract(HOUR FROM timestamp) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS hourly_avg FROM t WINDOW w AS (ORDER BY y), w1 AS (PARTITION BY y ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), w4 AS (PARTITION BY y ORDER BY x ROWS BETWEEN 3 PRECEDING AND CURRENT ROW), w5 AS (PARTITION BY z ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); ================================================ FILE: parser/testdata/query/select_window_cte.sql ================================================ WITH monthly AS ( SELECT toStartOfMonth(date) AS month, department, avg(salary) AS avg_salary FROM salary_table WHERE year = 2023 GROUP BY month, department ), ranked AS ( SELECT month, department, avg_salary, row_number() OVER (PARTITION BY department ORDER BY avg_salary DESC) AS dept_rank FROM monthly ) SELECT month, department, avg_salary, lag(avg_salary, 1, 0) OVER ( PARTITION BY department ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) AS prev_month_avg FROM ranked WHERE dept_rank <= 5 ORDER BY month, department; ================================================ FILE: parser/testdata/query/select_window_keyword_name_in_parens.sql ================================================ SELECT sum(x) OVER (order) AS sum_over_order FROM t WINDOW order AS (PARTITION BY team ORDER BY ts); ================================================ FILE: parser/testdata/query/select_window_named_in_parens.sql ================================================ SELECT sum(x) OVER (w) AS sum_over_w FROM t WINDOW w AS (PARTITION BY y ORDER BY x); ================================================ FILE: parser/testdata/query/select_window_named_reference_extensions.sql ================================================ SELECT sum(x) OVER (w1 ORDER BY ts ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum, avg(x) OVER (w2) AS avg_over_w2 FROM t WINDOW w1 AS (PARTITION BY team), w2 AS (w1 ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW); ================================================ FILE: parser/testdata/query/select_window_params.sql ================================================ -- Parameters in WHERE and in window frames (UInt32 & String; both spacing styles; shorthand frame) SELECT sum(x) OVER (ORDER BY y ROWS BETWEEN {start:UInt32} PRECEDING AND CURRENT ROW) AS total1, avg(x) OVER (ORDER BY y ROWS BETWEEN CURRENT ROW AND {end:UInt32} FOLLOWING) AS avg1, count(*) OVER (ORDER BY y RANGE BETWEEN {range_start:UInt32} PRECEDING AND {range_end:UInt32} FOLLOWING) AS cnt1, sum(x) OVER (ROWS {window_size :UInt32} PRECEDING) AS rows_shorthand FROM t WHERE category = {category :String} AND type = {type:String}; ================================================ FILE: parser/testdata/query/select_with_distinct.sql ================================================ SELECT count(DISTINCT(RECORD_ID)) FROM RECORD_TABLE ================================================ FILE: parser/testdata/query/select_with_distinct_keyword.sql ================================================ SELECT DISTINCT record_id FROM records ================================================ FILE: parser/testdata/query/select_with_distinct_on_dotted_columns.sql ================================================ SELECT DISTINCT ON (t.id, t.name) t.id, t.name, t.value FROM test_table t ================================================ FILE: parser/testdata/query/select_with_distinct_on_keyword.sql ================================================ SELECT DISTINCT ON(album,artist) record_id FROM records ================================================ FILE: parser/testdata/query/select_with_group_by.sql ================================================ SELECT datacenter, distro, SUM (quantity) AS qty FROM servers GROUP BY GROUPING SETS( (datacenter,distro), (datacenter), (distro), () ); SELECT datacenter, distro, SUM (quantity) AS qty FROM servers GROUP BY ALL; ================================================ FILE: parser/testdata/query/select_with_join_only.sql ================================================ SELECT * FROM "t1" JOIN "t2" ON true ================================================ FILE: parser/testdata/query/select_with_keyword_in_group_by.sql ================================================ SELECT toStartOfInterval(timestamp, toIntervalMinute(1)) AS interval, column_name FROM table WHERE true GROUP BY (interval, column_name) ORDER BY (interval AS i, column_name) ASC ================================================ FILE: parser/testdata/query/select_with_keyword_placeholder.sql ================================================ SELECT {name :String}; SELECT toString({name :String}); ================================================ FILE: parser/testdata/query/select_with_left_join.sql ================================================ WITH t1 AS ( SELECT 1 AS value ), t2 AS ( SELECT 2 AS value ) SELECT * FROM t1 LEFT JOIN t2 ON true ================================================ FILE: parser/testdata/query/select_with_literal_table_name.sql ================================================ select table_name from "information_schema"."tables" limit 1; ================================================ FILE: parser/testdata/query/select_with_multi_array_and_inner_join.sql ================================================ SELECT JSONExtractString(t3.props, 'value') AS value FROM t1 ARRAY JOIN JSONExtractArrayRaw(t1.props, 'arr1') AS a1 INNER JOIN t2 ON t2.id = JSONExtractString(a1, 'id') ARRAY JOIN JSONExtractArrayRaw(t2.props, 'arr2') AS a2 INNER JOIN t3 ON t3.id = JSONExtractString(a2, 'id') WHERE value != ''; ================================================ FILE: parser/testdata/query/select_with_multi_array_join.sql ================================================ SELECT v, j FROM t1 ARRAY JOIN JSONExtractArrayRaw(a) AS j ARRAY JOIN array( JSONExtractString(j, 'x'), JSONExtractString(j, 'y') ) AS v; ================================================ FILE: parser/testdata/query/select_with_multi_except.sql ================================================ SELECT number FROM numbers(1, 10) EXCEPT SELECT number FROM numbers(3, 6) EXCEPT SELECT number FROM numbers(8, 9) ================================================ FILE: parser/testdata/query/select_with_multi_join.sql ================================================ with t1 as ( select 'value1' as value ), t2 as ( select 'value2' as value ), t3 as ( select 'value3' as value ) select t1.value as value1, t2.value as value2, t3.value as value3 from t1 join t2 on true join t3 join t4 on true join t5 ================================================ FILE: parser/testdata/query/select_with_multi_line_comment.sql ================================================ select -- first line -- second line * from t0 ================================================ FILE: parser/testdata/query/select_with_multi_union.sql ================================================ SELECT 1 AS v1 UNION ALL SELECT 2 AS v2 UNION ALL SELECT 3 AS v3 ================================================ FILE: parser/testdata/query/select_with_multi_union_distinct.sql ================================================ SELECT 1 AS v1 UNION DISTINCT SELECT 2 AS v2 UNION DISTINCT SELECT 3 AS v3 ================================================ FILE: parser/testdata/query/select_with_number_field.sql ================================================ SELECT foo, bar.1, foo.2 FROM foo ARRAY JOIN m as bar ================================================ FILE: parser/testdata/query/select_with_placeholder.sql ================================================ SELECT * FROM t0 WHERE id = ?; ================================================ FILE: parser/testdata/query/select_with_query_parameter.sql ================================================ SET param_a = 13; SET param_b = 'str'; SET param_c = '2022-08-04 18:30:53'; SET param_d = {'10': [11, 12], '13': [14, 15]}; SELECT {a: UInt32}, {b: String}, {c: DateTime}, {d: Map(String, Array(UInt8))}; SELECT * FROM clickhouse WHERE tenant_id = {tenant_id: String}; ================================================ FILE: parser/testdata/query/select_with_settings_additional_table_filters.sql ================================================ SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'status = 1'}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = \'test\''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'value = ''test'''}; SELECT * FROM test_table SETTINGS additional_table_filters={'test_table': 'id IN (\'a\', \'b\') AND status = \'active\''} FORMAT JSON; SELECT number, x, y FROM (SELECT number FROM system.numbers LIMIT 5) f ANY LEFT JOIN (SELECT x, y FROM table_1) s ON f.number = s.x SETTINGS additional_table_filters={'system.numbers':'number != 3', 'table_1':'x != 2'}; ================================================ FILE: parser/testdata/query/select_with_single_quote_table.sql ================================================ SELECT * FROM 'test_table' ================================================ FILE: parser/testdata/query/select_with_string_expr.sql ================================================ WITH "abc" AS (SELECT 1 AS a) SELECT * FROM "abc" ================================================ FILE: parser/testdata/query/select_with_union_distinct.sql ================================================ SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON ================================================ FILE: parser/testdata/query/select_with_variable.sql ================================================ WITH $abc AS (SELECT 1 AS a) SELECT * FROM $abc ================================================ FILE: parser/testdata/query/select_with_window_function.sql ================================================ SELECT aggregation_target AS aggregation_target, timestamp AS timestamp, step_0 AS step_0, latest_0 AS latest_0, step_1 AS step_1, latest_1 AS latest_1, step_2 AS step_2, min(latest_2) OVER (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2, min(latest_1) OVER w AS latest_1 FROM t0 WINDOW w AS (PARTITION BY aggregation_target ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING); ================================================ FILE: parser/testdata/query/select_without_from_where.sql ================================================ SELECT 1 WHERE 1 = 1; SELECT {p :UInt8} WHERE {p :UInt8} = 1; ================================================ FILE: parser/testdata/query/set_simple.sql ================================================ SET max_threads = 1, max_insert_threads = 0, max_block_size = 8192, min_insert_block_size_rows = 8192, min_insert_block_size_bytes = 1048576; -- lower memory usage ================================================ FILE: parser/type.go ================================================ package parser var intervalUnits = NewSet("MILLISECOND", "SECOND", "MINUTE", "HOUR", "DAY", "WEEK", "MONTH", "QUARTER", "YEAR") ================================================ FILE: parser/visitor_test.go ================================================ package parser import ( "fmt" "os" "path/filepath" "strings" "testing" "github.com/sebdah/goldie/v2" "github.com/stretchr/testify/require" ) func TestVisitor_Identical(t *testing.T) { for _, dir := range []string{"./testdata/dml", "./testdata/ddl", "./testdata/query", "./testdata/basic"} { outputDir := dir + "/format" entries, err := os.ReadDir(dir) require.NoError(t, err) for _, entry := range entries { if !strings.HasSuffix(entry.Name(), ".sql") { continue } t.Run(entry.Name(), func(t *testing.T) { fileBytes, err := os.ReadFile(filepath.Join(dir, entry.Name())) require.NoError(t, err) parser := Parser{ lexer: NewLexer(string(fileBytes)), } stmts, err := parser.ParseStmts() require.NoError(t, err) var builder strings.Builder builder.WriteString("-- Origin SQL:\n") builder.Write(fileBytes) builder.WriteString("\n\n-- Format SQL:\n") var formatSQLBuilder strings.Builder for _, stmt := range stmts { // Use Walk to traverse the AST (equivalent to the visitor doing nothing) Walk(stmt, func(node Expr) bool { return true // Continue traversal }) formatSQLBuilder.WriteString(Format(stmt)) formatSQLBuilder.WriteByte(';') formatSQLBuilder.WriteByte('\n') } formatSQL := formatSQLBuilder.String() builder.WriteString(formatSQL) validFormatSQL(t, formatSQL) g := goldie.New(t, goldie.WithNameSuffix(""), goldie.WithDiffEngine(goldie.ColoredDiff), goldie.WithFixtureDir(outputDir)) g.Assert(t, entry.Name(), []byte(builder.String())) }) } } } func TestVisitor_SimpleRewrite(t *testing.T) { sql := `SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) stmt := stmts[0] // Rewrite using Walk function Walk(stmt, func(node Expr) bool { switch expr := node.(type) { case *TableIdentifier: if Format(expr.Table) == "group_by_all" { expr.Table = &Ident{Name: "hack"} } case *OrderExpr: expr.Direction = OrderDirectionDesc } return true // Continue traversal }) newSql := Format(stmt) require.NotSame(t, sql, newSql) require.True(t, strings.Contains(newSql, "hack")) require.True(t, strings.Contains(newSql, string(OrderDirectionDesc))) } func TestVisitor_NestRewrite(t *testing.T) { sql := `SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas format JSON` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) stmt := stmts[0] // Track nesting depth with closure variables var stack []Expr Walk(stmt, func(node Expr) bool { // Simulate Enter behavior if s, ok := node.(*SelectQuery); ok { stack = append(stack, s) } // Process TableIdentifier nodes if expr, ok := node.(*TableIdentifier); ok { expr.Table = &Ident{Name: fmt.Sprintf("table%d", len(stack))} } // Continue with children return true }) newSql := Format(stmt) require.NotSame(t, sql, newSql) // Both table names should be rewritten (they might both be table1 since they're at the same depth) require.True(t, strings.Contains(newSql, "table1") || strings.Contains(newSql, "table2")) } // TestWalk_NodeCounting verifies that Walk visits all nodes in the AST func TestWalk_NodeCounting(t *testing.T) { sql := `SELECT a FROM table1` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) var nodeCount int Walk(stmts[0], func(node Expr) bool { nodeCount++ return true }) // Verify that we visited multiple nodes require.Greater(t, nodeCount, 0, "Walk should visit nodes") require.Greater(t, nodeCount, 3, "Should visit at least SELECT, column, table nodes") } ================================================ FILE: parser/walk.go ================================================ package parser import "reflect" // WalkFunc is a function type for walking AST nodes. // It receives the current node and returns a boolean indicating whether to continue walking. // If the function returns false, the walking stops for the current subtree. type WalkFunc func(node Expr) bool // Walk traverses an AST in depth-first order, calling the provided function // for each node. If the function returns false, traversal stops for that subtree. func Walk(node Expr, fn WalkFunc) bool { if node == nil || reflect.ValueOf(node).IsNil() { return true } if !fn(node) { return false } switch n := node.(type) { case *SelectQuery: if !Walk(n.With, fn) { return false } if !Walk(n.DistinctOn, fn) { return false } if !Walk(n.Top, fn) { return false } for _, item := range n.SelectItems { if !Walk(item, fn) { return false } } if !Walk(n.From, fn) { return false } if !Walk(n.Window, fn) { return false } if !Walk(n.Prewhere, fn) { return false } if !Walk(n.Where, fn) { return false } if !Walk(n.GroupBy, fn) { return false } if !Walk(n.Having, fn) { return false } if !Walk(n.OrderBy, fn) { return false } if !Walk(n.LimitBy, fn) { return false } if !Walk(n.Limit, fn) { return false } if !Walk(n.Settings, fn) { return false } if !Walk(n.UnionAll, fn) { return false } if !Walk(n.UnionDistinct, fn) { return false } if !Walk(n.Format, fn) { return false } case *SubQuery: if !Walk(n.Select, fn) { return false } case *SelectItem: if !Walk(n.Expr, fn) { return false } for _, modifier := range n.Modifiers { if !Walk(modifier, fn) { return false } } if !Walk(n.Alias, fn) { return false } case *TableExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.Alias, fn) { return false } case *AliasExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.Alias, fn) { return false } case *FunctionExpr: if !Walk(n.Name, fn) { return false } if !Walk(n.Params, fn) { return false } case *TableIdentifier: if !Walk(n.Database, fn) { return false } if !Walk(n.Table, fn) { return false } case *Ident: // Leaf node case *NumberLiteral: // Leaf node case *StringLiteral: // Leaf node case *NullLiteral: // Leaf node case *NotNullLiteral: if !Walk(n.NullLiteral, fn) { return false } case *ColumnExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.Alias, fn) { return false } case *BinaryOperation: if !Walk(n.LeftExpr, fn) { return false } if !Walk(n.RightExpr, fn) { return false } case *WhenClause: if !Walk(n.When, fn) { return false } if !Walk(n.Then, fn) { return false } case *CaseExpr: if !Walk(n.Expr, fn) { return false } for _, when := range n.Whens { if !Walk(when, fn) { return false } } if !Walk(n.Else, fn) { return false } case *CastExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.AsType, fn) { return false } case *Path: for _, field := range n.Fields { if !Walk(field, fn) { return false } } case *WithClause: for _, cte := range n.CTEs { if !Walk(cte, fn) { return false } } case *CTEStmt: if !Walk(n.Expr, fn) { return false } if !Walk(n.Alias, fn) { return false } case *FromClause: if !Walk(n.Expr, fn) { return false } case *JoinExpr: if !Walk(n.Left, fn) { return false } if !Walk(n.Right, fn) { return false } if !Walk(n.Constraints, fn) { return false } case *JoinTableExpr: if !Walk(n.Table, fn) { return false } if !Walk(n.SampleRatio, fn) { return false } case *OnClause: if !Walk(n.On, fn) { return false } case *UsingClause: if !Walk(n.Using, fn) { return false } case *WhereClause: if !Walk(n.Expr, fn) { return false } case *PrewhereClause: if !Walk(n.Expr, fn) { return false } case *GroupByClause: if !Walk(n.Expr, fn) { return false } case *HavingClause: if !Walk(n.Expr, fn) { return false } case *OrderByClause: for _, item := range n.Items { if !Walk(item, fn) { return false } } if !Walk(n.Interpolate, fn) { return false } case *OrderExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.Alias, fn) { return false } if !Walk(n.Fill, fn) { return false } case *Fill: if !Walk(n.From, fn) { return false } if !Walk(n.To, fn) { return false } if !Walk(n.Step, fn) { return false } if !Walk(n.Staleness, fn) { return false } case *InterpolateClause: for _, item := range n.Items { if !Walk(item, fn) { return false } } case *InterpolateItem: if !Walk(n.Column, fn) { return false } if !Walk(n.Expr, fn) { return false } case *LimitClause: if !Walk(n.Limit, fn) { return false } if !Walk(n.Offset, fn) { return false } case *LimitByClause: if !Walk(n.Limit, fn) { return false } if !Walk(n.ByExpr, fn) { return false } case *SettingsClause: for _, item := range n.Items { if !Walk(item, fn) { return false } } case *SettingExpr: if !Walk(n.Name, fn) { return false } if !Walk(n.Expr, fn) { return false } case *FormatClause: if !Walk(n.Format, fn) { return false } case *InsertStmt: if !Walk(n.Table, fn) { return false } if !Walk(n.ColumnNames, fn) { return false } if !Walk(n.Format, fn) { return false } if !Walk(n.SelectExpr, fn) { return false } case *ColumnNamesExpr: for i := range n.ColumnNames { if !Walk(&n.ColumnNames[i], fn) { return false } } case *AssignmentValues: for _, value := range n.Values { if !Walk(value, fn) { return false } } case *TableFunctionExpr: if !Walk(n.Name, fn) { return false } if !Walk(n.Args, fn) { return false } case *TableArgListExpr: for _, arg := range n.Args { if !Walk(arg, fn) { return false } } case *NestedIdentifier: if !Walk(n.Ident, fn) { return false } if !Walk(n.DotIdent, fn) { return false } case *ArrayParamList: if !Walk(n.Items, fn) { return false } case *ColumnExprList: for _, item := range n.Items { if !Walk(item, fn) { return false } } case *ParamExprList: if !Walk(n.Items, fn) { return false } if !Walk(n.ColumnArgList, fn) { return false } case *ColumnArgList: for _, item := range n.Items { if !Walk(item, fn) { return false } } case *WindowClause: for _, window := range n.Windows { if window == nil { continue } if !Walk(window.Name, fn) { return false } if !Walk(window.Expr, fn) { return false } } case *WindowExpr: if !Walk(n.WindowName, fn) { return false } if !Walk(n.PartitionBy, fn) { return false } if !Walk(n.OrderBy, fn) { return false } if !Walk(n.Frame, fn) { return false } case *PartitionByClause: if !Walk(n.Expr, fn) { return false } case *WindowFrameClause: if !Walk(n.Extend, fn) { return false } case *WindowFrameExtendExpr: if !Walk(n.Expr, fn) { return false } case *BetweenClause: if !Walk(n.Expr, fn) { return false } if !Walk(n.Between, fn) { return false } if !Walk(n.And, fn) { return false } case *WindowFrameCurrentRow: // Leaf node case *WindowFrameUnbounded: // Leaf node case *WindowFrameNumber: if !Walk(n.Number, fn) { return false } case *TopClause: if !Walk(n.Number, fn) { return false } case *SampleClause: if !Walk(n.Ratio, fn) { return false } if !Walk(n.Offset, fn) { return false } case *RatioExpr: if !Walk(n.Numerator, fn) { return false } if !Walk(n.Denominator, fn) { return false } case *IntervalExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.Unit, fn) { return false } case *DropStmt: if !Walk(n.Name, fn) { return false } if !Walk(n.OnCluster, fn) { return false } case *DropDatabase: if !Walk(n.Name, fn) { return false } if !Walk(n.OnCluster, fn) { return false } case *DropUserOrRole: for _, name := range n.Names { if !Walk(name, fn) { return false } } if !Walk(n.From, fn) { return false } case *TruncateTable: if !Walk(n.Name, fn) { return false } if !Walk(n.OnCluster, fn) { return false } case *CheckStmt: if !Walk(n.Table, fn) { return false } if !Walk(n.Partition, fn) { return false } case *OptimizeStmt: if !Walk(n.Table, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.Partition, fn) { return false } if !Walk(n.Deduplicate, fn) { return false } case *DeduplicateClause: if !Walk(n.By, fn) { return false } if !Walk(n.Except, fn) { return false } case *SystemStmt: if !Walk(n.Expr, fn) { return false } case *SystemFlushExpr: if !Walk(n.Distributed, fn) { return false } case *SystemReloadExpr: if !Walk(n.Dictionary, fn) { return false } case *SystemSyncExpr: if !Walk(n.Cluster, fn) { return false } case *SystemCtrlExpr: if !Walk(n.Cluster, fn) { return false } case *SystemDropExpr: // Leaf node case *UseStmt: if !Walk(n.Database, fn) { return false } case *SetStmt: if !Walk(n.Settings, fn) { return false } case *ExplainStmt: if !Walk(n.Statement, fn) { return false } case *GrantPrivilegeStmt: for _, privilege := range n.Privileges { if !Walk(privilege, fn) { return false } } if !Walk(n.On, fn) { return false } for _, role := range n.To { if !Walk(role, fn) { return false } } if !Walk(n.OnCluster, fn) { return false } case *PrivilegeClause: if !Walk(n.Params, fn) { return false } case *RenameStmt: for _, pair := range n.TargetPairList { if !Walk(pair.Old, fn) { return false } if !Walk(pair.New, fn) { return false } } if !Walk(n.OnCluster, fn) { return false } case *DeleteClause: if !Walk(n.Table, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.WhereExpr, fn) { return false } case *CreateDatabase: if !Walk(n.Name, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.Engine, fn) { return false } if !Walk(n.Comment, fn) { return false } case *CreateTable: if !Walk(n.Name, fn) { return false } if !Walk(n.UUID, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.TableSchema, fn) { return false } if !Walk(n.Engine, fn) { return false } if !Walk(n.SubQuery, fn) { return false } if !Walk(n.TableFunction, fn) { return false } if !Walk(n.Comment, fn) { return false } case *CreateView: if !Walk(n.Name, fn) { return false } if !Walk(n.UUID, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.TableSchema, fn) { return false } if !Walk(n.Comment, fn) { return false } if !Walk(n.SubQuery, fn) { return false } case *CreateMaterializedView: if !Walk(n.Name, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.Refresh, fn) { return false } if !Walk(n.RandomizeFor, fn) { return false } for _, dep := range n.DependsOn { if !Walk(dep, fn) { return false } } if !Walk(n.Settings, fn) { return false } if !Walk(n.Engine, fn) { return false } if !Walk(n.Destination, fn) { return false } if !Walk(n.SubQuery, fn) { return false } if !Walk(n.Comment, fn) { return false } if !Walk(n.Definer, fn) { return false } case *CreateLiveView: if !Walk(n.Name, fn) { return false } if !Walk(n.UUID, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.Destination, fn) { return false } if !Walk(n.TableSchema, fn) { return false } if !Walk(n.WithTimeout, fn) { return false } if !Walk(n.SubQuery, fn) { return false } case *CreateDictionary: if !Walk(n.Name, fn) { return false } if !Walk(n.UUID, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.Schema, fn) { return false } if !Walk(n.Engine, fn) { return false } if !Walk(n.Comment, fn) { return false } case *CreateFunction: if !Walk(n.FunctionName, fn) { return false } if !Walk(n.OnCluster, fn) { return false } if !Walk(n.Params, fn) { return false } if !Walk(n.Expr, fn) { return false } case *CreateRole: for _, name := range n.RoleNames { if !Walk(name, fn) { return false } } if !Walk(n.AccessStorageType, fn) { return false } for _, setting := range n.Settings { if !Walk(setting, fn) { return false } } case *CreateUser: for _, name := range n.UserNames { if !Walk(name, fn) { return false } } if !Walk(n.Authentication, fn) { return false } if !Walk(n.ValidUntil, fn) { return false } for _, host := range n.Hosts { if !Walk(host, fn) { return false } } if !Walk(n.DefaultRole, fn) { return false } if !Walk(n.DefaultDatabase, fn) { return false } if !Walk(n.Grantees, fn) { return false } for _, setting := range n.Settings { if !Walk(setting, fn) { return false } } case *AlterTable: if !Walk(n.TableIdentifier, fn) { return false } if !Walk(n.OnCluster, fn) { return false } for _, expr := range n.AlterExprs { if !Walk(expr, fn) { return false } } case *AlterTableAttachPartition: if !Walk(n.Partition, fn) { return false } if !Walk(n.From, fn) { return false } case *AlterTableDetachPartition: if !Walk(n.Partition, fn) { return false } if !Walk(n.Settings, fn) { return false } case *AlterTableDropPartition: if !Walk(n.Partition, fn) { return false } if !Walk(n.Settings, fn) { return false } case *AlterTableMaterializeProjection: if !Walk(n.ProjectionName, fn) { return false } if !Walk(n.Partition, fn) { return false } case *AlterTableMaterializeIndex: if !Walk(n.IndexName, fn) { return false } if !Walk(n.Partition, fn) { return false } case *AlterTableFreezePartition: if !Walk(n.Partition, fn) { return false } case *AlterTableAddColumn: if !Walk(n.Column, fn) { return false } if !Walk(n.After, fn) { return false } if !Walk(n.Settings, fn) { return false } case *AlterTableAddIndex: if !Walk(n.Index, fn) { return false } if !Walk(n.After, fn) { return false } case *AlterTableAddProjection: if !Walk(n.TableProjection, fn) { return false } if !Walk(n.After, fn) { return false } case *AlterTableDropColumn: if !Walk(n.ColumnName, fn) { return false } case *AlterTableDropIndex: if !Walk(n.IndexName, fn) { return false } case *AlterTableDropProjection: if !Walk(n.ProjectionName, fn) { return false } case *AlterTableRemoveTTL: // Leaf node case *AlterTableClearColumn: if !Walk(n.ColumnName, fn) { return false } if !Walk(n.PartitionExpr, fn) { return false } case *AlterTableClearIndex: if !Walk(n.IndexName, fn) { return false } if !Walk(n.PartitionExpr, fn) { return false } case *AlterTableClearProjection: if !Walk(n.ProjectionName, fn) { return false } if !Walk(n.PartitionExpr, fn) { return false } case *AlterTableRenameColumn: if !Walk(n.OldColumnName, fn) { return false } if !Walk(n.NewColumnName, fn) { return false } case *AlterTableModifyQuery: if !Walk(n.SelectExpr, fn) { return false } case *AlterTableModifyTTL: if !Walk(n.TTL, fn) { return false } case *AlterTableModifyColumn: if !Walk(n.Column, fn) { return false } if !Walk(n.RemovePropertyType, fn) { return false } case *AlterTableModifySetting: for _, setting := range n.Settings { if !Walk(setting, fn) { return false } } case *AlterTableResetSetting: for _, setting := range n.Settings { if !Walk(setting, fn) { return false } } case *AlterTableReplacePartition: if !Walk(n.Partition, fn) { return false } if !Walk(n.Table, fn) { return false } case *AlterTableDelete: if !Walk(n.WhereClause, fn) { return false } case *AlterTableUpdate: for _, assignment := range n.Assignments { if !Walk(assignment, fn) { return false } } if !Walk(n.InPartition, fn) { return false } if !Walk(n.WhereClause, fn) { return false } case *UpdateAssignment: if !Walk(n.Column, fn) { return false } if !Walk(n.Expr, fn) { return false } case *AlterRole: for _, pair := range n.RoleRenamePairs { if !Walk(pair, fn) { return false } } for _, setting := range n.Settings { if !Walk(setting, fn) { return false } } case *RoleRenamePair: if !Walk(n.RoleName, fn) { return false } if !Walk(n.NewName, fn) { return false } case *TableSchemaClause: for _, column := range n.Columns { if !Walk(column, fn) { return false } } if !Walk(n.AliasTable, fn) { return false } if !Walk(n.TableFunction, fn) { return false } case *ColumnDef: if !Walk(n.Name, fn) { return false } if !Walk(n.Type, fn) { return false } if !Walk(n.NotNull, fn) { return false } if !Walk(n.Nullable, fn) { return false } if !Walk(n.DefaultExpr, fn) { return false } if !Walk(n.MaterializedExpr, fn) { return false } if !Walk(n.AliasExpr, fn) { return false } if !Walk(n.Codec, fn) { return false } if !Walk(n.TTL, fn) { return false } if !Walk(n.Comment, fn) { return false } case *ScalarType: if !Walk(n.Name, fn) { return false } case *JSONType: if !Walk(n.Name, fn) { return false } case *PropertyType: if !Walk(n.Name, fn) { return false } case *TypeWithParams: if !Walk(n.Name, fn) { return false } for _, param := range n.Params { if !Walk(param, fn) { return false } } case *ComplexType: if !Walk(n.Name, fn) { return false } for _, param := range n.Params { if !Walk(param, fn) { return false } } case *NestedType: if !Walk(n.Name, fn) { return false } for _, column := range n.Columns { if !Walk(column, fn) { return false } } case *CompressionCodec: if !Walk(n.Type, fn) { return false } if !Walk(n.TypeLevel, fn) { return false } if !Walk(n.Name, fn) { return false } if !Walk(n.Level, fn) { return false } case *EngineExpr: if !Walk(n.Params, fn) { return false } if !Walk(n.PrimaryKey, fn) { return false } if !Walk(n.PartitionBy, fn) { return false } if !Walk(n.SampleBy, fn) { return false } if !Walk(n.TTL, fn) { return false } if !Walk(n.Settings, fn) { return false } if !Walk(n.OrderBy, fn) { return false } case *PrimaryKeyClause: if !Walk(n.Expr, fn) { return false } case *SampleByClause: if !Walk(n.Expr, fn) { return false } case *TTLClause: for _, item := range n.Items { if !Walk(item, fn) { return false } } case *TTLExpr: if !Walk(n.Expr, fn) { return false } if !Walk(n.Policy, fn) { return false } case *TTLPolicy: if !Walk(n.Item, fn) { return false } if !Walk(n.Where, fn) { return false } if !Walk(n.GroupBy, fn) { return false } case *TTLPolicyRule: if !Walk(n.ToVolume, fn) { return false } if !Walk(n.ToDisk, fn) { return false } case *TTLPolicyRuleAction: if !Walk(n.Codec, fn) { return false } case *RefreshExpr: if !Walk(n.Interval, fn) { return false } if !Walk(n.Offset, fn) { return false } case *DestinationClause: if !Walk(n.TableIdentifier, fn) { return false } if !Walk(n.TableSchema, fn) { return false } case *ConstraintClause: if !Walk(n.Constraint, fn) { return false } if !Walk(n.Expr, fn) { return false } case *RoleName: if !Walk(n.Name, fn) { return false } if !Walk(n.Scope, fn) { return false } if !Walk(n.OnCluster, fn) { return false } case *SettingPair: if !Walk(n.Name, fn) { return false } if !Walk(n.Value, fn) { return false } case *RoleSetting: for _, pair := range n.SettingPairs { if !Walk(pair, fn) { return false } } if !Walk(n.Modifier, fn) { return false } case *AuthenticationClause: if !Walk(n.AuthValue, fn) { return false } if !Walk(n.LdapServer, fn) { return false } if !Walk(n.KerberosRealm, fn) { return false } case *HostClause: if !Walk(n.HostValue, fn) { return false } case *DefaultRoleClause: for _, role := range n.Roles { if !Walk(role, fn) { return false } } case *GranteesClause: for _, grantee := range n.Grantees { if !Walk(grantee, fn) { return false } } for _, except := range n.ExceptUsers { if !Walk(except, fn) { return false } } case *WithTimeoutClause: if !Walk(n.Number, fn) { return false } case *DictionarySchemaClause: for _, attr := range n.Attributes { if !Walk(attr, fn) { return false } } case *DictionaryAttribute: if !Walk(n.Name, fn) { return false } if !Walk(n.Type, fn) { return false } if !Walk(n.Default, fn) { return false } if !Walk(n.Expression, fn) { return false } case *DictionaryEngineClause: if !Walk(n.PrimaryKey, fn) { return false } if !Walk(n.Source, fn) { return false } if !Walk(n.Lifetime, fn) { return false } if !Walk(n.Layout, fn) { return false } if !Walk(n.Range, fn) { return false } if !Walk(n.Settings, fn) { return false } case *DictionaryPrimaryKeyClause: if !Walk(n.Keys, fn) { return false } case *DictionarySourceClause: if !Walk(n.Source, fn) { return false } for _, arg := range n.Args { if !Walk(arg, fn) { return false } } case *DictionaryArgExpr: if !Walk(n.Name, fn) { return false } if !Walk(n.Value, fn) { return false } case *DictionaryLifetimeClause: if !Walk(n.Value, fn) { return false } if !Walk(n.Min, fn) { return false } if !Walk(n.Max, fn) { return false } case *DictionaryLayoutClause: if !Walk(n.Layout, fn) { return false } for _, arg := range n.Args { if !Walk(arg, fn) { return false } } case *DictionaryRangeClause: if !Walk(n.Min, fn) { return false } if !Walk(n.Max, fn) { return false } case *PlaceHolder: // Leaf node case *TypedPlaceholder: if !Walk(n.Name, fn) { return false } if !Walk(n.Type, fn) { return false } case *QueryParam: if !Walk(n.Name, fn) { return false } if !Walk(n.Type, fn) { return false } case *MapLiteral: for _, kv := range n.KeyValues { if !Walk(&kv.Key, fn) { return false } if !Walk(kv.Value, fn) { return false } } case *NamedParameterExpr: if !Walk(n.Name, fn) { return false } if !Walk(n.Value, fn) { return false } case *ObjectParams: if !Walk(n.Object, fn) { return false } if !Walk(n.Params, fn) { return false } case *WindowFunctionExpr: if !Walk(n.Function, fn) { return false } if !Walk(n.OverExpr, fn) { return false } case *NotExpr: if !Walk(n.Expr, fn) { return false } case *NegateExpr: if !Walk(n.Expr, fn) { return false } case *GlobalInOperation: if !Walk(n.Expr, fn) { return false } case *ExtractExpr: for _, param := range n.Parameters { if !Walk(param, fn) { return false } } case *IntervalFrom: if !Walk(n.Interval, fn) { return false } if !Walk(n.FromExpr, fn) { return false } case *IsNullExpr: if !Walk(n.Expr, fn) { return false } case *IsNotNullExpr: if !Walk(n.Expr, fn) { return false } case *TernaryOperation: if !Walk(n.Condition, fn) { return false } if !Walk(n.TrueExpr, fn) { return false } if !Walk(n.FalseExpr, fn) { return false } case *IndexOperation: if !Walk(n.Object, fn) { return false } if !Walk(n.Index, fn) { return false } case *OperationExpr: // Leaf node case *TableIndex: if !Walk(n.Name, fn) { return false } if !Walk(n.ColumnExpr, fn) { return false } if !Walk(n.ColumnType, fn) { return false } if !Walk(n.Granularity, fn) { return false } case *ProjectionOrderByClause: if !Walk(n.Columns, fn) { return false } case *ProjectionSelectStmt: if !Walk(n.With, fn) { return false } if !Walk(n.SelectColumns, fn) { return false } if !Walk(n.GroupBy, fn) { return false } if !Walk(n.OrderBy, fn) { return false } case *TableProjection: if !Walk(n.Identifier, fn) { return false } if !Walk(n.Select, fn) { return false } case *RemovePropertyType: if !Walk(n.PropertyType, fn) { return false } case *EnumType: if !Walk(n.Name, fn) { return false } for i := range n.Values { if !Walk(&n.Values[i], fn) { return false } } case *EnumValue: if !Walk(n.Name, fn) { return false } if !Walk(n.Value, fn) { return false } case *ClusterClause: if !Walk(n.Expr, fn) { return false } case *PartitionClause: if !Walk(n.Expr, fn) { return false } if !Walk(n.ID, fn) { return false } case *UUID: if !Walk(n.Value, fn) { return false } case *ColumnTypeExpr: if !Walk(n.Name, fn) { return false } case *UnaryExpr: if !Walk(n.Expr, fn) { return false } case *JoinConstraintClause: if !Walk(n.On, fn) { return false } if !Walk(n.Using, fn) { return false } case *TargetPair: if !Walk(n.Old, fn) { return false } if !Walk(n.New, fn) { return false } case *ShowStmt: if !Walk(n.Target, fn) { return false } if !Walk(n.LikePattern, fn) { return false } if !Walk(n.Limit, fn) { return false } if !Walk(n.OutFile, fn) { return false } if !Walk(n.Format, fn) { return false } case *DescribeStmt: if !Walk(n.Target, fn) { return false } case *DistinctOn: for _, ident := range n.Idents { if !Walk(ident, fn) { return false } } } return true } // WalkWithBreak allows for early termination of tree traversal. // The provided function should return true to continue walking, // or false to stop the traversal entirely. func WalkWithBreak(node Expr, fn WalkFunc) bool { if node == nil { return true } // Call the function first - if it returns false, stop immediately if !fn(node) { return false } // For early termination support, use a helper that converts our function // to one that collects a boolean result var continueWalk = true Walk(node, func(child Expr) bool { // Skip the current node since we already processed it if child == node { return true } // Call our termination-aware function if !fn(child) { continueWalk = false return false } return true }) return continueWalk } // Find searches for the first node matching the given predicate. // Returns the matching node and true if found, or nil and false if not found. func Find(root Expr, predicate func(Expr) bool) (Expr, bool) { var found Expr WalkWithBreak(root, func(node Expr) bool { if predicate(node) { found = node return false // Stop traversal } return true // Continue traversal }) return found, found != nil } // FindAll collects all nodes matching the given predicate. func FindAll(root Expr, predicate func(Expr) bool) []Expr { var matches []Expr Walk(root, func(node Expr) bool { if predicate(node) { matches = append(matches, node) } return true // Always continue traversal }) return matches } // Transform applies a transformation function to all nodes in the tree. // The transformation function receives a node and should return the transformed node. // Note: This modifies the tree in place for mutable fields. func Transform(root Expr, transformer func(Expr) Expr) Expr { transformed := transformer(root) if transformed == nil { return nil } // Apply transformations to children Walk(transformed, func(node Expr) bool { // The actual in-place transformation would need to be implemented // based on the specific needs and mutability of the AST nodes return true }) return transformed } ================================================ FILE: parser/walk_test.go ================================================ package parser import ( "testing" "github.com/stretchr/testify/require" ) func TestWalk_BasicTraversal(t *testing.T) { sql := `SELECT a, COUNT(b) FROM table1 WHERE id > 10 ORDER BY a;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) var nodeCount int Walk(stmts[0], func(node Expr) bool { nodeCount++ return true }) // Verify we visited multiple nodes require.Greater(t, nodeCount, 10, "Should have visited more than 10 nodes") } func TestWalk_JoinExpr(t *testing.T) { sql := `SELECT a, COUNT(b) FROM table1 JOIN table2 ON table1.id = table2.id;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) var onClauses int Walk(stmts[0], func(node Expr) bool { if _, ok := node.(*OnClause); ok { onClauses++ } return true }) require.Equal(t, 1, onClauses, "Should have visited exactly 1 OnClause") } func TestWalkWithBreak_EarlyTermination(t *testing.T) { sql := `SELECT a, COUNT(b) FROM table1 WHERE id > 10 ORDER BY a;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) var nodeCount int result := WalkWithBreak(stmts[0], func(node Expr) bool { nodeCount++ // Stop after visiting 5 nodes return nodeCount < 5 }) require.False(t, result, "WalkWithBreak should return false when terminated early") require.Equal(t, 5, nodeCount, "Should have stopped at exactly 5 nodes") } func TestFind_FirstMatch(t *testing.T) { sql := `SELECT a, COUNT(b) FROM table1 WHERE id > 10;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) // Find the first FunctionExpr found, exists := Find(stmts[0], func(node Expr) bool { _, ok := node.(*FunctionExpr) return ok }) require.True(t, exists, "Should find a FunctionExpr") require.NotNil(t, found) funcExpr, ok := found.(*FunctionExpr) require.True(t, ok, "Found node should be a FunctionExpr") require.Equal(t, "COUNT", Format(funcExpr.Name), "Should find the COUNT function") } func TestFindAll_MultipleMatches(t *testing.T) { sql := `SELECT a, COUNT(b), MAX(c) FROM table1 WHERE id > 10;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) // Find all FunctionExprs functions := FindAll(stmts[0], func(node Expr) bool { _, ok := node.(*FunctionExpr) return ok }) require.Equal(t, 2, len(functions), "Should find 2 function expressions") funcNames := make([]string, len(functions)) for i, fn := range functions { funcExpr := fn.(*FunctionExpr) funcNames[i] = Format(funcExpr.Name) } require.Contains(t, funcNames, "COUNT") require.Contains(t, funcNames, "MAX") } func TestWalk_TableIdentifierRewriting(t *testing.T) { sql := `SELECT a, COUNT(b) FROM group_by_all GROUP BY CUBE(a) WITH CUBE WITH TOTALS ORDER BY a;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) // Rewrite table names Walk(stmts[0], func(node Expr) bool { if tableId, ok := node.(*TableIdentifier); ok { if Format(tableId.Table) == "group_by_all" { tableId.Table = &Ident{Name: "hack"} } } return true }) newSQL := Format(stmts[0]) require.Contains(t, newSQL, "hack", "Table name should be rewritten to 'hack'") require.NotContains(t, newSQL, "group_by_all", "Original table name should be gone") } func TestWalk_OrderByDirectionRewriting(t *testing.T) { sql := `SELECT a, COUNT(b) FROM table1 ORDER BY a ASC, b;` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) // Change all order directions to DESC Walk(stmts[0], func(node Expr) bool { if orderExpr, ok := node.(*OrderExpr); ok { orderExpr.Direction = OrderDirectionDesc } return true }) newSQL := Format(stmts[0]) require.Contains(t, newSQL, string(OrderDirectionDesc), "Should contain DESC direction") } func TestWalk_NestedQueryDepthTracking(t *testing.T) { sql := `SELECT replica_name FROM system.ha_replicas UNION DISTINCT SELECT replica_name FROM system.ha_unique_replicas` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) var tableNames []string Walk(stmts[0], func(node Expr) bool { // Track nesting depth if tableID, ok := node.(*JoinTableExpr); ok { tableName := Format(tableID.Table) tableNames = append(tableNames, tableName+"@depth") } return true }) require.Len(t, tableNames, 2, "Should find 2 table identifiers") } func TestWalk_SimpleNodeCounting(t *testing.T) { sql := `SELECT a FROM table1` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) var nodeCount int Walk(stmts[0], func(node Expr) bool { nodeCount++ return true }) require.Greater(t, nodeCount, 0, "Walk should visit nodes") require.Greater(t, nodeCount, 3, "Should visit at least SELECT, column, table nodes") } func TestFind_NoMatch(t *testing.T) { sql := `SELECT a FROM table1` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) // Try to find a non-existent node type found, exists := Find(stmts[0], func(node Expr) bool { // Look for AlterTable in a SELECT statement (should not exist) _, ok := node.(*AlterTable) return ok }) require.False(t, exists, "Should not find AlterTable in SELECT statement") require.Nil(t, found, "Found node should be nil when not found") } func TestFindAll_EmptyResult(t *testing.T) { sql := `SELECT a FROM table1` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) // Try to find non-existent node types results := FindAll(stmts[0], func(node Expr) bool { // Look for AlterTable in a SELECT statement (should not exist) _, ok := node.(*AlterTable) return ok }) require.Empty(t, results, "Should return empty slice when no matches found") } func TestWalk_ShowStmtNewFields(t *testing.T) { // Test that Walk properly traverses all new fields in ShowStmt sql := `SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON` parser := NewParser(sql) stmts, err := parser.ParseStmts() require.NoError(t, err) require.Equal(t, 1, len(stmts)) _, ok := stmts[0].(*ShowStmt) require.True(t, ok, "Statement should be ShowStmt") // Collect all nodes during walk var foundNodes []Expr Walk(stmts[0], func(node Expr) bool { foundNodes = append(foundNodes, node) return true }) // Should find the ShowStmt itself plus all its expression fields require.Greater(t, len(foundNodes), 4, "Should visit at least ShowStmt + 4 expression fields") // Find specific types of expressions that should be walked var stringLiterals []*StringLiteral var numberLiterals []*NumberLiteral for _, node := range foundNodes { switch n := node.(type) { case *StringLiteral: stringLiterals = append(stringLiterals, n) case *NumberLiteral: numberLiterals = append(numberLiterals, n) } } // Should find exactly 3 string literals: LIKE pattern, OUTFILE path, FORMAT type require.Equal(t, 3, len(stringLiterals), "Should find exactly 3 StringLiteral nodes") // Should find exactly 1 number literal: LIMIT value require.Equal(t, 1, len(numberLiterals), "Should find exactly 1 NumberLiteral node") // Verify the specific values stringValues := make([]string, len(stringLiterals)) for i, sl := range stringLiterals { stringValues[i] = sl.Literal } require.Contains(t, stringValues, "prod%", "Should contain LIKE pattern") require.Contains(t, stringValues, "/tmp/prod_dbs.txt", "Should contain OUTFILE path") require.Contains(t, stringValues, "JSON", "Should contain FORMAT type") require.Equal(t, "5", numberLiterals[0].Literal, "Should contain LIMIT value") }